summaryrefslogtreecommitdiff
path: root/AK/JsonValue.h
blob: 324201d3e5287fa2127027c4a05a54040aedc035 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#pragma once

#include <AK/AKString.h>

namespace AK {

class JsonArray;
class JsonObject;
class StringBuilder;

class JsonValue {
public:
    enum class Type {
        Undefined,
        Null,
        Int,
        Double,
        Bool,
        String,
        Array,
        Object,
    };

    static JsonValue from_string(const StringView&);

    explicit JsonValue(Type = Type::Null);
    ~JsonValue() { clear(); }

    JsonValue(const JsonValue&);
    JsonValue(JsonValue&&);

    JsonValue& operator=(const JsonValue&);
    JsonValue& operator=(JsonValue&&);

    JsonValue(int);
    JsonValue(unsigned);
    JsonValue(double);
    JsonValue(bool);
    JsonValue(const char*);
    JsonValue(const String&);
    JsonValue(const JsonArray&);
    JsonValue(const JsonObject&);

    String serialized() const;
    void serialize(StringBuilder&) const;

    String to_string(const String& default_value = {}) const
    {
        if (is_string())
            return as_string();
        return default_value;
    }

    String as_string() const
    {
        ASSERT(is_string());
        return *m_value.as_string;
    }

    const JsonObject& as_object() const
    {
        ASSERT(is_object());
        return *m_value.as_object;
    }

    const JsonArray& as_array() const
    {
        ASSERT(is_array());
        return *m_value.as_array;
    }

    Type type() const { return m_type; }

    bool is_null() const { return m_type == Type::Null; }
    bool is_undefined() const { return m_type == Type::Undefined; }
    bool is_string() const { return m_type == Type::String; }
    bool is_int() const { return m_type == Type::Int; }
    bool is_double() const { return m_type == Type::Double; }
    bool is_array() const { return m_type == Type::Array; }
    bool is_object() const { return m_type == Type::Object; }
    bool is_number() const { return m_type == Type::Int || m_type == Type::Double; }

    dword to_dword(dword default_value = 0) const
    {
        if (!is_number())
            return default_value;
        if (type() == Type::Int)
            return (dword)m_value.as_int;
        return (dword)m_value.as_double;
    }

private:
    void clear();
    void copy_from(const JsonValue&);

    Type m_type { Type::Undefined };

    union {
        StringImpl* as_string { nullptr };
        JsonArray* as_array;
        JsonObject* as_object;
        double as_double;
        int as_int;
        bool as_bool;
    } m_value;
};

}

using AK::JsonValue;