Serenity Operating System
at master 241 lines 5.3 kB view raw
1/* 2 * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <AK/JsonArray.h> 8#include <AK/JsonObject.h> 9#include <AK/JsonValue.h> 10#include <AK/StringView.h> 11 12#ifndef KERNEL 13# include <AK/JsonParser.h> 14#endif 15 16namespace AK { 17 18JsonValue::JsonValue(Type type) 19 : m_type(type) 20{ 21} 22 23JsonValue::JsonValue(JsonValue const& other) 24{ 25 copy_from(other); 26} 27 28JsonValue& JsonValue::operator=(JsonValue const& other) 29{ 30 if (this != &other) { 31 clear(); 32 copy_from(other); 33 } 34 return *this; 35} 36 37void JsonValue::copy_from(JsonValue const& other) 38{ 39 m_type = other.m_type; 40 switch (m_type) { 41 case Type::String: 42 VERIFY(!m_value.as_string); 43 m_value.as_string = other.m_value.as_string; 44 m_value.as_string->ref(); 45 break; 46 case Type::Object: 47 m_value.as_object = new JsonObject(*other.m_value.as_object); 48 break; 49 case Type::Array: 50 m_value.as_array = new JsonArray(*other.m_value.as_array); 51 break; 52 default: 53 m_value.as_u64 = other.m_value.as_u64; 54 break; 55 } 56} 57 58JsonValue::JsonValue(JsonValue&& other) 59{ 60 m_type = exchange(other.m_type, Type::Null); 61 m_value.as_u64 = exchange(other.m_value.as_u64, 0); 62} 63 64JsonValue& JsonValue::operator=(JsonValue&& other) 65{ 66 if (this != &other) { 67 clear(); 68 m_type = exchange(other.m_type, Type::Null); 69 m_value.as_u64 = exchange(other.m_value.as_u64, 0); 70 } 71 return *this; 72} 73 74bool JsonValue::equals(JsonValue const& other) const 75{ 76 if (is_null() && other.is_null()) 77 return true; 78 79 if (is_bool() && other.is_bool() && as_bool() == other.as_bool()) 80 return true; 81 82 if (is_string() && other.is_string() && as_string() == other.as_string()) 83 return true; 84 85#if !defined(KERNEL) 86 if (is_number() && other.is_number() && to_number<double>() == other.to_number<double>()) { 87 return true; 88 } 89#else 90 if (is_number() && other.is_number() && to_number<i64>() == other.to_number<i64>()) { 91 return true; 92 } 93#endif 94 95 if (is_array() && other.is_array() && as_array().size() == other.as_array().size()) { 96 bool result = true; 97 for (size_t i = 0; i < as_array().size(); ++i) { 98 result &= as_array().at(i).equals(other.as_array().at(i)); 99 } 100 return result; 101 } 102 103 if (is_object() && other.is_object() && as_object().size() == other.as_object().size()) { 104 bool result = true; 105 as_object().for_each_member([&](auto& key, auto& value) { 106 auto other_value = other.as_object().get(key); 107 if (other_value.has_value()) 108 result &= value.equals(*other_value); 109 else 110 result = false; 111 }); 112 return result; 113 } 114 115 return false; 116} 117 118JsonValue::JsonValue(int value) 119 : m_type(Type::Int32) 120{ 121 m_value.as_i32 = value; 122} 123 124JsonValue::JsonValue(unsigned value) 125 : m_type(Type::UnsignedInt32) 126{ 127 m_value.as_u32 = value; 128} 129 130JsonValue::JsonValue(long value) 131 : m_type(sizeof(long) == 8 ? Type::Int64 : Type::Int32) 132{ 133 if constexpr (sizeof(long) == 8) 134 m_value.as_i64 = value; 135 else 136 m_value.as_i32 = value; 137} 138 139JsonValue::JsonValue(unsigned long value) 140 : m_type(sizeof(long) == 8 ? Type::UnsignedInt64 : Type::UnsignedInt32) 141{ 142 if constexpr (sizeof(long) == 8) 143 m_value.as_u64 = value; 144 else 145 m_value.as_u32 = value; 146} 147 148JsonValue::JsonValue(long long value) 149 : m_type(Type::Int64) 150{ 151 static_assert(sizeof(long long unsigned) == 8); 152 m_value.as_i64 = value; 153} 154 155JsonValue::JsonValue(long long unsigned value) 156 : m_type(Type::UnsignedInt64) 157{ 158 static_assert(sizeof(long long unsigned) == 8); 159 m_value.as_u64 = value; 160} 161 162JsonValue::JsonValue(char const* cstring) 163 : JsonValue(DeprecatedString(cstring)) 164{ 165} 166 167#if !defined(KERNEL) 168JsonValue::JsonValue(double value) 169 : m_type(Type::Double) 170{ 171 m_value.as_double = value; 172} 173#endif 174 175JsonValue::JsonValue(DeprecatedString const& value) 176{ 177 if (value.is_null()) { 178 m_type = Type::Null; 179 } else { 180 m_type = Type::String; 181 m_value.as_string = const_cast<StringImpl*>(value.impl()); 182 m_value.as_string->ref(); 183 } 184} 185 186JsonValue::JsonValue(StringView value) 187 : JsonValue(value.to_deprecated_string()) 188{ 189} 190 191JsonValue::JsonValue(JsonObject const& value) 192 : m_type(Type::Object) 193{ 194 m_value.as_object = new JsonObject(value); 195} 196 197JsonValue::JsonValue(JsonArray const& value) 198 : m_type(Type::Array) 199{ 200 m_value.as_array = new JsonArray(value); 201} 202 203JsonValue::JsonValue(JsonObject&& value) 204 : m_type(Type::Object) 205{ 206 m_value.as_object = new JsonObject(move(value)); 207} 208 209JsonValue::JsonValue(JsonArray&& value) 210 : m_type(Type::Array) 211{ 212 m_value.as_array = new JsonArray(move(value)); 213} 214 215void JsonValue::clear() 216{ 217 switch (m_type) { 218 case Type::String: 219 m_value.as_string->unref(); 220 break; 221 case Type::Object: 222 delete m_value.as_object; 223 break; 224 case Type::Array: 225 delete m_value.as_array; 226 break; 227 default: 228 break; 229 } 230 m_type = Type::Null; 231 m_value.as_string = nullptr; 232} 233 234#ifndef KERNEL 235ErrorOr<JsonValue> JsonValue::from_string(StringView input) 236{ 237 return JsonParser(input).parse(); 238} 239#endif 240 241}