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