MsgPackDeserializer.hpp 9.2 KB

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