1 // janssonxx - C++ wrapper for jansson, implementation file
3 // author: Sean Middleditch <sean@middleditch.us>
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.
8 #if !defined(IN_JANSSON_HPP)
9 # error "jansson-impl.hpp may only by included from jansson.hpp"
14 // assignment operator
15 template <typename _Base>
16 ValueBase<_Base>& ValueBase<_Base>::operator=(const Value& value) {
17 _Base::operator=(value);
22 template <typename _Base>
23 bool ValueBase<_Base>::is_undefined() const {
24 return _Base::as_json() == 0;
27 template <typename _Base>
28 bool ValueBase<_Base>::is_object() const {
29 return json_is_object(_Base::as_json());
32 template <typename _Base>
33 bool ValueBase<_Base>::is_array() const {
34 return json_is_array(_Base::as_json());
37 template <typename _Base>
38 bool ValueBase<_Base>::is_string() const {
39 return json_is_string(_Base::as_json());
42 template <typename _Base>
43 bool ValueBase<_Base>::is_integer() const {
44 return json_is_integer(_Base::as_json());
47 template <typename _Base>
48 bool ValueBase<_Base>::is_real() const {
49 return json_is_real(_Base::as_json());
52 template <typename _Base>
53 bool ValueBase<_Base>::is_number() const {
54 return json_is_number(_Base::as_json());
57 template <typename _Base>
58 bool ValueBase<_Base>::is_true() const {
59 return json_is_true(_Base::as_json());
62 template <typename _Base>
63 bool ValueBase<_Base>::is_false() const {
64 return json_is_false(_Base::as_json());
67 template <typename _Base>
68 bool ValueBase<_Base>::is_boolean() const {
69 return json_is_boolean(_Base::as_json());
72 template <typename _Base>
73 bool ValueBase<_Base>::is_null() const {
74 return json_is_null(_Base::as_json());
77 // get size of array or object
78 template <typename _Base>
79 unsigned int ValueBase<_Base>::size() const {
81 return json_object_size(_Base::as_json());
83 return json_array_size(_Base::as_json());
86 // get value at array index (const version)
87 template <typename _Base>
88 const Value ValueBase<_Base>::at(unsigned int index) const {
89 return Value(json_array_get(_Base::as_json(), index));
92 template <typename _Base>
93 const Value ValueBase<_Base>::operator[](signed int index) const { return at(index); }
94 template <typename _Base>
95 const Value ValueBase<_Base>::operator[](unsigned int index) const { return at(index); }
96 template <typename _Base>
97 const Value ValueBase<_Base>::operator[](signed short index) const { return at(index); }
98 template <typename _Base>
99 const Value ValueBase<_Base>::operator[](unsigned short index) const { return at(index); }
100 template <typename _Base>
101 const Value ValueBase<_Base>::operator[](signed long index) const { return at(index); }
102 template <typename _Base>
103 const Value ValueBase<_Base>::operator[](unsigned long index) const { return at(index); }
105 // get value at array index (non-const version)
106 template <typename _Base>
107 ValueBase<ElementProxy> ValueBase<_Base>::at(unsigned int index) {
108 return ElementProxy(_Base::as_json(), index);
111 template <typename _Base>
112 ValueBase<ElementProxy> ValueBase<_Base>::operator[](signed int index) {
116 template <typename _Base>
117 ValueBase<ElementProxy> ValueBase<_Base>::operator[](unsigned int index) {
121 template <typename _Base>
122 ValueBase<ElementProxy> ValueBase<_Base>::operator[](signed short index) {
126 template <typename _Base>
127 ValueBase<ElementProxy> ValueBase<_Base>::operator[](unsigned short index) {
131 template <typename _Base>
132 ValueBase<ElementProxy> ValueBase<_Base>::operator[](signed long index) {
136 template <typename _Base>
137 ValueBase<ElementProxy> ValueBase<_Base>::operator[](unsigned long index) {
141 // get object property (const version)
142 template <typename _Base>
143 const Value ValueBase<_Base>::get(const char* key) const {
144 return Value(json_object_get(_Base::as_json(), key));
147 template <typename _Base>
148 const Value ValueBase<_Base>::get(const std::string& key) const {
149 return get(key.c_str());
152 template <typename _Base>
153 const Value ValueBase<_Base>::operator[](const char* key) const {
157 template <typename _Base>
158 const Value ValueBase<_Base>::operator[](const std::string& key) const {
159 return get(key.c_str());
162 // get object property (non-const version)
163 template <typename _Base>
164 ValueBase<PropertyProxy> ValueBase<_Base>::get(const char* key) {
165 return PropertyProxy(_Base::as_json(), key);
168 template <typename _Base>
169 ValueBase<PropertyProxy> ValueBase<_Base>::get(const std::string& key) {
170 return get(key.c_str());
173 template <typename _Base>
174 ValueBase<PropertyProxy> ValueBase<_Base>::operator[](const char* key) {
178 template <typename _Base>
179 ValueBase<PropertyProxy> ValueBase<_Base>::operator[](const std::string& key) {
180 return get(key.c_str());
183 // clear all array/object values
184 template <typename _Base>
185 void ValueBase<_Base>::clear() {
187 json_object_clear(_Base::as_json());
189 json_array_clear(_Base::as_json());
192 // get value cast to specified type
193 template <typename _Base>
194 const char* ValueBase<_Base>::as_cstring() const {
195 return json_string_value(_Base::as_json());
198 template <typename _Base>
199 std::string ValueBase<_Base>::as_string() const {
200 const char* tmp = as_cstring();
201 return tmp == 0 ? "" : tmp;
204 template <typename _Base>
205 int ValueBase<_Base>::as_integer() const {
206 return json_integer_value(_Base::as_json());
209 template <typename _Base>
210 double ValueBase<_Base>::as_real() const {
211 return json_real_value(_Base::as_json());
214 template <typename _Base>
215 double ValueBase<_Base>::as_number() const {
216 return json_number_value(_Base::as_json());
219 template <typename _Base>
220 bool ValueBase<_Base>::as_boolean() const {
224 // set an object property (converts value to object is not one already)
225 template <typename _Base>
226 _Base& ValueBase<_Base>::set_key(const char* key, const Value& value) {
227 json_object_set(_Base::as_json(), key, value._Base::as_json());
231 template <typename _Base>
232 _Base& ValueBase<_Base>::set_key(const std::string& key, const Value& value) {
233 return set_key(key.c_str(), value);
236 // set an array index (converts value to object is not one already)
237 template <typename _Base>
238 _Base& ValueBase<_Base>::set_at(unsigned int index, const Value& value) {
240 json_array_append(_Base::as_json(), value._Base::as_json());
242 json_array_set(_Base::as_json(), index, value._Base::as_json());
246 // delete an object key
247 template <typename _Base>
248 _Base& ValueBase<_Base>::del_key(const char* key) {
249 json_object_del(_Base::as_json(), key);
253 template <typename _Base>
254 _Base& ValueBase<_Base>::del_key(const std::string& key) {
255 return del_key(key.c_str());
258 // delete an item from an array by index
259 template <typename _Base>
260 _Base& ValueBase<_Base>::del_at(unsigned int index) {
261 json_array_remove(_Base::as_json(), index);
265 // insert an item into an array at a given index
266 template <typename _Base>
267 _Base& ValueBase<_Base>::insert_at(unsigned int index, const Value& value) {
268 json_array_insert(_Base::as_json(), index, value._Base::as_json());
272 // write the value to a file
273 template <typename _Base>
274 int ValueBase<_Base>::save_file(const char* path, int flags) const {
275 return json_dump_file(_Base::as_json(), path, flags);
278 // write the value to a string (caller must deallocate with free()!)
279 template <typename _Base>
280 char* ValueBase<_Base>::save_string(int flags) const {
281 return json_dumps(_Base::as_json(), flags);
288 // copy an existing Value
289 Basic& Basic::operator=(const Basic& e) {
292 _value = json_incref(e._value);
297 // get the underlying json_t
298 json_t* Basic::as_json() const {
302 // take ownership of a json_t (does not increase reference count)
303 Basic Basic::take_ownership(json_t* json) {
309 // assign value to proxied array element
310 ElementProxy& ElementProxy::operator=(const Value& value) {
311 json_array_set(_array, _index, value.as_json());
315 // get the proxied element
316 json_t* ElementProxy::as_json() const {
317 return json_array_get(_array, _index);
320 // assign value to proxied object property
321 PropertyProxy& PropertyProxy::operator=(const Value& value) {
322 json_object_set(_object, _key, value.as_json());
326 json_t* PropertyProxy::as_json() const {
327 return json_object_get(_object, _key);
330 } // namespace json::_private
332 // construct Value::Value input
333 Value::Value(const char* value) {
334 _value = json_string(value);
337 Value::Value(const std::string& value) {
338 _value = json_string(value.c_str());
341 Value::Value(bool value) {
342 _value = value ? json_true() : json_false();
345 Value::Value(signed int value) {
346 _value = json_integer(value);
349 Value::Value(unsigned int value) {
350 _value = json_integer(value);
353 Value::Value(signed short value) {
354 _value = json_integer(value);
357 Value::Value(unsigned short value) {
358 _value = json_integer(value);
361 Value::Value(signed long value) {
362 _value = json_integer(value);
365 Value::Value(unsigned long value) {
366 _value = json_integer(value);
369 Value::Value(float value) {
370 _value = json_real(value);
373 Value::Value(double value) {
374 _value = json_real(value);
377 // construct a new iterator for a given object
378 Iterator::Iterator(const Value& value) : _object(value), _iter(0) {
379 _iter = json_object_iter(_object.as_json());
382 // construct a new iterator for a given object
383 Iterator::Iterator(const _private::ValueBase<_private::PropertyProxy>& value) :
384 _object(value.as_json()), _iter(0) {
385 _iter = json_object_iter(_object.as_json());
388 // increment iterator
389 void Iterator::next() {
390 _iter = json_object_iter_next(_object.as_json(), _iter);
393 Iterator& Iterator::operator++() { next(); return *this; }
395 // test if iterator is still valid
396 bool Iterator::valid() const {
400 Iterator::operator bool() const {
405 const char* Iterator::ckey() const {
406 return json_object_iter_key(_iter);
409 std::string Iterator::key() const {
414 const Value Iterator::value() const {
415 return Value(json_object_iter_value(_iter));
419 const Value Iterator::operator*() const {
423 // create a new empty object
425 return Value::take_ownership(json_object());
428 // create a new empty array
430 return Value::take_ownership(json_array());
433 // create a new null value
435 return Value::take_ownership(json_null());
438 // load a file as a JSON value
439 Value load_file(const char* path, json_error_t* error) {
440 return Value::take_ownership(json_load_file(path, error));
443 // load a string as a JSON value
444 Value load_string(const char* string, json_error_t* error) {
445 return Value::take_ownership(json_loads(string, error));
450 // stream JSON value out
451 std::ostream& operator<<(std::ostream& os, const json::Value& value) {
452 // get the temporary serialize string
453 char* tmp = value.save_string();
455 // stream temp string out and release it
463 std::istream& operator>>(std::istream& is, json::Value& value) {
464 // buffer the remaining bytes into a single string for Jansson
465 std::stringstream tmp;
467 tmp << static_cast<char>(is.get());
468 // parse the buffered string
469 value = json::load_string(tmp.str().c_str());