Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
MsgPackDeserializer.hpp
00001 // ArduinoJson - arduinojson.org 00002 // Copyright Benoit Blanchon 2014-2021 00003 // MIT License 00004 00005 #pragma once 00006 00007 #include <ArduinoJson/Deserialization/deserialize.hpp> 00008 #include <ArduinoJson/Memory/MemoryPool.hpp> 00009 #include <ArduinoJson/MsgPack/endianess.hpp> 00010 #include <ArduinoJson/MsgPack/ieee754.hpp> 00011 #include <ArduinoJson/Polyfills/type_traits.hpp> 00012 #include <ArduinoJson/Variant/VariantData.hpp> 00013 00014 namespace ARDUINOJSON_NAMESPACE { 00015 00016 template <typename TReader, typename TStringStorage> 00017 class MsgPackDeserializer { 00018 public: 00019 MsgPackDeserializer(MemoryPool &pool, TReader reader, 00020 TStringStorage stringStorage) 00021 : _pool(&pool), 00022 _reader(reader), 00023 _stringStorage(stringStorage), 00024 _error(DeserializationError::Ok), 00025 _foundSomething(false) {} 00026 00027 template <typename TFilter> 00028 DeserializationError parse(VariantData &variant, TFilter filter, 00029 NestingLimit nestingLimit) { 00030 parseVariant(variant, filter, nestingLimit); 00031 return _foundSomething ? _error : DeserializationError::EmptyInput; 00032 } 00033 00034 private: 00035 // Prevent VS warning "assignment operator could not be generated" 00036 MsgPackDeserializer &operator=(const MsgPackDeserializer &); 00037 00038 bool invalidInput() { 00039 _error = DeserializationError::InvalidInput; 00040 return false; 00041 } 00042 00043 bool notSupported() { 00044 _error = DeserializationError::NotSupported; 00045 return false; 00046 } 00047 00048 template <typename TFilter> 00049 bool parseVariant(VariantData &variant, TFilter filter, 00050 NestingLimit nestingLimit) { 00051 uint8_t code = 0; // TODO: why do we need to initialize this variable? 00052 if (!readByte(code)) 00053 return false; 00054 00055 _foundSomething = true; 00056 00057 bool allowValue = filter.allowValue(); 00058 00059 switch (code) { 00060 case 0xc0: 00061 // already null 00062 return true; 00063 00064 case 0xc1: 00065 return invalidInput(); 00066 00067 case 0xc2: 00068 if (allowValue) 00069 variant.setBoolean(false); 00070 return true; 00071 00072 case 0xc3: 00073 if (allowValue) 00074 variant.setBoolean(true); 00075 return true; 00076 00077 case 0xc4: // bin 8 00078 if (allowValue) 00079 return notSupported(); 00080 else 00081 return skipString<uint8_t>(); 00082 00083 case 0xc5: // bin 16 00084 if (allowValue) 00085 return notSupported(); 00086 else 00087 return skipString<uint16_t>(); 00088 00089 case 0xc6: // bin 32 00090 if (allowValue) 00091 return notSupported(); 00092 else 00093 return skipString<uint32_t>(); 00094 00095 case 0xc7: // ext 8 00096 if (allowValue) 00097 return notSupported(); 00098 else 00099 return skipExt<uint8_t>(); 00100 00101 case 0xc8: // ext 16 00102 if (allowValue) 00103 return notSupported(); 00104 else 00105 return skipExt<uint16_t>(); 00106 00107 case 0xc9: // ext 32 00108 if (allowValue) 00109 return notSupported(); 00110 else 00111 return skipExt<uint32_t>(); 00112 00113 case 0xca: 00114 if (allowValue) 00115 return readFloat<float>(variant); 00116 else 00117 return skipBytes(4); 00118 00119 case 0xcb: 00120 if (allowValue) 00121 return readDouble<double>(variant); 00122 else 00123 return skipBytes(8); 00124 00125 case 0xcc: 00126 if (allowValue) 00127 return readInteger<uint8_t>(variant); 00128 else 00129 return skipBytes(1); 00130 00131 case 0xcd: 00132 if (allowValue) 00133 return readInteger<uint16_t>(variant); 00134 else 00135 return skipBytes(2); 00136 00137 case 0xce: 00138 if (allowValue) 00139 return readInteger<uint32_t>(variant); 00140 else 00141 return skipBytes(4); 00142 00143 case 0xcf: 00144 if (allowValue) 00145 #if ARDUINOJSON_USE_LONG_LONG 00146 return readInteger<uint64_t>(variant); 00147 #else 00148 return notSupported(); 00149 #endif 00150 else 00151 return skipBytes(8); 00152 00153 case 0xd0: 00154 if (allowValue) 00155 return readInteger<int8_t>(variant); 00156 else 00157 return skipBytes(1); 00158 00159 case 0xd1: 00160 if (allowValue) 00161 return readInteger<int16_t>(variant); 00162 else 00163 return skipBytes(2); 00164 00165 case 0xd2: 00166 if (allowValue) 00167 return readInteger<int32_t>(variant); 00168 else 00169 return skipBytes(4); 00170 00171 case 0xd3: 00172 if (allowValue) 00173 #if ARDUINOJSON_USE_LONG_LONG 00174 return readInteger<int64_t>(variant); 00175 #else 00176 return notSupported(); 00177 #endif 00178 else 00179 return skipBytes(8); 00180 00181 case 0xd4: // fixext 1 00182 if (allowValue) 00183 return notSupported(); 00184 else 00185 return skipBytes(2); 00186 00187 case 0xd5: // fixext 2 00188 if (allowValue) 00189 return notSupported(); 00190 else 00191 return skipBytes(3); 00192 00193 case 0xd6: // fixext 4 00194 if (allowValue) 00195 return notSupported(); 00196 else 00197 return skipBytes(5); 00198 00199 case 0xd7: // fixext 8 00200 if (allowValue) 00201 return notSupported(); 00202 else 00203 return skipBytes(9); 00204 00205 case 0xd8: // fixext 16 00206 if (allowValue) 00207 return notSupported(); 00208 else 00209 return skipBytes(17); 00210 00211 case 0xd9: 00212 if (allowValue) 00213 return readString<uint8_t>(variant); 00214 else 00215 return skipString<uint8_t>(); 00216 00217 case 0xda: 00218 if (allowValue) 00219 return readString<uint16_t>(variant); 00220 else 00221 return skipString<uint16_t>(); 00222 00223 case 0xdb: 00224 if (allowValue) 00225 return readString<uint32_t>(variant); 00226 else 00227 return skipString<uint32_t>(); 00228 00229 case 0xdc: 00230 return readArray<uint16_t>(variant, filter, nestingLimit); 00231 00232 case 0xdd: 00233 return readArray<uint32_t>(variant, filter, nestingLimit); 00234 00235 case 0xde: 00236 return readObject<uint16_t>(variant, filter, nestingLimit); 00237 00238 case 0xdf: 00239 return readObject<uint32_t>(variant, filter, nestingLimit); 00240 } 00241 00242 switch (code & 0xf0) { 00243 case 0x80: 00244 return readObject(variant, code & 0x0F, filter, nestingLimit); 00245 00246 case 0x90: 00247 return readArray(variant, code & 0x0F, filter, nestingLimit); 00248 } 00249 00250 if ((code & 0xe0) == 0xa0) { 00251 if (allowValue) 00252 return readString(variant, code & 0x1f); 00253 else 00254 return skipBytes(code & 0x1f); 00255 } 00256 00257 if (allowValue) 00258 variant.setInteger(static_cast<int8_t>(code)); 00259 00260 return true; 00261 } 00262 00263 bool readByte(uint8_t &value) { 00264 int c = _reader.read(); 00265 if (c < 0) { 00266 _error = DeserializationError::IncompleteInput; 00267 return false; 00268 } 00269 value = static_cast<uint8_t>(c); 00270 return true; 00271 } 00272 00273 bool readBytes(uint8_t *p, size_t n) { 00274 if (_reader.readBytes(reinterpret_cast<char *>(p), n) == n) 00275 return true; 00276 _error = DeserializationError::IncompleteInput; 00277 return false; 00278 } 00279 00280 template <typename T> 00281 bool readBytes(T &value) { 00282 return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value)); 00283 } 00284 00285 bool skipBytes(size_t n) { 00286 for (; n; --n) { 00287 if (_reader.read() < 0) { 00288 _error = DeserializationError::IncompleteInput; 00289 return false; 00290 } 00291 } 00292 return true; 00293 } 00294 00295 template <typename T> 00296 bool readInteger(T &value) { 00297 if (!readBytes(value)) 00298 return false; 00299 fixEndianess(value); 00300 return true; 00301 } 00302 00303 template <typename T> 00304 bool readInteger(VariantData &variant) { 00305 T value; 00306 if (!readInteger(value)) 00307 return false; 00308 variant.setInteger(value); 00309 return true; 00310 } 00311 00312 template <typename T> 00313 typename enable_if<sizeof(T) == 4, bool>::type readFloat( 00314 VariantData &variant) { 00315 T value; 00316 if (!readBytes(value)) 00317 return false; 00318 fixEndianess(value); 00319 variant.setFloat(value); 00320 return true; 00321 } 00322 00323 template <typename T> 00324 typename enable_if<sizeof(T) == 8, bool>::type readDouble( 00325 VariantData &variant) { 00326 T value; 00327 if (!readBytes(value)) 00328 return false; 00329 fixEndianess(value); 00330 variant.setFloat(value); 00331 return true; 00332 } 00333 00334 template <typename T> 00335 typename enable_if<sizeof(T) == 4, bool>::type readDouble( 00336 VariantData &variant) { 00337 uint8_t i[8]; // input is 8 bytes 00338 T value; // output is 4 bytes 00339 uint8_t *o = reinterpret_cast<uint8_t *>(&value); 00340 if (!readBytes(i, 8)) 00341 return false; 00342 doubleToFloat(i, o); 00343 fixEndianess(value); 00344 variant.setFloat(value); 00345 return true; 00346 } 00347 00348 template <typename T> 00349 bool readString(VariantData &variant) { 00350 T size; 00351 if (!readInteger(size)) 00352 return false; 00353 return readString(variant, size); 00354 } 00355 00356 template <typename T> 00357 bool readString() { 00358 T size; 00359 if (!readInteger(size)) 00360 return false; 00361 return readString(size); 00362 } 00363 00364 template <typename T> 00365 bool skipString() { 00366 T size; 00367 if (!readInteger(size)) 00368 return false; 00369 return skipBytes(size); 00370 } 00371 00372 bool readString(VariantData &variant, size_t n) { 00373 if (!readString(n)) 00374 return false; 00375 variant.setStringPointer(_stringStorage.save(), 00376 typename TStringStorage::storage_policy()); 00377 return true; 00378 } 00379 00380 bool readString(size_t n) { 00381 _stringStorage.startString(); 00382 for (; n; --n) { 00383 uint8_t c; 00384 if (!readBytes(c)) 00385 return false; 00386 _stringStorage.append(static_cast<char>(c)); 00387 } 00388 _stringStorage.append('\0'); 00389 if (!_stringStorage.isValid()) { 00390 _error = DeserializationError::NoMemory; 00391 return false; 00392 } 00393 00394 return true; 00395 } 00396 00397 template <typename TSize, typename TFilter> 00398 bool readArray(VariantData &variant, TFilter filter, 00399 NestingLimit nestingLimit) { 00400 TSize size; 00401 if (!readInteger(size)) 00402 return false; 00403 return readArray(variant, size, filter, nestingLimit); 00404 } 00405 00406 template <typename TFilter> 00407 bool readArray(VariantData &variant, size_t n, TFilter filter, 00408 NestingLimit nestingLimit) { 00409 if (nestingLimit.reached()) { 00410 _error = DeserializationError::TooDeep; 00411 return false; 00412 } 00413 00414 bool allowArray = filter.allowArray(); 00415 00416 CollectionData *array = allowArray ? &variant.toArray() : 0; 00417 00418 TFilter memberFilter = filter[0U]; 00419 00420 for (; n; --n) { 00421 VariantData *value; 00422 00423 if (memberFilter.allow()) { 00424 value = array->addElement(_pool); 00425 if (!value) { 00426 _error = DeserializationError::NoMemory; 00427 return false; 00428 } 00429 } else { 00430 value = 0; 00431 } 00432 00433 if (!parseVariant(*value, memberFilter, nestingLimit.decrement())) 00434 return false; 00435 } 00436 00437 return true; 00438 } 00439 00440 template <typename TSize, typename TFilter> 00441 bool readObject(VariantData &variant, TFilter filter, 00442 NestingLimit nestingLimit) { 00443 TSize size; 00444 if (!readInteger(size)) 00445 return false; 00446 return readObject(variant, size, filter, nestingLimit); 00447 } 00448 00449 template <typename TFilter> 00450 bool readObject(VariantData &variant, size_t n, TFilter filter, 00451 NestingLimit nestingLimit) { 00452 if (nestingLimit.reached()) { 00453 _error = DeserializationError::TooDeep; 00454 return false; 00455 } 00456 00457 CollectionData *object = filter.allowObject() ? &variant.toObject() : 0; 00458 00459 for (; n; --n) { 00460 if (!readKey()) 00461 return false; 00462 00463 const char *key = _stringStorage.c_str(); 00464 TFilter memberFilter = filter[key]; 00465 VariantData *member; 00466 00467 if (memberFilter.allow()) { 00468 // Save key in memory pool. 00469 // This MUST be done before adding the slot. 00470 key = _stringStorage.save(); 00471 00472 VariantSlot *slot = object->addSlot(_pool); 00473 if (!slot) { 00474 _error = DeserializationError::NoMemory; 00475 return false; 00476 } 00477 00478 slot->setKey(key, typename TStringStorage::storage_policy()); 00479 00480 member = slot->data(); 00481 } else { 00482 member = 0; 00483 } 00484 00485 if (!parseVariant(*member, memberFilter, nestingLimit.decrement())) 00486 return false; 00487 } 00488 00489 return true; 00490 } 00491 00492 bool readKey() { 00493 uint8_t code; 00494 if (!readByte(code)) 00495 return false; 00496 00497 if ((code & 0xe0) == 0xa0) 00498 return readString(code & 0x1f); 00499 00500 switch (code) { 00501 case 0xd9: 00502 return readString<uint8_t>(); 00503 00504 case 0xda: 00505 return readString<uint16_t>(); 00506 00507 case 0xdb: 00508 return readString<uint32_t>(); 00509 00510 default: 00511 return notSupported(); 00512 } 00513 } 00514 00515 template <typename T> 00516 bool skipExt() { 00517 T size; 00518 if (!readInteger(size)) 00519 return false; 00520 return skipBytes(size + 1); 00521 } 00522 00523 MemoryPool *_pool; 00524 TReader _reader; 00525 TStringStorage _stringStorage; 00526 DeserializationError _error; 00527 bool _foundSomething; 00528 }; 00529 00530 // 00531 // deserializeMsgPack(JsonDocument&, const std::string&, ...) 00532 // 00533 // ... = NestingLimit 00534 template <typename TString> 00535 DeserializationError deserializeMsgPack( 00536 JsonDocument &doc, const TString &input, 00537 NestingLimit nestingLimit = NestingLimit()) { 00538 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, 00539 AllowAllFilter()); 00540 } 00541 // ... = Filter, NestingLimit 00542 template <typename TString> 00543 DeserializationError deserializeMsgPack( 00544 JsonDocument &doc, const TString &input, Filter filter, 00545 NestingLimit nestingLimit = NestingLimit()) { 00546 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00547 } 00548 // ... = NestingLimit, Filter 00549 template <typename TString> 00550 DeserializationError deserializeMsgPack(JsonDocument &doc, const TString &input, 00551 NestingLimit nestingLimit, 00552 Filter filter) { 00553 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00554 } 00555 00556 // 00557 // deserializeMsgPack(JsonDocument&, std::istream&, ...) 00558 // 00559 // ... = NestingLimit 00560 template <typename TStream> 00561 DeserializationError deserializeMsgPack( 00562 JsonDocument &doc, TStream &input, 00563 NestingLimit nestingLimit = NestingLimit()) { 00564 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, 00565 AllowAllFilter()); 00566 } 00567 // ... = Filter, NestingLimit 00568 template <typename TStream> 00569 DeserializationError deserializeMsgPack( 00570 JsonDocument &doc, TStream &input, Filter filter, 00571 NestingLimit nestingLimit = NestingLimit()) { 00572 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00573 } 00574 // ... = NestingLimit, Filter 00575 template <typename TStream> 00576 DeserializationError deserializeMsgPack(JsonDocument &doc, TStream &input, 00577 NestingLimit nestingLimit, 00578 Filter filter) { 00579 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00580 } 00581 00582 // 00583 // deserializeMsgPack(JsonDocument&, char*, ...) 00584 // 00585 // ... = NestingLimit 00586 template <typename TChar> 00587 DeserializationError deserializeMsgPack( 00588 JsonDocument &doc, TChar *input, 00589 NestingLimit nestingLimit = NestingLimit()) { 00590 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, 00591 AllowAllFilter()); 00592 } 00593 // ... = Filter, NestingLimit 00594 template <typename TChar> 00595 DeserializationError deserializeMsgPack( 00596 JsonDocument &doc, TChar *input, Filter filter, 00597 NestingLimit nestingLimit = NestingLimit()) { 00598 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00599 } 00600 // ... = NestingLimit, Filter 00601 template <typename TChar> 00602 DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input, 00603 NestingLimit nestingLimit, 00604 Filter filter) { 00605 return deserialize<MsgPackDeserializer>(doc, input, nestingLimit, filter); 00606 } 00607 00608 // 00609 // deserializeMsgPack(JsonDocument&, char*, size_t, ...) 00610 // 00611 // ... = NestingLimit 00612 template <typename TChar> 00613 DeserializationError deserializeMsgPack( 00614 JsonDocument &doc, TChar *input, size_t inputSize, 00615 NestingLimit nestingLimit = NestingLimit()) { 00616 return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, 00617 AllowAllFilter()); 00618 } 00619 // ... = Filter, NestingLimit 00620 template <typename TChar> 00621 DeserializationError deserializeMsgPack( 00622 JsonDocument &doc, TChar *input, size_t inputSize, Filter filter, 00623 NestingLimit nestingLimit = NestingLimit()) { 00624 return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, 00625 filter); 00626 } 00627 // ... = NestingLimit, Filter 00628 template <typename TChar> 00629 DeserializationError deserializeMsgPack(JsonDocument &doc, TChar *input, 00630 size_t inputSize, 00631 NestingLimit nestingLimit, 00632 Filter filter) { 00633 return deserialize<MsgPackDeserializer>(doc, input, inputSize, nestingLimit, 00634 filter); 00635 } 00636 00637 } // namespace ARDUINOJSON_NAMESPACE
Generated on Wed Jul 13 2022 01:10:36 by
1.7.2