2020-01-18 05:38:21 -03:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
|
|
|
|
|
*
|
2021-04-22 05:24:48 -03:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 05:38:21 -03:00
|
|
|
*/
|
|
|
|
|
|
2019-06-17 14:47:35 -03:00
|
|
|
#include <AK/JsonArray.h>
|
|
|
|
|
#include <AK/JsonObject.h>
|
|
|
|
|
#include <AK/JsonValue.h>
|
2022-01-27 09:01:10 -03:00
|
|
|
#include <AK/StringView.h>
|
2019-06-17 16:34:12 -03:00
|
|
|
|
2021-06-29 17:19:29 -03:00
|
|
|
#ifndef KERNEL
|
|
|
|
|
# include <AK/JsonParser.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2019-06-17 16:34:12 -03:00
|
|
|
namespace AK {
|
2019-06-17 14:47:35 -03:00
|
|
|
|
|
|
|
|
JsonValue::JsonValue(Type type)
|
|
|
|
|
: m_type(type)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue::JsonValue(JsonValue const& other)
|
2019-06-17 14:47:35 -03:00
|
|
|
{
|
|
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue& JsonValue::operator=(JsonValue const& other)
|
2019-06-17 14:47:35 -03:00
|
|
|
{
|
|
|
|
|
if (this != &other) {
|
|
|
|
|
clear();
|
|
|
|
|
copy_from(other);
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
void JsonValue::copy_from(JsonValue const& other)
|
2019-06-17 14:47:35 -03:00
|
|
|
{
|
|
|
|
|
m_type = other.m_type;
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case Type::String:
|
2021-02-23 16:42:32 -03:00
|
|
|
VERIFY(!m_value.as_string);
|
2019-06-17 14:47:35 -03:00
|
|
|
m_value.as_string = other.m_value.as_string;
|
2019-06-29 07:03:53 -03:00
|
|
|
m_value.as_string->ref();
|
2019-06-17 14:47:35 -03:00
|
|
|
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:
|
2020-07-06 12:17:46 -03:00
|
|
|
m_value.as_u64 = other.m_value.as_u64;
|
2019-06-17 14:47:35 -03:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonValue::JsonValue(JsonValue&& other)
|
|
|
|
|
{
|
2020-06-11 01:40:27 -03:00
|
|
|
m_type = exchange(other.m_type, Type::Null);
|
2020-07-06 12:17:46 -03:00
|
|
|
m_value.as_u64 = exchange(other.m_value.as_u64, 0);
|
2019-06-17 14:47:35 -03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonValue& JsonValue::operator=(JsonValue&& other)
|
|
|
|
|
{
|
|
|
|
|
if (this != &other) {
|
2019-06-18 04:22:19 -03:00
|
|
|
clear();
|
2020-06-11 01:40:27 -03:00
|
|
|
m_type = exchange(other.m_type, Type::Null);
|
2020-07-06 12:17:46 -03:00
|
|
|
m_value.as_u64 = exchange(other.m_value.as_u64, 0);
|
2019-06-17 14:47:35 -03:00
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
bool JsonValue::equals(JsonValue const& other) const
|
2020-03-31 15:44:34 -03:00
|
|
|
{
|
|
|
|
|
if (is_null() && other.is_null())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (is_bool() && other.is_bool() && as_bool() == other.as_bool())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
if (is_string() && other.is_string() && as_string() == other.as_string())
|
|
|
|
|
return true;
|
|
|
|
|
|
2020-05-16 07:00:04 -03:00
|
|
|
#if !defined(KERNEL)
|
2020-03-31 15:44:34 -03:00
|
|
|
if (is_number() && other.is_number() && to_number<double>() == other.to_number<double>()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (is_number() && other.is_number() && to_number<i64>() == other.to_number<i64>()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
if (is_array() && other.is_array() && as_array().size() == other.as_array().size()) {
|
|
|
|
|
bool result = true;
|
2021-06-28 06:57:37 -03:00
|
|
|
for (size_t i = 0; i < as_array().size(); ++i) {
|
2020-03-31 15:44:34 -03:00
|
|
|
result &= as_array().at(i).equals(other.as_array().at(i));
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (is_object() && other.is_object() && as_object().size() == other.as_object().size()) {
|
|
|
|
|
bool result = true;
|
|
|
|
|
as_object().for_each_member([&](auto& key, auto& value) {
|
|
|
|
|
result &= value.equals(other.as_object().get(key));
|
|
|
|
|
});
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-22 08:57:23 -03:00
|
|
|
JsonValue::JsonValue(int value)
|
2019-10-29 12:36:50 -03:00
|
|
|
: m_type(Type::Int32)
|
2019-06-17 14:47:35 -03:00
|
|
|
{
|
2019-10-29 12:36:50 -03:00
|
|
|
m_value.as_i32 = value;
|
2019-06-17 14:47:35 -03:00
|
|
|
}
|
|
|
|
|
|
2020-05-22 08:57:23 -03:00
|
|
|
JsonValue::JsonValue(unsigned value)
|
2019-10-29 12:36:50 -03:00
|
|
|
: m_type(Type::UnsignedInt32)
|
2019-06-29 04:04:45 -03:00
|
|
|
{
|
2019-10-29 12:36:50 -03:00
|
|
|
m_value.as_u32 = value;
|
2019-06-29 04:04:45 -03:00
|
|
|
}
|
|
|
|
|
|
2020-05-22 08:57:23 -03:00
|
|
|
JsonValue::JsonValue(long value)
|
|
|
|
|
: m_type(sizeof(long) == 8 ? Type::Int64 : Type::Int32)
|
|
|
|
|
{
|
|
|
|
|
if constexpr (sizeof(long) == 8)
|
|
|
|
|
m_value.as_i64 = value;
|
|
|
|
|
else
|
|
|
|
|
m_value.as_i32 = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonValue::JsonValue(unsigned long value)
|
|
|
|
|
: m_type(sizeof(long) == 8 ? Type::UnsignedInt64 : Type::UnsignedInt32)
|
|
|
|
|
{
|
|
|
|
|
if constexpr (sizeof(long) == 8)
|
|
|
|
|
m_value.as_u64 = value;
|
|
|
|
|
else
|
|
|
|
|
m_value.as_u32 = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonValue::JsonValue(long long value)
|
2019-10-29 12:36:50 -03:00
|
|
|
: m_type(Type::Int64)
|
2019-06-18 03:55:58 -03:00
|
|
|
{
|
2020-05-22 08:57:23 -03:00
|
|
|
static_assert(sizeof(long long unsigned) == 8);
|
2019-10-29 12:36:50 -03:00
|
|
|
m_value.as_i64 = value;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-22 08:57:23 -03:00
|
|
|
JsonValue::JsonValue(long long unsigned value)
|
2019-10-29 12:36:50 -03:00
|
|
|
: m_type(Type::UnsignedInt64)
|
|
|
|
|
{
|
2020-05-22 08:57:23 -03:00
|
|
|
static_assert(sizeof(long long unsigned) == 8);
|
2019-10-29 12:36:50 -03:00
|
|
|
m_value.as_u64 = value;
|
2019-06-18 03:55:58 -03:00
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue::JsonValue(char const* cstring)
|
2019-06-18 04:11:31 -03:00
|
|
|
: JsonValue(String(cstring))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-16 07:00:04 -03:00
|
|
|
#if !defined(KERNEL)
|
2019-06-17 14:47:35 -03:00
|
|
|
JsonValue::JsonValue(double value)
|
|
|
|
|
: m_type(Type::Double)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_double = value;
|
|
|
|
|
}
|
2019-06-29 04:04:45 -03:00
|
|
|
#endif
|
2019-06-17 14:47:35 -03:00
|
|
|
|
|
|
|
|
JsonValue::JsonValue(bool value)
|
|
|
|
|
: m_type(Type::Bool)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_bool = value;
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue::JsonValue(String const& value)
|
2019-06-17 14:47:35 -03:00
|
|
|
{
|
|
|
|
|
if (value.is_null()) {
|
|
|
|
|
m_type = Type::Null;
|
|
|
|
|
} else {
|
|
|
|
|
m_type = Type::String;
|
|
|
|
|
m_value.as_string = const_cast<StringImpl*>(value.impl());
|
2019-06-29 07:03:53 -03:00
|
|
|
m_value.as_string->ref();
|
2019-06-17 14:47:35 -03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-27 09:01:10 -03:00
|
|
|
JsonValue::JsonValue(StringView value)
|
|
|
|
|
: JsonValue(value.to_string())
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue::JsonValue(JsonObject const& value)
|
2019-06-17 14:47:35 -03:00
|
|
|
: m_type(Type::Object)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_object = new JsonObject(value);
|
|
|
|
|
}
|
|
|
|
|
|
2022-04-01 14:58:27 -03:00
|
|
|
JsonValue::JsonValue(JsonArray const& value)
|
2019-06-17 14:47:35 -03:00
|
|
|
: m_type(Type::Array)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_array = new JsonArray(value);
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-04 06:46:31 -03:00
|
|
|
JsonValue::JsonValue(JsonObject&& value)
|
|
|
|
|
: m_type(Type::Object)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_object = new JsonObject(move(value));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
JsonValue::JsonValue(JsonArray&& value)
|
|
|
|
|
: m_type(Type::Array)
|
|
|
|
|
{
|
|
|
|
|
m_value.as_array = new JsonArray(move(value));
|
|
|
|
|
}
|
|
|
|
|
|
2019-06-17 14:47:35 -03:00
|
|
|
void JsonValue::clear()
|
|
|
|
|
{
|
|
|
|
|
switch (m_type) {
|
|
|
|
|
case Type::String:
|
2020-01-23 11:14:21 -03:00
|
|
|
m_value.as_string->unref();
|
2019-06-17 14:47:35 -03:00
|
|
|
break;
|
|
|
|
|
case Type::Object:
|
|
|
|
|
delete m_value.as_object;
|
|
|
|
|
break;
|
|
|
|
|
case Type::Array:
|
|
|
|
|
delete m_value.as_array;
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
2020-06-11 01:40:27 -03:00
|
|
|
m_type = Type::Null;
|
2019-06-17 14:47:35 -03:00
|
|
|
m_value.as_string = nullptr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-29 17:19:29 -03:00
|
|
|
#ifndef KERNEL
|
2021-11-14 21:46:51 -03:00
|
|
|
ErrorOr<JsonValue> JsonValue::from_string(StringView input)
|
2019-06-24 06:25:10 -03:00
|
|
|
{
|
2019-06-24 08:38:59 -03:00
|
|
|
return JsonParser(input).parse();
|
2019-06-24 06:25:10 -03:00
|
|
|
}
|
2021-06-29 17:19:29 -03:00
|
|
|
#endif
|
2019-06-24 06:25:10 -03:00
|
|
|
|
2019-06-17 14:47:35 -03:00
|
|
|
}
|