2020-01-18 08:38:21 +00:00
|
|
|
/*
|
2024-10-04 11:19:50 +00:00
|
|
|
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
2023-11-15 08:03:07 +00:00
|
|
|
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
|
2020-01-18 08:38:21 +00:00
|
|
|
*
|
2021-04-22 08:24:48 +00:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-01-18 08:38:21 +00:00
|
|
|
*/
|
|
|
|
|
2019-06-17 17:47:35 +00:00
|
|
|
#include <AK/JsonArray.h>
|
|
|
|
#include <AK/JsonObject.h>
|
2023-11-15 08:03:07 +00:00
|
|
|
#include <AK/JsonParser.h>
|
2019-06-17 17:47:35 +00:00
|
|
|
#include <AK/JsonValue.h>
|
2022-01-27 12:01:10 +00:00
|
|
|
#include <AK/StringView.h>
|
2019-06-17 19:34:12 +00:00
|
|
|
|
|
|
|
namespace AK {
|
2019-06-17 17:47:35 +00:00
|
|
|
|
2023-11-15 08:03:07 +00:00
|
|
|
namespace {
|
|
|
|
using JsonValueStorage = Variant<
|
|
|
|
Empty,
|
|
|
|
bool,
|
|
|
|
i64,
|
|
|
|
u64,
|
|
|
|
double,
|
|
|
|
ByteString,
|
|
|
|
NonnullOwnPtr<JsonArray>,
|
|
|
|
NonnullOwnPtr<JsonObject>>;
|
|
|
|
|
|
|
|
static ErrorOr<JsonValueStorage> clone(JsonValueStorage const& other)
|
|
|
|
{
|
|
|
|
return other.visit(
|
|
|
|
[](NonnullOwnPtr<JsonArray> const& value) -> ErrorOr<JsonValueStorage> {
|
|
|
|
return TRY(try_make<JsonArray>(*value));
|
|
|
|
},
|
|
|
|
[](NonnullOwnPtr<JsonObject> const& value) -> ErrorOr<JsonValueStorage> {
|
|
|
|
return TRY(try_make<JsonObject>(*value));
|
|
|
|
},
|
|
|
|
[](auto const& value) -> ErrorOr<JsonValueStorage> { return JsonValueStorage(value); });
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue::JsonValue() = default;
|
|
|
|
JsonValue::~JsonValue() = default;
|
|
|
|
JsonValue::JsonValue(JsonValue&&) = default;
|
|
|
|
JsonValue& JsonValue::operator=(JsonValue&&) = default;
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
JsonValue::JsonValue(JsonValue const& other)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(MUST(clone(other.m_value)))
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
JsonValue& JsonValue::operator=(JsonValue const& other)
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
2023-11-15 08:03:07 +00:00
|
|
|
if (this != &other)
|
|
|
|
m_value = MUST(clone(other.m_value));
|
2019-06-17 17:47:35 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2023-11-15 08:03:07 +00:00
|
|
|
JsonValue& JsonValue::operator=(JsonArray const& other)
|
|
|
|
{
|
|
|
|
return *this = JsonValue(other);
|
2019-06-17 17:47:35 +00:00
|
|
|
}
|
|
|
|
|
2023-11-15 08:03:07 +00:00
|
|
|
JsonValue& JsonValue::operator=(JsonArray&& other)
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
2023-11-15 08:03:07 +00:00
|
|
|
return *this = JsonValue(other);
|
2019-06-17 17:47:35 +00:00
|
|
|
}
|
|
|
|
|
2023-11-15 08:03:07 +00:00
|
|
|
JsonValue& JsonValue::operator=(JsonObject const& other)
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
2023-11-15 08:03:07 +00:00
|
|
|
return *this = JsonValue(other);
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue& JsonValue::operator=(JsonObject&& other)
|
|
|
|
{
|
|
|
|
return *this = JsonValue(other);
|
2019-06-17 17:47:35 +00:00
|
|
|
}
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
bool JsonValue::equals(JsonValue const& other) const
|
2020-03-31 18:44:34 +00: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;
|
|
|
|
|
2024-01-13 01:52:38 +00:00
|
|
|
if (is_number() && other.is_number()) {
|
|
|
|
auto normalize = [](Variant<u64, i64, double> representation, bool& is_negative) {
|
|
|
|
return representation.visit(
|
|
|
|
[&](u64& value) -> Variant<u64, double> {
|
|
|
|
is_negative = false;
|
|
|
|
return value;
|
|
|
|
},
|
|
|
|
[&](i64& value) -> Variant<u64, double> {
|
|
|
|
is_negative = value < 0;
|
|
|
|
return static_cast<u64>(abs(value));
|
|
|
|
},
|
|
|
|
[&](double& value) -> Variant<u64, double> {
|
|
|
|
is_negative = value < 0;
|
|
|
|
value = abs(value);
|
|
|
|
if (static_cast<double>(static_cast<u64>(value)) == value)
|
|
|
|
return static_cast<u64>(value);
|
|
|
|
return value;
|
|
|
|
});
|
|
|
|
};
|
|
|
|
bool is_this_negative;
|
|
|
|
auto normalized_this = normalize(as_number(), is_this_negative);
|
|
|
|
bool is_that_negative;
|
|
|
|
auto normalized_that = normalize(other.as_number(), is_that_negative);
|
|
|
|
return is_this_negative == is_that_negative && normalized_this == normalized_that;
|
2020-03-31 18:44:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (is_array() && other.is_array() && as_array().size() == other.as_array().size()) {
|
|
|
|
bool result = true;
|
2021-06-28 09:57:37 +00:00
|
|
|
for (size_t i = 0; i < as_array().size(); ++i) {
|
2020-03-31 18:44:34 +00: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) {
|
2022-12-21 14:37:12 +00:00
|
|
|
auto other_value = other.as_object().get(key);
|
|
|
|
if (other_value.has_value())
|
|
|
|
result &= value.equals(*other_value);
|
|
|
|
else
|
|
|
|
result = false;
|
2020-03-31 18:44:34 +00:00
|
|
|
});
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2020-05-22 11:57:23 +00:00
|
|
|
JsonValue::JsonValue(int value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(i64 { value })
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-22 11:57:23 +00:00
|
|
|
JsonValue::JsonValue(unsigned value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(i64 { value })
|
2019-06-29 07:04:45 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-05-22 11:57:23 +00:00
|
|
|
JsonValue::JsonValue(long value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(i64 { value })
|
2020-05-22 11:57:23 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue::JsonValue(unsigned long value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(u64 { value })
|
2020-05-22 11:57:23 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue::JsonValue(long long value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(i64 { value })
|
2019-06-18 06:55:58 +00:00
|
|
|
{
|
2019-10-29 15:36:50 +00:00
|
|
|
}
|
|
|
|
|
2020-05-22 11:57:23 +00:00
|
|
|
JsonValue::JsonValue(long long unsigned value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(u64 { value })
|
2019-10-29 15:36:50 +00:00
|
|
|
{
|
2019-06-18 06:55:58 +00:00
|
|
|
}
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
JsonValue::JsonValue(char const* cstring)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(ByteString { cstring })
|
2019-06-18 07:11:31 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-06-17 17:47:35 +00:00
|
|
|
JsonValue::JsonValue(double value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(double { value })
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2023-12-16 14:19:34 +00:00
|
|
|
JsonValue::JsonValue(ByteString const& value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(value)
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-01-27 12:01:10 +00:00
|
|
|
JsonValue::JsonValue(StringView value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(ByteString { value })
|
2022-01-27 12:01:10 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
JsonValue::JsonValue(JsonObject const& value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(make<JsonObject>(value))
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-04-01 17:58:27 +00:00
|
|
|
JsonValue::JsonValue(JsonArray const& value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(make<JsonArray>(value))
|
2019-06-17 17:47:35 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-08-04 09:46:31 +00:00
|
|
|
JsonValue::JsonValue(JsonObject&& value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(make<JsonObject>(value))
|
2019-08-04 09:46:31 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
JsonValue::JsonValue(JsonArray&& value)
|
2023-11-15 08:03:07 +00:00
|
|
|
: m_value(make<JsonArray>(value))
|
2019-08-04 09:46:31 +00:00
|
|
|
{
|
2019-06-17 17:47:35 +00:00
|
|
|
}
|
|
|
|
|
2021-11-15 00:46:51 +00:00
|
|
|
ErrorOr<JsonValue> JsonValue::from_string(StringView input)
|
2019-06-24 09:25:10 +00:00
|
|
|
{
|
2019-06-24 11:38:59 +00:00
|
|
|
return JsonParser(input).parse();
|
2019-06-24 09:25:10 +00:00
|
|
|
}
|
|
|
|
|
2019-06-17 17:47:35 +00:00
|
|
|
}
|