json_value.h
1 /*
2 ** ClanLib SDK
3 ** Copyright (c) 1997-2013 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 Type
52  {
59  };
60 
63 public:
65  static JsonValue object() { return JsonValue(type_object); }
66 
68  static JsonValue array() { return JsonValue(type_array); }
69 
71  static JsonValue null() { return JsonValue(type_null); }
72 
74  static JsonValue string(const std::string &value) { return JsonValue(value); }
75 
77  static JsonValue boolean(bool value) { return JsonValue(value); }
78 
80  static JsonValue number(int value) { return JsonValue(value); }
81  static JsonValue number(double value) { return JsonValue(value); }
82 
84  static JsonValue from_json(const std::string &json);
85 
87  JsonValue() : type(type_null), value_number(), value_boolean() { }
88  JsonValue(Type type) : type(type), value_number(), value_boolean() { }
89  JsonValue(const std::string &value) : type(type_string), value_string(value), value_number(), value_boolean() { }
90  JsonValue(int value) : type(type_number), value_number((double)value), value_boolean() { }
91  JsonValue(double value) : type(type_number), value_number(value), value_boolean() { }
92  explicit JsonValue(bool value) : type(type_boolean), value_number(), value_boolean(value) { }
94 
97 public:
99  operator bool() const { return to_boolean(); }
100  operator std::string() const { return to_string(); }
101  operator double() const { return to_double(); }
102  operator int() const { return to_int(); }
103 
105  JsonValue &operator[](const char *key) { return members[key]; }
106  JsonValue &operator[](const std::string &key) { return members[key]; }
107  const JsonValue &operator[](int index) const { return items[index]; }
108  JsonValue &operator[](int index) { return items[index]; }
109 
111  Type get_type() const { return type; }
112 
114  size_t get_size() const
115  {
116  switch (type)
117  {
118  case type_object: return members.size();
119  case type_array: return items.size();
120  case type_string: return value_string.size();
121  default: return 0;
122  }
123  }
124 
126  std::map<std::string, JsonValue> &get_members() { return members; }
127  const std::map<std::string, JsonValue> &get_members() const { return members; }
128 
130  std::vector<JsonValue> &get_items() { return items; }
131  const std::vector<JsonValue> &get_items() const { return items; }
132 
134  bool is_null() const { return type == type_null; }
135 
137  bool is_object() const { return type == type_object; }
138 
140  bool is_array() const { return type == type_array; }
141 
143  bool is_string() const { return type == type_string; }
144 
146  bool is_number() const { return type == type_number; }
147 
149  bool is_boolean() const { return type == type_boolean; }
150 
152  std::string to_string() const { if (type != type_string) throw JsonException("JSON Value is not a string"); return value_string; }
153 
155  int to_int() const { if (type != type_number) throw JsonException("JSON Value is not a number"); return (int)value_number; }
156 
158  float to_float() const { if (type != type_number) throw JsonException("JSON Value is not a number"); return (float)value_number; }
159 
161  double to_double() const { if (type != type_number) throw JsonException("JSON Value is not a number"); return value_number; }
162 
164  bool to_boolean() const { if (type != type_boolean) throw JsonException("JSON Value is not a boolean"); return value_boolean; }
166 
169 public:
171  JsonValue &operator =(const std::string &value) { *this = JsonValue(value); return *this; }
172  JsonValue &operator =(int value) { *this = JsonValue(value); return *this; }
173  JsonValue &operator =(double value) { *this = JsonValue(value); return *this; }
174  JsonValue &operator =(bool &value) { *this = JsonValue(value); return *this; }
175 
177  template<typename Type>
178  std::map<std::string, Type> to_map() const
179  {
180  if (type != type_object)
181  throw JsonException("JSON Value is not an object");
182 
183  std::map<std::string, Type> object;
184  std::map<std::string, JsonValue>::const_iterator it;
185  for (it = members.begin(); it != members.end(); ++it)
186  object[it->first] = it->second;
187  return object;
188  }
189 
191  template<typename Type>
192  std::vector<Type> to_vector() const
193  {
194  if (type != type_array)
195  throw JsonException("JSON Value is not an array");
196 
197  std::vector<Type> list;
198  list.reserve(items.size());
199  for (size_t i = 0; i < items.size(); i++)
200  list.push_back(items[i]);
201  return list;
202  }
203 
205  std::string to_json() const;
206  void to_json(std::string &result) const;
208 
211 private:
212  void write(std::string &json) const;
213  void write_array(std::string &json) const;
214  void write_object(std::string &json) const;
215  static void write_string(const std::string &str, std::string &json);
216  void write_number(std::string &json) const;
217 
218  static JsonValue read(const std::string &json, size_t &pos);
219  static JsonValue read_object(const std::string &json, size_t &pos);
220  static JsonValue read_array(const std::string &json, size_t &pos);
221  static std::string read_string(const std::string &json, size_t &pos);
222  static JsonValue read_number(const std::string &json, size_t &pos);
223  static JsonValue read_boolean(const std::string &json, size_t &pos);
224  static void read_whitespace(const std::string &json, size_t &pos);
225 
226  Type type;
227  std::map<std::string, JsonValue> members;
228  std::vector<JsonValue> items;
229  std::string value_string;
230  double value_number;
231  bool value_boolean;
233 };
234 
236 }
static JsonValue string(const std::string &value)
Create a string value.
Definition: json_value.h:74
static JsonValue number(double value)
Definition: json_value.h:81
JsonException(const std::string &message)
Definition: json_value.h:43
bool to_boolean() const
Convert value object to a boolean.
Definition: json_value.h:164
JsonValue & operator[](const std::string &key)
Definition: json_value.h:106
int to_int() const
Convert value object to an int.
Definition: json_value.h:155
static JsonValue from_json(const std::string &json)
Create a value from UTF-8 JSON string.
std::string message
Description of exception.
Definition: exception.h:59
Definition: json_value.h:54
bool is_boolean() const
Return true if value is a boolean.
Definition: json_value.h:149
JsonValue()
Constructs a value.
Definition: json_value.h:87
JsonValue(double value)
Definition: json_value.h:91
Definition: json_value.h:56
static JsonValue boolean(bool value)
Create a boolean value.
Definition: json_value.h:77
Definition: json_value.h:58
std::string to_json() const
Create an UTF-8 JSON string for the value.
bool is_number() const
Return true if value is a number.
Definition: json_value.h:146
JsonValue(Type type)
Definition: json_value.h:88
Definition: json_value.h:53
const std::vector< JsonValue > & get_items() const
Definition: json_value.h:131
Definition: json_value.h:55
Exception class thrown for JSON exceptions.
Definition: json_value.h:40
Top-level exception class.
Definition: exception.h:43
std::string to_string() const
Convert value object to a string.
Definition: json_value.h:152
JsonValue & operator=(const std::string &value)
Assign a new value.
Definition: json_value.h:171
Class representing a JSON value.
Definition: json_value.h:47
static JsonValue object()
Create a object value.
Definition: json_value.h:65
bool is_object() const
Return true if value is an object.
Definition: json_value.h:137
bool is_null() const
Return true if value is null.
Definition: json_value.h:134
Type get_type() const
Get value type.
Definition: json_value.h:111
bool is_string() const
Return true if value is a string.
Definition: json_value.h:143
JsonValue & operator[](const char *key)
Indexers for object members or array items.
Definition: json_value.h:105
static JsonValue null()
Create a null value.
Definition: json_value.h:71
const JsonValue & operator[](int index) const
Definition: json_value.h:107
Definition: json_value.h:57
bool is_array() const
Return true if value is an array.
Definition: json_value.h:140
std::vector< Type > to_vector() const
Convert value array to a std::vector with the template specified value type.
Definition: json_value.h:192
float to_float() const
Convert value object to a float.
Definition: json_value.h:158
Type
value type
Definition: json_value.h:51
double to_double() const
Convert value object to a double.
Definition: json_value.h:161
JsonValue & operator[](int index)
Definition: json_value.h:108
static JsonValue number(int value)
Create a number value.
Definition: json_value.h:80
JsonValue(bool value)
Definition: json_value.h:92
JsonValue(int value)
Definition: json_value.h:90
size_t get_size() const
Get size of value.
Definition: json_value.h:114
JsonValue(const std::string &value)
Definition: json_value.h:89
const std::map< std::string, JsonValue > & get_members() const
Definition: json_value.h:127
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:178
std::vector< JsonValue > & get_items()
Get array items.
Definition: json_value.h:130
static JsonValue array()
Create a array value.
Definition: json_value.h:68
std::map< std::string, JsonValue > & get_members()
Get object members.
Definition: json_value.h:126