blob: 8ed02398fb370ea834c6a27e56e2c8edc075df1d [file] [log] [blame]
Michael Clarkf0d08882007-03-13 08:26:18 +00001/*
Michael Clarka850f8e2007-03-13 08:26:26 +00002 * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
Michael Clarkf0d08882007-03-13 08:26:18 +00003 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00004 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
Michael Clarkf0d08882007-03-13 08:26:18 +00005 * Michael Clark <michael@metaparadigm.com>
Keith Derrick69175862012-04-12 11:44:13 -07006 * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
Michael Clarkf0d08882007-03-13 08:26:18 +00007 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00008 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the MIT license. See COPYING for details.
Michael Clarkf0d08882007-03-13 08:26:18 +000010 *
11 */
12
Michael Clark4504df72007-03-13 08:26:20 +000013#include "config.h"
14
Michael Clarkf0d08882007-03-13 08:26:18 +000015#include <stdio.h>
16#include <stdlib.h>
Michael Clarkc8f4a6e2007-12-07 02:44:24 +000017#include <stddef.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000018#include <string.h>
Adrian Yanesd086e202013-06-07 13:14:54 -070019#include <math.h>
Keith Derrickc51b88d2013-10-01 09:18:51 -070020#include <errno.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000021
22#include "debug.h"
23#include "printbuf.h"
24#include "linkhash.h"
25#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000026#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000027#include "json_object.h"
28#include "json_object_private.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000029#include "json_util.h"
Eric Haszlakiewicze6f13222014-03-02 12:16:37 -050030#include "math_compat.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000031
Mateusz Loskota6f39a32012-05-21 23:22:36 +010032#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
33 /* MSC has the version as _strdup */
34# define strdup _strdup
35#elif !defined(HAVE_STRDUP)
36# error You do not have strdup on your system.
37#endif /* HAVE_STRDUP */
38
Anatol Belskied819fb2013-06-04 20:18:05 +020039#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
40 /* MSC has the version as _snprintf */
41# define snprintf _snprintf
42#elif !defined(HAVE_SNPRINTF)
43# error You do not have snprintf on your system.
44#endif /* HAVE_SNPRINTF */
45
Keith Derrick69175862012-04-12 11:44:13 -070046// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000047/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000048
Michael Clark68cafad2009-01-06 22:56:57 +000049const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010050const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000051
Michael Clark266a3fd2009-02-25 01:55:31 +000052static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000053static struct json_object* json_object_new(enum json_type o_type);
54
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -050055static json_object_to_json_string_fn json_object_object_to_json_string;
56static json_object_to_json_string_fn json_object_boolean_to_json_string;
57static json_object_to_json_string_fn json_object_int_to_json_string;
58static json_object_to_json_string_fn json_object_double_to_json_string;
59static json_object_to_json_string_fn json_object_string_to_json_string;
60static json_object_to_json_string_fn json_object_array_to_json_string;
61
Michael Clarkf0d08882007-03-13 08:26:18 +000062
63/* ref count debugging */
64
65#ifdef REFCOUNT_DEBUG
66
67static struct lh_table *json_object_table;
68
Michael Clark14862b12007-12-07 02:50:42 +000069static void json_object_init(void) __attribute__ ((constructor));
70static void json_object_init(void) {
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -040071 MC_DEBUG("json_object_init: creating object table\n");
72 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
Michael Clarkf0d08882007-03-13 08:26:18 +000073}
74
Michael Clark14862b12007-12-07 02:50:42 +000075static void json_object_fini(void) __attribute__ ((destructor));
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -040076static void json_object_fini(void)
77{
78 struct lh_entry *ent;
79 if (MC_GET_DEBUG())
80 {
81 if (json_object_table->count)
82 {
83 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
84 json_object_table->count);
85 lh_foreach(json_object_table, ent)
86 {
87 struct json_object* obj = (struct json_object*)ent->v;
88 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
89 }
90 }
91 }
92 MC_DEBUG("json_object_fini: freeing object table\n");
93 lh_table_free(json_object_table);
Michael Clarkf0d08882007-03-13 08:26:18 +000094}
Michael Clark4504df72007-03-13 08:26:20 +000095#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000096
97
98/* string escaping */
99
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000100static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000101{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400102 int pos = 0, start_offset = 0;
103 unsigned char c;
104 while (len--)
105 {
106 c = str[pos];
107 switch(c)
108 {
109 case '\b':
110 case '\n':
111 case '\r':
112 case '\t':
113 case '\f':
114 case '"':
115 case '\\':
116 case '/':
117 if(pos - start_offset > 0)
118 printbuf_memappend(pb, str + start_offset, pos - start_offset);
119
120 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
121 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
122 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
123 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
124 else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
125 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
126 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
127 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
128
129 start_offset = ++pos;
130 break;
131 default:
132 if(c < ' ')
133 {
134 if(pos - start_offset > 0)
135 printbuf_memappend(pb, str + start_offset, pos - start_offset);
136 sprintbuf(pb, "\\u00%c%c",
137 json_hex_chars[c >> 4],
138 json_hex_chars[c & 0xf]);
139 start_offset = ++pos;
140 } else
141 pos++;
142 }
143 }
144 if (pos - start_offset > 0)
145 printbuf_memappend(pb, str + start_offset, pos - start_offset);
146 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000147}
148
149
150/* reference counting */
151
Michael Clark266a3fd2009-02-25 01:55:31 +0000152extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000153{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400154 if (jso)
155 jso->_ref_count++;
156 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000157}
158
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500159int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000160{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500161 if(jso)
162 {
163 jso->_ref_count--;
164 if(!jso->_ref_count)
165 {
166 if (jso->_user_delete)
167 jso->_user_delete(jso, jso->_userdata);
168 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500169 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500170 }
171 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500172 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000173}
174
175
176/* generic object construction and destruction parts */
177
Michael Clark266a3fd2009-02-25 01:55:31 +0000178static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000179{
180#ifdef REFCOUNT_DEBUG
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400181 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000182 json_type_to_name(jso->o_type), jso);
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400183 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000184#endif /* REFCOUNT_DEBUG */
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400185 printbuf_free(jso->_pb);
186 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000187}
188
189static struct json_object* json_object_new(enum json_type o_type)
190{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400191 struct json_object *jso;
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000192
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400193 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
194 if (!jso)
195 return NULL;
196 jso->o_type = o_type;
197 jso->_ref_count = 1;
198 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000199#ifdef REFCOUNT_DEBUG
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400200 lh_table_insert(json_object_table, jso, jso);
201 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000202#endif /* REFCOUNT_DEBUG */
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400203 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000204}
205
206
207/* type checking functions */
208
Michael Clark266a3fd2009-02-25 01:55:31 +0000209int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000210{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400211 if (!jso)
212 return (type == json_type_null);
213 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000214}
215
Michael Clark266a3fd2009-02-25 01:55:31 +0000216enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000217{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400218 if (!jso)
219 return json_type_null;
220 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000221}
222
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500223/* set a custom conversion to string */
224
225void json_object_set_serializer(json_object *jso,
226 json_object_to_json_string_fn to_string_func,
227 void *userdata,
228 json_object_delete_fn *user_delete)
229{
230 // First, clean up any previously existing user info
231 if (jso->_user_delete)
232 {
233 jso->_user_delete(jso, jso->_userdata);
234 }
235 jso->_userdata = NULL;
236 jso->_user_delete = NULL;
237
238 if (to_string_func == NULL)
239 {
240 // Reset to the standard serialization function
241 switch(jso->o_type)
242 {
243 case json_type_null:
244 jso->_to_json_string = NULL;
245 break;
246 case json_type_boolean:
247 jso->_to_json_string = &json_object_boolean_to_json_string;
248 break;
249 case json_type_double:
250 jso->_to_json_string = &json_object_double_to_json_string;
251 break;
252 case json_type_int:
253 jso->_to_json_string = &json_object_int_to_json_string;
254 break;
255 case json_type_object:
256 jso->_to_json_string = &json_object_object_to_json_string;
257 break;
258 case json_type_array:
259 jso->_to_json_string = &json_object_array_to_json_string;
260 break;
261 case json_type_string:
262 jso->_to_json_string = &json_object_string_to_json_string;
263 break;
264 }
265 return;
266 }
267
268 jso->_to_json_string = to_string_func;
269 jso->_userdata = userdata;
270 jso->_user_delete = user_delete;
271}
272
273
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500274/* extended conversion to string */
275
276const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
277{
278 if (!jso)
279 return "null";
280
281 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
282 return NULL;
283
284 printbuf_reset(jso->_pb);
285
286 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
287 return NULL;
288
289 return jso->_pb->buf;
290}
291
292/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000293
Michael Clark266a3fd2009-02-25 01:55:31 +0000294const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000295{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500296 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000297}
298
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500299static void indent(struct printbuf *pb, int level, int flags)
300{
301 if (flags & JSON_C_TO_STRING_PRETTY)
302 {
303 printbuf_memset(pb, -1, ' ', level * 2);
304 }
305}
Michael Clarkf0d08882007-03-13 08:26:18 +0000306
307/* json_object_object */
308
Michael Clark266a3fd2009-02-25 01:55:31 +0000309static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500310 struct printbuf *pb,
311 int level,
312 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000313{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500314 int had_children = 0;
315 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000316
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500317 sprintbuf(pb, "{" /*}*/);
318 if (flags & JSON_C_TO_STRING_PRETTY)
319 sprintbuf(pb, "\n");
320 json_object_object_foreachC(jso, iter)
321 {
322 if (had_children)
323 {
324 sprintbuf(pb, ",");
325 if (flags & JSON_C_TO_STRING_PRETTY)
326 sprintbuf(pb, "\n");
327 }
328 had_children = 1;
329 if (flags & JSON_C_TO_STRING_SPACED)
330 sprintbuf(pb, " ");
331 indent(pb, level+1, flags);
332 sprintbuf(pb, "\"");
333 json_escape_str(pb, iter.key, strlen(iter.key));
334 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000335 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500336 else
337 sprintbuf(pb, "\":");
338 if(iter.val == NULL)
339 sprintbuf(pb, "null");
340 else
341 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000342 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500343 if (flags & JSON_C_TO_STRING_PRETTY)
344 {
345 if (had_children)
346 sprintbuf(pb, "\n");
347 indent(pb,level,flags);
348 }
349 if (flags & JSON_C_TO_STRING_SPACED)
350 return sprintbuf(pb, /*{*/ " }");
351 else
352 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000353}
354
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500355
Michael Clarkf0d08882007-03-13 08:26:18 +0000356static void json_object_lh_entry_free(struct lh_entry *ent)
357{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400358 free(ent->k);
359 json_object_put((struct json_object*)ent->v);
Michael Clarkf0d08882007-03-13 08:26:18 +0000360}
361
Michael Clark266a3fd2009-02-25 01:55:31 +0000362static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000363{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400364 lh_table_free(jso->o.c_object);
365 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000366}
367
Michael Clarke8de0782009-02-25 01:45:00 +0000368struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000369{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400370 struct json_object *jso = json_object_new(json_type_object);
371 if (!jso)
372 return NULL;
373 jso->_delete = &json_object_object_delete;
374 jso->_to_json_string = &json_object_object_to_json_string;
375 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000376 NULL, &json_object_lh_entry_free);
Eric Haszlakiewicz2149a042014-04-19 20:33:05 -0400377 if (!jso->o.c_object)
378 {
379 json_object_generic_delete(jso);
380 errno = ENOMEM;
381 return NULL;
382 }
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400383 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000384}
385
Michael Clark266a3fd2009-02-25 01:55:31 +0000386struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000387{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400388 if (!jso)
389 return NULL;
390 switch(jso->o_type)
391 {
392 case json_type_object:
393 return jso->o.c_object;
394 default:
395 return NULL;
396 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000397}
398
Michael Clark266a3fd2009-02-25 01:55:31 +0000399void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000400 struct json_object *val)
401{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500402 // We lookup the entry and replace the value, rather than just deleting
403 // and re-adding it, so the existing key remains valid.
404 json_object *existing_value = NULL;
405 struct lh_entry *existing_entry;
406 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
407 if (!existing_entry)
408 {
409 lh_table_insert(jso->o.c_object, strdup(key), val);
410 return;
411 }
412 existing_value = (void *)existing_entry->v;
413 if (existing_value)
414 json_object_put(existing_value);
415 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000416}
417
Greg Hazelcca74c62013-01-11 01:36:55 -0800418int json_object_object_length(struct json_object *jso)
419{
420 return lh_table_length(jso->o.c_object);
421}
422
Michael Clark266a3fd2009-02-25 01:55:31 +0000423struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000424{
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500425 struct json_object *result = NULL;
426 json_object_object_get_ex(jso, key, &result);
427 return result;
Keith Derrick69175862012-04-12 11:44:13 -0700428}
429
430json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
431{
Eric Haszlakiewicz5450bed2012-10-18 17:14:41 -0500432 if (value != NULL)
433 *value = NULL;
434
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500435 if (NULL == jso)
436 return FALSE;
Keith Derrick69175862012-04-12 11:44:13 -0700437
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500438 switch(jso->o_type)
439 {
440 case json_type_object:
441 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
442 default:
443 if (value != NULL)
444 *value = NULL;
445 return FALSE;
446 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000447}
448
Michael Clark266a3fd2009-02-25 01:55:31 +0000449void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000450{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500451 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000452}
453
454
455/* json_object_boolean */
456
Michael Clark266a3fd2009-02-25 01:55:31 +0000457static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500458 struct printbuf *pb,
459 int level,
460 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000461{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400462 if (jso->o.c_boolean)
463 return sprintbuf(pb, "true");
464 else
465 return sprintbuf(pb, "false");
Michael Clarkf0d08882007-03-13 08:26:18 +0000466}
467
Keith Derrick37e74672012-03-26 14:29:31 -0700468struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000469{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400470 struct json_object *jso = json_object_new(json_type_boolean);
471 if (!jso)
472 return NULL;
473 jso->_to_json_string = &json_object_boolean_to_json_string;
474 jso->o.c_boolean = b;
475 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000476}
477
Keith Derrick37e74672012-03-26 14:29:31 -0700478json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000479{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400480 if (!jso)
481 return FALSE;
482 switch(jso->o_type)
483 {
484 case json_type_boolean:
485 return jso->o.c_boolean;
486 case json_type_int:
487 return (jso->o.c_int64 != 0);
488 case json_type_double:
489 return (jso->o.c_double != 0);
490 case json_type_string:
491 return (jso->o.c_string.len != 0);
492 default:
493 return FALSE;
494 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000495}
496
497
498/* json_object_int */
499
Michael Clark266a3fd2009-02-25 01:55:31 +0000500static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500501 struct printbuf *pb,
502 int level,
503 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000504{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400505 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000506}
507
508struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000509{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400510 struct json_object *jso = json_object_new(json_type_int);
511 if (!jso)
512 return NULL;
513 jso->_to_json_string = &json_object_int_to_json_string;
514 jso->o.c_int64 = i;
515 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000516}
517
Michael Clarkc4dceae2010-10-06 16:39:20 +0000518int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000519{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100520 int64_t cint64;
521 enum json_type o_type;
522
Michael Clarkc4dceae2010-10-06 16:39:20 +0000523 if(!jso) return 0;
524
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100525 o_type = jso->o_type;
526 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000527
528 if (o_type == json_type_string)
529 {
530 /*
531 * Parse strings into 64-bit numbers, then use the
532 * 64-to-32-bit number handling below.
533 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000534 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000535 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000536 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000537 }
538
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000539 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000540 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000541 /* Make sure we return the correct values for out of range numbers. */
542 if (cint64 <= INT32_MIN)
543 return INT32_MIN;
544 else if (cint64 >= INT32_MAX)
545 return INT32_MAX;
546 else
547 return (int32_t)cint64;
548 case json_type_double:
549 return (int32_t)jso->o.c_double;
550 case json_type_boolean:
551 return jso->o.c_boolean;
552 default:
553 return 0;
554 }
555}
556
557struct json_object* json_object_new_int64(int64_t i)
558{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400559 struct json_object *jso = json_object_new(json_type_int);
560 if (!jso)
561 return NULL;
562 jso->_to_json_string = &json_object_int_to_json_string;
563 jso->o.c_int64 = i;
564 return jso;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000565}
566
567int64_t json_object_get_int64(struct json_object *jso)
568{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400569 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000570
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400571 if (!jso)
572 return 0;
573 switch(jso->o_type)
574 {
575 case json_type_int:
576 return jso->o.c_int64;
577 case json_type_double:
578 return (int64_t)jso->o.c_double;
579 case json_type_boolean:
580 return jso->o.c_boolean;
581 case json_type_string:
582 if (json_parse_int64(jso->o.c_string.str, &cint) == 0)
583 return cint;
584 default:
585 return 0;
586 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000587}
588
589
590/* json_object_double */
591
Michael Clark266a3fd2009-02-25 01:55:31 +0000592static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500593 struct printbuf *pb,
594 int level,
595 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000596{
Remi Collet8c847962012-12-13 11:22:31 +0100597 char buf[128], *p, *q;
Remi Collet4014fe82012-12-13 11:16:03 +0100598 int size;
Adrian Yanesd086e202013-06-07 13:14:54 -0700599 /* Although JSON RFC does not support
600 NaN or Infinity as numeric values
601 ECMA 262 section 9.8.1 defines
602 how to handle these cases as strings */
603 if(isnan(jso->o.c_double))
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500604 size = snprintf(buf, sizeof(buf), "NaN");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300605 else if(isinf(jso->o.c_double))
606 if(jso->o.c_double > 0)
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500607 size = snprintf(buf, sizeof(buf), "Infinity");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300608 else
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500609 size = snprintf(buf, sizeof(buf), "-Infinity");
Adrian Yanesd086e202013-06-07 13:14:54 -0700610 else
Eric Haszlakiewicz06450202013-09-11 21:09:43 -0500611 size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double);
Remi Collet4014fe82012-12-13 11:16:03 +0100612
Remi Collet4014fe82012-12-13 11:16:03 +0100613 p = strchr(buf, ',');
614 if (p) {
615 *p = '.';
Remi Collet8c847962012-12-13 11:22:31 +0100616 } else {
617 p = strchr(buf, '.');
618 }
Remi Collet32d149c2012-12-13 11:46:04 +0100619 if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
Remi Collet8c847962012-12-13 11:22:31 +0100620 /* last useful digit, always keep 1 zero */
621 p++;
622 for (q=p ; *q ; q++) {
623 if (*q!='0') p=q;
624 }
625 /* drop trailing zeroes */
626 *(++p) = 0;
627 size = p-buf;
Remi Collet4014fe82012-12-13 11:16:03 +0100628 }
629 printbuf_memappend(pb, buf, size);
630 return size;
Michael Clarkf0d08882007-03-13 08:26:18 +0000631}
632
633struct json_object* json_object_new_double(double d)
634{
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500635 struct json_object *jso = json_object_new(json_type_double);
636 if (!jso)
637 return NULL;
638 jso->_to_json_string = &json_object_double_to_json_string;
639 jso->o.c_double = d;
640 return jso;
641}
642
643struct json_object* json_object_new_double_s(double d, const char *ds)
644{
645 struct json_object *jso = json_object_new_double(d);
646 if (!jso)
647 return NULL;
648
Eric Haszlakiewicz2149a042014-04-19 20:33:05 -0400649 char *new_ds = strdup(ds);
650 if (!new_ds)
651 {
652 json_object_generic_delete(jso);
653 errno = ENOMEM;
654 return NULL;
655 }
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500656 json_object_set_serializer(jso, json_object_userdata_to_json_string,
Eric Haszlakiewicz2149a042014-04-19 20:33:05 -0400657 new_ds, json_object_free_userdata);
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500658 return jso;
659}
660
661int json_object_userdata_to_json_string(struct json_object *jso,
662 struct printbuf *pb, int level, int flags)
663{
664 int userdata_len = strlen(jso->_userdata);
665 printbuf_memappend(pb, jso->_userdata, userdata_len);
666 return userdata_len;
667}
668
669void json_object_free_userdata(struct json_object *jso, void *userdata)
670{
671 free(userdata);
Michael Clarkf0d08882007-03-13 08:26:18 +0000672}
673
Michael Clark266a3fd2009-02-25 01:55:31 +0000674double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000675{
676 double cdouble;
Keith Derrickc51b88d2013-10-01 09:18:51 -0700677 char *errPtr = NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000678
Michael Clark266a3fd2009-02-25 01:55:31 +0000679 if(!jso) return 0.0;
680 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000681 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000682 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000683 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000684 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000685 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000686 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000687 case json_type_string:
Keith Derrickc51b88d2013-10-01 09:18:51 -0700688 errno = 0;
689 cdouble = strtod(jso->o.c_string.str,&errPtr);
690
691 /* if conversion stopped at the first character, return 0.0 */
692 if (errPtr == jso->o.c_string.str)
693 return 0.0;
694
695 /*
696 * Check that the conversion terminated on something sensible
697 *
698 * For example, { "pay" : 123AB } would parse as 123.
699 */
700 if (*errPtr != '\0')
701 return 0.0;
702
703 /*
704 * If strtod encounters a string which would exceed the
705 * capacity of a double, it returns +/- HUGE_VAL and sets
706 * errno to ERANGE. But +/- HUGE_VAL is also a valid result
707 * from a conversion, so we need to check errno.
708 *
709 * Underflow also sets errno to ERANGE, but it returns 0 in
710 * that case, which is what we will return anyway.
711 *
712 * See CERT guideline ERR30-C
713 */
714 if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
715 (ERANGE == errno))
716 cdouble = 0.0;
717 return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000718 default:
719 return 0.0;
720 }
721}
722
723
724/* json_object_string */
725
Michael Clark266a3fd2009-02-25 01:55:31 +0000726static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500727 struct printbuf *pb,
728 int level,
729 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000730{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400731 sprintbuf(pb, "\"");
732 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
733 sprintbuf(pb, "\"");
734 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000735}
736
Michael Clark266a3fd2009-02-25 01:55:31 +0000737static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000738{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400739 free(jso->o.c_string.str);
740 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000741}
742
Michael Clark68cafad2009-01-06 22:56:57 +0000743struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000744{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400745 struct json_object *jso = json_object_new(json_type_string);
746 if (!jso)
747 return NULL;
748 jso->_delete = &json_object_string_delete;
749 jso->_to_json_string = &json_object_string_to_json_string;
750 jso->o.c_string.str = strdup(s);
Eric Haszlakiewicz2149a042014-04-19 20:33:05 -0400751 if (!jso->o.c_string.str)
752 {
753 json_object_generic_delete(jso);
754 errno = ENOMEM;
755 return NULL;
756 }
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400757 jso->o.c_string.len = strlen(s);
758 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000759}
760
Michael Clark68cafad2009-01-06 22:56:57 +0000761struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000762{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400763 struct json_object *jso = json_object_new(json_type_string);
764 if (!jso)
765 return NULL;
766 jso->_delete = &json_object_string_delete;
767 jso->_to_json_string = &json_object_string_to_json_string;
768 jso->o.c_string.str = (char*)malloc(len + 1);
Eric Haszlakiewicz2149a042014-04-19 20:33:05 -0400769 if (!jso->o.c_string.str)
770 {
771 json_object_generic_delete(jso);
772 errno = ENOMEM;
773 return NULL;
774 }
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400775 memcpy(jso->o.c_string.str, (void *)s, len);
776 jso->o.c_string.str[len] = '\0';
777 jso->o.c_string.len = len;
778 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000779}
780
Michael Clark266a3fd2009-02-25 01:55:31 +0000781const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000782{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400783 if (!jso)
784 return NULL;
785 switch(jso->o_type)
786 {
787 case json_type_string:
788 return jso->o.c_string.str;
789 default:
790 return json_object_to_json_string(jso);
791 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000792}
793
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400794int json_object_get_string_len(struct json_object *jso)
795{
796 if (!jso)
797 return 0;
798 switch(jso->o_type)
799 {
800 case json_type_string:
801 return jso->o.c_string.len;
802 default:
803 return 0;
804 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000805}
806
Michael Clarkf0d08882007-03-13 08:26:18 +0000807
808/* json_object_array */
809
Michael Clark266a3fd2009-02-25 01:55:31 +0000810static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500811 struct printbuf *pb,
812 int level,
813 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000814{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500815 int had_children = 0;
816 int ii;
817 sprintbuf(pb, "[");
818 if (flags & JSON_C_TO_STRING_PRETTY)
819 sprintbuf(pb, "\n");
820 for(ii=0; ii < json_object_array_length(jso); ii++)
821 {
822 struct json_object *val;
823 if (had_children)
824 {
825 sprintbuf(pb, ",");
826 if (flags & JSON_C_TO_STRING_PRETTY)
827 sprintbuf(pb, "\n");
828 }
829 had_children = 1;
830 if (flags & JSON_C_TO_STRING_SPACED)
831 sprintbuf(pb, " ");
832 indent(pb, level + 1, flags);
833 val = json_object_array_get_idx(jso, ii);
834 if(val == NULL)
835 sprintbuf(pb, "null");
836 else
837 val->_to_json_string(val, pb, level+1, flags);
838 }
839 if (flags & JSON_C_TO_STRING_PRETTY)
840 {
841 if (had_children)
842 sprintbuf(pb, "\n");
843 indent(pb,level,flags);
844 }
Michael Clark4504df72007-03-13 08:26:20 +0000845
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500846 if (flags & JSON_C_TO_STRING_SPACED)
847 return sprintbuf(pb, " ]");
848 else
849 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000850}
851
852static void json_object_array_entry_free(void *data)
853{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400854 json_object_put((struct json_object*)data);
Michael Clarkf0d08882007-03-13 08:26:18 +0000855}
856
Michael Clark266a3fd2009-02-25 01:55:31 +0000857static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000858{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400859 array_list_free(jso->o.c_array);
860 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000861}
862
Michael Clarke8de0782009-02-25 01:45:00 +0000863struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000864{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400865 struct json_object *jso = json_object_new(json_type_array);
866 if (!jso)
867 return NULL;
868 jso->_delete = &json_object_array_delete;
869 jso->_to_json_string = &json_object_array_to_json_string;
870 jso->o.c_array = array_list_new(&json_object_array_entry_free);
871 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000872}
873
Michael Clark266a3fd2009-02-25 01:55:31 +0000874struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000875{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400876 if (!jso)
877 return NULL;
878 switch(jso->o_type)
879 {
880 case json_type_array:
881 return jso->o.c_array;
882 default:
883 return NULL;
884 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000885}
886
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200887void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
888{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400889 array_list_sort(jso->o.c_array, sort_fn);
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200890}
891
Michael Clark266a3fd2009-02-25 01:55:31 +0000892int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000893{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400894 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000895}
896
Michael Clark266a3fd2009-02-25 01:55:31 +0000897int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000898{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400899 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000900}
901
Michael Clark266a3fd2009-02-25 01:55:31 +0000902int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000903 struct json_object *val)
904{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400905 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000906}
907
Michael Clark266a3fd2009-02-25 01:55:31 +0000908struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000909 int idx)
910{
Eric Haszlakiewicz92a77402014-04-19 20:23:54 -0400911 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000912}
913