blob: b63faa48d4d2b40fdadc282b0c4652eedfccac91 [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>
Michael Clarkf0d08882007-03-13 08:26:18 +000020
21#include "debug.h"
22#include "printbuf.h"
23#include "linkhash.h"
24#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000025#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000026#include "json_object.h"
27#include "json_object_private.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000028#include "json_util.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000029
Mateusz Loskota6f39a32012-05-21 23:22:36 +010030#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
31 /* MSC has the version as _strdup */
32# define strdup _strdup
33#elif !defined(HAVE_STRDUP)
34# error You do not have strdup on your system.
35#endif /* HAVE_STRDUP */
36
37#if !defined(HAVE_STRNDUP)
Michael Clark837240f2007-03-13 08:26:25 +000038 char* strndup(const char* str, size_t n);
39#endif /* !HAVE_STRNDUP */
40
Anatol Belskied819fb2013-06-04 20:18:05 +020041#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
42 /* MSC has the version as _snprintf */
43# define snprintf _snprintf
44#elif !defined(HAVE_SNPRINTF)
45# error You do not have snprintf on your system.
46#endif /* HAVE_SNPRINTF */
47
Keith Derrick69175862012-04-12 11:44:13 -070048// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000049/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000050
Michael Clark68cafad2009-01-06 22:56:57 +000051const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010052const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000053
Michael Clark266a3fd2009-02-25 01:55:31 +000054static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000055static struct json_object* json_object_new(enum json_type o_type);
56
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -050057static json_object_to_json_string_fn json_object_object_to_json_string;
58static json_object_to_json_string_fn json_object_boolean_to_json_string;
59static json_object_to_json_string_fn json_object_int_to_json_string;
60static json_object_to_json_string_fn json_object_double_to_json_string;
61static json_object_to_json_string_fn json_object_string_to_json_string;
62static json_object_to_json_string_fn json_object_array_to_json_string;
63
Michael Clarkf0d08882007-03-13 08:26:18 +000064
65/* ref count debugging */
66
67#ifdef REFCOUNT_DEBUG
68
69static struct lh_table *json_object_table;
70
Michael Clark14862b12007-12-07 02:50:42 +000071static void json_object_init(void) __attribute__ ((constructor));
72static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000073 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000074 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
75}
76
Michael Clark14862b12007-12-07 02:50:42 +000077static void json_object_fini(void) __attribute__ ((destructor));
78static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000079 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000080 if(MC_GET_DEBUG()) {
81 if (json_object_table->count) {
82 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
83 json_object_table->count);
84 lh_foreach(json_object_table, ent) {
85 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000086 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000087 }
Michael Clarkf0d08882007-03-13 08:26:18 +000088 }
89 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000090 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000091 lh_table_free(json_object_table);
92}
Michael Clark4504df72007-03-13 08:26:20 +000093#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000094
95
96/* string escaping */
97
Jehiah Czebotarac601b52011-01-14 17:23:06 +000098static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000099{
100 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +0000101 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000102 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000103 c = str[pos];
104 switch(c) {
105 case '\b':
106 case '\n':
107 case '\r':
108 case '\t':
Abioy7eaa8492012-12-24 22:22:05 +0800109 case '\f':
Michael Clark4504df72007-03-13 08:26:20 +0000110 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000111 case '\\':
112 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000113 if(pos - start_offset > 0)
114 printbuf_memappend(pb, str + start_offset, pos - start_offset);
115 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
116 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
117 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
118 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Abioy7eaa8492012-12-24 22:22:05 +0800119 else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000120 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000121 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
122 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000123 start_offset = ++pos;
124 break;
125 default:
Michael Clark837240f2007-03-13 08:26:25 +0000126 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000127 if(pos - start_offset > 0)
128 printbuf_memappend(pb, str + start_offset, pos - start_offset);
129 sprintbuf(pb, "\\u00%c%c",
130 json_hex_chars[c >> 4],
131 json_hex_chars[c & 0xf]);
132 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000133 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000134 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000135 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000136 if(pos - start_offset > 0)
137 printbuf_memappend(pb, str + start_offset, pos - start_offset);
138 return 0;
139}
140
141
142/* reference counting */
143
Michael Clark266a3fd2009-02-25 01:55:31 +0000144extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000145{
Michael Clark266a3fd2009-02-25 01:55:31 +0000146 if(jso) {
147 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000148 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000149 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000150}
151
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500152int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000153{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500154 if(jso)
155 {
156 jso->_ref_count--;
157 if(!jso->_ref_count)
158 {
159 if (jso->_user_delete)
160 jso->_user_delete(jso, jso->_userdata);
161 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500162 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500163 }
164 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500165 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000166}
167
168
169/* generic object construction and destruction parts */
170
Michael Clark266a3fd2009-02-25 01:55:31 +0000171static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000172{
173#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000174 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000175 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000176 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000177#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000178 printbuf_free(jso->_pb);
179 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000180}
181
182static struct json_object* json_object_new(enum json_type o_type)
183{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000184 struct json_object *jso;
185
186 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000187 if(!jso) return NULL;
188 jso->o_type = o_type;
189 jso->_ref_count = 1;
190 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000191#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000192 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000193 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000194#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000195 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000196}
197
198
199/* type checking functions */
200
Michael Clark266a3fd2009-02-25 01:55:31 +0000201int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000202{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500203 if (!jso)
204 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000205 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000206}
207
Michael Clark266a3fd2009-02-25 01:55:31 +0000208enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000209{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500210 if (!jso)
211 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000212 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000213}
214
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500215/* set a custom conversion to string */
216
217void json_object_set_serializer(json_object *jso,
218 json_object_to_json_string_fn to_string_func,
219 void *userdata,
220 json_object_delete_fn *user_delete)
221{
222 // First, clean up any previously existing user info
223 if (jso->_user_delete)
224 {
225 jso->_user_delete(jso, jso->_userdata);
226 }
227 jso->_userdata = NULL;
228 jso->_user_delete = NULL;
229
230 if (to_string_func == NULL)
231 {
232 // Reset to the standard serialization function
233 switch(jso->o_type)
234 {
235 case json_type_null:
236 jso->_to_json_string = NULL;
237 break;
238 case json_type_boolean:
239 jso->_to_json_string = &json_object_boolean_to_json_string;
240 break;
241 case json_type_double:
242 jso->_to_json_string = &json_object_double_to_json_string;
243 break;
244 case json_type_int:
245 jso->_to_json_string = &json_object_int_to_json_string;
246 break;
247 case json_type_object:
248 jso->_to_json_string = &json_object_object_to_json_string;
249 break;
250 case json_type_array:
251 jso->_to_json_string = &json_object_array_to_json_string;
252 break;
253 case json_type_string:
254 jso->_to_json_string = &json_object_string_to_json_string;
255 break;
256 }
257 return;
258 }
259
260 jso->_to_json_string = to_string_func;
261 jso->_userdata = userdata;
262 jso->_user_delete = user_delete;
263}
264
265
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500266/* extended conversion to string */
267
268const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
269{
270 if (!jso)
271 return "null";
272
273 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
274 return NULL;
275
276 printbuf_reset(jso->_pb);
277
278 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
279 return NULL;
280
281 return jso->_pb->buf;
282}
283
284/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000285
Michael Clark266a3fd2009-02-25 01:55:31 +0000286const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000287{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500288 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000289}
290
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500291static void indent(struct printbuf *pb, int level, int flags)
292{
293 if (flags & JSON_C_TO_STRING_PRETTY)
294 {
295 printbuf_memset(pb, -1, ' ', level * 2);
296 }
297}
Michael Clarkf0d08882007-03-13 08:26:18 +0000298
299/* json_object_object */
300
Michael Clark266a3fd2009-02-25 01:55:31 +0000301static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500302 struct printbuf *pb,
303 int level,
304 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000305{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500306 int had_children = 0;
307 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000308
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500309 sprintbuf(pb, "{" /*}*/);
310 if (flags & JSON_C_TO_STRING_PRETTY)
311 sprintbuf(pb, "\n");
312 json_object_object_foreachC(jso, iter)
313 {
314 if (had_children)
315 {
316 sprintbuf(pb, ",");
317 if (flags & JSON_C_TO_STRING_PRETTY)
318 sprintbuf(pb, "\n");
319 }
320 had_children = 1;
321 if (flags & JSON_C_TO_STRING_SPACED)
322 sprintbuf(pb, " ");
323 indent(pb, level+1, flags);
324 sprintbuf(pb, "\"");
325 json_escape_str(pb, iter.key, strlen(iter.key));
326 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000327 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500328 else
329 sprintbuf(pb, "\":");
330 if(iter.val == NULL)
331 sprintbuf(pb, "null");
332 else
333 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000334 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500335 if (flags & JSON_C_TO_STRING_PRETTY)
336 {
337 if (had_children)
338 sprintbuf(pb, "\n");
339 indent(pb,level,flags);
340 }
341 if (flags & JSON_C_TO_STRING_SPACED)
342 return sprintbuf(pb, /*{*/ " }");
343 else
344 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000345}
346
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500347
Michael Clarkf0d08882007-03-13 08:26:18 +0000348static void json_object_lh_entry_free(struct lh_entry *ent)
349{
350 free(ent->k);
351 json_object_put((struct json_object*)ent->v);
352}
353
Michael Clark266a3fd2009-02-25 01:55:31 +0000354static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000355{
Michael Clark266a3fd2009-02-25 01:55:31 +0000356 lh_table_free(jso->o.c_object);
357 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000358}
359
Michael Clarke8de0782009-02-25 01:45:00 +0000360struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000361{
Michael Clark266a3fd2009-02-25 01:55:31 +0000362 struct json_object *jso = json_object_new(json_type_object);
363 if(!jso) return NULL;
364 jso->_delete = &json_object_object_delete;
365 jso->_to_json_string = &json_object_object_to_json_string;
366 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000367 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000368 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000369}
370
Michael Clark266a3fd2009-02-25 01:55:31 +0000371struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000372{
Michael Clark266a3fd2009-02-25 01:55:31 +0000373 if(!jso) return NULL;
374 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000375 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000376 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000377 default:
378 return NULL;
379 }
380}
381
Michael Clark266a3fd2009-02-25 01:55:31 +0000382void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000383 struct json_object *val)
384{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500385 // We lookup the entry and replace the value, rather than just deleting
386 // and re-adding it, so the existing key remains valid.
387 json_object *existing_value = NULL;
388 struct lh_entry *existing_entry;
389 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
390 if (!existing_entry)
391 {
392 lh_table_insert(jso->o.c_object, strdup(key), val);
393 return;
394 }
395 existing_value = (void *)existing_entry->v;
396 if (existing_value)
397 json_object_put(existing_value);
398 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000399}
400
Greg Hazelcca74c62013-01-11 01:36:55 -0800401int json_object_object_length(struct json_object *jso)
402{
403 return lh_table_length(jso->o.c_object);
404}
405
Michael Clark266a3fd2009-02-25 01:55:31 +0000406struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000407{
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500408 struct json_object *result = NULL;
409 json_object_object_get_ex(jso, key, &result);
410 return result;
Keith Derrick69175862012-04-12 11:44:13 -0700411}
412
413json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
414{
Eric Haszlakiewicz5450bed2012-10-18 17:14:41 -0500415 if (value != NULL)
416 *value = NULL;
417
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500418 if (NULL == jso)
419 return FALSE;
Keith Derrick69175862012-04-12 11:44:13 -0700420
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500421 switch(jso->o_type)
422 {
423 case json_type_object:
424 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
425 default:
426 if (value != NULL)
427 *value = NULL;
428 return FALSE;
429 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000430}
431
Michael Clark266a3fd2009-02-25 01:55:31 +0000432void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000433{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500434 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000435}
436
437
438/* json_object_boolean */
439
Michael Clark266a3fd2009-02-25 01:55:31 +0000440static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500441 struct printbuf *pb,
442 int level,
443 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000444{
Michael Clark266a3fd2009-02-25 01:55:31 +0000445 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000446 else return sprintbuf(pb, "false");
447}
448
Keith Derrick37e74672012-03-26 14:29:31 -0700449struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000450{
Michael Clark266a3fd2009-02-25 01:55:31 +0000451 struct json_object *jso = json_object_new(json_type_boolean);
452 if(!jso) return NULL;
453 jso->_to_json_string = &json_object_boolean_to_json_string;
454 jso->o.c_boolean = b;
455 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000456}
457
Keith Derrick37e74672012-03-26 14:29:31 -0700458json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000459{
Michael Clark266a3fd2009-02-25 01:55:31 +0000460 if(!jso) return FALSE;
461 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000462 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000463 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000465 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000467 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000468 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000469 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000470 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000471 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000472 }
473}
474
475
476/* json_object_int */
477
Michael Clark266a3fd2009-02-25 01:55:31 +0000478static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500479 struct printbuf *pb,
480 int level,
481 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000482{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000483 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
484}
485
486struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000487{
Michael Clark266a3fd2009-02-25 01:55:31 +0000488 struct json_object *jso = json_object_new(json_type_int);
489 if(!jso) return NULL;
490 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000491 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000492 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000493}
494
Michael Clarkc4dceae2010-10-06 16:39:20 +0000495int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000496{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100497 int64_t cint64;
498 enum json_type o_type;
499
Michael Clarkc4dceae2010-10-06 16:39:20 +0000500 if(!jso) return 0;
501
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100502 o_type = jso->o_type;
503 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000504
505 if (o_type == json_type_string)
506 {
507 /*
508 * Parse strings into 64-bit numbers, then use the
509 * 64-to-32-bit number handling below.
510 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000511 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000512 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000513 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000514 }
515
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000516 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000517 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000518 /* Make sure we return the correct values for out of range numbers. */
519 if (cint64 <= INT32_MIN)
520 return INT32_MIN;
521 else if (cint64 >= INT32_MAX)
522 return INT32_MAX;
523 else
524 return (int32_t)cint64;
525 case json_type_double:
526 return (int32_t)jso->o.c_double;
527 case json_type_boolean:
528 return jso->o.c_boolean;
529 default:
530 return 0;
531 }
532}
533
534struct json_object* json_object_new_int64(int64_t i)
535{
ehaszla252669c2010-12-07 18:15:35 +0000536 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000537 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000538 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000539 jso->o.c_int64 = i;
540 return jso;
541}
542
543int64_t json_object_get_int64(struct json_object *jso)
544{
545 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000546
Michael Clark266a3fd2009-02-25 01:55:31 +0000547 if(!jso) return 0;
548 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000549 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000550 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000551 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000552 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000553 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000554 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000555 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000556 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000557 default:
558 return 0;
559 }
560}
561
562
563/* json_object_double */
564
Michael Clark266a3fd2009-02-25 01:55:31 +0000565static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500566 struct printbuf *pb,
567 int level,
568 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000569{
Remi Collet8c847962012-12-13 11:22:31 +0100570 char buf[128], *p, *q;
Remi Collet4014fe82012-12-13 11:16:03 +0100571 int size;
Adrian Yanesd086e202013-06-07 13:14:54 -0700572 /* Although JSON RFC does not support
573 NaN or Infinity as numeric values
574 ECMA 262 section 9.8.1 defines
575 how to handle these cases as strings */
576 if(isnan(jso->o.c_double))
577 size = snprintf(buf, 128, "NaN");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300578 else if(isinf(jso->o.c_double))
579 if(jso->o.c_double > 0)
580 size = snprintf(buf, 128, "Infinity");
581 else
582 size = snprintf(buf, 128, "-Infinity");
Adrian Yanesd086e202013-06-07 13:14:54 -0700583 else
584 size = snprintf(buf, 128, "%f", jso->o.c_double);
Remi Collet4014fe82012-12-13 11:16:03 +0100585
Remi Collet4014fe82012-12-13 11:16:03 +0100586 p = strchr(buf, ',');
587 if (p) {
588 *p = '.';
Remi Collet8c847962012-12-13 11:22:31 +0100589 } else {
590 p = strchr(buf, '.');
591 }
Remi Collet32d149c2012-12-13 11:46:04 +0100592 if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
Remi Collet8c847962012-12-13 11:22:31 +0100593 /* last useful digit, always keep 1 zero */
594 p++;
595 for (q=p ; *q ; q++) {
596 if (*q!='0') p=q;
597 }
598 /* drop trailing zeroes */
599 *(++p) = 0;
600 size = p-buf;
Remi Collet4014fe82012-12-13 11:16:03 +0100601 }
602 printbuf_memappend(pb, buf, size);
603 return size;
Michael Clarkf0d08882007-03-13 08:26:18 +0000604}
605
606struct json_object* json_object_new_double(double d)
607{
Michael Clark266a3fd2009-02-25 01:55:31 +0000608 struct json_object *jso = json_object_new(json_type_double);
609 if(!jso) return NULL;
610 jso->_to_json_string = &json_object_double_to_json_string;
611 jso->o.c_double = d;
612 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000613}
614
Michael Clark266a3fd2009-02-25 01:55:31 +0000615double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000616{
617 double cdouble;
618
Michael Clark266a3fd2009-02-25 01:55:31 +0000619 if(!jso) return 0.0;
620 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000621 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000622 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000623 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000624 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000625 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000626 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000627 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000628 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000629 default:
630 return 0.0;
631 }
632}
633
634
635/* json_object_string */
636
Michael Clark266a3fd2009-02-25 01:55:31 +0000637static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500638 struct printbuf *pb,
639 int level,
640 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000641{
642 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000643 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000644 sprintbuf(pb, "\"");
645 return 0;
646}
647
Michael Clark266a3fd2009-02-25 01:55:31 +0000648static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000649{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000650 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000651 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000652}
653
Michael Clark68cafad2009-01-06 22:56:57 +0000654struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000655{
Michael Clark266a3fd2009-02-25 01:55:31 +0000656 struct json_object *jso = json_object_new(json_type_string);
657 if(!jso) return NULL;
658 jso->_delete = &json_object_string_delete;
659 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000660 jso->o.c_string.str = strdup(s);
661 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000662 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000663}
664
Michael Clark68cafad2009-01-06 22:56:57 +0000665struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000666{
Michael Clark266a3fd2009-02-25 01:55:31 +0000667 struct json_object *jso = json_object_new(json_type_string);
668 if(!jso) return NULL;
669 jso->_delete = &json_object_string_delete;
670 jso->_to_json_string = &json_object_string_to_json_string;
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600671 jso->o.c_string.str = (char*)malloc(len + 1);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000672 memcpy(jso->o.c_string.str, (void *)s, len);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600673 jso->o.c_string.str[len] = '\0';
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000674 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000675 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000676}
677
Michael Clark266a3fd2009-02-25 01:55:31 +0000678const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000679{
Michael Clark266a3fd2009-02-25 01:55:31 +0000680 if(!jso) return NULL;
681 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000682 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000683 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000684 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000685 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000686 }
687}
688
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000689int json_object_get_string_len(struct json_object *jso) {
690 if(!jso) return 0;
691 switch(jso->o_type) {
692 case json_type_string:
693 return jso->o.c_string.len;
694 default:
695 return 0;
696 }
697}
698
Michael Clarkf0d08882007-03-13 08:26:18 +0000699
700/* json_object_array */
701
Michael Clark266a3fd2009-02-25 01:55:31 +0000702static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500703 struct printbuf *pb,
704 int level,
705 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000706{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500707 int had_children = 0;
708 int ii;
709 sprintbuf(pb, "[");
710 if (flags & JSON_C_TO_STRING_PRETTY)
711 sprintbuf(pb, "\n");
712 for(ii=0; ii < json_object_array_length(jso); ii++)
713 {
714 struct json_object *val;
715 if (had_children)
716 {
717 sprintbuf(pb, ",");
718 if (flags & JSON_C_TO_STRING_PRETTY)
719 sprintbuf(pb, "\n");
720 }
721 had_children = 1;
722 if (flags & JSON_C_TO_STRING_SPACED)
723 sprintbuf(pb, " ");
724 indent(pb, level + 1, flags);
725 val = json_object_array_get_idx(jso, ii);
726 if(val == NULL)
727 sprintbuf(pb, "null");
728 else
729 val->_to_json_string(val, pb, level+1, flags);
730 }
731 if (flags & JSON_C_TO_STRING_PRETTY)
732 {
733 if (had_children)
734 sprintbuf(pb, "\n");
735 indent(pb,level,flags);
736 }
Michael Clark4504df72007-03-13 08:26:20 +0000737
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500738 if (flags & JSON_C_TO_STRING_SPACED)
739 return sprintbuf(pb, " ]");
740 else
741 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000742}
743
744static void json_object_array_entry_free(void *data)
745{
746 json_object_put((struct json_object*)data);
747}
748
Michael Clark266a3fd2009-02-25 01:55:31 +0000749static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000750{
Michael Clark266a3fd2009-02-25 01:55:31 +0000751 array_list_free(jso->o.c_array);
752 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000753}
754
Michael Clarke8de0782009-02-25 01:45:00 +0000755struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000756{
Michael Clark266a3fd2009-02-25 01:55:31 +0000757 struct json_object *jso = json_object_new(json_type_array);
758 if(!jso) return NULL;
759 jso->_delete = &json_object_array_delete;
760 jso->_to_json_string = &json_object_array_to_json_string;
761 jso->o.c_array = array_list_new(&json_object_array_entry_free);
762 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000763}
764
Michael Clark266a3fd2009-02-25 01:55:31 +0000765struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000766{
Michael Clark266a3fd2009-02-25 01:55:31 +0000767 if(!jso) return NULL;
768 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000769 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000770 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000771 default:
772 return NULL;
773 }
774}
775
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200776void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
777{
778 array_list_sort(jso->o.c_array, sort_fn);
779}
780
Michael Clark266a3fd2009-02-25 01:55:31 +0000781int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000782{
Michael Clark266a3fd2009-02-25 01:55:31 +0000783 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000784}
785
Michael Clark266a3fd2009-02-25 01:55:31 +0000786int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000787{
Michael Clark266a3fd2009-02-25 01:55:31 +0000788 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000789}
790
Michael Clark266a3fd2009-02-25 01:55:31 +0000791int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000792 struct json_object *val)
793{
Michael Clark266a3fd2009-02-25 01:55:31 +0000794 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000795}
796
Michael Clark266a3fd2009-02-25 01:55:31 +0000797struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000798 int idx)
799{
Michael Clark266a3fd2009-02-25 01:55:31 +0000800 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000801}
802