2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * JSONObject utilities.
37 #include "gssapiP_eap.h"
45 #define JSON_INIT(obj) do { \
47 throw std::bad_alloc(); \
51 #define JSON_CHECK_CONTAINER() do { \
52 if (!json_is_object(m_obj) && !json_is_array(m_obj)) { \
53 std::string s("JSONObject is not a container"); \
54 throw JSONException(m_obj); \
58 #define JSON_CHECK_OBJECT() do { \
59 if (!json_is_object(m_obj)) { \
60 std::string s("JSONObject is not a dictionary"); \
61 throw JSONException(m_obj, JSON_OBJECT); \
65 #define JSON_CHECK_ARRAY() do { \
66 if (!json_is_array(m_obj)) { \
67 throw JSONException(m_obj, JSON_ARRAY); \
71 #define JSON_CHECK(s) do { \
73 throw JSONException(); \
77 JSONObject::load(const char *input, size_t flags, json_error_t *error)
81 obj = json_loads(input, flags, error);
83 return JSONObject(obj, false);
87 JSONObject::load(FILE *fp, size_t flags, json_error_t *error)
91 obj = json_loadf(fp, flags, error);
93 return JSONObject(obj, false);
97 JSONObject::dump(size_t flags) const
99 char *s = json_dumps(m_obj, flags);
102 throw std::bad_alloc();
108 JSONObject::dump(FILE *fp, size_t flags) const
110 int r = json_dumpf(m_obj, fp, flags);
113 throw std::bad_alloc();
117 JSONObject::size(void) const
119 if (json_is_object(m_obj))
120 return json_object_size(m_obj);
121 else if (json_is_array(m_obj))
122 return json_array_size(m_obj);
127 JSONObject::JSONObject(json_t *obj, bool retain)
134 JSONObject::JSONObject(const char *value)
136 json_t *obj = json_string(value);
141 JSONObject::JSONObject(json_int_t value)
143 json_t *obj = json_integer(value);
148 JSONObject::JSONObject(double value)
150 json_t *obj = json_real(value);
155 JSONObject::JSONObject(bool value)
157 json_t *obj = value ? json_true() : json_false();
162 JSONObject::JSONObject(void)
164 json_t *obj = json_object();
170 JSONObject::object(void)
176 JSONObject::null(void)
178 return JSONObject(json_null(), false);
182 JSONObject::array(void)
184 return JSONObject(json_array(), false);
188 JSONObject::set(const char *key, JSONObject &value)
191 JSON_CHECK(json_object_set_new(m_obj, key, value.get()));
195 JSONObject::set(const char *key, const char *value)
197 JSONObject jobj(value);
202 JSONObject::set(const char *key, json_int_t value)
204 JSONObject jobj(value);
209 JSONObject::del(const char *key)
211 json_object_del(m_obj, key);
215 JSONObject::get(const char *key) const
219 obj = json_object_get(m_obj, key);
221 return JSONObject::null();
223 return JSONObject(obj, true);
227 JSONObject::get(size_t index) const
231 obj = json_array_get(m_obj, index);
233 return JSONObject::null();
235 return JSONObject(obj, true);
239 JSONObject::update(JSONObject &value)
242 json_t *other = value.get();
243 JSON_CHECK(json_object_update(m_obj, other));
248 JSONObject::operator[](size_t index) const
254 JSONObject::operator[](const char *key) const
260 JSONObject::append(JSONObject &value)
263 JSON_CHECK(json_array_append_new(m_obj, value.get()));
267 JSONObject::insert(size_t index, JSONObject &value)
270 JSON_CHECK(json_array_insert_new(m_obj, index, value.get()));
274 JSONObject::remove(size_t index)
277 JSON_CHECK(json_array_remove(m_obj, index));
281 JSONObject::clear(void)
283 JSON_CHECK_CONTAINER();
285 if (json_is_object(m_obj)) {
286 JSON_CHECK(json_object_clear(m_obj));
287 } else if (json_is_array(m_obj)) {
288 JSON_CHECK(json_array_clear(m_obj));
293 JSONObject::extend(JSONObject &value)
296 json_t *other = value.get();
297 JSON_CHECK(json_array_extend(m_obj, other));
302 JSONObject::string(void) const
304 return json_string_value(m_obj);
308 JSONObject::integer(void) const
310 return json_integer_value(m_obj);
314 JSONObject::real(void) const
316 return json_real_value(m_obj);
320 JSONObject::number(void) const
322 return json_number_value(m_obj);
326 JSONObject::ddf(DDF &ddf)
328 if (ddf.isstruct()) {
329 DDF elem = ddf.first();
330 JSONObject jobj = JSONObject::object();
332 while (!elem.isnull()) {
333 JSONObject jtmp = JSONObject::ddf(elem);
334 jobj.set(elem.name(), jtmp);
339 } else if (ddf.islist()) {
340 DDF elem = ddf.first();
341 JSONObject jobj = JSONObject::array();
343 while (!elem.isnull()) {
344 JSONObject jtmp = JSONObject::ddf(elem);
350 } else if (ddf.isstring()) {
351 return JSONObject(ddf.string());
352 } else if (ddf.isint()) {
353 return JSONObject((json_int_t)ddf.integer());
354 } else if (ddf.isfloat()) {
355 return JSONObject(ddf.floating());
356 } else if (ddf.isempty() || ddf.ispointer()) {
357 return JSONObject::object();
358 } else if (ddf.isnull()) {
359 return JSONObject::null();
362 std::string s("Unbridgeable DDF object");
363 throw JSONException();
367 JSONObject::ddf(void) const
373 JSONIterator iter = iterator();
376 const char *key = iter.key();
377 DDF value = iter.value().ddf();
378 ddf.addmember(key).swap(value);
379 } while (iter.next());
383 size_t i, nelems = size();
385 for (i = 0; i < nelems; i++) {
386 DDF value = get(i).ddf();
392 ddf.string(string());
395 ddf.integer(integer());
398 ddf.floating(real());
413 bool JSONObject::isObject(void) const
415 return json_is_object(m_obj);
418 bool JSONObject::isArray(void) const
420 return json_is_array(m_obj);
423 bool JSONObject::isString(void) const
425 return json_is_string(m_obj);
428 bool JSONObject::isInteger(void) const
430 return json_is_integer(m_obj);
433 bool JSONObject::isNumber(void) const
435 return json_is_number(m_obj);
438 bool JSONObject::isBoolean(void) const
440 return json_is_boolean(m_obj);
443 bool JSONObject::isNull(void) const
445 return json_is_null(m_obj);
448 JSONIterator::JSONIterator(const JSONObject &obj)
451 m_iter = json_object_iter(m_obj);
454 JSONIterator::~JSONIterator(void)
460 JSONIterator::key(void) const
462 return json_object_iter_key(m_iter);
466 JSONIterator::value(void) const
468 return JSONObject(json_object_iter_value(m_iter));
472 JSONIterator::next(void)
474 m_iter = json_object_iter_next(m_obj, m_iter);
475 return m_iter != NULL;
478 JSONException::JSONException(json_t *obj, json_type type)
483 m_obj = json_incref(obj);
487 s = json_dumps(m_obj, 0);
490 case JSON_OBJECT: t = "OBJECT"; break;
491 case JSON_ARRAY: t = "ARRAY"; break;
492 case JSON_STRING: t = "STRING"; break;
493 case JSON_INTEGER: t = "INTEGER"; break;
494 case JSON_REAL: t = "REAL"; break;
495 case JSON_TRUE: t = "TRUE"; break;
496 case JSON_FALSE: t = "FALSE"; break;
497 case JSON_NULL: t = "NULL"; break;
498 default: t = "UNKNOWN"; break;
502 m_reason = "Invalid JSON object: " + std::string(s);
503 if (type != JSON_NULL)
504 m_reason += " (excepted type " + std::string(t) + ")";
506 m_reason = "Internal JSON error";