diff --git a/Source/core/JSON.h b/Source/core/JSON.h index eb8dd51d7..d445e0842 100644 --- a/Source/core/JSON.h +++ b/Source/core/JSON.h @@ -129,7 +129,7 @@ namespace Core { realObject.Clear(); - while (handled < size) { + while ( (handled < size) && (error.IsSet() == false) ) { uint16_t payload = static_cast(std::min((size - handled) + 1, static_cast(0xFFFF))); @@ -3829,9 +3829,11 @@ namespace Core { skip = SKIP_AFTER_KEY; } else { loaded += _current.json->Deserialize(&(stream[loaded]), maxLength - loaded, offset, error); - // It could be that the field name was used, as we are not interested in this field, if so, - // do not forget to reset the field name.. - _fieldName.Clear(); + if (offset == FIND_MARKER) { + // It could be that the field name was used, as we are not interested in this field, if so, + // do not forget to reset the field name.. + _fieldName.Clear(); + } } offset = (offset == FIND_MARKER ? skip : offset + PARSE); } @@ -4150,7 +4152,6 @@ namespace Core { { } - Variant(const VariantContainer& object); ~Variant() override = default; @@ -4170,6 +4171,8 @@ namespace Core { } public: + inline bool IsValid() const; + type Content() const { return _type; @@ -4640,7 +4643,14 @@ namespace Core { return (index->second); } + bool IsValid() const { + Elements::const_iterator index(_elements.begin()); + while ((index != _elements.end()) && (index->second.IsValid() == true)) { + index++; + } + return (index == _elements.end()); + } const JSON::Variant& operator[](const TCHAR fieldName[]) const { static const JSON::Variant emptyVariant; @@ -4720,41 +4730,94 @@ namespace Core { return (result); } + inline bool Variant::IsValid() const { + bool result = false; + switch (_type) + { + case type::EMPTY: + case type::STRING: { + result = true; + break; + } + case type::BOOLEAN: { + Core::OptionalType error; + JSON::Boolean stacked; + stacked.FromString(Value(), error); + result = (error.IsSet() == false); + break; + } + case type::NUMBER: { + Core::OptionalType error; + JSON::DecUInt64 stacked; + stacked.FromString(Value(), error); + result = (error.IsSet() == false); + break; + } + case type::DOUBLE: + case type::FLOAT: { + Core::OptionalType error; + JSON::Double stacked; + stacked.FromString(Value(), error); + result = (error.IsSet() == false); + break; + } + case type::ARRAY: { + Core::OptionalType error; + Core::JSON::ArrayType stacked; + stacked.FromString(Value(), error); + result = (error.IsSet() == false); + Core::JSON::ArrayType::ConstIterator index = static_cast&>(stacked).Elements(); + if ((result == true) && (index.Next() == true) && index.Current().IsValid()) { + Variant::type type = index.Current().Content(); + while ((index.Next() == true) && (index.Current().Content() == type) && (index.Current().IsValid())) { + // Intentionally left empty + } + } + result = result && (index.IsValid() == false); + break; + } + case type::OBJECT: { + Core::OptionalType error; + VariantContainer stacked; + stacked.FromString(Value(), error); + result = ((error.IsSet() == false) && (stacked.IsValid() == true)); + break; + } + default: + break; + } + return (result); + } + inline uint16_t Variant::Deserialize(const char stream[], const uint16_t maxLength, uint32_t& offset, Core::OptionalType& error) { - uint16_t result = 0; - if (stream[0] == '{' || stream[0] == '[') { - uint16_t endIndex = FindEndOfScope(stream, maxLength); - if (endIndex > 0 && endIndex < maxLength) { - result = endIndex + 1; - SetQuoted(false); - string str(stream, endIndex + 1); - if (stream[0] == '{') { + uint16_t result = String::Deserialize(stream, maxLength, offset, error); + + // If we are complete, try to guess what it was that we received... + if (offset == 0) { + if (IsQuoted() == false) { + const string base = JSON::String::Value(); + if (IsNull() == true) { + _type = type::EMPTY; + } + else if (base[0] == '{') { _type = type::OBJECT; - String::operator=(str); - } else { + } + else if (base[0] == '[') { _type = type::ARRAY; - String::operator=(str); } - } - } - if (result == 0) { - result = String::Deserialize(stream, maxLength, offset, error); - - _type = type::STRING; - - // If we are complete, try to guess what it was that we received... - if (offset == 0) { - bool quoted = IsQuoted(); - SetQuoted(quoted); - // If it is not quoted, it can be a boolean or a number... - if (quoted == false) { - if ((Value() == _T("true")) || (Value() == _T("false"))) { - _type = type::BOOLEAN; - } else if (IsNull() == false) { - _type = type::NUMBER; - } + else if ((base == _T("true")) || (base == _T("false"))) { + _type = type::BOOLEAN; } + else if (base.find('.') != std::string::npos) { + _type = type::DOUBLE; + } + else { + _type = type::NUMBER; + } + } + else { + _type = type::STRING; } } return (result);