json_value.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2015 The ClanLib Team
4 **
5 ** This software is provided 'as-is', without any express or implied
6 ** warranty. In no event will the authors be held liable for any damages
7 ** arising from the use of this software.
8 **
9 ** Permission is granted to anyone to use this software for any purpose,
10 ** including commercial applications, and to alter it and redistribute it
11 ** freely, subject to the following restrictions:
12 **
13 ** 1. The origin of this software must not be misrepresented; you must not
14 ** claim that you wrote the original software. If you use this software
15 ** in a product, an acknowledgment in the product documentation would be
16 ** appreciated but is not required.
17 ** 2. Altered source versions must be plainly marked as such, and must not be
18 ** misrepresented as being the original software.
19 ** 3. This notice may not be removed or altered from any source distribution.
20 **
21 ** Note: Some of the libraries ClanLib may link to may have additional
22 ** requirements or restrictions.
23 **
24 ** File Author(s):
25 **
26 ** Magnus Norddahl
27 */
28
29 #pragma once
30
31 #include <map>
32 #include <vector>
33
34 namespace clan
35 {
38
40 class JsonException : public Exception
41 {
42 public:
43 JsonException(const std::string &message) : Exception(message) { }
44 };
45
47 class JsonValue
48 {
49 public:
51 enum class Type
52 {
53 undefined,
54 null,
55 object,
56 array,
57 string,
58 number,
59 boolean
60 };
61
64 public:
66 static JsonValue object() { return JsonValue(Type::object); }
67
69 static JsonValue array() { return JsonValue(Type::array); }
70
72 static JsonValue null() { return JsonValue(Type::null); }
73
75 static JsonValue string(const std::string &value) { return JsonValue(value); }
76
78 static JsonValue boolean(bool value) { return JsonValue(value); }
79
81 static JsonValue number(int value) { return JsonValue(value); }
82 static JsonValue number(double value) { return JsonValue(value); }
83
85 static JsonValue from_json(const std::string &json);
86
88 JsonValue() : type(Type::undefined), value_number(), value_boolean() { }
89 JsonValue(Type type) : type(type), value_number(), value_boolean() { }
90 JsonValue(bool value) : type(Type::boolean), value_number(), value_boolean(value) { }
91 JsonValue(int value) : type(Type::number), value_number((double)value), value_boolean() { }
92 JsonValue(double value) : type(Type::number), value_number(value), value_boolean() { }
93 JsonValue(const char *value) : type(Type::string), value_string(value), value_number(), value_boolean() { }
94 JsonValue(const std::string &value) : type(Type::string), value_string(value), value_number(), value_boolean() { }
96
99 public:
101 explicit operator bool() const { return to_boolean(); }
102 operator std::string() const { return to_string(); }
103 operator float() const { return to_float(); }
104 operator double() const { return to_double(); }
105 operator int() const { return to_int(); }
106
108 JsonValue &operator[](const char *key) { return members[key]; }
109 JsonValue &operator[](const std::string &key) { return members[key]; }
110 const JsonValue &operator[](const char *key) const
111 {
112 static JsonValue undefined;
113 auto it = members.find(key);
114 if (it == members.end()) return undefined;
115 else return it->second;
116 }
117 const JsonValue &operator[](const std::string &key) const
118 {
119 static JsonValue undefined;
120 auto it = members.find(key);
121 if (it == members.end()) return undefined;
122 else return it->second;
123 }
124
125 const JsonValue &operator[](int index) const { return items[index]; }
126 JsonValue &operator[](int index) { return items[index]; }
127
129 Type get_type() const { return type; }
130
132 size_t get_size() const
133 {
134 switch (type)
135 {
136 case Type::object: return members.size();
137 case Type::array: return items.size();
138 case Type::string: return value_string.size();
139 default: return 0;
140 }
141 }
142
144 std::map<std::string, JsonValue> &get_members() { return members; }
145 const std::map<std::string, JsonValue> &get_members() const { return members; }
146
148 std::vector<JsonValue> &get_items() { return items; }
149 const std::vector<JsonValue> &get_items() const { return items; }
150
152 bool is_undefined() const { return type == Type::undefined; }
153
155 bool is_null() const { return type == Type::null; }
156
158 bool is_object() const { return type == Type::object; }
159
161 bool is_array() const { return type == Type::array; }
162
164 bool is_string() const { return type == Type::string; }
165
167 bool is_number() const { return type == Type::number; }
168
170 bool is_boolean() const { return type == Type::boolean; }
171
173 std::string to_string() const { if (type != Type::string) throw JsonException("JSON Value is not a string"); return value_string; }
174
176 int to_int() const { if (type != Type::number) throw JsonException("JSON Value is not a number"); return (int)value_number; }
177
179 float to_float() const { if (type != Type::number) throw JsonException("JSON Value is not a number"); return (float)value_number; }
180
182 double to_double() const { if (type != Type::number) throw JsonException("JSON Value is not a number"); return value_number; }
183
185 bool to_boolean() const { if (type != Type::boolean) throw JsonException("JSON Value is not a boolean"); return value_boolean; }
187
190 public:
192 template<typename T>
193 JsonValue &operator =(const T &value) { *this = JsonValue(value); return *this; }
194
195 JsonValue &operator =(const JsonValue &value)
196 {
197 type = value.type;
198 members = value.members;
199 items = value.items;
200 value_string = value.value_string;
201 value_number = value.value_number;
202 value_boolean = value.value_boolean;
203 return *this;
204 }
205
207 template<typename Type>
208 std::map<std::string, Type> to_map() const
209 {
210 if (type != Type::object)
211 throw JsonException("JSON Value is not an object");
212
213 std::map<std::string, Type> object;
214 std::map<std::string, JsonValue>::const_iterator it;
215 for (it = members.begin(); it != members.end(); ++it)
216 object[it->first] = it->second;
217 return object;
218 }
219
221 template<typename Type>
222 std::vector<Type> to_vector() const
223 {
224 if (type != Type::array)
225 throw JsonException("JSON Value is not an array");
226
227 std::vector<Type> list;
228 list.reserve(items.size());
229 for (auto & elem : items)
230 list.push_back(elem);
231 return list;
232 }
233
235 std::string to_json() const;
236 void to_json(std::string &result) const;
238
241 private:
242 void write(std::string &json) const;
243 void write_array(std::string &json) const;
244 void write_object(std::string &json) const;
245 static void write_string(const std::string &str, std::string &json);
246 void write_number(std::string &json) const;
247
248 static JsonValue read(const std::string &json, size_t &pos);
249 static JsonValue read_object(const std::string &json, size_t &pos);
250 static JsonValue read_array(const std::string &json, size_t &pos);
251 static std::string read_string(const std::string &json, size_t &pos);
252 static JsonValue read_number(const std::string &json, size_t &pos);
253 static JsonValue read_boolean(const std::string &json, size_t &pos);
254 static void read_whitespace(const std::string &json, size_t &pos);
255
256 Type type;
257 std::map<std::string, JsonValue> members;
258 std::vector<JsonValue> items;
259 std::string value_string;
260 double value_number;
261 bool value_boolean;
263 };
264
266 }
clan::JsonValue::string
static JsonValue string(const std::string &value)
Create a string value.
Definition: json_value.h:75
clan::JsonValue::number
static JsonValue number(double value)
Definition: json_value.h:82
clan
Definition: clanapp.h:35
clan::JsonValue::is_undefined
bool is_undefined() const
Return true if value is undefined.
Definition: json_value.h:152
clan::JsonException::JsonException
JsonException(const std::string &message)
Definition: json_value.h:43
clan::JsonValue::to_boolean
bool to_boolean() const
Convert value object to a boolean.
Definition: json_value.h:185
clan::JsonValue::Type::number
clan::JsonValue::operator[]
JsonValue & operator[](const std::string &key)
Definition: json_value.h:109
clan::JsonValue::to_int
int to_int() const
Convert value object to an int.
Definition: json_value.h:176
clan::JsonValue::from_json
static JsonValue from_json(const std::string &json)
Create a value from UTF-8 JSON string.
clan::Exception::message
std::string message
Description of exception.
Definition: exception.h:58
clan::JsonValue::is_boolean
bool is_boolean() const
Return true if value is a boolean.
Definition: json_value.h:170
clan::JsonValue::JsonValue
JsonValue()
Constructs a value.
Definition: json_value.h:88
clan::JsonValue::operator=
JsonValue & operator=(const T &value)
Assign a new value.
Definition: json_value.h:193
clan::JsonValue::JsonValue
JsonValue(double value)
Definition: json_value.h:92
clan::JsonValue::boolean
static JsonValue boolean(bool value)
Create a boolean value.
Definition: json_value.h:78
clan::JsonValue::to_json
std::string to_json() const
Create an UTF-8 JSON string for the value.
clan::JsonValue::is_number
bool is_number() const
Return true if value is a number.
Definition: json_value.h:167
clan::JsonValue::JsonValue
JsonValue(Type type)
Definition: json_value.h:89
clan::JsonValue::Type::object
clan::JsonValue::get_items
const std::vector< JsonValue > & get_items() const
Definition: json_value.h:149
clan::JsonException
Exception class thrown for JSON exceptions.
Definition: json_value.h:40
clan::Exception
Top-level exception class.
Definition: exception.h:42
clan::StyleTokenType::string
@ keyword
clan::JsonValue::to_string
std::string to_string() const
Convert value object to a string.
Definition: json_value.h:173
clan::JsonValue::Type::array
clan::StyleValueType::undefined
clan::JsonValue
Class representing a JSON value.
Definition: json_value.h:47
clan::JsonValue::object
static JsonValue object()
Create a object value.
Definition: json_value.h:66
clan::JsonValue::Type::undefined
clan::JsonValue::is_object
bool is_object() const
Return true if value is an object.
Definition: json_value.h:158
clan::JsonValue::is_null
bool is_null() const
Return true if value is null.
Definition: json_value.h:155
clan::JsonValue::get_type
Type get_type() const
Get value type.
Definition: json_value.h:129
clan::JsonValue::is_string
bool is_string() const
Return true if value is a string.
Definition: json_value.h:164
clan::JsonValue::operator[]
JsonValue & operator[](const char *key)
Indexers for object members or array items.
Definition: json_value.h:108
clan::JsonValue::Type::string
clan::JsonValue::Type
Type
value type
Definition: json_value.h:51
clan::JsonValue::null
static JsonValue null()
Create a null value.
Definition: json_value.h:72
clan::JsonValue::operator[]
const JsonValue & operator[](int index) const
Definition: json_value.h:125
clan::JsonValue::JsonValue
JsonValue(const char *value)
Definition: json_value.h:93
clan::JsonValue::operator[]
const JsonValue & operator[](const std::string &key) const
Definition: json_value.h:117
clan::JsonValue::is_array
bool is_array() const
Return true if value is an array.
Definition: json_value.h:161
clan::JsonValue::to_vector
std::vector< Type > to_vector() const
Convert value array to a std::vector with the template specified value type.
Definition: json_value.h:222
clan::JsonValue::to_float
float to_float() const
Convert value object to a float.
Definition: json_value.h:179
clan::JsonValue::to_double
double to_double() const
Convert value object to a double.
Definition: json_value.h:182
clan::JsonValue::operator[]
const JsonValue & operator[](const char *key) const
Definition: json_value.h:110
clan::JsonValue::Type::null
clan::JsonValue::operator[]
JsonValue & operator[](int index)
Definition: json_value.h:126
clan::JsonValue::number
static JsonValue number(int value)
Create a number value.
Definition: json_value.h:81
clan::JsonValue::JsonValue
JsonValue(bool value)
Definition: json_value.h:90
clan::JsonValue::JsonValue
JsonValue(int value)
Definition: json_value.h:91
clan::JsonValue::get_size
size_t get_size() const
Get size of value.
Definition: json_value.h:132
clan::JsonValue::JsonValue
JsonValue(const std::string &value)
Definition: json_value.h:94
clan::JsonValue::get_members
const std::map< std::string, JsonValue > & get_members() const
Definition: json_value.h:145
clan::JsonValue::Type::boolean
clan::JsonValue::to_map
std::map< std::string, Type > to_map() const
Convert value object to a std::map with the template specified value type.
Definition: json_value.h:208
clan::JsonValue::get_items
std::vector< JsonValue > & get_items()
Get array items.
Definition: json_value.h:148
clan::JsonValue::array
static JsonValue array()
Create a array value.
Definition: json_value.h:69
clan::JsonValue::get_members
std::map< std::string, JsonValue > & get_members()
Get object members.
Definition: json_value.h:144