mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-29 19:10:26 +00:00
7bb1e465c6
They still use string storage, but this change makes it nice and easy to work with IPv4 addresses in JSON data.
198 lines
4 KiB
C++
198 lines
4 KiB
C++
#include <AK/Function.h>
|
|
#include <AK/JsonArray.h>
|
|
#include <AK/JsonObject.h>
|
|
#include <AK/JsonParser.h>
|
|
#include <AK/JsonValue.h>
|
|
#include <AK/StringBuilder.h>
|
|
|
|
namespace AK {
|
|
|
|
JsonValue::JsonValue(Type type)
|
|
: m_type(type)
|
|
{
|
|
}
|
|
|
|
JsonValue::JsonValue(const JsonValue& other)
|
|
{
|
|
copy_from(other);
|
|
}
|
|
|
|
JsonValue& JsonValue::operator=(const JsonValue& other)
|
|
{
|
|
if (this != &other) {
|
|
clear();
|
|
copy_from(other);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
void JsonValue::copy_from(const JsonValue& other)
|
|
{
|
|
m_type = other.m_type;
|
|
switch (m_type) {
|
|
case Type::String:
|
|
ASSERT(!m_value.as_string);
|
|
m_value.as_string = other.m_value.as_string;
|
|
m_value.as_string->ref();
|
|
break;
|
|
case Type::Object:
|
|
m_value.as_object = new JsonObject(*other.m_value.as_object);
|
|
break;
|
|
case Type::Array:
|
|
m_value.as_array = new JsonArray(*other.m_value.as_array);
|
|
break;
|
|
default:
|
|
m_value.as_string = other.m_value.as_string;
|
|
break;
|
|
}
|
|
}
|
|
|
|
JsonValue::JsonValue(JsonValue&& other)
|
|
{
|
|
m_type = exchange(other.m_type, Type::Undefined);
|
|
m_value.as_string = exchange(other.m_value.as_string, nullptr);
|
|
}
|
|
|
|
JsonValue& JsonValue::operator=(JsonValue&& other)
|
|
{
|
|
if (this != &other) {
|
|
clear();
|
|
m_type = exchange(other.m_type, Type::Undefined);
|
|
m_value.as_string = exchange(other.m_value.as_string, nullptr);
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
JsonValue::JsonValue(int value)
|
|
: m_type(Type::Int)
|
|
{
|
|
m_value.as_int = value;
|
|
}
|
|
|
|
JsonValue::JsonValue(long unsigned value)
|
|
: JsonValue((unsigned)value)
|
|
{
|
|
}
|
|
|
|
JsonValue::JsonValue(unsigned value)
|
|
: m_type(Type::UnsignedInt)
|
|
{
|
|
m_value.as_uint = value;
|
|
}
|
|
|
|
JsonValue::JsonValue(const char* cstring)
|
|
: JsonValue(String(cstring))
|
|
{
|
|
}
|
|
|
|
#ifndef KERNEL
|
|
JsonValue::JsonValue(double value)
|
|
: m_type(Type::Double)
|
|
{
|
|
m_value.as_double = value;
|
|
}
|
|
#endif
|
|
|
|
JsonValue::JsonValue(bool value)
|
|
: m_type(Type::Bool)
|
|
{
|
|
m_value.as_bool = value;
|
|
}
|
|
|
|
JsonValue::JsonValue(const String& value)
|
|
{
|
|
if (value.is_null()) {
|
|
m_type = Type::Null;
|
|
} else {
|
|
m_type = Type::String;
|
|
m_value.as_string = const_cast<StringImpl*>(value.impl());
|
|
m_value.as_string->ref();
|
|
}
|
|
}
|
|
|
|
JsonValue::JsonValue(const IPv4Address& value)
|
|
: JsonValue(value.to_string())
|
|
{
|
|
}
|
|
|
|
JsonValue::JsonValue(const JsonObject& value)
|
|
: m_type(Type::Object)
|
|
{
|
|
m_value.as_object = new JsonObject(value);
|
|
}
|
|
|
|
JsonValue::JsonValue(const JsonArray& value)
|
|
: m_type(Type::Array)
|
|
{
|
|
m_value.as_array = new JsonArray(value);
|
|
}
|
|
|
|
void JsonValue::clear()
|
|
{
|
|
switch (m_type) {
|
|
case Type::String:
|
|
m_value.as_string->deref();
|
|
break;
|
|
case Type::Object:
|
|
delete m_value.as_object;
|
|
break;
|
|
case Type::Array:
|
|
delete m_value.as_array;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
m_type = Type::Undefined;
|
|
m_value.as_string = nullptr;
|
|
}
|
|
|
|
void JsonValue::serialize(StringBuilder& builder) const
|
|
{
|
|
switch (m_type) {
|
|
case Type::String:
|
|
builder.appendf("\"%s\"", m_value.as_string->characters());
|
|
break;
|
|
case Type::Array:
|
|
m_value.as_array->serialize(builder);
|
|
break;
|
|
case Type::Object:
|
|
m_value.as_object->serialize(builder);
|
|
break;
|
|
case Type::Bool:
|
|
builder.append(m_value.as_bool ? "true" : "false");
|
|
break;
|
|
#ifndef KERNEL
|
|
case Type::Double:
|
|
builder.appendf("%g", m_value.as_double);
|
|
break;
|
|
#endif
|
|
case Type::Int:
|
|
builder.appendf("%d", m_value.as_int);
|
|
break;
|
|
case Type::UnsignedInt:
|
|
builder.appendf("%u", m_value.as_uint);
|
|
break;
|
|
case Type::Undefined:
|
|
builder.append("undefined");
|
|
break;
|
|
case Type::Null:
|
|
builder.append("null");
|
|
break;
|
|
default:
|
|
ASSERT_NOT_REACHED();
|
|
}
|
|
}
|
|
|
|
String JsonValue::serialized() const
|
|
{
|
|
StringBuilder builder;
|
|
serialize(builder);
|
|
return builder.to_string();
|
|
}
|
|
|
|
JsonValue JsonValue::from_string(const StringView& input)
|
|
{
|
|
return JsonParser(input).parse();
|
|
}
|
|
|
|
}
|