blob: bb344af0965ee320c0ac04530ccefb96d81b1eb9 [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':
Michael Clark4504df72007-03-13 08:26:20 +0000101 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000102 case '\\':
103 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000104 if(pos - start_offset > 0)
105 printbuf_memappend(pb, str + start_offset, pos - start_offset);
106 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
107 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
108 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
109 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000110 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000111 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
112 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000113 start_offset = ++pos;
114 break;
115 default:
Michael Clark837240f2007-03-13 08:26:25 +0000116 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000117 if(pos - start_offset > 0)
118 printbuf_memappend(pb, str + start_offset, pos - start_offset);
119 sprintbuf(pb, "\\u00%c%c",
120 json_hex_chars[c >> 4],
121 json_hex_chars[c & 0xf]);
122 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000123 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000124 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000125 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000126 if(pos - start_offset > 0)
127 printbuf_memappend(pb, str + start_offset, pos - start_offset);
128 return 0;
129}
130
131
132/* reference counting */
133
Michael Clark266a3fd2009-02-25 01:55:31 +0000134extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000135{
Michael Clark266a3fd2009-02-25 01:55:31 +0000136 if(jso) {
137 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000138 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000139 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000140}
141
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500142int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000143{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500144 if(jso)
145 {
146 jso->_ref_count--;
147 if(!jso->_ref_count)
148 {
149 if (jso->_user_delete)
150 jso->_user_delete(jso, jso->_userdata);
151 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500152 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500153 }
154 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500155 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000156}
157
158
159/* generic object construction and destruction parts */
160
Michael Clark266a3fd2009-02-25 01:55:31 +0000161static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000162{
163#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000164 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000165 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000166 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000167#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000168 printbuf_free(jso->_pb);
169 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000170}
171
172static struct json_object* json_object_new(enum json_type o_type)
173{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000174 struct json_object *jso;
175
176 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000177 if(!jso) return NULL;
178 jso->o_type = o_type;
179 jso->_ref_count = 1;
180 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000181#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000182 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000183 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000184#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000185 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000186}
187
188
189/* type checking functions */
190
Michael Clark266a3fd2009-02-25 01:55:31 +0000191int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000192{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500193 if (!jso)
194 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000195 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000196}
197
Michael Clark266a3fd2009-02-25 01:55:31 +0000198enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000199{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500200 if (!jso)
201 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000202 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000203}
204
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500205/* set a custom conversion to string */
206
207void json_object_set_serializer(json_object *jso,
208 json_object_to_json_string_fn to_string_func,
209 void *userdata,
210 json_object_delete_fn *user_delete)
211{
212 // First, clean up any previously existing user info
213 if (jso->_user_delete)
214 {
215 jso->_user_delete(jso, jso->_userdata);
216 }
217 jso->_userdata = NULL;
218 jso->_user_delete = NULL;
219
220 if (to_string_func == NULL)
221 {
222 // Reset to the standard serialization function
223 switch(jso->o_type)
224 {
225 case json_type_null:
226 jso->_to_json_string = NULL;
227 break;
228 case json_type_boolean:
229 jso->_to_json_string = &json_object_boolean_to_json_string;
230 break;
231 case json_type_double:
232 jso->_to_json_string = &json_object_double_to_json_string;
233 break;
234 case json_type_int:
235 jso->_to_json_string = &json_object_int_to_json_string;
236 break;
237 case json_type_object:
238 jso->_to_json_string = &json_object_object_to_json_string;
239 break;
240 case json_type_array:
241 jso->_to_json_string = &json_object_array_to_json_string;
242 break;
243 case json_type_string:
244 jso->_to_json_string = &json_object_string_to_json_string;
245 break;
246 }
247 return;
248 }
249
250 jso->_to_json_string = to_string_func;
251 jso->_userdata = userdata;
252 jso->_user_delete = user_delete;
253}
254
255
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500256/* extended conversion to string */
257
258const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
259{
260 if (!jso)
261 return "null";
262
263 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
264 return NULL;
265
266 printbuf_reset(jso->_pb);
267
268 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
269 return NULL;
270
271 return jso->_pb->buf;
272}
273
274/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000275
Michael Clark266a3fd2009-02-25 01:55:31 +0000276const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000277{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500278 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000279}
280
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500281static void indent(struct printbuf *pb, int level, int flags)
282{
283 if (flags & JSON_C_TO_STRING_PRETTY)
284 {
285 printbuf_memset(pb, -1, ' ', level * 2);
286 }
287}
Michael Clarkf0d08882007-03-13 08:26:18 +0000288
289/* json_object_object */
290
Michael Clark266a3fd2009-02-25 01:55:31 +0000291static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500292 struct printbuf *pb,
293 int level,
294 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000295{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500296 int had_children = 0;
297 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000298
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500299 sprintbuf(pb, "{" /*}*/);
300 if (flags & JSON_C_TO_STRING_PRETTY)
301 sprintbuf(pb, "\n");
302 json_object_object_foreachC(jso, iter)
303 {
304 if (had_children)
305 {
306 sprintbuf(pb, ",");
307 if (flags & JSON_C_TO_STRING_PRETTY)
308 sprintbuf(pb, "\n");
309 }
310 had_children = 1;
311 if (flags & JSON_C_TO_STRING_SPACED)
312 sprintbuf(pb, " ");
313 indent(pb, level+1, flags);
314 sprintbuf(pb, "\"");
315 json_escape_str(pb, iter.key, strlen(iter.key));
316 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000317 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500318 else
319 sprintbuf(pb, "\":");
320 if(iter.val == NULL)
321 sprintbuf(pb, "null");
322 else
323 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000324 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500325 if (flags & JSON_C_TO_STRING_PRETTY)
326 {
327 if (had_children)
328 sprintbuf(pb, "\n");
329 indent(pb,level,flags);
330 }
331 if (flags & JSON_C_TO_STRING_SPACED)
332 return sprintbuf(pb, /*{*/ " }");
333 else
334 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000335}
336
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500337
Michael Clarkf0d08882007-03-13 08:26:18 +0000338static void json_object_lh_entry_free(struct lh_entry *ent)
339{
340 free(ent->k);
341 json_object_put((struct json_object*)ent->v);
342}
343
Michael Clark266a3fd2009-02-25 01:55:31 +0000344static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000345{
Michael Clark266a3fd2009-02-25 01:55:31 +0000346 lh_table_free(jso->o.c_object);
347 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000348}
349
Michael Clarke8de0782009-02-25 01:45:00 +0000350struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000351{
Michael Clark266a3fd2009-02-25 01:55:31 +0000352 struct json_object *jso = json_object_new(json_type_object);
353 if(!jso) return NULL;
354 jso->_delete = &json_object_object_delete;
355 jso->_to_json_string = &json_object_object_to_json_string;
356 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000357 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000358 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000359}
360
Michael Clark266a3fd2009-02-25 01:55:31 +0000361struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000362{
Michael Clark266a3fd2009-02-25 01:55:31 +0000363 if(!jso) return NULL;
364 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000365 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000366 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000367 default:
368 return NULL;
369 }
370}
371
Michael Clark266a3fd2009-02-25 01:55:31 +0000372void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000373 struct json_object *val)
374{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500375 // We lookup the entry and replace the value, rather than just deleting
376 // and re-adding it, so the existing key remains valid.
377 json_object *existing_value = NULL;
378 struct lh_entry *existing_entry;
379 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
380 if (!existing_entry)
381 {
382 lh_table_insert(jso->o.c_object, strdup(key), val);
383 return;
384 }
385 existing_value = (void *)existing_entry->v;
386 if (existing_value)
387 json_object_put(existing_value);
388 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000389}
390
Michael Clark266a3fd2009-02-25 01:55:31 +0000391struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000392{
Keith Derrick69175862012-04-12 11:44:13 -0700393 struct json_object *result;
394 json_object_object_get_ex(jso, key, &result);
395 return result;
396}
397
398json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
399{
400 if (NULL == jso) return FALSE;
401
402 switch(jso->o_type) {
403 case json_type_object:
404 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
405 default:
406 if (value != NULL) {
407 *value = NULL;
408 }
409 return FALSE;
410 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000411}
412
Michael Clark266a3fd2009-02-25 01:55:31 +0000413void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000414{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500415 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000416}
417
418
419/* json_object_boolean */
420
Michael Clark266a3fd2009-02-25 01:55:31 +0000421static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500422 struct printbuf *pb,
423 int level,
424 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000425{
Michael Clark266a3fd2009-02-25 01:55:31 +0000426 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000427 else return sprintbuf(pb, "false");
428}
429
Keith Derrick37e74672012-03-26 14:29:31 -0700430struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000431{
Michael Clark266a3fd2009-02-25 01:55:31 +0000432 struct json_object *jso = json_object_new(json_type_boolean);
433 if(!jso) return NULL;
434 jso->_to_json_string = &json_object_boolean_to_json_string;
435 jso->o.c_boolean = b;
436 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000437}
438
Keith Derrick37e74672012-03-26 14:29:31 -0700439json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000440{
Michael Clark266a3fd2009-02-25 01:55:31 +0000441 if(!jso) return FALSE;
442 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000443 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000444 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000445 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000446 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000447 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000448 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000449 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000450 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000451 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000452 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000453 }
454}
455
456
457/* json_object_int */
458
Michael Clark266a3fd2009-02-25 01:55:31 +0000459static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500460 struct printbuf *pb,
461 int level,
462 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000463{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000464 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
465}
466
467struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000468{
Michael Clark266a3fd2009-02-25 01:55:31 +0000469 struct json_object *jso = json_object_new(json_type_int);
470 if(!jso) return NULL;
471 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000472 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000473 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000474}
475
Michael Clarkc4dceae2010-10-06 16:39:20 +0000476int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000477{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100478 int64_t cint64;
479 enum json_type o_type;
480
Michael Clarkc4dceae2010-10-06 16:39:20 +0000481 if(!jso) return 0;
482
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100483 o_type = jso->o_type;
484 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000485
486 if (o_type == json_type_string)
487 {
488 /*
489 * Parse strings into 64-bit numbers, then use the
490 * 64-to-32-bit number handling below.
491 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000492 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000493 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000494 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000495 }
496
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000497 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000498 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000499 /* Make sure we return the correct values for out of range numbers. */
500 if (cint64 <= INT32_MIN)
501 return INT32_MIN;
502 else if (cint64 >= INT32_MAX)
503 return INT32_MAX;
504 else
505 return (int32_t)cint64;
506 case json_type_double:
507 return (int32_t)jso->o.c_double;
508 case json_type_boolean:
509 return jso->o.c_boolean;
510 default:
511 return 0;
512 }
513}
514
515struct json_object* json_object_new_int64(int64_t i)
516{
ehaszla252669c2010-12-07 18:15:35 +0000517 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000518 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000519 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000520 jso->o.c_int64 = i;
521 return jso;
522}
523
524int64_t json_object_get_int64(struct json_object *jso)
525{
526 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000527
Michael Clark266a3fd2009-02-25 01:55:31 +0000528 if(!jso) return 0;
529 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000530 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000531 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000532 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000533 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000534 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000535 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000536 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000537 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000538 default:
539 return 0;
540 }
541}
542
543
544/* json_object_double */
545
Michael Clark266a3fd2009-02-25 01:55:31 +0000546static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500547 struct printbuf *pb,
548 int level,
549 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000550{
Eric Haszlakiewicz0cc1db62012-04-29 11:04:33 -0500551 return sprintbuf(pb, "%f", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000552}
553
554struct json_object* json_object_new_double(double d)
555{
Michael Clark266a3fd2009-02-25 01:55:31 +0000556 struct json_object *jso = json_object_new(json_type_double);
557 if(!jso) return NULL;
558 jso->_to_json_string = &json_object_double_to_json_string;
559 jso->o.c_double = d;
560 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000561}
562
Michael Clark266a3fd2009-02-25 01:55:31 +0000563double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000564{
565 double cdouble;
566
Michael Clark266a3fd2009-02-25 01:55:31 +0000567 if(!jso) return 0.0;
568 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000569 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000570 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000571 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000572 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000573 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000574 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000575 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000576 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000577 default:
578 return 0.0;
579 }
580}
581
582
583/* json_object_string */
584
Michael Clark266a3fd2009-02-25 01:55:31 +0000585static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500586 struct printbuf *pb,
587 int level,
588 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000589{
590 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000591 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000592 sprintbuf(pb, "\"");
593 return 0;
594}
595
Michael Clark266a3fd2009-02-25 01:55:31 +0000596static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000597{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000598 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000599 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000600}
601
Michael Clark68cafad2009-01-06 22:56:57 +0000602struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000603{
Michael Clark266a3fd2009-02-25 01:55:31 +0000604 struct json_object *jso = json_object_new(json_type_string);
605 if(!jso) return NULL;
606 jso->_delete = &json_object_string_delete;
607 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000608 jso->o.c_string.str = strdup(s);
609 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000610 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000611}
612
Michael Clark68cafad2009-01-06 22:56:57 +0000613struct json_object* json_object_new_string_len(const char *s, int len)
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;
Mateusz Loskot271c53e2012-05-22 23:51:44 +0100619 jso->o.c_string.str = (char*)malloc(len);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000620 memcpy(jso->o.c_string.str, (void *)s, len);
621 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000622 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000623}
624
Michael Clark266a3fd2009-02-25 01:55:31 +0000625const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000626{
Michael Clark266a3fd2009-02-25 01:55:31 +0000627 if(!jso) return NULL;
628 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000629 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000630 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000631 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000632 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000633 }
634}
635
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000636int json_object_get_string_len(struct json_object *jso) {
637 if(!jso) return 0;
638 switch(jso->o_type) {
639 case json_type_string:
640 return jso->o.c_string.len;
641 default:
642 return 0;
643 }
644}
645
Michael Clarkf0d08882007-03-13 08:26:18 +0000646
647/* json_object_array */
648
Michael Clark266a3fd2009-02-25 01:55:31 +0000649static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500650 struct printbuf *pb,
651 int level,
652 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000653{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500654 int had_children = 0;
655 int ii;
656 sprintbuf(pb, "[");
657 if (flags & JSON_C_TO_STRING_PRETTY)
658 sprintbuf(pb, "\n");
659 for(ii=0; ii < json_object_array_length(jso); ii++)
660 {
661 struct json_object *val;
662 if (had_children)
663 {
664 sprintbuf(pb, ",");
665 if (flags & JSON_C_TO_STRING_PRETTY)
666 sprintbuf(pb, "\n");
667 }
668 had_children = 1;
669 if (flags & JSON_C_TO_STRING_SPACED)
670 sprintbuf(pb, " ");
671 indent(pb, level + 1, flags);
672 val = json_object_array_get_idx(jso, ii);
673 if(val == NULL)
674 sprintbuf(pb, "null");
675 else
676 val->_to_json_string(val, pb, level+1, flags);
677 }
678 if (flags & JSON_C_TO_STRING_PRETTY)
679 {
680 if (had_children)
681 sprintbuf(pb, "\n");
682 indent(pb,level,flags);
683 }
Michael Clark4504df72007-03-13 08:26:20 +0000684
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500685 if (flags & JSON_C_TO_STRING_SPACED)
686 return sprintbuf(pb, " ]");
687 else
688 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000689}
690
691static void json_object_array_entry_free(void *data)
692{
693 json_object_put((struct json_object*)data);
694}
695
Michael Clark266a3fd2009-02-25 01:55:31 +0000696static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000697{
Michael Clark266a3fd2009-02-25 01:55:31 +0000698 array_list_free(jso->o.c_array);
699 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000700}
701
Michael Clarke8de0782009-02-25 01:45:00 +0000702struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000703{
Michael Clark266a3fd2009-02-25 01:55:31 +0000704 struct json_object *jso = json_object_new(json_type_array);
705 if(!jso) return NULL;
706 jso->_delete = &json_object_array_delete;
707 jso->_to_json_string = &json_object_array_to_json_string;
708 jso->o.c_array = array_list_new(&json_object_array_entry_free);
709 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000710}
711
Michael Clark266a3fd2009-02-25 01:55:31 +0000712struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000713{
Michael Clark266a3fd2009-02-25 01:55:31 +0000714 if(!jso) return NULL;
715 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000716 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000717 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000718 default:
719 return NULL;
720 }
721}
722
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200723void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
724{
725 array_list_sort(jso->o.c_array, sort_fn);
726}
727
Michael Clark266a3fd2009-02-25 01:55:31 +0000728int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000729{
Michael Clark266a3fd2009-02-25 01:55:31 +0000730 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000731}
732
Michael Clark266a3fd2009-02-25 01:55:31 +0000733int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000734{
Michael Clark266a3fd2009-02-25 01:55:31 +0000735 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000736}
737
Michael Clark266a3fd2009-02-25 01:55:31 +0000738int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000739 struct json_object *val)
740{
Michael Clark266a3fd2009-02-25 01:55:31 +0000741 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000742}
743
Michael Clark266a3fd2009-02-25 01:55:31 +0000744struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000745 int idx)
746{
Michael Clark266a3fd2009-02-25 01:55:31 +0000747 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000748}
749