1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 02:37:36 +00:00

AK: JsonParser improvements

- Parsing invalid JSON no longer asserts
    Instead of asserting when coming across malformed JSON,
    JsonParser::parse now returns an Optional<JsonValue>.
- Disallow trailing commas in JSON objects and arrays
- No longer parse 'undefined', as that is a purely JS thing
- No longer allow non-whitespace after anything consumed by the initial
  parse() call. Examples of things that were valid and no longer are:
    - undefineddfz
    - {"foo": 1}abcd
    - [1,2,3]4
- JsonObject.for_each_member now iterates in original insertion order
This commit is contained in:
Matthew Olsson 2020-06-10 21:40:27 -07:00 committed by Andreas Kling
parent 39576b2238
commit e8e728454c
29 changed files with 189 additions and 118 deletions

View file

@ -41,26 +41,32 @@ public:
~JsonObject() {}
JsonObject(const JsonObject& other)
: m_members(other.m_members)
: m_order(other.m_order)
, m_members(other.m_members)
{
}
JsonObject(JsonObject&& other)
: m_members(move(other.m_members))
: m_order(move(other.m_order))
, m_members(move(other.m_members))
{
}
JsonObject& operator=(const JsonObject& other)
{
if (this != &other)
if (this != &other) {
m_members = other.m_members;
m_order = other.m_order;
}
return *this;
}
JsonObject& operator=(JsonObject&& other)
{
if (this != &other)
if (this != &other) {
m_members = move(other.m_members);
m_order = move(other.m_order);
}
return *this;
}
@ -70,7 +76,7 @@ public:
JsonValue get(const String& key) const
{
auto* value = get_ptr(key);
return value ? *value : JsonValue(JsonValue::Type::Undefined);
return value ? *value : JsonValue(JsonValue::Type::Null);
}
JsonValue get_or(const String& key, JsonValue alternative) const
@ -94,14 +100,17 @@ public:
void set(const String& key, JsonValue value)
{
m_order.append(key);
m_members.set(key, move(value));
}
template<typename Callback>
void for_each_member(Callback callback) const
{
for (auto& it : m_members)
callback(it.key, it.value);
for (size_t i = 0; i < m_order.size(); ++i) {
auto property = m_order[i];
callback(property, m_members.get(property).value());
}
}
template<typename Builder>
@ -113,6 +122,7 @@ public:
String to_string() const { return serialized<StringBuilder>(); }
private:
Vector<String> m_order;
HashMap<String, JsonValue> m_members;
};
@ -193,9 +203,6 @@ inline void JsonValue::serialize(Builder& builder) const
case Type::UnsignedInt64:
builder.appendf("%llu", as_u64());
break;
case Type::Undefined:
builder.append("undefined");
break;
case Type::Null:
builder.append("null");
break;