Remove member MsgPackDeserializer::_error

This reduces the code size by 54 bytes on AVR.
This commit is contained in:
Benoit Blanchon
2022-07-29 10:51:47 +02:00
parent a6da4ad452
commit dde9e9fc26

View File

@ -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;
};