/* * Copyright (c) 2018-2020, Andreas Kling * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include 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(i32 value) : m_type(Type::Int32) { m_value.as_i32 = value; } JsonValue::JsonValue(u32 value) : m_type(Type::UnsignedInt32) { m_value.as_u32 = value; } JsonValue::JsonValue(i64 value) : m_type(Type::Int64) { m_value.as_i64 = value; } JsonValue::JsonValue(u64 value) : m_type(Type::UnsignedInt64) { m_value.as_u64 = 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(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); } 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)); } void JsonValue::clear() { switch (m_type) { case Type::String: m_value.as_string->unref(); 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; } JsonValue JsonValue::from_string(const StringView& input) { return JsonParser(input).parse(); } }