mirror of
				https://github.com/eledio-devices/thirdparty-ArduinoJson.git
				synced 2025-10-31 16:14:11 +01:00 
			
		
		
		
	Remove member MsgPackDeserializer::_error
				
					
				
			This reduces the code size by 54 bytes on AVR.
This commit is contained in:
		| @@ -21,28 +21,26 @@ class MsgPackDeserializer { | ||||
|       : _pool(&pool), | ||||
|         _reader(reader), | ||||
|         _stringStorage(stringStorage), | ||||
|         _error(DeserializationError::Ok), | ||||
|         _foundSomething(false) {} | ||||
|  | ||||
|   template <typename TFilter> | ||||
|   DeserializationError parse(VariantData &variant, TFilter filter, | ||||
|                              NestingLimit nestingLimit) { | ||||
|     parseVariant(&variant, filter, nestingLimit); | ||||
|     return _foundSomething ? _error : DeserializationError::EmptyInput; | ||||
|     DeserializationError::Code err; | ||||
|     err = parseVariant(&variant, filter, nestingLimit); | ||||
|     return _foundSomething ? err : DeserializationError::EmptyInput; | ||||
|   } | ||||
|  | ||||
|  private: | ||||
|   bool invalidInput() { | ||||
|     _error = DeserializationError::InvalidInput; | ||||
|     return false; | ||||
|   } | ||||
|  | ||||
|   template <typename TFilter> | ||||
|   bool parseVariant(VariantData *variant, TFilter filter, | ||||
|                     NestingLimit nestingLimit) { | ||||
|   DeserializationError::Code parseVariant(VariantData *variant, TFilter filter, | ||||
|                                           NestingLimit nestingLimit) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     uint8_t code = 0;  // TODO: why do we need to initialize this variable? | ||||
|     if (!readByte(code)) | ||||
|       return false; | ||||
|     err = readByte(code); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     _foundSomething = true; | ||||
|  | ||||
| @@ -56,20 +54,20 @@ class MsgPackDeserializer { | ||||
|     switch (code) { | ||||
|       case 0xc0: | ||||
|         // already null | ||||
|         return true; | ||||
|         return DeserializationError::Ok; | ||||
|  | ||||
|       case 0xc1: | ||||
|         return invalidInput(); | ||||
|         return DeserializationError::InvalidInput; | ||||
|  | ||||
|       case 0xc2: | ||||
|         if (allowValue) | ||||
|           variant->setBoolean(false); | ||||
|         return true; | ||||
|         return DeserializationError::Ok; | ||||
|  | ||||
|       case 0xc3: | ||||
|         if (allowValue) | ||||
|           variant->setBoolean(true); | ||||
|         return true; | ||||
|         return DeserializationError::Ok; | ||||
|  | ||||
|       case 0xc4:  // bin 8 (not supported) | ||||
|         return skipString<uint8_t>(); | ||||
| @@ -221,157 +219,202 @@ class MsgPackDeserializer { | ||||
|     if (allowValue) | ||||
|       variant->setInteger(static_cast<int8_t>(code)); | ||||
|  | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   bool readByte(uint8_t &value) { | ||||
|   DeserializationError::Code readByte(uint8_t &value) { | ||||
|     int c = _reader.read(); | ||||
|     if (c < 0) { | ||||
|       _error = DeserializationError::IncompleteInput; | ||||
|       return false; | ||||
|     } | ||||
|     if (c < 0) | ||||
|       return DeserializationError::IncompleteInput; | ||||
|     value = static_cast<uint8_t>(c); | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   bool readBytes(uint8_t *p, size_t n) { | ||||
|   DeserializationError::Code readBytes(uint8_t *p, size_t n) { | ||||
|     if (_reader.readBytes(reinterpret_cast<char *>(p), n) == n) | ||||
|       return true; | ||||
|     _error = DeserializationError::IncompleteInput; | ||||
|     return false; | ||||
|       return DeserializationError::Ok; | ||||
|     return DeserializationError::IncompleteInput; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool readBytes(T &value) { | ||||
|   DeserializationError::Code readBytes(T &value) { | ||||
|     return readBytes(reinterpret_cast<uint8_t *>(&value), sizeof(value)); | ||||
|   } | ||||
|  | ||||
|   bool skipBytes(size_t n) { | ||||
|   DeserializationError::Code skipBytes(size_t n) { | ||||
|     for (; n; --n) { | ||||
|       if (_reader.read() < 0) { | ||||
|         _error = DeserializationError::IncompleteInput; | ||||
|         return false; | ||||
|       } | ||||
|       if (_reader.read() < 0) | ||||
|         return DeserializationError::IncompleteInput; | ||||
|     } | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool readInteger(T &value) { | ||||
|     if (!readBytes(value)) | ||||
|       return false; | ||||
|   DeserializationError::Code readInteger(T &value) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     err = readBytes(value); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     fixEndianess(value); | ||||
|     return true; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool readInteger(VariantData *variant) { | ||||
|   DeserializationError::Code readInteger(VariantData *variant) { | ||||
|     DeserializationError::Code err; | ||||
|     T value; | ||||
|     if (!readInteger(value)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(value); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     variant->setInteger(value); | ||||
|     return true; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   typename enable_if<sizeof(T) == 4, bool>::type readFloat( | ||||
|       VariantData *variant) { | ||||
|   typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type | ||||
|   readFloat(VariantData *variant) { | ||||
|     DeserializationError::Code err; | ||||
|     T value; | ||||
|     if (!readBytes(value)) | ||||
|       return false; | ||||
|  | ||||
|     err = readBytes(value); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     fixEndianess(value); | ||||
|     variant->setFloat(value); | ||||
|     return true; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   typename enable_if<sizeof(T) == 8, bool>::type readDouble( | ||||
|       VariantData *variant) { | ||||
|   typename enable_if<sizeof(T) == 8, DeserializationError::Code>::type | ||||
|   readDouble(VariantData *variant) { | ||||
|     DeserializationError::Code err; | ||||
|     T value; | ||||
|     if (!readBytes(value)) | ||||
|       return false; | ||||
|  | ||||
|     err = readBytes(value); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     fixEndianess(value); | ||||
|     variant->setFloat(value); | ||||
|     return true; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   typename enable_if<sizeof(T) == 4, bool>::type readDouble( | ||||
|       VariantData *variant) { | ||||
|   typename enable_if<sizeof(T) == 4, DeserializationError::Code>::type | ||||
|   readDouble(VariantData *variant) { | ||||
|     DeserializationError::Code err; | ||||
|     uint8_t i[8];  // input is 8 bytes | ||||
|     T value;       // output is 4 bytes | ||||
|     uint8_t *o = reinterpret_cast<uint8_t *>(&value); | ||||
|     if (!readBytes(i, 8)) | ||||
|       return false; | ||||
|  | ||||
|     err = readBytes(i, 8); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     doubleToFloat(i, o); | ||||
|     fixEndianess(value); | ||||
|     variant->setFloat(value); | ||||
|     return true; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool readString(VariantData *variant) { | ||||
|   DeserializationError::Code readString(VariantData *variant) { | ||||
|     DeserializationError::Code err; | ||||
|     T size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return readString(variant, size); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool readString() { | ||||
|   DeserializationError::Code readString() { | ||||
|     DeserializationError::Code err; | ||||
|     T size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return readString(size); | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool skipString() { | ||||
|   DeserializationError::Code skipString() { | ||||
|     DeserializationError::Code err; | ||||
|     T size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return skipBytes(size); | ||||
|   } | ||||
|  | ||||
|   bool readString(VariantData *variant, size_t n) { | ||||
|     if (!readString(n)) | ||||
|       return false; | ||||
|   DeserializationError::Code readString(VariantData *variant, size_t n) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     err = readString(n); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     variant->setString(_stringStorage.save()); | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   bool readString(size_t n) { | ||||
|   DeserializationError::Code readString(size_t n) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     _stringStorage.startString(); | ||||
|     for (; n; --n) { | ||||
|       uint8_t c; | ||||
|       if (!readBytes(c)) | ||||
|         return false; | ||||
|  | ||||
|       err = readBytes(c); | ||||
|       if (err) | ||||
|         return err; | ||||
|  | ||||
|       _stringStorage.append(static_cast<char>(c)); | ||||
|     } | ||||
|     if (!_stringStorage.isValid()) { | ||||
|       _error = DeserializationError::NoMemory; | ||||
|       return false; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|     if (!_stringStorage.isValid()) | ||||
|       return DeserializationError::NoMemory; | ||||
|  | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename TSize, typename TFilter> | ||||
|   bool readArray(VariantData *variant, TFilter filter, | ||||
|                  NestingLimit nestingLimit) { | ||||
|   DeserializationError::Code readArray(VariantData *variant, TFilter filter, | ||||
|                                        NestingLimit nestingLimit) { | ||||
|     DeserializationError::Code err; | ||||
|     TSize size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return readArray(variant, size, filter, nestingLimit); | ||||
|   } | ||||
|  | ||||
|   template <typename TFilter> | ||||
|   bool readArray(VariantData *variant, size_t n, TFilter filter, | ||||
|                  NestingLimit nestingLimit) { | ||||
|     if (nestingLimit.reached()) { | ||||
|       _error = DeserializationError::TooDeep; | ||||
|       return false; | ||||
|     } | ||||
|   DeserializationError::Code readArray(VariantData *variant, size_t n, | ||||
|                                        TFilter filter, | ||||
|                                        NestingLimit nestingLimit) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     if (nestingLimit.reached()) | ||||
|       return DeserializationError::TooDeep; | ||||
|  | ||||
|     bool allowArray = filter.allowArray(); | ||||
|  | ||||
| @@ -384,43 +427,48 @@ class MsgPackDeserializer { | ||||
|  | ||||
|       if (memberFilter.allow()) { | ||||
|         value = array->addElement(_pool); | ||||
|         if (!value) { | ||||
|           _error = DeserializationError::NoMemory; | ||||
|           return false; | ||||
|         } | ||||
|         if (!value) | ||||
|           return DeserializationError::NoMemory; | ||||
|       } else { | ||||
|         value = 0; | ||||
|       } | ||||
|  | ||||
|       if (!parseVariant(value, memberFilter, nestingLimit.decrement())) | ||||
|         return false; | ||||
|       err = parseVariant(value, memberFilter, nestingLimit.decrement()); | ||||
|       if (err) | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   template <typename TSize, typename TFilter> | ||||
|   bool readObject(VariantData *variant, TFilter filter, | ||||
|                   NestingLimit nestingLimit) { | ||||
|   DeserializationError::Code readObject(VariantData *variant, TFilter filter, | ||||
|                                         NestingLimit nestingLimit) { | ||||
|     DeserializationError::Code err; | ||||
|     TSize size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return readObject(variant, size, filter, nestingLimit); | ||||
|   } | ||||
|  | ||||
|   template <typename TFilter> | ||||
|   bool readObject(VariantData *variant, size_t n, TFilter filter, | ||||
|                   NestingLimit nestingLimit) { | ||||
|     if (nestingLimit.reached()) { | ||||
|       _error = DeserializationError::TooDeep; | ||||
|       return false; | ||||
|     } | ||||
|   DeserializationError::Code readObject(VariantData *variant, size_t n, | ||||
|                                         TFilter filter, | ||||
|                                         NestingLimit nestingLimit) { | ||||
|     DeserializationError::Code err; | ||||
|  | ||||
|     if (nestingLimit.reached()) | ||||
|       return DeserializationError::TooDeep; | ||||
|  | ||||
|     CollectionData *object = filter.allowObject() ? &variant->toObject() : 0; | ||||
|  | ||||
|     for (; n; --n) { | ||||
|       if (!readKey()) | ||||
|         return false; | ||||
|       err = readKey(); | ||||
|       if (err) | ||||
|         return err; | ||||
|  | ||||
|       String key = _stringStorage.str(); | ||||
|       TFilter memberFilter = filter[key.c_str()]; | ||||
| @@ -434,10 +482,8 @@ class MsgPackDeserializer { | ||||
|         key = _stringStorage.save(); | ||||
|  | ||||
|         VariantSlot *slot = object->addSlot(_pool); | ||||
|         if (!slot) { | ||||
|           _error = DeserializationError::NoMemory; | ||||
|           return false; | ||||
|         } | ||||
|         if (!slot) | ||||
|           return DeserializationError::NoMemory; | ||||
|  | ||||
|         slot->setKey(key); | ||||
|  | ||||
| @@ -446,17 +492,21 @@ class MsgPackDeserializer { | ||||
|         member = 0; | ||||
|       } | ||||
|  | ||||
|       if (!parseVariant(member, memberFilter, nestingLimit.decrement())) | ||||
|         return false; | ||||
|       err = parseVariant(member, memberFilter, nestingLimit.decrement()); | ||||
|       if (err) | ||||
|         return err; | ||||
|     } | ||||
|  | ||||
|     return true; | ||||
|     return DeserializationError::Ok; | ||||
|   } | ||||
|  | ||||
|   bool readKey() { | ||||
|   DeserializationError::Code readKey() { | ||||
|     DeserializationError::Code err; | ||||
|     uint8_t code; | ||||
|     if (!readByte(code)) | ||||
|       return false; | ||||
|  | ||||
|     err = readByte(code); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     if ((code & 0xe0) == 0xa0) | ||||
|       return readString(code & 0x1f); | ||||
| @@ -472,22 +522,25 @@ class MsgPackDeserializer { | ||||
|         return readString<uint32_t>(); | ||||
|  | ||||
|       default: | ||||
|         return invalidInput(); | ||||
|         return DeserializationError::InvalidInput; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   template <typename T> | ||||
|   bool skipExt() { | ||||
|   DeserializationError::Code skipExt() { | ||||
|     DeserializationError::Code err; | ||||
|     T size; | ||||
|     if (!readInteger(size)) | ||||
|       return false; | ||||
|  | ||||
|     err = readInteger(size); | ||||
|     if (err) | ||||
|       return err; | ||||
|  | ||||
|     return skipBytes(size + 1U); | ||||
|   } | ||||
|  | ||||
|   MemoryPool *_pool; | ||||
|   TReader _reader; | ||||
|   TStringStorage _stringStorage; | ||||
|   DeserializationError _error; | ||||
|   bool _foundSomething; | ||||
| }; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user