blob: 9dc66375e8bb551a763d2869d74da130a9bb5e6c [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>
19
20#include "debug.h"
21#include "printbuf.h"
22#include "linkhash.h"
23#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000024#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000025#include "json_object.h"
26#include "json_object_private.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000027#include "json_util.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000028
Mateusz Loskota6f39a32012-05-21 23:22:36 +010029#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
30 /* MSC has the version as _strdup */
31# define strdup _strdup
32#elif !defined(HAVE_STRDUP)
33# error You do not have strdup on your system.
34#endif /* HAVE_STRDUP */
35
36#if !defined(HAVE_STRNDUP)
Michael Clark837240f2007-03-13 08:26:25 +000037 char* strndup(const char* str, size_t n);
38#endif /* !HAVE_STRNDUP */
39
Keith Derrick69175862012-04-12 11:44:13 -070040// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000041/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000042
Michael Clark68cafad2009-01-06 22:56:57 +000043const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010044const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000045
Michael Clark266a3fd2009-02-25 01:55:31 +000046static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000047static struct json_object* json_object_new(enum json_type o_type);
48
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -050049static json_object_to_json_string_fn json_object_object_to_json_string;
50static json_object_to_json_string_fn json_object_boolean_to_json_string;
51static json_object_to_json_string_fn json_object_int_to_json_string;
52static json_object_to_json_string_fn json_object_double_to_json_string;
53static json_object_to_json_string_fn json_object_string_to_json_string;
54static json_object_to_json_string_fn json_object_array_to_json_string;
55
Michael Clarkf0d08882007-03-13 08:26:18 +000056
57/* ref count debugging */
58
59#ifdef REFCOUNT_DEBUG
60
61static struct lh_table *json_object_table;
62
Michael Clark14862b12007-12-07 02:50:42 +000063static void json_object_init(void) __attribute__ ((constructor));
64static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000065 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000066 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
67}
68
Michael Clark14862b12007-12-07 02:50:42 +000069static void json_object_fini(void) __attribute__ ((destructor));
70static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000071 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000072 if(MC_GET_DEBUG()) {
73 if (json_object_table->count) {
74 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
75 json_object_table->count);
76 lh_foreach(json_object_table, ent) {
77 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000078 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000079 }
Michael Clarkf0d08882007-03-13 08:26:18 +000080 }
81 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000082 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000083 lh_table_free(json_object_table);
84}
Michael Clark4504df72007-03-13 08:26:20 +000085#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000086
87
88/* string escaping */
89
Jehiah Czebotarac601b52011-01-14 17:23:06 +000090static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000091{
92 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000093 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000094 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000095 c = str[pos];
96 switch(c) {
97 case '\b':
98 case '\n':
99 case '\r':
100 case '\t':
Abioy7eaa8492012-12-24 22:22:05 +0800101 case '\f':
Michael Clark4504df72007-03-13 08:26:20 +0000102 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000103 case '\\':
104 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000105 if(pos - start_offset > 0)
106 printbuf_memappend(pb, str + start_offset, pos - start_offset);
107 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
108 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
109 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
110 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Abioy7eaa8492012-12-24 22:22:05 +0800111 else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000112 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000113 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
114 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000115 start_offset = ++pos;
116 break;
117 default:
Michael Clark837240f2007-03-13 08:26:25 +0000118 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000119 if(pos - start_offset > 0)
120 printbuf_memappend(pb, str + start_offset, pos - start_offset);
121 sprintbuf(pb, "\\u00%c%c",
122 json_hex_chars[c >> 4],
123 json_hex_chars[c & 0xf]);
124 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000125 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000126 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000127 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000128 if(pos - start_offset > 0)
129 printbuf_memappend(pb, str + start_offset, pos - start_offset);
130 return 0;
131}
132
133
134/* reference counting */
135
Michael Clark266a3fd2009-02-25 01:55:31 +0000136extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000137{
Michael Clark266a3fd2009-02-25 01:55:31 +0000138 if(jso) {
139 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000140 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000141 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000142}
143
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500144int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000145{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500146 if(jso)
147 {
148 jso->_ref_count--;
149 if(!jso->_ref_count)
150 {
151 if (jso->_user_delete)
152 jso->_user_delete(jso, jso->_userdata);
153 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500154 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500155 }
156 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500157 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000158}
159
160
161/* generic object construction and destruction parts */
162
Michael Clark266a3fd2009-02-25 01:55:31 +0000163static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000164{
165#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000166 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000167 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000168 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000169#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000170 printbuf_free(jso->_pb);
171 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000172}
173
174static struct json_object* json_object_new(enum json_type o_type)
175{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000176 struct json_object *jso;
177
178 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000179 if(!jso) return NULL;
180 jso->o_type = o_type;
181 jso->_ref_count = 1;
182 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000183#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000184 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000185 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000186#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000187 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000188}
189
190
191/* type checking functions */
192
Michael Clark266a3fd2009-02-25 01:55:31 +0000193int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000194{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500195 if (!jso)
196 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000197 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000198}
199
Michael Clark266a3fd2009-02-25 01:55:31 +0000200enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000201{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500202 if (!jso)
203 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000204 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000205}
206
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500207/* set a custom conversion to string */
208
209void json_object_set_serializer(json_object *jso,
210 json_object_to_json_string_fn to_string_func,
211 void *userdata,
212 json_object_delete_fn *user_delete)
213{
214 // First, clean up any previously existing user info
215 if (jso->_user_delete)
216 {
217 jso->_user_delete(jso, jso->_userdata);
218 }
219 jso->_userdata = NULL;
220 jso->_user_delete = NULL;
221
222 if (to_string_func == NULL)
223 {
224 // Reset to the standard serialization function
225 switch(jso->o_type)
226 {
227 case json_type_null:
228 jso->_to_json_string = NULL;
229 break;
230 case json_type_boolean:
231 jso->_to_json_string = &json_object_boolean_to_json_string;
232 break;
233 case json_type_double:
234 jso->_to_json_string = &json_object_double_to_json_string;
235 break;
236 case json_type_int:
237 jso->_to_json_string = &json_object_int_to_json_string;
238 break;
239 case json_type_object:
240 jso->_to_json_string = &json_object_object_to_json_string;
241 break;
242 case json_type_array:
243 jso->_to_json_string = &json_object_array_to_json_string;
244 break;
245 case json_type_string:
246 jso->_to_json_string = &json_object_string_to_json_string;
247 break;
248 }
249 return;
250 }
251
252 jso->_to_json_string = to_string_func;
253 jso->_userdata = userdata;
254 jso->_user_delete = user_delete;
255}
256
257
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500258/* extended conversion to string */
259
260const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
261{
262 if (!jso)
263 return "null";
264
265 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
266 return NULL;
267
268 printbuf_reset(jso->_pb);
269
270 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
271 return NULL;
272
273 return jso->_pb->buf;
274}
275
276/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000277
Michael Clark266a3fd2009-02-25 01:55:31 +0000278const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000279{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500280 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000281}
282
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500283static void indent(struct printbuf *pb, int level, int flags)
284{
285 if (flags & JSON_C_TO_STRING_PRETTY)
286 {
287 printbuf_memset(pb, -1, ' ', level * 2);
288 }
289}
Michael Clarkf0d08882007-03-13 08:26:18 +0000290
291/* json_object_object */
292
Michael Clark266a3fd2009-02-25 01:55:31 +0000293static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500294 struct printbuf *pb,
295 int level,
296 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000297{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500298 int had_children = 0;
299 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000300
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500301 sprintbuf(pb, "{" /*}*/);
302 if (flags & JSON_C_TO_STRING_PRETTY)
303 sprintbuf(pb, "\n");
304 json_object_object_foreachC(jso, iter)
305 {
306 if (had_children)
307 {
308 sprintbuf(pb, ",");
309 if (flags & JSON_C_TO_STRING_PRETTY)
310 sprintbuf(pb, "\n");
311 }
312 had_children = 1;
313 if (flags & JSON_C_TO_STRING_SPACED)
314 sprintbuf(pb, " ");
315 indent(pb, level+1, flags);
316 sprintbuf(pb, "\"");
317 json_escape_str(pb, iter.key, strlen(iter.key));
318 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000319 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500320 else
321 sprintbuf(pb, "\":");
322 if(iter.val == NULL)
323 sprintbuf(pb, "null");
324 else
325 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000326 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500327 if (flags & JSON_C_TO_STRING_PRETTY)
328 {
329 if (had_children)
330 sprintbuf(pb, "\n");
331 indent(pb,level,flags);
332 }
333 if (flags & JSON_C_TO_STRING_SPACED)
334 return sprintbuf(pb, /*{*/ " }");
335 else
336 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000337}
338
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500339
Michael Clarkf0d08882007-03-13 08:26:18 +0000340static void json_object_lh_entry_free(struct lh_entry *ent)
341{
342 free(ent->k);
343 json_object_put((struct json_object*)ent->v);
344}
345
Michael Clark266a3fd2009-02-25 01:55:31 +0000346static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000347{
Michael Clark266a3fd2009-02-25 01:55:31 +0000348 lh_table_free(jso->o.c_object);
349 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000350}
351
Michael Clarke8de0782009-02-25 01:45:00 +0000352struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000353{
Michael Clark266a3fd2009-02-25 01:55:31 +0000354 struct json_object *jso = json_object_new(json_type_object);
355 if(!jso) return NULL;
356 jso->_delete = &json_object_object_delete;
357 jso->_to_json_string = &json_object_object_to_json_string;
358 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000359 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000360 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000361}
362
Michael Clark266a3fd2009-02-25 01:55:31 +0000363struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000364{
Michael Clark266a3fd2009-02-25 01:55:31 +0000365 if(!jso) return NULL;
366 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000367 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000368 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000369 default:
370 return NULL;
371 }
372}
373
Michael Clark266a3fd2009-02-25 01:55:31 +0000374void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000375 struct json_object *val)
376{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500377 // We lookup the entry and replace the value, rather than just deleting
378 // and re-adding it, so the existing key remains valid.
379 json_object *existing_value = NULL;
380 struct lh_entry *existing_entry;
381 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
382 if (!existing_entry)
383 {
384 lh_table_insert(jso->o.c_object, strdup(key), val);
385 return;
386 }
387 existing_value = (void *)existing_entry->v;
388 if (existing_value)
389 json_object_put(existing_value);
390 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000391}
392
Greg Hazelcca74c62013-01-11 01:36:55 -0800393int json_object_object_length(struct json_object *jso)
394{
395 return lh_table_length(jso->o.c_object);
396}
397
Michael Clark266a3fd2009-02-25 01:55:31 +0000398struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000399{
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500400 struct json_object *result = NULL;
401 json_object_object_get_ex(jso, key, &result);
402 return result;
Keith Derrick69175862012-04-12 11:44:13 -0700403}
404
405json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
406{
Eric Haszlakiewicz5450bed2012-10-18 17:14:41 -0500407 if (value != NULL)
408 *value = NULL;
409
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500410 if (NULL == jso)
411 return FALSE;
Keith Derrick69175862012-04-12 11:44:13 -0700412
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500413 switch(jso->o_type)
414 {
415 case json_type_object:
416 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
417 default:
418 if (value != NULL)
419 *value = NULL;
420 return FALSE;
421 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000422}
423
Michael Clark266a3fd2009-02-25 01:55:31 +0000424void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000425{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500426 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000427}
428
429
430/* json_object_boolean */
431
Michael Clark266a3fd2009-02-25 01:55:31 +0000432static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500433 struct printbuf *pb,
434 int level,
435 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000436{
Michael Clark266a3fd2009-02-25 01:55:31 +0000437 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000438 else return sprintbuf(pb, "false");
439}
440
Keith Derrick37e74672012-03-26 14:29:31 -0700441struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000442{
Michael Clark266a3fd2009-02-25 01:55:31 +0000443 struct json_object *jso = json_object_new(json_type_boolean);
444 if(!jso) return NULL;
445 jso->_to_json_string = &json_object_boolean_to_json_string;
446 jso->o.c_boolean = b;
447 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000448}
449
Keith Derrick37e74672012-03-26 14:29:31 -0700450json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000451{
Michael Clark266a3fd2009-02-25 01:55:31 +0000452 if(!jso) return FALSE;
453 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000454 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000455 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000456 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000457 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000458 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000459 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000460 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000461 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000462 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000463 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 }
465}
466
467
468/* json_object_int */
469
Michael Clark266a3fd2009-02-25 01:55:31 +0000470static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500471 struct printbuf *pb,
472 int level,
473 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000474{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000475 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
476}
477
478struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000479{
Michael Clark266a3fd2009-02-25 01:55:31 +0000480 struct json_object *jso = json_object_new(json_type_int);
481 if(!jso) return NULL;
482 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000483 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000484 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000485}
486
Michael Clarkc4dceae2010-10-06 16:39:20 +0000487int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000488{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100489 int64_t cint64;
490 enum json_type o_type;
491
Michael Clarkc4dceae2010-10-06 16:39:20 +0000492 if(!jso) return 0;
493
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100494 o_type = jso->o_type;
495 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000496
497 if (o_type == json_type_string)
498 {
499 /*
500 * Parse strings into 64-bit numbers, then use the
501 * 64-to-32-bit number handling below.
502 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000503 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000504 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000505 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000506 }
507
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000508 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000509 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000510 /* Make sure we return the correct values for out of range numbers. */
511 if (cint64 <= INT32_MIN)
512 return INT32_MIN;
513 else if (cint64 >= INT32_MAX)
514 return INT32_MAX;
515 else
516 return (int32_t)cint64;
517 case json_type_double:
518 return (int32_t)jso->o.c_double;
519 case json_type_boolean:
520 return jso->o.c_boolean;
521 default:
522 return 0;
523 }
524}
525
526struct json_object* json_object_new_int64(int64_t i)
527{
ehaszla252669c2010-12-07 18:15:35 +0000528 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000529 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000530 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000531 jso->o.c_int64 = i;
532 return jso;
533}
534
535int64_t json_object_get_int64(struct json_object *jso)
536{
537 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000538
Michael Clark266a3fd2009-02-25 01:55:31 +0000539 if(!jso) return 0;
540 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000541 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000542 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000543 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000544 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000545 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000546 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000547 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000548 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000549 default:
550 return 0;
551 }
552}
553
554
555/* json_object_double */
556
Michael Clark266a3fd2009-02-25 01:55:31 +0000557static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500558 struct printbuf *pb,
559 int level,
560 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000561{
Eric Haszlakiewicz0cc1db62012-04-29 11:04:33 -0500562 return sprintbuf(pb, "%f", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000563}
564
565struct json_object* json_object_new_double(double d)
566{
Michael Clark266a3fd2009-02-25 01:55:31 +0000567 struct json_object *jso = json_object_new(json_type_double);
568 if(!jso) return NULL;
569 jso->_to_json_string = &json_object_double_to_json_string;
570 jso->o.c_double = d;
571 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000572}
573
Michael Clark266a3fd2009-02-25 01:55:31 +0000574double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000575{
576 double cdouble;
577
Michael Clark266a3fd2009-02-25 01:55:31 +0000578 if(!jso) return 0.0;
579 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000580 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000581 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000582 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000583 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000584 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000585 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000586 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000587 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000588 default:
589 return 0.0;
590 }
591}
592
593
594/* json_object_string */
595
Michael Clark266a3fd2009-02-25 01:55:31 +0000596static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500597 struct printbuf *pb,
598 int level,
599 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000600{
601 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000602 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000603 sprintbuf(pb, "\"");
604 return 0;
605}
606
Michael Clark266a3fd2009-02-25 01:55:31 +0000607static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000608{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000609 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000610 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000611}
612
Michael Clark68cafad2009-01-06 22:56:57 +0000613struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000614{
Michael Clark266a3fd2009-02-25 01:55:31 +0000615 struct json_object *jso = json_object_new(json_type_string);
616 if(!jso) return NULL;
617 jso->_delete = &json_object_string_delete;
618 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000619 jso->o.c_string.str = strdup(s);
620 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000621 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000622}
623
Michael Clark68cafad2009-01-06 22:56:57 +0000624struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000625{
Michael Clark266a3fd2009-02-25 01:55:31 +0000626 struct json_object *jso = json_object_new(json_type_string);
627 if(!jso) return NULL;
628 jso->_delete = &json_object_string_delete;
629 jso->_to_json_string = &json_object_string_to_json_string;
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600630 jso->o.c_string.str = (char*)malloc(len + 1);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000631 memcpy(jso->o.c_string.str, (void *)s, len);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600632 jso->o.c_string.str[len] = '\0';
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000633 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000634 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000635}
636
Michael Clark266a3fd2009-02-25 01:55:31 +0000637const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000638{
Michael Clark266a3fd2009-02-25 01:55:31 +0000639 if(!jso) return NULL;
640 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000641 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000642 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000643 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000644 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000645 }
646}
647
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000648int json_object_get_string_len(struct json_object *jso) {
649 if(!jso) return 0;
650 switch(jso->o_type) {
651 case json_type_string:
652 return jso->o.c_string.len;
653 default:
654 return 0;
655 }
656}
657
Michael Clarkf0d08882007-03-13 08:26:18 +0000658
659/* json_object_array */
660
Michael Clark266a3fd2009-02-25 01:55:31 +0000661static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500662 struct printbuf *pb,
663 int level,
664 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000665{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500666 int had_children = 0;
667 int ii;
668 sprintbuf(pb, "[");
669 if (flags & JSON_C_TO_STRING_PRETTY)
670 sprintbuf(pb, "\n");
671 for(ii=0; ii < json_object_array_length(jso); ii++)
672 {
673 struct json_object *val;
674 if (had_children)
675 {
676 sprintbuf(pb, ",");
677 if (flags & JSON_C_TO_STRING_PRETTY)
678 sprintbuf(pb, "\n");
679 }
680 had_children = 1;
681 if (flags & JSON_C_TO_STRING_SPACED)
682 sprintbuf(pb, " ");
683 indent(pb, level + 1, flags);
684 val = json_object_array_get_idx(jso, ii);
685 if(val == NULL)
686 sprintbuf(pb, "null");
687 else
688 val->_to_json_string(val, pb, level+1, flags);
689 }
690 if (flags & JSON_C_TO_STRING_PRETTY)
691 {
692 if (had_children)
693 sprintbuf(pb, "\n");
694 indent(pb,level,flags);
695 }
Michael Clark4504df72007-03-13 08:26:20 +0000696
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500697 if (flags & JSON_C_TO_STRING_SPACED)
698 return sprintbuf(pb, " ]");
699 else
700 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000701}
702
703static void json_object_array_entry_free(void *data)
704{
705 json_object_put((struct json_object*)data);
706}
707
Michael Clark266a3fd2009-02-25 01:55:31 +0000708static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000709{
Michael Clark266a3fd2009-02-25 01:55:31 +0000710 array_list_free(jso->o.c_array);
711 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000712}
713
Michael Clarke8de0782009-02-25 01:45:00 +0000714struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000715{
Michael Clark266a3fd2009-02-25 01:55:31 +0000716 struct json_object *jso = json_object_new(json_type_array);
717 if(!jso) return NULL;
718 jso->_delete = &json_object_array_delete;
719 jso->_to_json_string = &json_object_array_to_json_string;
720 jso->o.c_array = array_list_new(&json_object_array_entry_free);
721 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000722}
723
Michael Clark266a3fd2009-02-25 01:55:31 +0000724struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000725{
Michael Clark266a3fd2009-02-25 01:55:31 +0000726 if(!jso) return NULL;
727 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000728 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000729 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000730 default:
731 return NULL;
732 }
733}
734
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200735void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
736{
737 array_list_sort(jso->o.c_array, sort_fn);
738}
739
Michael Clark266a3fd2009-02-25 01:55:31 +0000740int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000741{
Michael Clark266a3fd2009-02-25 01:55:31 +0000742 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000743}
744
Michael Clark266a3fd2009-02-25 01:55:31 +0000745int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000746{
Michael Clark266a3fd2009-02-25 01:55:31 +0000747 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000748}
749
Michael Clark266a3fd2009-02-25 01:55:31 +0000750int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000751 struct json_object *val)
752{
Michael Clark266a3fd2009-02-25 01:55:31 +0000753 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000754}
755
Michael Clark266a3fd2009-02-25 01:55:31 +0000756struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000757 int idx)
758{
Michael Clark266a3fd2009-02-25 01:55:31 +0000759 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000760}
761