Open Lighting Architecture
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Json.h
1 /*
2  * This library is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU Lesser General Public
4  * License as published by the Free Software Foundation; either
5  * version 2.1 of the License, or (at your option) any later version.
6  *
7  * This library is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10  * Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public
13  * License along with this library; if not, write to the Free Software
14  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15  *
16  * Json.h
17  * A simple set of classes for generating JSON.
18  * See http://www.json.org/
19  * Copyright (C) 2012 Simon Newton
20  */
21 
22 #ifndef INCLUDE_OLA_WEB_JSON_H_
23 #define INCLUDE_OLA_WEB_JSON_H_
24 
25 #include <ola/StringUtils.h>
26 #include <map>
27 #include <ostream>
28 #include <sstream>
29 #include <string>
30 #include <vector>
31 
32 namespace ola {
33 namespace web {
34 
35 using std::map;
36 using std::ostream;
37 using std::string;
38 using std::stringstream;
39 using std::vector;
40 
41 
45 class JsonValue {
46  public:
47  virtual ~JsonValue() {}
48  virtual void ToString(ostream *output, unsigned int indent) const = 0;
49 
50  protected:
51  void Indent(ostream *output, unsigned int indent) const {
52  *output << string(indent, ' ');
53  }
54 
55  static const unsigned int INDENT = 2;
56 };
57 
58 
62 class JsonStringValue: public JsonValue {
63  public:
64  explicit JsonStringValue(const string &value)
65  : m_value(value) {
66  }
67 
68  void ToString(ostream *output, unsigned int) const {
69  *output << '"' << EscapeString(m_value) << '"';
70  }
71 
72  private:
73  const string m_value;
74 };
75 
76 
80 class JsonUIntValue: public JsonValue {
81  public:
82  explicit JsonUIntValue(unsigned int value)
83  : m_value(value) {
84  }
85 
86  void ToString(ostream *output, unsigned int) const {
87  *output << m_value;
88  }
89 
90  private:
91  const unsigned int m_value;
92 };
93 
94 
98 class JsonIntValue: public JsonValue {
99  public:
100  explicit JsonIntValue(int value)
101  : m_value(value) {
102  }
103 
104  void ToString(ostream *output, unsigned int) const {
105  *output << m_value;
106  }
107 
108  private:
109  const int m_value;
110 };
111 
112 
116 class JsonBoolValue: public JsonValue {
117  public:
118  explicit JsonBoolValue(bool value)
119  : m_value(value) {
120  }
121 
122  void ToString(ostream *output, unsigned int) const {
123  *output << (m_value ? "true" : "false");
124  }
125 
126  private:
127  const bool m_value;
128 };
129 
130 
134 class JsonNullValue: public JsonValue {
135  public:
136  explicit JsonNullValue() {}
137 
138  void ToString(ostream *output, unsigned int) const {
139  *output << "null";
140  }
141 };
142 
143 
147 class JsonRawValue: public JsonValue {
148  public:
149  explicit JsonRawValue(const string &value)
150  : m_value(value) {
151  }
152 
153  void ToString(ostream *output, unsigned int) const {
154  *output << m_value;
155  }
156 
157  private:
158  const string m_value;
159 };
160 
166 class JsonObject: public JsonValue {
167  public:
168  JsonObject() {}
169  ~JsonObject();
170 
171  // if the same value is added twice we'll override it
172  void Add(const string &key, const string &value);
173  void Add(const string &key, const char *value);
174  void Add(const string &key, unsigned int i);
175  void Add(const string &key, int i);
176  void Add(const string &key, bool value);
177  void Add(const string &key);
178 
179  JsonObject* AddObject(const string &key);
180  class JsonArray* AddArray(const string &key);
181 
182  void AddRaw(const string &key, const string &value);
183 
184  void ToString(ostream *output, unsigned int indent) const;
185 
186  private:
187  typedef map<string, JsonValue*> MemberMap;
188  MemberMap m_members;
189 
190  JsonObject(const JsonObject&);
191  JsonObject& operator=(const JsonObject&);
192 
193  inline void FreeIfExists(const string &key) const;
194 };
195 
196 
202 class JsonArray: public JsonValue {
203  public:
204  JsonArray()
205  : m_complex_type(false) {
206  }
207  ~JsonArray();
208 
209  void Append(const string &value) {
210  m_values.push_back(new JsonStringValue(value));
211  }
212 
213  void Append(const char *value) {
214  m_values.push_back(new JsonStringValue(value));
215  }
216 
217  void Append(unsigned int i) {
218  m_values.push_back(new JsonUIntValue(i));
219  }
220 
221  void Append(int i) {
222  m_values.push_back(new JsonIntValue(i));
223  }
224 
225  void Append(bool value) {
226  m_values.push_back(new JsonBoolValue(value));
227  }
228 
229  void Append() {
230  m_values.push_back(new JsonNullValue());
231  }
232 
233  JsonObject* AppendObject() {
234  JsonObject *obj = new JsonObject();
235  m_values.push_back(obj);
236  m_complex_type = true;
237  return obj;
238  }
239 
240  JsonArray* AppendArray() {
241  JsonArray *array = new JsonArray();
242  m_values.push_back(array);
243  m_complex_type = true;
244  return array;
245  }
246 
247  void AppendRaw(const string &value) {
248  m_values.push_back(new JsonRawValue(value));
249  }
250 
251  void ToString(ostream *output, unsigned int indent) const;
252 
253  private:
254  typedef vector<JsonValue*> ValuesVector;
255  ValuesVector m_values;
256  // true if this array contains a nested object or array
257  bool m_complex_type;
258 
259  JsonArray(const JsonArray&);
260  JsonArray& operator=(const JsonArray&);
261 };
262 
263 
264 class JsonWriter {
265  public:
266  static void Write(ostream *output, const JsonValue &obj);
267  static string AsString(const JsonValue &obj);
268 };
269 } // namespace web
270 } // namespace ola
271 #endif // INCLUDE_OLA_WEB_JSON_H_