rename the set() 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                 if (&e != this) {
31                         json_decref(_value);
32                         _value = json_incref(e._value);
33                 }
34                 return *this;
35         }
36
37         // load a file as a JSON value
38         static Value load_file(const char* path, json_error_t* error = 0) {
39                 return Value::_take(json_load_file(path, error));
40         }
41
42         // load a string as a JSON value
43         static Value load_string(const char* string, json_error_t* error = 0) {
44                 return Value::_take(json_loads(string, error));
45         }
46
47         // write the value to a file
48         int save_file(const char* path, int flags = JSON_INDENT(2)) const {
49                 return json_dump_file(_value, path, flags);
50         }
51
52         // write the value to a string (caller must deallocate with free()!)
53         char* save_string(int flags = JSON_INDENT(2)) const {
54                 return json_dumps(_value, flags);
55         }
56
57         // construct Value from input
58         static Value from(const char* value) { return Value::_take(json_string(value)); }
59         static Value from(const std::string& value) { return from(value.c_str()); }
60         static Value from(bool value) { return Value::_take(value ? json_true() : json_false()); }
61         static Value from(int value) { return Value::_take(json_integer(value)); }
62         static Value from(double value) { return Value::_take(json_real(value)); }
63
64         // create a new empty object
65         static Value object() { return Value::_take(json_object()); }
66
67         // create a new empty array
68         static Value array() { return Value::_take(json_array()); }
69
70         // create a new null value
71         static Value null() { return Value::_take(json_null()); }
72
73         // get the underlying json_t
74         json_t* as_json_t() const { return _value; }
75
76         // check value type
77         bool is_undefined() const { return _value == 0; }
78         bool is_object() const { return json_is_object(_value); }
79         bool is_array() const { return json_is_array(_value); }
80         bool is_string() const { return json_is_string(_value); }
81         bool is_integer() const { return json_is_integer(_value); }
82         bool is_real() const { return json_is_real(_value); }
83         bool is_number() const { return json_is_number(_value); }
84         bool is_true() const { return json_is_true(_value); }
85         bool is_false() const { return json_is_false(_value); }
86         bool is_boolean() const { return json_is_boolean(_value); }
87         bool is_null() const { return json_is_null(_value); }
88
89         // get size of array or object
90         unsigned int size() const {
91                 if (is_object())
92                         return json_object_size(_value);
93                 else
94                         return json_array_size(_value);
95         }
96
97         // get value at array index (const version)
98         const Value at(unsigned int index) const {
99                 return Value(json_array_get(_value, index));
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                 return Value(json_array_get(_value, index));
112         }
113
114         Value operator[](signed int index) { return at(index); }
115         Value operator[](unsigned int index) { return at(index); }
116         Value operator[](signed short index) { return at(index); }
117         Value operator[](unsigned short index) { return at(index); }
118         Value operator[](signed long index) { return at(index); }
119         Value operator[](unsigned long index) { return at(index); }
120
121         // get object property
122         const Value get(const char* key) const {
123                 return Value(json_object_get(_value, key));
124         }
125
126         const Value get(const std::string& key) const { return get(key.c_str()); }
127         const Value operator[](const char* key) const { return get(key); }
128         const Value operator[](const std::string& key) const { return get(key.c_str()); }
129
130         // clear all array/object values
131         void clear() {
132                 if (is_object())
133                         json_object_clear(_value);
134                 else
135                         json_array_clear(_value);
136         }
137
138         // get value cast to specified type
139         const char* as_cstring() const { return json_string_value(_value); }
140         std::string as_string() const { return as_cstring(); }
141         int as_integer() const { return json_integer_value(_value); }
142         double as_real() const { return json_real_value(_value); }
143         double as_number() const { return json_number_value(_value); }
144         bool as_boolean() const { return is_true(); }
145
146         // set an object property (converts value to object is not one already)
147         Value& set_key(const char* key, const Value& value) {
148                 if (!is_object()) {
149                         json_decref(_value);
150                         _value = json_object();
151                 }
152
153                 json_object_set(_value, key, value.as_json_t());
154
155                 return *this;
156         }
157
158         Value& set_key(const std::string& key, const Value& value) {
159                 return set_key(key.c_str(), value);
160         }
161
162         // set an array index (converts value to object is not one already)
163         Value& set_at(unsigned int index, const Value& value) {
164                 if (!is_array()) {
165                         json_decref(_value);
166                         _value = json_array();
167                 }
168
169                 if (index == size())
170                         json_array_append(_value, value.as_json_t());
171                 else
172                         json_array_set(_value, index, value.as_json_t());
173
174                 return *this;
175         }
176
177         Value& set_at(int index, const Value& value) {
178                 return set_at(static_cast<unsigned int>(index), value);
179         }
180
181 private:
182         // take ownership of a json_t (does not increase reference count)
183         static Value _take(json_t* json) {
184                 Value v;
185                 v._value = json;
186                 return v;
187         }
188
189         // internal value pointer
190         json_t* _value;
191 };
192
193 // iterators over a JSON object
194 class Iterator {
195 public:
196         // construct a new iterator for a given object
197         Iterator(const Value& value) : _object(value), _iter(0) {
198                 _iter = json_object_iter(_object.as_json_t());
199         }
200
201         // increment iterator
202         void next() {
203                 _iter = json_object_iter_next(_object.as_json_t(), _iter);
204         }
205
206         Iterator& operator++() { next(); return *this; }
207
208         // test if iterator is still valid
209         bool valid() const { return _iter != 0; }
210         operator bool() const { return valid(); }
211
212         // get key
213         const char* ckey() const {
214                 return json_object_iter_key(_iter);
215         }
216
217         std::string key() const { return ckey(); }
218
219         // get value
220         const Value value() const {
221                 return Value(json_object_iter_value(_iter));
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