added save_file and save_string methods
[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         // write the value to a file
53         int save_file(const char* path, int flags = JSON_INDENT(2)) const {
54                 return json_dump_file(_value, path, flags);
55         }
56
57         // write the value to a string (caller must deallocate with free()!)
58         char* save_string(int flags = JSON_INDENT(2)) const {
59                 return json_dumps(_value, flags);
60         }
61
62         // construct Value from input
63         static Value from(const char* value) { return Value().take_ownership(json_string(value)); }
64         static Value from(const std::string& value) { return from(value.c_str()); }
65         static Value from(bool value) { return Value().take_ownership(value ? json_true() : json_false()); }
66         static Value from(int value) { return Value().take_ownership(json_integer(value)); }
67         static Value from(double value) { return Value().take_ownership(json_real(value)); }
68
69         // create a new empty object
70         static Value object() { return Value().take_ownership(json_object()); }
71
72         // create a new empty array
73         static Value array() { return Value().take_ownership(json_array()); }
74
75         // create a new null value
76         static Value null() { return Value().take_ownership(json_null()); }
77
78         // get the underlying json_t
79         json_t* as_json_t() const { return _value; }
80
81         // check value type
82         bool is_undefined() const { return _value == 0; }
83         bool is_object() const { return json_is_object(_value); }
84         bool is_array() const { return json_is_array(_value); }
85         bool is_string() const { return json_is_string(_value); }
86         bool is_integer() const { return json_is_integer(_value); }
87         bool is_real() const { return json_is_real(_value); }
88         bool is_number() const { return json_is_number(_value); }
89         bool is_true() const { return json_is_true(_value); }
90         bool is_false() const { return json_is_false(_value); }
91         bool is_boolean() const { return json_is_boolean(_value); }
92         bool is_null() const { return json_is_null(_value); }
93
94         // get size of array or object
95         unsigned int size() const {
96                 if (is_object())
97                         return json_object_size(_value);
98                 else if (is_array())
99                         return json_array_size(_value);
100                 else
101                         return 0;
102         }
103
104         // get value at array index (const version)
105         const Value at(unsigned int index) const {
106                 if (is_array())
107                         return Value(json_array_get(_value, index));
108                 else
109                         return Value();
110         }
111
112         const Value operator[](signed int index) const { return at(index); }
113         const Value operator[](unsigned int index) const { return at(index); }
114         const Value operator[](signed short index) const { return at(index); }
115         const Value operator[](unsigned short index) const { return at(index); }
116         const Value operator[](signed long index) const { return at(index); }
117         const Value operator[](unsigned long index) const { return at(index); }
118
119         // get value at array index (non-const version)
120         Value at(unsigned int index) {
121                 if (is_array())
122                         return Value(json_array_get(_value, index));
123                 else
124                         return Value();
125         }
126
127         Value operator[](signed int index) { return at(index); }
128         Value operator[](unsigned int index) { return at(index); }
129         Value operator[](signed short index) { return at(index); }
130         Value operator[](unsigned short index) { return at(index); }
131         Value operator[](signed long index) { return at(index); }
132         Value operator[](unsigned long index) { return at(index); }
133
134         // get object property
135         const Value get(const char* key) const {
136                 if (is_object())
137                         return Value(json_object_get(_value, key));
138                 else
139                         return Value();
140         }
141
142         const Value get(const std::string& key) const { return get(key.c_str()); }
143         const Value operator[](const char* key) const { return get(key); }
144         const Value operator[](const std::string& key) const { return get(key.c_str()); }
145
146         // clear all array/object values
147         void clear() {
148                 if (is_object())
149                         json_object_clear(_value);
150                 else if (is_array())
151                         json_array_clear(_value);
152         }
153
154         // get value cast to specified type
155         const char* as_cstring() const { return json_string_value(_value); }
156         std::string as_string() const { return as_cstring(); }
157         int as_integer() const { return json_integer_value(_value); }
158         double as_real() const { return json_real_value(_value); }
159         double as_number() const { return json_number_value(_value); }
160         bool as_boolean() const { return is_true(); }
161
162         // set an object property (converts value to object is not one already)
163         Value& set(const char* key, const Value& value) {
164                 if (!is_object()) {
165                         json_decref(_value);
166                         _value = json_object();
167                 }
168
169                 json_object_set(_value, key, value.as_json_t());
170
171                 return *this;
172         }
173
174         // set an array index (converts value to object is not one already)
175         Value& set(unsigned int index, const Value& value) {
176                 if (!is_array()) {
177                         json_decref(_value);
178                         _value = json_array();
179                 }
180
181                 if (index == size())
182                         json_array_append(_value, value.as_json_t());
183                 else
184                         json_array_set(_value, index, value.as_json_t());
185
186                 return *this;
187         }
188
189         Value& set(int index, const Value& value) { return set(static_cast<unsigned int>(index), value); }
190
191 private:
192         // internal value pointer
193         json_t* _value;
194 };
195
196 // iterators over a JSON object
197 class Iterator {
198 public:
199         // construct a new iterator for a given object
200         Iterator(const Value& value) : _object(value), _iter(0) {
201                 _iter = json_object_iter(_object.as_json_t());
202         }
203
204         // increment iterator
205         void next() {
206                 if (_iter != 0)
207                         _iter = json_object_iter_next(_object.as_json_t(), _iter);
208         }
209
210         Iterator& operator++() { next(); return *this; }
211
212         // test if iterator is still valid
213         bool valid() const { return _iter != 0; }
214         operator bool() const { return valid(); }
215
216         // get key
217         const char* ckey() const {
218                 if (_iter != 0)
219                         return json_object_iter_key(_iter);
220                 else
221                         return "";
222         }
223
224         std::string key() const { return ckey(); }
225
226         // get value
227         const Value value() const {
228                 if (_iter != 0)
229                         return Value(json_object_iter_value(_iter));
230                 else
231                         return Value();
232         }
233
234         // dereference value
235         const Value operator*() const { return value(); }
236
237 private:
238         // disallow copying
239         Iterator(const Iterator&);
240         Iterator& operator=(const Iterator&);
241
242         // object being iterated over
243         Value _object;
244
245         // iterator value
246         void* _iter;
247 };
248
249 } // namespace jansson
250
251 #endif