9085652e1693f8d8dd60f6b9f1a2d3bbeb1797ef
[jansson.git] / janssonxx.h
1 #if !defined(JANSSONXX_H)
2 #define JANSSONXX_H 1
3
4 #include <string>
5
6 namespace jansson {
7
8 // include in the jansson namespace
9 #include <jansson.h>
10
11 class Iterator;
12
13 // represents any JSON value
14 class Value {
15 public:
16         // construct new Value with an undefined value
17         Value() : _value(0) {}
18
19         // free Value resources
20         ~Value() { json_decref(_value); }
21
22         // copy an existing Value
23         Value(const Value& e) : _value(json_incref(e._value)) {}
24
25         // make a reference to an existing json_t value
26         explicit Value(json_t* value) : _value(json_incref(value)) {}
27
28         // copy an existing Value
29         Value& operator=(const Value& e) {
30                 json_decref(_value);
31                 _value = json_incref(e._value);
32                 return *this;
33         }
34
35         // take ownership of a json_t (does not increase reference count)
36         Value& take_ownership(json_t* value) {
37                 json_decref(_value);
38                 _value = value;
39                 return *this;
40         }
41
42         // load a file as a JSON value
43         static Value load_file(const char* path, json_error_t* error = 0) {
44                 return Value().take_ownership(json_load_file(path, error));
45         }
46
47         // load a string as a JSON value
48         static Value load_string(const char* string, json_error_t* error = 0) {
49                 return Value().take_ownership(json_loads(string, error));
50         }
51
52         // construct Value from input
53         static Value from(const char* value) { return Value().take_ownership(json_string(value)); }
54         static Value from(const std::string& value) { return from(value.c_str()); }
55         static Value from(bool value) { return Value().take_ownership(value ? json_true() : json_false()); }
56         static Value from(int value) { return Value().take_ownership(json_integer(value)); }
57         static Value from(double value) { return Value().take_ownership(json_real(value)); }
58
59         // create a new empty object
60         static Value object() { return Value().take_ownership(json_object()); }
61
62         // create a new empty array
63         static Value array() { return Value().take_ownership(json_array()); }
64
65         // create a new null value
66         static Value null() { return Value().take_ownership(json_null()); }
67
68         // get the underlying json_t
69         json_t* as_json_t() const { return _value; }
70
71         // check value type
72         bool is_undefined() const { return _value == 0; }
73         bool is_object() const { return json_is_object(_value); }
74         bool is_array() const { return json_is_array(_value); }
75         bool is_string() const { return json_is_string(_value); }
76         bool is_integer() const { return json_is_integer(_value); }
77         bool is_real() const { return json_is_real(_value); }
78         bool is_number() const { return json_is_number(_value); }
79         bool is_true() const { return json_is_true(_value); }
80         bool is_false() const { return json_is_false(_value); }
81         bool is_boolean() const { return json_is_boolean(_value); }
82         bool is_null() const { return json_is_null(_value); }
83
84         // get size of array or object
85         unsigned int size() const {
86                 if (is_object())
87                         return json_object_size(_value);
88                 else if (is_array())
89                         return json_array_size(_value);
90                 else
91                         return 0;
92         }
93
94         // get value at array index (const version)
95         const Value at(unsigned int index) const {
96                 if (is_array())
97                         return Value(json_array_get(_value, index));
98                 else
99                         return Value();
100         }
101
102         const Value operator[](signed int index) const { return at(index); }
103         const Value operator[](unsigned int index) const { return at(index); }
104         const Value operator[](signed short index) const { return at(index); }
105         const Value operator[](unsigned short index) const { return at(index); }
106         const Value operator[](signed long index) const { return at(index); }
107         const Value operator[](unsigned long index) const { return at(index); }
108
109         // get value at array index (non-const version)
110         Value at(unsigned int index) {
111                 if (is_array())
112                         return Value(json_array_get(_value, index));
113                 else
114                         return Value();
115         }
116
117         Value operator[](signed int index) { return at(index); }
118         Value operator[](unsigned int index) { return at(index); }
119         Value operator[](signed short index) { return at(index); }
120         Value operator[](unsigned short index) { return at(index); }
121         Value operator[](signed long index) { return at(index); }
122         Value operator[](unsigned long index) { return at(index); }
123
124         // get object property
125         const Value get(const char* key) const {
126                 if (is_object())
127                         return Value(json_object_get(_value, key));
128                 else
129                         return Value();
130         }
131
132         const Value get(const std::string& key) const { return get(key.c_str()); }
133         const Value operator[](const char* key) const { return get(key); }
134         const Value operator[](const std::string& key) const { return get(key.c_str()); }
135
136         // clear all array/object values
137         void clear() {
138                 if (is_object())
139                         json_object_clear(_value);
140                 else if (is_array())
141                         json_array_clear(_value);
142         }
143
144         // get value cast to specified type
145         const char* as_cstring() const { return json_string_value(_value); }
146         std::string as_string() const { return as_cstring(); }
147         int as_integer() const { return json_integer_value(_value); }
148         double as_real() const { return json_real_value(_value); }
149         double as_number() const { return json_number_value(_value); }
150         bool as_boolean() const { return is_true(); }
151
152         // set an object property (converts value to object is not one already)
153         Value& set(const char* key, const Value& value) {
154                 if (!is_object()) {
155                         json_decref(_value);
156                         _value = json_object();
157                 }
158
159                 json_object_set(_value, key, value.as_json_t());
160
161                 return *this;
162         }
163
164         // set an array index (converts value to object is not one already)
165         Value& set(unsigned int index, const Value& value) {
166                 if (!is_array()) {
167                         json_decref(_value);
168                         _value = json_array();
169                 }
170
171                 if (index == size())
172                         json_array_append(_value, value.as_json_t());
173                 else
174                         json_array_set(_value, index, value.as_json_t());
175
176                 return *this;
177         }
178
179         Value& set(int index, const Value& value) { return set(static_cast<unsigned int>(index), value); }
180
181 private:
182         // internal value pointer
183         json_t* _value;
184 };
185
186 // iterators over a JSON object
187 class Iterator {
188 public:
189         // construct a new iterator for a given object
190         Iterator(const Value& value) : _object(value), _iter(0) {
191                 _iter = json_object_iter(_object.as_json_t());
192         }
193
194         // increment iterator
195         void next() {
196                 if (_iter != 0)
197                         _iter = json_object_iter_next(_object.as_json_t(), _iter);
198         }
199
200         Iterator& operator++() { next(); return *this; }
201
202         // test if iterator is still valid
203         bool valid() const { return _iter != 0; }
204         operator bool() const { return valid(); }
205
206         // get key
207         const char* ckey() const {
208                 if (_iter != 0)
209                         return json_object_iter_key(_iter);
210                 else
211                         return "";
212         }
213
214         std::string key() const { return ckey(); }
215
216         // get value
217         const Value value() const {
218                 if (_iter != 0)
219                         return Value(json_object_iter_value(_iter));
220                 else
221                         return Value();
222         }
223
224         // dereference value
225         const Value operator*() const { return value(); }
226
227 private:
228         // disallow copying
229         Iterator(const Iterator&);
230         Iterator& operator=(const Iterator&);
231
232         // object being iterated over
233         Value _object;
234
235         // iterator value
236         void* _iter;
237 };
238
239 } // namespace jansson
240
241 #endif