mirror of
https://github.com/eledio-devices/thirdparty-ArduinoJson.git
synced 2025-11-01 08:48:30 +01:00
Extracted VariantData and CollectionData classes
This commit is contained in:
@@ -7,7 +7,7 @@
|
||||
#include "../Deserialization/deserialize.hpp"
|
||||
#include "../Memory/MemoryPool.hpp"
|
||||
#include "../Polyfills/type_traits.hpp"
|
||||
#include "../Variant/VariantRef.hpp"
|
||||
#include "../Variant/VariantData.hpp"
|
||||
#include "endianess.hpp"
|
||||
#include "ieee754.hpp"
|
||||
|
||||
@@ -17,27 +17,28 @@ template <typename TReader, typename TStringStorage>
|
||||
class MsgPackDeserializer {
|
||||
typedef typename remove_reference<TStringStorage>::type::StringBuilder
|
||||
StringBuilder;
|
||||
typedef typename StringBuilder::StringType StringType;
|
||||
typedef const char *StringType;
|
||||
|
||||
public:
|
||||
MsgPackDeserializer(MemoryPool &memoryPool, TReader reader,
|
||||
MsgPackDeserializer(MemoryPool &pool, TReader reader,
|
||||
TStringStorage stringStorage, uint8_t nestingLimit)
|
||||
: _memoryPool(&memoryPool),
|
||||
: _pool(&pool),
|
||||
_reader(reader),
|
||||
_stringStorage(stringStorage),
|
||||
_nestingLimit(nestingLimit) {}
|
||||
|
||||
DeserializationError parse(VariantRef variant) {
|
||||
DeserializationError parse(VariantData &variant) {
|
||||
uint8_t code;
|
||||
if (!readByte(code)) return DeserializationError::IncompleteInput;
|
||||
|
||||
if ((code & 0x80) == 0) {
|
||||
variant.set(code);
|
||||
variant.setUnsignedInteger(code);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
if ((code & 0xe0) == 0xe0) {
|
||||
variant.set(static_cast<int8_t>(code));
|
||||
// TODO: add setNegativeInteger()
|
||||
variant.setSignedInteger(static_cast<int8_t>(code));
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
@@ -45,9 +46,13 @@ class MsgPackDeserializer {
|
||||
return readString(variant, code & 0x1f);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x90) return readArray(variant, code & 0x0F);
|
||||
if ((code & 0xf0) == 0x90) {
|
||||
return readArray(variant.toArray(), code & 0x0F);
|
||||
}
|
||||
|
||||
if ((code & 0xf0) == 0x80) return readObject(variant, code & 0x0F);
|
||||
if ((code & 0xf0) == 0x80) {
|
||||
return readObject(variant.toObject(), code & 0x0F);
|
||||
}
|
||||
|
||||
switch (code) {
|
||||
case 0xc0:
|
||||
@@ -55,11 +60,11 @@ class MsgPackDeserializer {
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc2:
|
||||
variant.set(false);
|
||||
variant.setBoolean(false);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xc3:
|
||||
variant.set(true);
|
||||
variant.setBoolean(true);
|
||||
return DeserializationError::Ok;
|
||||
|
||||
case 0xcc:
|
||||
@@ -112,16 +117,16 @@ class MsgPackDeserializer {
|
||||
return readString<uint32_t>(variant);
|
||||
|
||||
case 0xdc:
|
||||
return readArray<uint16_t>(variant);
|
||||
return readArray<uint16_t>(variant.toArray());
|
||||
|
||||
case 0xdd:
|
||||
return readArray<uint32_t>(variant);
|
||||
return readArray<uint32_t>(variant.toArray());
|
||||
|
||||
case 0xde:
|
||||
return readObject<uint16_t>(variant);
|
||||
return readObject<uint16_t>(variant.toObject());
|
||||
|
||||
case 0xdf:
|
||||
return readObject<uint32_t>(variant);
|
||||
return readObject<uint32_t>(variant.toObject());
|
||||
|
||||
default:
|
||||
return DeserializationError::NotSupported;
|
||||
@@ -174,48 +179,48 @@ class MsgPackDeserializer {
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readInteger(VariantRef variant) {
|
||||
DeserializationError readInteger(VariantData &variant) {
|
||||
T value;
|
||||
if (!readInteger(value)) return DeserializationError::IncompleteInput;
|
||||
variant.set(value);
|
||||
variant.setInteger(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError>::type readFloat(
|
||||
VariantRef variant) {
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value)) return DeserializationError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
variant.set(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 8, DeserializationError>::type readDouble(
|
||||
VariantRef variant) {
|
||||
VariantData &variant) {
|
||||
T value;
|
||||
if (!readBytes(value)) return DeserializationError::IncompleteInput;
|
||||
fixEndianess(value);
|
||||
variant.set(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
typename enable_if<sizeof(T) == 4, DeserializationError>::type readDouble(
|
||||
VariantRef variant) {
|
||||
VariantData &variant) {
|
||||
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 DeserializationError::IncompleteInput;
|
||||
doubleToFloat(i, o);
|
||||
fixEndianess(value);
|
||||
variant.set(value);
|
||||
variant.setFloat(value);
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DeserializationError readString(VariantRef variant) {
|
||||
DeserializationError readString(VariantData &variant) {
|
||||
T size;
|
||||
if (!readInteger(size)) return DeserializationError::IncompleteInput;
|
||||
return readString(variant, size);
|
||||
@@ -228,46 +233,40 @@ class MsgPackDeserializer {
|
||||
return readString(str, size);
|
||||
}
|
||||
|
||||
DeserializationError readString(VariantRef variant, size_t n) {
|
||||
DeserializationError readString(VariantData &variant, size_t n) {
|
||||
StringType s;
|
||||
DeserializationError err = readString(s, n);
|
||||
if (!err) variant.set(s);
|
||||
if (!err) variant.setOwnedString(s);
|
||||
return err;
|
||||
}
|
||||
|
||||
DeserializationError readString(StringType &s, size_t n) {
|
||||
DeserializationError readString(StringType &result, size_t n) {
|
||||
StringBuilder builder = _stringStorage.startString();
|
||||
for (; n; --n) {
|
||||
uint8_t c;
|
||||
if (!readBytes(c)) return DeserializationError::IncompleteInput;
|
||||
builder.append(static_cast<char>(c));
|
||||
}
|
||||
s = builder.complete();
|
||||
if (s.isNull()) return DeserializationError::NoMemory;
|
||||
result = builder.complete();
|
||||
if (!result) return DeserializationError::NoMemory;
|
||||
return DeserializationError::Ok;
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
DeserializationError readArray(VariantRef variant) {
|
||||
DeserializationError readArray(CollectionData &array) {
|
||||
TSize size;
|
||||
if (!readInteger(size)) return DeserializationError::IncompleteInput;
|
||||
return readArray(variant, size);
|
||||
return readArray(array, size);
|
||||
}
|
||||
|
||||
DeserializationError readArray(VariantRef variant, size_t n) {
|
||||
ArrayRef array = variant.to<ArrayRef>();
|
||||
if (array.isNull()) return DeserializationError::NoMemory;
|
||||
return readArray(array, n);
|
||||
}
|
||||
|
||||
DeserializationError readArray(ArrayRef array, size_t n) {
|
||||
DeserializationError readArray(CollectionData &array, size_t n) {
|
||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||
--_nestingLimit;
|
||||
for (; n; --n) {
|
||||
VariantRef value = array.add();
|
||||
if (value.isInvalid()) return DeserializationError::NoMemory;
|
||||
VariantData *value = array.add(_pool);
|
||||
if (!value) return DeserializationError::NoMemory;
|
||||
|
||||
DeserializationError err = parse(value);
|
||||
DeserializationError err = parse(*value);
|
||||
if (err) return err;
|
||||
}
|
||||
++_nestingLimit;
|
||||
@@ -275,31 +274,25 @@ class MsgPackDeserializer {
|
||||
}
|
||||
|
||||
template <typename TSize>
|
||||
DeserializationError readObject(VariantRef variant) {
|
||||
DeserializationError readObject(CollectionData &object) {
|
||||
TSize size;
|
||||
if (!readInteger(size)) return DeserializationError::IncompleteInput;
|
||||
return readObject(variant, size);
|
||||
return readObject(object, size);
|
||||
}
|
||||
|
||||
DeserializationError readObject(VariantRef variant, size_t n) {
|
||||
ObjectRef object = variant.to<ObjectRef>();
|
||||
if (object.isNull()) return DeserializationError::NoMemory;
|
||||
|
||||
return readObject(object, n);
|
||||
}
|
||||
|
||||
DeserializationError readObject(ObjectRef object, size_t n) {
|
||||
DeserializationError readObject(CollectionData &object, size_t n) {
|
||||
if (_nestingLimit == 0) return DeserializationError::TooDeep;
|
||||
--_nestingLimit;
|
||||
for (; n; --n) {
|
||||
VariantSlot *slot = object.addSlot(_pool);
|
||||
if (!slot) return DeserializationError::NoMemory;
|
||||
|
||||
StringType key;
|
||||
DeserializationError err = parseKey(key);
|
||||
if (err) return err;
|
||||
slot->setOwnedKey(key);
|
||||
|
||||
VariantRef value = object.set(key);
|
||||
if (value.isInvalid()) return DeserializationError::NoMemory;
|
||||
|
||||
err = parse(value);
|
||||
err = parse(*slot->data());
|
||||
if (err) return err;
|
||||
}
|
||||
++_nestingLimit;
|
||||
@@ -327,7 +320,7 @@ class MsgPackDeserializer {
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPool *_memoryPool;
|
||||
MemoryPool *_pool;
|
||||
TReader _reader;
|
||||
TStringStorage _stringStorage;
|
||||
uint8_t _nestingLimit;
|
||||
|
||||
Reference in New Issue
Block a user