MsgPackDeserializer.hpp 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. // ArduinoJson - arduinojson.org
  2. // Copyright Benoit Blanchon 2014-2019
  3. // MIT License
  4. #pragma once
  5. #include "../Deserialization/deserialize.hpp"
  6. #include "../Memory/MemoryPool.hpp"
  7. #include "../Polyfills/type_traits.hpp"
  8. #include "../Variant/VariantData.hpp"
  9. #include "endianess.hpp"
  10. #include "ieee754.hpp"
  11. namespace ARDUINOJSON_NAMESPACE {
  12. template <typename TReader, typename TStringStorage>
  13. class MsgPackDeserializer {
  14. typedef typename remove_reference<TStringStorage>::type::StringBuilder
  15. StringBuilder;
  16. typedef const char *StringType;
  17. public:
  18. MsgPackDeserializer(MemoryPool &pool, TReader reader,
  19. TStringStorage stringStorage, uint8_t nestingLimit)
  20. : _pool(&pool),
  21. _reader(reader),
  22. _stringStorage(stringStorage),
  23. _nestingLimit(nestingLimit) {}
  24. DeserializationError parse(VariantData &variant) {
  25. uint8_t code;
  26. if (!readByte(code)) return DeserializationError::IncompleteInput;
  27. if ((code & 0x80) == 0) {
  28. variant.setUnsignedInteger(code);
  29. return DeserializationError::Ok;
  30. }
  31. if ((code & 0xe0) == 0xe0) {
  32. // TODO: add setNegativeInteger()
  33. variant.setSignedInteger(static_cast<int8_t>(code));
  34. return DeserializationError::Ok;
  35. }
  36. if ((code & 0xe0) == 0xa0) {
  37. return readString(variant, code & 0x1f);
  38. }
  39. if ((code & 0xf0) == 0x90) {
  40. return readArray(variant.toArray(), code & 0x0F);
  41. }
  42. if ((code & 0xf0) == 0x80) {
  43. return readObject(variant.toObject(), code & 0x0F);
  44. }
  45. switch (code) {
  46. case 0xc0:
  47. // already null
  48. return DeserializationError::Ok;
  49. case 0xc2:
  50. variant.setBoolean(false);
  51. return DeserializationError::Ok;
  52. case 0xc3:
  53. variant.setBoolean(true);
  54. return DeserializationError::Ok;
  55. case 0xcc:
  56. return readInteger<uint8_t>(variant);
  57. case 0xcd:
  58. return readInteger<uint16_t>(variant);
  59. case 0xce:
  60. return readInteger<uint32_t>(variant);
  61. case 0xcf:
  62. #if ARDUINOJSON_USE_LONG_LONG
  63. return readInteger<uint64_t>(variant);
  64. #else
  65. readInteger<uint32_t>();
  66. return readInteger<uint32_t>(variant);
  67. #endif
  68. case 0xd0:
  69. return readInteger<int8_t>(variant);
  70. case 0xd1:
  71. return readInteger<int16_t>(variant);
  72. case 0xd2:
  73. return readInteger<int32_t>(variant);
  74. case 0xd3:
  75. #if ARDUINOJSON_USE_LONG_LONG
  76. return readInteger<int64_t>(variant);
  77. #else
  78. if (!skip(4)) return DeserializationError::IncompleteInput;
  79. return readInteger<int32_t>(variant);
  80. #endif
  81. case 0xca:
  82. return readFloat<float>(variant);
  83. case 0xcb:
  84. return readDouble<double>(variant);
  85. case 0xd9:
  86. return readString<uint8_t>(variant);
  87. case 0xda:
  88. return readString<uint16_t>(variant);
  89. case 0xdb:
  90. return readString<uint32_t>(variant);
  91. case 0xdc:
  92. return readArray<uint16_t>(variant.toArray());
  93. case 0xdd:
  94. return readArray<uint32_t>(variant.toArray());
  95. case 0xde:
  96. return readObject<uint16_t>(variant.toObject());
  97. case 0xdf:
  98. return readObject<uint32_t>(variant.toObject());
  99. default:
  100. return DeserializationError::NotSupported;
  101. }
  102. }
  103. private:
  104. // Prevent VS warning "assignment operator could not be generated"
  105. MsgPackDeserializer &operator=(const MsgPackDeserializer &);
  106. bool skip(uint8_t n) {
  107. while (n--) {
  108. if (_reader.ended()) return false;
  109. _reader.read();
  110. }
  111. return true;
  112. }
  113. bool readByte(uint8_t &value) {
  114. if (_reader.ended()) return false;
  115. value = static_cast<uint8_t>(_reader.read());
  116. return true;
  117. }
  118. bool readBytes(uint8_t *p, size_t n) {
  119. for (size_t i = 0; i < n; i++) {
  120. if (!readByte(p[i])) return false;
  121. }
  122. return true;
  123. }
  124. template <typename T>
  125. bool readBytes(T &value) {
  126. return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value));
  127. }
  128. template <typename T>
  129. T readInteger() {
  130. T value;
  131. readBytes(value);
  132. fixEndianess(value);
  133. return value;
  134. }
  135. template <typename T>
  136. bool readInteger(T &value) {
  137. if (!readBytes(value)) return false;
  138. fixEndianess(value);
  139. return true;
  140. }
  141. template <typename T>
  142. DeserializationError readInteger(VariantData &variant) {
  143. T value;
  144. if (!readInteger(value)) return DeserializationError::IncompleteInput;
  145. variant.setInteger(value);
  146. return DeserializationError::Ok;
  147. }
  148. template <typename T>
  149. typename enable_if<sizeof(T) == 4, DeserializationError>::type readFloat(
  150. VariantData &variant) {
  151. T value;
  152. if (!readBytes(value)) return DeserializationError::IncompleteInput;
  153. fixEndianess(value);
  154. variant.setFloat(value);
  155. return DeserializationError::Ok;
  156. }
  157. template <typename T>
  158. typename enable_if<sizeof(T) == 8, DeserializationError>::type readDouble(
  159. VariantData &variant) {
  160. T value;
  161. if (!readBytes(value)) return DeserializationError::IncompleteInput;
  162. fixEndianess(value);
  163. variant.setFloat(value);
  164. return DeserializationError::Ok;
  165. }
  166. template <typename T>
  167. typename enable_if<sizeof(T) == 4, DeserializationError>::type readDouble(
  168. VariantData &variant) {
  169. uint8_t i[8]; // input is 8 bytes
  170. T value; // output is 4 bytes
  171. uint8_t *o = reinterpret_cast<uint8_t *>(&value);
  172. if (!readBytes(i, 8)) return DeserializationError::IncompleteInput;
  173. doubleToFloat(i, o);
  174. fixEndianess(value);
  175. variant.setFloat(value);
  176. return DeserializationError::Ok;
  177. }
  178. template <typename T>
  179. DeserializationError readString(VariantData &variant) {
  180. T size;
  181. if (!readInteger(size)) return DeserializationError::IncompleteInput;
  182. return readString(variant, size);
  183. }
  184. template <typename T>
  185. DeserializationError readString(StringType &str) {
  186. T size;
  187. if (!readInteger(size)) return DeserializationError::IncompleteInput;
  188. return readString(str, size);
  189. }
  190. DeserializationError readString(VariantData &variant, size_t n) {
  191. StringType s;
  192. DeserializationError err = readString(s, n);
  193. if (!err) variant.setOwnedString(s);
  194. return err;
  195. }
  196. DeserializationError readString(StringType &result, size_t n) {
  197. StringBuilder builder = _stringStorage.startString();
  198. for (; n; --n) {
  199. uint8_t c;
  200. if (!readBytes(c)) return DeserializationError::IncompleteInput;
  201. builder.append(static_cast<char>(c));
  202. }
  203. result = builder.complete();
  204. if (!result) return DeserializationError::NoMemory;
  205. return DeserializationError::Ok;
  206. }
  207. template <typename TSize>
  208. DeserializationError readArray(CollectionData &array) {
  209. TSize size;
  210. if (!readInteger(size)) return DeserializationError::IncompleteInput;
  211. return readArray(array, size);
  212. }
  213. DeserializationError readArray(CollectionData &array, size_t n) {
  214. if (_nestingLimit == 0) return DeserializationError::TooDeep;
  215. --_nestingLimit;
  216. for (; n; --n) {
  217. VariantData *value = array.add(_pool);
  218. if (!value) return DeserializationError::NoMemory;
  219. DeserializationError err = parse(*value);
  220. if (err) return err;
  221. }
  222. ++_nestingLimit;
  223. return DeserializationError::Ok;
  224. }
  225. template <typename TSize>
  226. DeserializationError readObject(CollectionData &object) {
  227. TSize size;
  228. if (!readInteger(size)) return DeserializationError::IncompleteInput;
  229. return readObject(object, size);
  230. }
  231. DeserializationError readObject(CollectionData &object, size_t n) {
  232. if (_nestingLimit == 0) return DeserializationError::TooDeep;
  233. --_nestingLimit;
  234. for (; n; --n) {
  235. VariantSlot *slot = object.addSlot(_pool);
  236. if (!slot) return DeserializationError::NoMemory;
  237. StringType key;
  238. DeserializationError err = parseKey(key);
  239. if (err) return err;
  240. slot->setOwnedKey(key);
  241. err = parse(*slot->data());
  242. if (err) return err;
  243. }
  244. ++_nestingLimit;
  245. return DeserializationError::Ok;
  246. }
  247. DeserializationError parseKey(StringType &key) {
  248. uint8_t code;
  249. if (!readByte(code)) return DeserializationError::IncompleteInput;
  250. if ((code & 0xe0) == 0xa0) return readString(key, code & 0x1f);
  251. switch (code) {
  252. case 0xd9:
  253. return readString<uint8_t>(key);
  254. case 0xda:
  255. return readString<uint16_t>(key);
  256. case 0xdb:
  257. return readString<uint32_t>(key);
  258. default:
  259. return DeserializationError::NotSupported;
  260. }
  261. }
  262. MemoryPool *_pool;
  263. TReader _reader;
  264. TStringStorage _stringStorage;
  265. uint8_t _nestingLimit;
  266. };
  267. template <typename TInput>
  268. DeserializationError deserializeMsgPack(
  269. JsonDocument &doc, const TInput &input,
  270. NestingLimit nestingLimit = NestingLimit()) {
  271. return deserialize<MsgPackDeserializer>(doc, input, nestingLimit);
  272. }
  273. template <typename TInput>
  274. DeserializationError deserializeMsgPack(
  275. JsonDocument &doc, TInput *input,
  276. NestingLimit nestingLimit = NestingLimit()) {
  277. return deserialize<MsgPackDeserializer>(doc, input, nestingLimit);
  278. }
  279. template <typename TInput>
  280. DeserializationError deserializeMsgPack(
  281. JsonDocument &doc, TInput *input, size_t inputSize,
  282. NestingLimit nestingLimit = NestingLimit()) {
  283. return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit);
  284. }
  285. template <typename TInput>
  286. DeserializationError deserializeMsgPack(
  287. JsonDocument &doc, TInput &input,
  288. NestingLimit nestingLimit = NestingLimit()) {
  289. return deserialize<MsgPackDeserializer>(doc, input, nestingLimit);
  290. }
  291. } // namespace ARDUINOJSON_NAMESPACE