blob: faf61930c65715e6a621417ecafb0608806c80b7 [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
Anatol Belskied819fb2013-06-04 20:18:05 +020037#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
38 /* MSC has the version as _snprintf */
39# define snprintf _snprintf
40#elif !defined(HAVE_SNPRINTF)
41# error You do not have snprintf on your system.
42#endif /* HAVE_SNPRINTF */
43
Keith Derrick69175862012-04-12 11:44:13 -070044// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000045/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000046
Michael Clark68cafad2009-01-06 22:56:57 +000047const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010048const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000049
Michael Clark266a3fd2009-02-25 01:55:31 +000050static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000051static struct json_object* json_object_new(enum json_type o_type);
52
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -050053static json_object_to_json_string_fn json_object_object_to_json_string;
54static json_object_to_json_string_fn json_object_boolean_to_json_string;
55static json_object_to_json_string_fn json_object_int_to_json_string;
56static json_object_to_json_string_fn json_object_double_to_json_string;
57static json_object_to_json_string_fn json_object_string_to_json_string;
58static json_object_to_json_string_fn json_object_array_to_json_string;
59
Michael Clarkf0d08882007-03-13 08:26:18 +000060
61/* ref count debugging */
62
63#ifdef REFCOUNT_DEBUG
64
65static struct lh_table *json_object_table;
66
Michael Clark14862b12007-12-07 02:50:42 +000067static void json_object_init(void) __attribute__ ((constructor));
68static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000069 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000070 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
71}
72
Michael Clark14862b12007-12-07 02:50:42 +000073static void json_object_fini(void) __attribute__ ((destructor));
74static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000075 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000076 if(MC_GET_DEBUG()) {
77 if (json_object_table->count) {
78 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
79 json_object_table->count);
80 lh_foreach(json_object_table, ent) {
81 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000082 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000083 }
Michael Clarkf0d08882007-03-13 08:26:18 +000084 }
85 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000086 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000087 lh_table_free(json_object_table);
88}
Michael Clark4504df72007-03-13 08:26:20 +000089#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000090
91
92/* string escaping */
93
Jehiah Czebotarac601b52011-01-14 17:23:06 +000094static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000095{
96 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000097 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000098 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000099 c = str[pos];
100 switch(c) {
101 case '\b':
102 case '\n':
103 case '\r':
104 case '\t':
Abioy7eaa8492012-12-24 22:22:05 +0800105 case '\f':
Michael Clark4504df72007-03-13 08:26:20 +0000106 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000107 case '\\':
108 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000109 if(pos - start_offset > 0)
110 printbuf_memappend(pb, str + start_offset, pos - start_offset);
111 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
112 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
113 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
114 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Abioy7eaa8492012-12-24 22:22:05 +0800115 else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000116 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000117 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
118 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000119 start_offset = ++pos;
120 break;
121 default:
Michael Clark837240f2007-03-13 08:26:25 +0000122 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000123 if(pos - start_offset > 0)
124 printbuf_memappend(pb, str + start_offset, pos - start_offset);
125 sprintbuf(pb, "\\u00%c%c",
126 json_hex_chars[c >> 4],
127 json_hex_chars[c & 0xf]);
128 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000129 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000130 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000131 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000132 if(pos - start_offset > 0)
133 printbuf_memappend(pb, str + start_offset, pos - start_offset);
134 return 0;
135}
136
137
138/* reference counting */
139
Michael Clark266a3fd2009-02-25 01:55:31 +0000140extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000141{
Michael Clark266a3fd2009-02-25 01:55:31 +0000142 if(jso) {
143 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000144 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000145 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000146}
147
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500148int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000149{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500150 if(jso)
151 {
152 jso->_ref_count--;
153 if(!jso->_ref_count)
154 {
155 if (jso->_user_delete)
156 jso->_user_delete(jso, jso->_userdata);
157 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500158 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500159 }
160 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500161 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000162}
163
164
165/* generic object construction and destruction parts */
166
Michael Clark266a3fd2009-02-25 01:55:31 +0000167static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000168{
169#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000170 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000171 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000172 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000173#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000174 printbuf_free(jso->_pb);
175 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000176}
177
178static struct json_object* json_object_new(enum json_type o_type)
179{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000180 struct json_object *jso;
181
182 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000183 if(!jso) return NULL;
184 jso->o_type = o_type;
185 jso->_ref_count = 1;
186 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000187#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000188 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000189 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000190#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000191 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000192}
193
194
195/* type checking functions */
196
Michael Clark266a3fd2009-02-25 01:55:31 +0000197int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000198{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500199 if (!jso)
200 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000201 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000202}
203
Michael Clark266a3fd2009-02-25 01:55:31 +0000204enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000205{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500206 if (!jso)
207 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000208 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000209}
210
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500211/* set a custom conversion to string */
212
213void json_object_set_serializer(json_object *jso,
214 json_object_to_json_string_fn to_string_func,
215 void *userdata,
216 json_object_delete_fn *user_delete)
217{
218 // First, clean up any previously existing user info
219 if (jso->_user_delete)
220 {
221 jso->_user_delete(jso, jso->_userdata);
222 }
223 jso->_userdata = NULL;
224 jso->_user_delete = NULL;
225
226 if (to_string_func == NULL)
227 {
228 // Reset to the standard serialization function
229 switch(jso->o_type)
230 {
231 case json_type_null:
232 jso->_to_json_string = NULL;
233 break;
234 case json_type_boolean:
235 jso->_to_json_string = &json_object_boolean_to_json_string;
236 break;
237 case json_type_double:
238 jso->_to_json_string = &json_object_double_to_json_string;
239 break;
240 case json_type_int:
241 jso->_to_json_string = &json_object_int_to_json_string;
242 break;
243 case json_type_object:
244 jso->_to_json_string = &json_object_object_to_json_string;
245 break;
246 case json_type_array:
247 jso->_to_json_string = &json_object_array_to_json_string;
248 break;
249 case json_type_string:
250 jso->_to_json_string = &json_object_string_to_json_string;
251 break;
252 }
253 return;
254 }
255
256 jso->_to_json_string = to_string_func;
257 jso->_userdata = userdata;
258 jso->_user_delete = user_delete;
259}
260
261
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500262/* extended conversion to string */
263
264const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
265{
266 if (!jso)
267 return "null";
268
269 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
270 return NULL;
271
272 printbuf_reset(jso->_pb);
273
274 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
275 return NULL;
276
277 return jso->_pb->buf;
278}
279
280/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000281
Michael Clark266a3fd2009-02-25 01:55:31 +0000282const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000283{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500284 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000285}
286
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500287static void indent(struct printbuf *pb, int level, int flags)
288{
289 if (flags & JSON_C_TO_STRING_PRETTY)
290 {
291 printbuf_memset(pb, -1, ' ', level * 2);
292 }
293}
Michael Clarkf0d08882007-03-13 08:26:18 +0000294
295/* json_object_object */
296
Michael Clark266a3fd2009-02-25 01:55:31 +0000297static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500298 struct printbuf *pb,
299 int level,
300 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000301{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500302 int had_children = 0;
303 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000304
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500305 sprintbuf(pb, "{" /*}*/);
306 if (flags & JSON_C_TO_STRING_PRETTY)
307 sprintbuf(pb, "\n");
308 json_object_object_foreachC(jso, iter)
309 {
310 if (had_children)
311 {
312 sprintbuf(pb, ",");
313 if (flags & JSON_C_TO_STRING_PRETTY)
314 sprintbuf(pb, "\n");
315 }
316 had_children = 1;
317 if (flags & JSON_C_TO_STRING_SPACED)
318 sprintbuf(pb, " ");
319 indent(pb, level+1, flags);
320 sprintbuf(pb, "\"");
321 json_escape_str(pb, iter.key, strlen(iter.key));
322 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000323 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500324 else
325 sprintbuf(pb, "\":");
326 if(iter.val == NULL)
327 sprintbuf(pb, "null");
328 else
329 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000330 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500331 if (flags & JSON_C_TO_STRING_PRETTY)
332 {
333 if (had_children)
334 sprintbuf(pb, "\n");
335 indent(pb,level,flags);
336 }
337 if (flags & JSON_C_TO_STRING_SPACED)
338 return sprintbuf(pb, /*{*/ " }");
339 else
340 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000341}
342
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500343
Michael Clarkf0d08882007-03-13 08:26:18 +0000344static void json_object_lh_entry_free(struct lh_entry *ent)
345{
346 free(ent->k);
347 json_object_put((struct json_object*)ent->v);
348}
349
Michael Clark266a3fd2009-02-25 01:55:31 +0000350static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000351{
Michael Clark266a3fd2009-02-25 01:55:31 +0000352 lh_table_free(jso->o.c_object);
353 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000354}
355
Michael Clarke8de0782009-02-25 01:45:00 +0000356struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000357{
Michael Clark266a3fd2009-02-25 01:55:31 +0000358 struct json_object *jso = json_object_new(json_type_object);
359 if(!jso) return NULL;
360 jso->_delete = &json_object_object_delete;
361 jso->_to_json_string = &json_object_object_to_json_string;
362 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000363 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000364 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000365}
366
Michael Clark266a3fd2009-02-25 01:55:31 +0000367struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000368{
Michael Clark266a3fd2009-02-25 01:55:31 +0000369 if(!jso) return NULL;
370 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000371 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000372 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000373 default:
374 return NULL;
375 }
376}
377
Michael Clark266a3fd2009-02-25 01:55:31 +0000378void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000379 struct json_object *val)
380{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500381 // We lookup the entry and replace the value, rather than just deleting
382 // and re-adding it, so the existing key remains valid.
383 json_object *existing_value = NULL;
384 struct lh_entry *existing_entry;
385 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
386 if (!existing_entry)
387 {
388 lh_table_insert(jso->o.c_object, strdup(key), val);
389 return;
390 }
391 existing_value = (void *)existing_entry->v;
392 if (existing_value)
393 json_object_put(existing_value);
394 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000395}
396
Greg Hazelcca74c62013-01-11 01:36:55 -0800397int json_object_object_length(struct json_object *jso)
398{
399 return lh_table_length(jso->o.c_object);
400}
401
Michael Clark266a3fd2009-02-25 01:55:31 +0000402struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000403{
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500404 struct json_object *result = NULL;
405 json_object_object_get_ex(jso, key, &result);
406 return result;
Keith Derrick69175862012-04-12 11:44:13 -0700407}
408
409json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
410{
Eric Haszlakiewicz5450bed2012-10-18 17:14:41 -0500411 if (value != NULL)
412 *value = NULL;
413
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500414 if (NULL == jso)
415 return FALSE;
Keith Derrick69175862012-04-12 11:44:13 -0700416
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500417 switch(jso->o_type)
418 {
419 case json_type_object:
420 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
421 default:
422 if (value != NULL)
423 *value = NULL;
424 return FALSE;
425 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000426}
427
Michael Clark266a3fd2009-02-25 01:55:31 +0000428void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000429{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500430 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000431}
432
433
434/* json_object_boolean */
435
Michael Clark266a3fd2009-02-25 01:55:31 +0000436static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500437 struct printbuf *pb,
438 int level,
439 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000440{
Michael Clark266a3fd2009-02-25 01:55:31 +0000441 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000442 else return sprintbuf(pb, "false");
443}
444
Keith Derrick37e74672012-03-26 14:29:31 -0700445struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000446{
Michael Clark266a3fd2009-02-25 01:55:31 +0000447 struct json_object *jso = json_object_new(json_type_boolean);
448 if(!jso) return NULL;
449 jso->_to_json_string = &json_object_boolean_to_json_string;
450 jso->o.c_boolean = b;
451 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000452}
453
Keith Derrick37e74672012-03-26 14:29:31 -0700454json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000455{
Michael Clark266a3fd2009-02-25 01:55:31 +0000456 if(!jso) return FALSE;
457 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000458 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000459 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000460 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000461 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000462 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000463 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000465 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000467 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000468 }
469}
470
471
472/* json_object_int */
473
Michael Clark266a3fd2009-02-25 01:55:31 +0000474static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500475 struct printbuf *pb,
476 int level,
477 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000478{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000479 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
480}
481
482struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000483{
Michael Clark266a3fd2009-02-25 01:55:31 +0000484 struct json_object *jso = json_object_new(json_type_int);
485 if(!jso) return NULL;
486 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000487 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000488 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000489}
490
Michael Clarkc4dceae2010-10-06 16:39:20 +0000491int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000492{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100493 int64_t cint64;
494 enum json_type o_type;
495
Michael Clarkc4dceae2010-10-06 16:39:20 +0000496 if(!jso) return 0;
497
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100498 o_type = jso->o_type;
499 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000500
501 if (o_type == json_type_string)
502 {
503 /*
504 * Parse strings into 64-bit numbers, then use the
505 * 64-to-32-bit number handling below.
506 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000507 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000508 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000509 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000510 }
511
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000512 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000513 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000514 /* Make sure we return the correct values for out of range numbers. */
515 if (cint64 <= INT32_MIN)
516 return INT32_MIN;
517 else if (cint64 >= INT32_MAX)
518 return INT32_MAX;
519 else
520 return (int32_t)cint64;
521 case json_type_double:
522 return (int32_t)jso->o.c_double;
523 case json_type_boolean:
524 return jso->o.c_boolean;
525 default:
526 return 0;
527 }
528}
529
530struct json_object* json_object_new_int64(int64_t i)
531{
ehaszla252669c2010-12-07 18:15:35 +0000532 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000533 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000534 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000535 jso->o.c_int64 = i;
536 return jso;
537}
538
539int64_t json_object_get_int64(struct json_object *jso)
540{
541 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000542
Michael Clark266a3fd2009-02-25 01:55:31 +0000543 if(!jso) return 0;
544 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000545 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000546 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000547 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000548 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000549 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000550 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000551 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000552 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000553 default:
554 return 0;
555 }
556}
557
558
559/* json_object_double */
560
Michael Clark266a3fd2009-02-25 01:55:31 +0000561static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500562 struct printbuf *pb,
563 int level,
564 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000565{
Remi Collet8c847962012-12-13 11:22:31 +0100566 char buf[128], *p, *q;
Remi Collet4014fe82012-12-13 11:16:03 +0100567 int size;
Adrian Yanesd086e202013-06-07 13:14:54 -0700568 /* Although JSON RFC does not support
569 NaN or Infinity as numeric values
570 ECMA 262 section 9.8.1 defines
571 how to handle these cases as strings */
572 if(isnan(jso->o.c_double))
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500573 size = snprintf(buf, sizeof(buf), "NaN");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300574 else if(isinf(jso->o.c_double))
575 if(jso->o.c_double > 0)
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500576 size = snprintf(buf, sizeof(buf), "Infinity");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300577 else
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500578 size = snprintf(buf, sizeof(buf), "-Infinity");
Adrian Yanesd086e202013-06-07 13:14:54 -0700579 else
Eric Haszlakiewicz06450202013-09-11 21:09:43 -0500580 size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double);
Remi Collet4014fe82012-12-13 11:16:03 +0100581
Remi Collet4014fe82012-12-13 11:16:03 +0100582 p = strchr(buf, ',');
583 if (p) {
584 *p = '.';
Remi Collet8c847962012-12-13 11:22:31 +0100585 } else {
586 p = strchr(buf, '.');
587 }
Remi Collet32d149c2012-12-13 11:46:04 +0100588 if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
Remi Collet8c847962012-12-13 11:22:31 +0100589 /* last useful digit, always keep 1 zero */
590 p++;
591 for (q=p ; *q ; q++) {
592 if (*q!='0') p=q;
593 }
594 /* drop trailing zeroes */
595 *(++p) = 0;
596 size = p-buf;
Remi Collet4014fe82012-12-13 11:16:03 +0100597 }
598 printbuf_memappend(pb, buf, size);
599 return size;
Michael Clarkf0d08882007-03-13 08:26:18 +0000600}
601
602struct json_object* json_object_new_double(double d)
603{
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500604 struct json_object *jso = json_object_new(json_type_double);
605 if (!jso)
606 return NULL;
607 jso->_to_json_string = &json_object_double_to_json_string;
608 jso->o.c_double = d;
609 return jso;
610}
611
612struct json_object* json_object_new_double_s(double d, const char *ds)
613{
614 struct json_object *jso = json_object_new_double(d);
615 if (!jso)
616 return NULL;
617
618 json_object_set_serializer(jso, json_object_userdata_to_json_string,
619 strdup(ds), json_object_free_userdata);
620 return jso;
621}
622
623int json_object_userdata_to_json_string(struct json_object *jso,
624 struct printbuf *pb, int level, int flags)
625{
626 int userdata_len = strlen(jso->_userdata);
627 printbuf_memappend(pb, jso->_userdata, userdata_len);
628 return userdata_len;
629}
630
631void json_object_free_userdata(struct json_object *jso, void *userdata)
632{
633 free(userdata);
Michael Clarkf0d08882007-03-13 08:26:18 +0000634}
635
Michael Clark266a3fd2009-02-25 01:55:31 +0000636double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000637{
638 double cdouble;
639
Michael Clark266a3fd2009-02-25 01:55:31 +0000640 if(!jso) return 0.0;
641 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000642 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000643 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000644 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000645 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000646 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000647 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000648 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000649 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000650 default:
651 return 0.0;
652 }
653}
654
655
656/* json_object_string */
657
Michael Clark266a3fd2009-02-25 01:55:31 +0000658static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500659 struct printbuf *pb,
660 int level,
661 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000662{
663 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000664 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000665 sprintbuf(pb, "\"");
666 return 0;
667}
668
Michael Clark266a3fd2009-02-25 01:55:31 +0000669static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000670{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000671 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000672 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000673}
674
Michael Clark68cafad2009-01-06 22:56:57 +0000675struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000676{
Michael Clark266a3fd2009-02-25 01:55:31 +0000677 struct json_object *jso = json_object_new(json_type_string);
678 if(!jso) return NULL;
679 jso->_delete = &json_object_string_delete;
680 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000681 jso->o.c_string.str = strdup(s);
682 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000683 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000684}
685
Michael Clark68cafad2009-01-06 22:56:57 +0000686struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000687{
Michael Clark266a3fd2009-02-25 01:55:31 +0000688 struct json_object *jso = json_object_new(json_type_string);
689 if(!jso) return NULL;
690 jso->_delete = &json_object_string_delete;
691 jso->_to_json_string = &json_object_string_to_json_string;
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600692 jso->o.c_string.str = (char*)malloc(len + 1);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000693 memcpy(jso->o.c_string.str, (void *)s, len);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600694 jso->o.c_string.str[len] = '\0';
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000695 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000696 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000697}
698
Michael Clark266a3fd2009-02-25 01:55:31 +0000699const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000700{
Michael Clark266a3fd2009-02-25 01:55:31 +0000701 if(!jso) return NULL;
702 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000703 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000704 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000705 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000706 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000707 }
708}
709
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000710int json_object_get_string_len(struct json_object *jso) {
711 if(!jso) return 0;
712 switch(jso->o_type) {
713 case json_type_string:
714 return jso->o.c_string.len;
715 default:
716 return 0;
717 }
718}
719
Michael Clarkf0d08882007-03-13 08:26:18 +0000720
721/* json_object_array */
722
Michael Clark266a3fd2009-02-25 01:55:31 +0000723static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500724 struct printbuf *pb,
725 int level,
726 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000727{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500728 int had_children = 0;
729 int ii;
730 sprintbuf(pb, "[");
731 if (flags & JSON_C_TO_STRING_PRETTY)
732 sprintbuf(pb, "\n");
733 for(ii=0; ii < json_object_array_length(jso); ii++)
734 {
735 struct json_object *val;
736 if (had_children)
737 {
738 sprintbuf(pb, ",");
739 if (flags & JSON_C_TO_STRING_PRETTY)
740 sprintbuf(pb, "\n");
741 }
742 had_children = 1;
743 if (flags & JSON_C_TO_STRING_SPACED)
744 sprintbuf(pb, " ");
745 indent(pb, level + 1, flags);
746 val = json_object_array_get_idx(jso, ii);
747 if(val == NULL)
748 sprintbuf(pb, "null");
749 else
750 val->_to_json_string(val, pb, level+1, flags);
751 }
752 if (flags & JSON_C_TO_STRING_PRETTY)
753 {
754 if (had_children)
755 sprintbuf(pb, "\n");
756 indent(pb,level,flags);
757 }
Michael Clark4504df72007-03-13 08:26:20 +0000758
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500759 if (flags & JSON_C_TO_STRING_SPACED)
760 return sprintbuf(pb, " ]");
761 else
762 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000763}
764
765static void json_object_array_entry_free(void *data)
766{
767 json_object_put((struct json_object*)data);
768}
769
Michael Clark266a3fd2009-02-25 01:55:31 +0000770static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000771{
Michael Clark266a3fd2009-02-25 01:55:31 +0000772 array_list_free(jso->o.c_array);
773 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000774}
775
Michael Clarke8de0782009-02-25 01:45:00 +0000776struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000777{
Michael Clark266a3fd2009-02-25 01:55:31 +0000778 struct json_object *jso = json_object_new(json_type_array);
779 if(!jso) return NULL;
780 jso->_delete = &json_object_array_delete;
781 jso->_to_json_string = &json_object_array_to_json_string;
782 jso->o.c_array = array_list_new(&json_object_array_entry_free);
783 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000784}
785
Michael Clark266a3fd2009-02-25 01:55:31 +0000786struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000787{
Michael Clark266a3fd2009-02-25 01:55:31 +0000788 if(!jso) return NULL;
789 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000790 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000791 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000792 default:
793 return NULL;
794 }
795}
796
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200797void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
798{
799 array_list_sort(jso->o.c_array, sort_fn);
800}
801
Michael Clark266a3fd2009-02-25 01:55:31 +0000802int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000803{
Michael Clark266a3fd2009-02-25 01:55:31 +0000804 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000805}
806
Michael Clark266a3fd2009-02-25 01:55:31 +0000807int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000808{
Michael Clark266a3fd2009-02-25 01:55:31 +0000809 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000810}
811
Michael Clark266a3fd2009-02-25 01:55:31 +0000812int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000813 struct json_object *val)
814{
Michael Clark266a3fd2009-02-25 01:55:31 +0000815 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000816}
817
Michael Clark266a3fd2009-02-25 01:55:31 +0000818struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000819 int idx)
820{
Michael Clark266a3fd2009-02-25 01:55:31 +0000821 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000822}
823