rename and move the _* private classes to _private namespace
[jansson.git] / janssonxx.h
1 // janssonxx - C++ wrapper for jansson
2 //
3 // author: Sean Middleditch <sean@middleditch.us>
4 //
5 // janssonxx is free software; you can redistribute it and/or modify
6 // it under the terms of the MIT license. See LICENSE for details.
7
8
9 #if !defined(JANSSONXX_H)
10 #define JANSSONXX_H 1
11
12 #include <string>
13 #include <ostream>
14 #include <istream>
15 #include <sstream>
16 #include <cstdlib>
17
18 namespace jansson {
19         // include in the jansson namespace
20 #       include <jansson.h>
21
22         class Iterator;
23         class Value;
24
25         namespace _private {
26                 class ArrayProxy;
27                 class ObjectProxy;
28
29                 // base class for JSON value interface
30                 template <typename _Base>
31                 class ValueBase : public _Base {
32                 public:
33                         // empty constructor
34                         ValueBase() : _Base() {}
35
36                         // copy constructor
37                         ValueBase(const _Base& base) : _Base(base) {}
38
39                         // create reference to value
40                         ValueBase(json_t* json) : _Base(json) {}
41
42                         // assignment operator
43                         ValueBase& operator=(const Value& value) { _Base::operator=(value); return *this; }
44
45                         // check value type
46                         bool is_undefined() const { return _Base::as_json() == 0; }
47                         bool is_object() const { return json_is_object(_Base::as_json()); }
48                         bool is_array() const { return json_is_array(_Base::as_json()); }
49                         bool is_string() const { return json_is_string(_Base::as_json()); }
50                         bool is_integer() const { return json_is_integer(_Base::as_json()); }
51                         bool is_real() const { return json_is_real(_Base::as_json()); }
52                         bool is_number() const { return json_is_number(_Base::as_json()); }
53                         bool is_true() const { return json_is_true(_Base::as_json()); }
54                         bool is_false() const { return json_is_false(_Base::as_json()); }
55                         bool is_boolean() const { return json_is_boolean(_Base::as_json()); }
56                         bool is_null() const { return json_is_null(_Base::as_json()); }
57
58                         // get size of array or object
59                         inline unsigned int size() const;
60
61                         // get value at array index (const version)
62                         inline const Value at(unsigned int index) const;
63
64                         inline const Value operator[](signed int index) const;
65                         inline const Value operator[](unsigned int index) const;
66                         inline const Value operator[](signed short index) const;
67                         inline const Value operator[](unsigned short index) const;
68                         inline const Value operator[](signed long index) const;
69                         inline const Value operator[](unsigned long index) const;
70
71                         // get value at array index (non-const version)
72                         inline ValueBase<ArrayProxy> at(unsigned int index);
73
74                         inline ValueBase<ArrayProxy> operator[](signed int index);
75                         inline ValueBase<ArrayProxy> operator[](unsigned int index);
76                         inline ValueBase<ArrayProxy> operator[](signed short index);
77                         inline ValueBase<ArrayProxy> operator[](unsigned short index);
78                         inline ValueBase<ArrayProxy> operator[](signed long index);
79                         inline ValueBase<ArrayProxy> operator[](unsigned long index);
80
81                         // get object property (const version)
82                         inline const Value get(const char* key) const;
83
84                         inline const Value get(const std::string& key) const;
85                         inline const Value operator[](const char* key) const;
86                         inline const Value operator[](const std::string& key) const;
87
88                         // get object property (non-const version)
89                         inline ValueBase<ObjectProxy> get(const char* key);
90
91                         inline ValueBase<ObjectProxy> get(const std::string& key);
92                         inline ValueBase<ObjectProxy> operator[](const char* key);
93                         inline ValueBase<ObjectProxy> operator[](const std::string& key);
94
95                         // clear all array/object values
96                         inline void clear();
97
98                         // get value cast to specified type
99                         inline const char* as_cstring() const;
100                         inline std::string as_string() const;
101                         inline int as_integer() const;
102                         inline double as_real() const;
103                         inline double as_number() const;
104                         inline bool as_boolean() const;
105
106                         // set an object property (converts value to object is not one already)
107                         inline _Base& set_key(const char* key, const Value& value);
108
109                         inline _Base& set_key(const std::string& key, const Value& value);
110
111                         // set an array index (converts value to object is not one already)
112                         inline _Base& set_at(unsigned int index, const Value& value);
113
114                         // delete an object key
115                         inline _Base& del_key(const char* key);
116
117                         inline _Base& del_key(const std::string& key);
118
119                         // delete an item from an array by index
120                         inline _Base& del_at(unsigned int index);
121
122                         // insert an item into an array at a given index
123                         inline _Base& insert_at(unsigned int index, const Value& value);
124                 };
125
126                 // represents any JSON value, private base
127                 class Basic {
128                 public:
129                         // construct new Value with an undefined value
130                         Basic() : _value(0) {}
131
132                         // copy constructor
133                         Basic(const Basic& value) : _value(json_incref(value._value)) {}
134
135                         // make a reference to an existing json_t value
136                         explicit Basic(json_t* value) : _value(json_incref(value)) {}
137
138                         // free Value resources
139                         ~Basic() { json_decref(_value); }
140
141                         // copy an existing Value
142                         Basic& operator=(const Basic& e) {
143                                 if (&e != this) {
144                                         json_decref(_value);
145                                         _value = json_incref(e._value);
146                                 }
147                                 return *this;
148                         }
149
150                         // get the underlying json_t
151                         json_t* as_json() const { return _value; }
152
153                 protected:
154                         // take ownership of a json_t (does not increase reference count)
155                         static Basic _take(json_t* json) {
156                                 Basic v;
157                                 v._value = json;
158                                 return v;
159                         }
160
161                 private:
162                         // internal value pointer
163                         json_t* _value;
164                 };
165
166                 // proxies an array element
167                 class ArrayProxy {
168                 public:
169                         // constructor
170                         ArrayProxy(json_t* array, unsigned int index) : _array(array), _index(index) {}
171
172                         // assign to the proxied element
173                         inline ArrayProxy& operator=(const Value& value);
174
175                         // get the proxied element
176                         json_t* as_json() const { return json_array_get(_array, _index); }
177
178                 private:
179                         // array object we wrap
180                         json_t* _array;
181
182                         // index of property
183                         unsigned int _index;
184                 };
185
186                 // proxies an object property
187                 class ObjectProxy {
188                 public:
189                         // constructor
190                         ObjectProxy(json_t* array, const char* key) : _object(array), _key(key) {}
191
192                         // assign to the proxied element
193                         inline ObjectProxy& operator=(const Value& value);
194
195                         // get the proxied element
196                         json_t* as_json() const { return json_object_get(_object, _key); }
197
198                 private:
199                         // array object we wrap
200                         json_t* _object;
201
202                         // key of property
203                         const char* _key;
204                 };
205
206         } // namespace jansson::_private
207
208         // represents any JSON value
209         class Value : public _private::ValueBase<_private::Basic> {
210         public:
211                 // empty constructor
212                 Value() : _private::ValueBase<_private::Basic>() {}
213
214                 // copy constructor for base
215                 Value(const _private::Basic& value) : _private::ValueBase<_private::Basic>(value) {}
216         
217                 // copy constructor for base
218                 Value(const _private::ValueBase<_private::Basic>& value) : _private::ValueBase<_private::Basic>(value) {}
219
220                 // copy constructor
221                 Value(const Value& value) : _private::ValueBase<_private::Basic>(value) {}
222
223                 // create reference to value
224                 explicit Value(json_t* json) : _private::ValueBase<_private::Basic>(json) {}
225
226                 // construct Value from input
227                 static inline Value from(const char* value) { return Value::_take(json_string(value)); }
228                 static inline Value from(const std::string& value) { return from(value.c_str()); }
229                 static inline Value from(bool value) { return Value::_take(value ? json_true() : json_false()); }
230                 static inline Value from(signed int value) { return Value::_take(json_integer(value)); }
231                 static inline Value from(unsigned int value) { return Value::_take(json_integer(value)); }
232                 static inline Value from(signed short value) { return Value::_take(json_integer(value)); }
233                 static inline Value from(unsigned short value) { return Value::_take(json_integer(value)); }
234                 static inline Value from(signed long value) { return Value::_take(json_integer(value)); }
235                 static inline Value from(unsigned long value) { return Value::_take(json_integer(value)); }
236                 static inline Value from(float value) { return Value::_take(json_real(value)); }
237                 static inline Value from(double value) { return Value::_take(json_real(value)); }
238
239                 // create a new empty object
240                 static inline Value object() { return Value::_take(json_object()); }
241
242                 // create a new empty array
243                 static inline Value array() { return Value::_take(json_array()); }
244
245                 // create a new null value
246                 static inline Value null() { return Value::_take(json_null()); }
247
248                 // load a file as a JSON value
249                 static Value load_file(const char* path, json_error_t* error = 0) {
250                         return Value::_take(json_load_file(path, error));
251                 }
252
253                 // load a string as a JSON value
254                 static Value load_string(const char* string, json_error_t* error = 0) {
255                         return Value::_take(json_loads(string, error));
256                 }
257
258                 // write the value to a file
259                 int save_file(const char* path, int flags = 0) const {
260                         return json_dump_file(as_json(), path, flags);
261                 }
262
263                 // write the value to a string (caller must deallocate with free()!)
264                 char* save_string(int flags = 0) const {
265                         return json_dumps(as_json(), flags);
266                 }
267         };
268
269         // iterators over a JSON object
270         class Iterator {
271         public:
272                 // construct a new iterator for a given object
273                 Iterator(const Value& value) : _object(value), _iter(0) {
274                         _iter = json_object_iter(_object.as_json());
275                 }
276
277                 // construct a new iterator for a given object
278                 Iterator(const _private::ValueBase<_private::ObjectProxy>& value) : _object(value.as_json()), _iter(0) {
279                         _iter = json_object_iter(_object.as_json());
280                 }
281
282                 // increment iterator
283                 void next() {
284                         _iter = json_object_iter_next(_object.as_json(), _iter);
285                 }
286
287                 Iterator& operator++() { next(); return *this; }
288
289                 // test if iterator is still valid
290                 bool valid() const { return _iter != 0; }
291                 operator bool() const { return valid(); }
292
293                 // get key
294                 const char* ckey() const {
295                         return json_object_iter_key(_iter);
296                 }
297
298                 std::string key() const { return ckey(); }
299
300                 // get value
301                 const Value value() const {
302                         return Value(json_object_iter_value(_iter));
303                 }
304
305                 // dereference value
306                 const Value operator*() const { return value(); }
307
308         private:
309                 // disallow copying
310                 Iterator(const Iterator&);
311                 Iterator& operator=(const Iterator&);
312
313                 // object being iterated over
314                 Value _object;
315
316                 // iterator value
317                 void* _iter;
318         };
319
320 } // namespace jansson
321
322 // stream JSON value out
323 std::ostream& operator<<(std::ostream& os, const jansson::Value& value) {
324         char* tmp = value.save_string();
325         if (tmp != 0) {
326                 os << tmp;
327                 free(tmp);
328         }
329         return os;
330 }
331
332 // read JSON value
333 std::istream& operator>>(std::istream& is, jansson::Value& value) {
334         std::stringstream tmp;
335         while (is)
336                 tmp << static_cast<char>(is.get());
337         value = jansson::Value::load_string(tmp.str().c_str());
338         return is;
339 }
340
341 #include "janssonxx.tcc"
342
343 #endif