JSON: Add JSON serializers

These are two new types that allow serializing JSON on-the-fly
as it's generated, without building the whole JSON in memory
first.
This commit is contained in:
Sergey Bugaev 2019-08-27 14:12:44 +03:00 committed by Andreas Kling
parent 4ec698d1b0
commit 56f5c14d86
2 changed files with 142 additions and 0 deletions

65
AK/JsonArraySerializer.h Normal file
View file

@ -0,0 +1,65 @@
#pragma once
#include <AK/JsonValue.h>
namespace AK {
template<typename Builder>
class JsonObjectSerializer;
template<typename Builder>
class JsonArraySerializer {
public:
explicit JsonArraySerializer(Builder& builder)
: m_builder(builder)
{
m_builder.append('[');
}
JsonArraySerializer(const JsonArraySerializer&) = delete;
JsonArraySerializer(JsonArraySerializer&&) = delete;
~JsonArraySerializer()
{
if (!m_finished)
finish();
}
void add(const JsonValue& value)
{
begin_item();
value.serialize(m_builder);
}
JsonArraySerializer<Builder> add_array()
{
begin_item();
return JsonArraySerializer(m_builder);
}
// Implemented in JsonObjectSerializer.h
JsonObjectSerializer<Builder> add_object();
void finish()
{
ASSERT(!m_finished);
m_finished = true;
m_builder.append(']');
}
private:
void begin_item()
{
if (!m_empty)
m_builder.append(',');
m_empty = false;
}
Builder& m_builder;
bool m_empty { true };
bool m_finished { false };
};
}
using AK::JsonArraySerializer;

77
AK/JsonObjectSerializer.h Normal file
View file

@ -0,0 +1,77 @@
#pragma once
#include <AK/JsonArraySerializer.h>
#include <AK/JsonValue.h>
namespace AK {
template<typename Builder>
class JsonObjectSerializer {
public:
explicit JsonObjectSerializer(Builder& builder)
: m_builder(builder)
{
m_builder.append('{');
}
JsonObjectSerializer(const JsonObjectSerializer&) = delete;
JsonObjectSerializer(JsonObjectSerializer&&) = delete;
~JsonObjectSerializer()
{
if (!m_finished)
finish();
}
void add(const StringView& key, const JsonValue& value)
{
begin_item(key);
value.serialize(m_builder);
}
JsonArraySerializer<Builder> add_array(const StringView& key)
{
begin_item(key);
return JsonArraySerializer(m_builder);
}
JsonObjectSerializer<Builder> add_object(const StringView& key)
{
begin_item(key);
return JsonObjectSerializer(m_builder);
}
void finish()
{
ASSERT(!m_finished);
m_finished = true;
m_builder.append('}');
}
private:
void begin_item(const StringView& key)
{
if (!m_empty)
m_builder.append(',');
m_empty = false;
m_builder.append('"');
m_builder.append(key);
m_builder.append("\":");
}
Builder& m_builder;
bool m_empty { true };
bool m_finished { false };
};
template<typename Builder>
JsonObjectSerializer<Builder> JsonArraySerializer<Builder>::add_object()
{
begin_item();
return JsonObjectSerializer(m_builder);
}
}
using AK::JsonObjectSerializer;