blob: 6cc73bce8c3de2b5a4852d7f0c91f44f6d8af836 [file] [log] [blame]
Michael Clarkf0d08882007-03-13 08:26:18 +00001/*
Michael Clarka850f8e2007-03-13 08:26:26 +00002 * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
Michael Clarkf0d08882007-03-13 08:26:18 +00003 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00004 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
Michael Clarkf0d08882007-03-13 08:26:18 +00005 * Michael Clark <michael@metaparadigm.com>
Keith Derrick69175862012-04-12 11:44:13 -07006 * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
Michael Clarkf0d08882007-03-13 08:26:18 +00007 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00008 * This library is free software; you can redistribute it and/or modify
9 * it under the terms of the MIT license. See COPYING for details.
Michael Clarkf0d08882007-03-13 08:26:18 +000010 *
11 */
12
Michael Clark4504df72007-03-13 08:26:20 +000013#include "config.h"
14
Michael Clarkf0d08882007-03-13 08:26:18 +000015#include <stdio.h>
16#include <stdlib.h>
Michael Clarkc8f4a6e2007-12-07 02:44:24 +000017#include <stddef.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000018#include <string.h>
Adrian Yanesd086e202013-06-07 13:14:54 -070019#include <math.h>
Keith Derrickc51b88d2013-10-01 09:18:51 -070020#include <errno.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000021
22#include "debug.h"
23#include "printbuf.h"
24#include "linkhash.h"
25#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000026#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000027#include "json_object.h"
28#include "json_object_private.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000029#include "json_util.h"
Eric Haszlakiewicze6f13222014-03-02 12:16:37 -050030#include "math_compat.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000031
Mateusz Loskota6f39a32012-05-21 23:22:36 +010032#if !defined(HAVE_STRDUP) && defined(_MSC_VER)
33 /* MSC has the version as _strdup */
34# define strdup _strdup
35#elif !defined(HAVE_STRDUP)
36# error You do not have strdup on your system.
37#endif /* HAVE_STRDUP */
38
Anatol Belskied819fb2013-06-04 20:18:05 +020039#if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
40 /* MSC has the version as _snprintf */
41# define snprintf _snprintf
42#elif !defined(HAVE_SNPRINTF)
43# error You do not have snprintf on your system.
44#endif /* HAVE_SNPRINTF */
45
Keith Derrick69175862012-04-12 11:44:13 -070046// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000047/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000048
Michael Clark68cafad2009-01-06 22:56:57 +000049const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010050const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000051
Michael Clark266a3fd2009-02-25 01:55:31 +000052static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000053static struct json_object* json_object_new(enum json_type o_type);
54
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -050055static json_object_to_json_string_fn json_object_object_to_json_string;
56static json_object_to_json_string_fn json_object_boolean_to_json_string;
57static json_object_to_json_string_fn json_object_int_to_json_string;
58static json_object_to_json_string_fn json_object_double_to_json_string;
59static json_object_to_json_string_fn json_object_string_to_json_string;
60static json_object_to_json_string_fn json_object_array_to_json_string;
61
Michael Clarkf0d08882007-03-13 08:26:18 +000062
63/* ref count debugging */
64
65#ifdef REFCOUNT_DEBUG
66
67static struct lh_table *json_object_table;
68
Michael Clark14862b12007-12-07 02:50:42 +000069static void json_object_init(void) __attribute__ ((constructor));
70static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000071 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000072 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
73}
74
Michael Clark14862b12007-12-07 02:50:42 +000075static void json_object_fini(void) __attribute__ ((destructor));
76static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000077 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000078 if(MC_GET_DEBUG()) {
79 if (json_object_table->count) {
80 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
81 json_object_table->count);
82 lh_foreach(json_object_table, ent) {
83 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000084 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000085 }
Michael Clarkf0d08882007-03-13 08:26:18 +000086 }
87 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000088 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000089 lh_table_free(json_object_table);
90}
Michael Clark4504df72007-03-13 08:26:20 +000091#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000092
93
94/* string escaping */
95
Jehiah Czebotarac601b52011-01-14 17:23:06 +000096static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000097{
98 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000099 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000100 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000101 c = str[pos];
102 switch(c) {
103 case '\b':
104 case '\n':
105 case '\r':
106 case '\t':
Abioy7eaa8492012-12-24 22:22:05 +0800107 case '\f':
Michael Clark4504df72007-03-13 08:26:20 +0000108 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000109 case '\\':
110 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000111 if(pos - start_offset > 0)
112 printbuf_memappend(pb, str + start_offset, pos - start_offset);
113 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
114 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
115 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
116 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Abioy7eaa8492012-12-24 22:22:05 +0800117 else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000118 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000119 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
120 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000121 start_offset = ++pos;
122 break;
123 default:
Michael Clark837240f2007-03-13 08:26:25 +0000124 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000125 if(pos - start_offset > 0)
126 printbuf_memappend(pb, str + start_offset, pos - start_offset);
127 sprintbuf(pb, "\\u00%c%c",
128 json_hex_chars[c >> 4],
129 json_hex_chars[c & 0xf]);
130 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000131 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000132 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000133 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000134 if(pos - start_offset > 0)
135 printbuf_memappend(pb, str + start_offset, pos - start_offset);
136 return 0;
137}
138
139
140/* reference counting */
141
Michael Clark266a3fd2009-02-25 01:55:31 +0000142extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000143{
Michael Clark266a3fd2009-02-25 01:55:31 +0000144 if(jso) {
145 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000146 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000147 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000148}
149
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500150int json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000151{
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500152 if(jso)
153 {
154 jso->_ref_count--;
155 if(!jso->_ref_count)
156 {
157 if (jso->_user_delete)
158 jso->_user_delete(jso, jso->_userdata);
159 jso->_delete(jso);
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500160 return 1;
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500161 }
162 }
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500163 return 0;
Michael Clarkf0d08882007-03-13 08:26:18 +0000164}
165
166
167/* generic object construction and destruction parts */
168
Michael Clark266a3fd2009-02-25 01:55:31 +0000169static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000170{
171#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000172 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000173 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000174 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000175#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000176 printbuf_free(jso->_pb);
177 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000178}
179
180static struct json_object* json_object_new(enum json_type o_type)
181{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000182 struct json_object *jso;
183
184 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000185 if(!jso) return NULL;
186 jso->o_type = o_type;
187 jso->_ref_count = 1;
188 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000189#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000190 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000191 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000192#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000193 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000194}
195
196
197/* type checking functions */
198
Michael Clark266a3fd2009-02-25 01:55:31 +0000199int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000200{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500201 if (!jso)
202 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000203 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000204}
205
Michael Clark266a3fd2009-02-25 01:55:31 +0000206enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000207{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500208 if (!jso)
209 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000210 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000211}
212
Eric Haszlakiewicz38f421a2012-09-02 15:21:56 -0500213/* set a custom conversion to string */
214
215void json_object_set_serializer(json_object *jso,
216 json_object_to_json_string_fn to_string_func,
217 void *userdata,
218 json_object_delete_fn *user_delete)
219{
220 // First, clean up any previously existing user info
221 if (jso->_user_delete)
222 {
223 jso->_user_delete(jso, jso->_userdata);
224 }
225 jso->_userdata = NULL;
226 jso->_user_delete = NULL;
227
228 if (to_string_func == NULL)
229 {
230 // Reset to the standard serialization function
231 switch(jso->o_type)
232 {
233 case json_type_null:
234 jso->_to_json_string = NULL;
235 break;
236 case json_type_boolean:
237 jso->_to_json_string = &json_object_boolean_to_json_string;
238 break;
239 case json_type_double:
240 jso->_to_json_string = &json_object_double_to_json_string;
241 break;
242 case json_type_int:
243 jso->_to_json_string = &json_object_int_to_json_string;
244 break;
245 case json_type_object:
246 jso->_to_json_string = &json_object_object_to_json_string;
247 break;
248 case json_type_array:
249 jso->_to_json_string = &json_object_array_to_json_string;
250 break;
251 case json_type_string:
252 jso->_to_json_string = &json_object_string_to_json_string;
253 break;
254 }
255 return;
256 }
257
258 jso->_to_json_string = to_string_func;
259 jso->_userdata = userdata;
260 jso->_user_delete = user_delete;
261}
262
263
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500264/* extended conversion to string */
265
266const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
267{
268 if (!jso)
269 return "null";
270
271 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
272 return NULL;
273
274 printbuf_reset(jso->_pb);
275
276 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
277 return NULL;
278
279 return jso->_pb->buf;
280}
281
282/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000283
Michael Clark266a3fd2009-02-25 01:55:31 +0000284const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000285{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500286 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000287}
288
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500289static void indent(struct printbuf *pb, int level, int flags)
290{
291 if (flags & JSON_C_TO_STRING_PRETTY)
292 {
293 printbuf_memset(pb, -1, ' ', level * 2);
294 }
295}
Michael Clarkf0d08882007-03-13 08:26:18 +0000296
297/* json_object_object */
298
Michael Clark266a3fd2009-02-25 01:55:31 +0000299static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500300 struct printbuf *pb,
301 int level,
302 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000303{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500304 int had_children = 0;
305 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000306
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500307 sprintbuf(pb, "{" /*}*/);
308 if (flags & JSON_C_TO_STRING_PRETTY)
309 sprintbuf(pb, "\n");
310 json_object_object_foreachC(jso, iter)
311 {
312 if (had_children)
313 {
314 sprintbuf(pb, ",");
315 if (flags & JSON_C_TO_STRING_PRETTY)
316 sprintbuf(pb, "\n");
317 }
318 had_children = 1;
319 if (flags & JSON_C_TO_STRING_SPACED)
320 sprintbuf(pb, " ");
321 indent(pb, level+1, flags);
322 sprintbuf(pb, "\"");
323 json_escape_str(pb, iter.key, strlen(iter.key));
324 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000325 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500326 else
327 sprintbuf(pb, "\":");
328 if(iter.val == NULL)
329 sprintbuf(pb, "null");
330 else
331 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000332 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500333 if (flags & JSON_C_TO_STRING_PRETTY)
334 {
335 if (had_children)
336 sprintbuf(pb, "\n");
337 indent(pb,level,flags);
338 }
339 if (flags & JSON_C_TO_STRING_SPACED)
340 return sprintbuf(pb, /*{*/ " }");
341 else
342 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000343}
344
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500345
Michael Clarkf0d08882007-03-13 08:26:18 +0000346static void json_object_lh_entry_free(struct lh_entry *ent)
347{
348 free(ent->k);
349 json_object_put((struct json_object*)ent->v);
350}
351
Michael Clark266a3fd2009-02-25 01:55:31 +0000352static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000353{
Michael Clark266a3fd2009-02-25 01:55:31 +0000354 lh_table_free(jso->o.c_object);
355 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000356}
357
Michael Clarke8de0782009-02-25 01:45:00 +0000358struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000359{
Michael Clark266a3fd2009-02-25 01:55:31 +0000360 struct json_object *jso = json_object_new(json_type_object);
361 if(!jso) return NULL;
362 jso->_delete = &json_object_object_delete;
363 jso->_to_json_string = &json_object_object_to_json_string;
364 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000365 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000366 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000367}
368
Michael Clark266a3fd2009-02-25 01:55:31 +0000369struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000370{
Michael Clark266a3fd2009-02-25 01:55:31 +0000371 if(!jso) return NULL;
372 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000373 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000374 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000375 default:
376 return NULL;
377 }
378}
379
Michael Clark266a3fd2009-02-25 01:55:31 +0000380void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000381 struct json_object *val)
382{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500383 // We lookup the entry and replace the value, rather than just deleting
384 // and re-adding it, so the existing key remains valid.
385 json_object *existing_value = NULL;
386 struct lh_entry *existing_entry;
387 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
388 if (!existing_entry)
389 {
390 lh_table_insert(jso->o.c_object, strdup(key), val);
391 return;
392 }
393 existing_value = (void *)existing_entry->v;
394 if (existing_value)
395 json_object_put(existing_value);
396 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000397}
398
Greg Hazelcca74c62013-01-11 01:36:55 -0800399int json_object_object_length(struct json_object *jso)
400{
401 return lh_table_length(jso->o.c_object);
402}
403
Michael Clark266a3fd2009-02-25 01:55:31 +0000404struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000405{
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500406 struct json_object *result = NULL;
407 json_object_object_get_ex(jso, key, &result);
408 return result;
Keith Derrick69175862012-04-12 11:44:13 -0700409}
410
411json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
412{
Eric Haszlakiewicz5450bed2012-10-18 17:14:41 -0500413 if (value != NULL)
414 *value = NULL;
415
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500416 if (NULL == jso)
417 return FALSE;
Keith Derrick69175862012-04-12 11:44:13 -0700418
Eric Haszlakiewicze36e5622012-10-18 17:16:36 -0500419 switch(jso->o_type)
420 {
421 case json_type_object:
422 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
423 default:
424 if (value != NULL)
425 *value = NULL;
426 return FALSE;
427 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000428}
429
Michael Clark266a3fd2009-02-25 01:55:31 +0000430void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000431{
Eric Haszlakiewicz5f4739e2012-10-18 17:10:09 -0500432 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000433}
434
435
436/* json_object_boolean */
437
Michael Clark266a3fd2009-02-25 01:55:31 +0000438static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500439 struct printbuf *pb,
440 int level,
441 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000442{
Michael Clark266a3fd2009-02-25 01:55:31 +0000443 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000444 else return sprintbuf(pb, "false");
445}
446
Keith Derrick37e74672012-03-26 14:29:31 -0700447struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000448{
Michael Clark266a3fd2009-02-25 01:55:31 +0000449 struct json_object *jso = json_object_new(json_type_boolean);
450 if(!jso) return NULL;
451 jso->_to_json_string = &json_object_boolean_to_json_string;
452 jso->o.c_boolean = b;
453 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000454}
455
Keith Derrick37e74672012-03-26 14:29:31 -0700456json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000457{
Michael Clark266a3fd2009-02-25 01:55:31 +0000458 if(!jso) return FALSE;
459 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000460 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000461 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000462 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000463 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000465 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000467 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000468 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000469 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000470 }
471}
472
473
474/* json_object_int */
475
Michael Clark266a3fd2009-02-25 01:55:31 +0000476static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500477 struct printbuf *pb,
478 int level,
479 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000480{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000481 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
482}
483
484struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000485{
Michael Clark266a3fd2009-02-25 01:55:31 +0000486 struct json_object *jso = json_object_new(json_type_int);
487 if(!jso) return NULL;
488 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000489 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000490 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000491}
492
Michael Clarkc4dceae2010-10-06 16:39:20 +0000493int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000494{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100495 int64_t cint64;
496 enum json_type o_type;
497
Michael Clarkc4dceae2010-10-06 16:39:20 +0000498 if(!jso) return 0;
499
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100500 o_type = jso->o_type;
501 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000502
503 if (o_type == json_type_string)
504 {
505 /*
506 * Parse strings into 64-bit numbers, then use the
507 * 64-to-32-bit number handling below.
508 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000509 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000510 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000511 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000512 }
513
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000514 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000515 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000516 /* Make sure we return the correct values for out of range numbers. */
517 if (cint64 <= INT32_MIN)
518 return INT32_MIN;
519 else if (cint64 >= INT32_MAX)
520 return INT32_MAX;
521 else
522 return (int32_t)cint64;
523 case json_type_double:
524 return (int32_t)jso->o.c_double;
525 case json_type_boolean:
526 return jso->o.c_boolean;
527 default:
528 return 0;
529 }
530}
531
532struct json_object* json_object_new_int64(int64_t i)
533{
ehaszla252669c2010-12-07 18:15:35 +0000534 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000535 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000536 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000537 jso->o.c_int64 = i;
538 return jso;
539}
540
541int64_t json_object_get_int64(struct json_object *jso)
542{
543 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000544
Michael Clark266a3fd2009-02-25 01:55:31 +0000545 if(!jso) return 0;
546 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000547 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000548 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000549 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000550 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000551 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000552 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000553 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000554 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000555 default:
556 return 0;
557 }
558}
559
560
561/* json_object_double */
562
Michael Clark266a3fd2009-02-25 01:55:31 +0000563static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500564 struct printbuf *pb,
565 int level,
566 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000567{
Remi Collet8c847962012-12-13 11:22:31 +0100568 char buf[128], *p, *q;
Remi Collet4014fe82012-12-13 11:16:03 +0100569 int size;
Adrian Yanesd086e202013-06-07 13:14:54 -0700570 /* Although JSON RFC does not support
571 NaN or Infinity as numeric values
572 ECMA 262 section 9.8.1 defines
573 how to handle these cases as strings */
574 if(isnan(jso->o.c_double))
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500575 size = snprintf(buf, sizeof(buf), "NaN");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300576 else if(isinf(jso->o.c_double))
577 if(jso->o.c_double > 0)
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500578 size = snprintf(buf, sizeof(buf), "Infinity");
Taneli Mielikainenc5523a12013-08-04 00:21:58 +0300579 else
Eric Haszlakiewicza23caf62013-09-11 20:28:56 -0500580 size = snprintf(buf, sizeof(buf), "-Infinity");
Adrian Yanesd086e202013-06-07 13:14:54 -0700581 else
Eric Haszlakiewicz06450202013-09-11 21:09:43 -0500582 size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double);
Remi Collet4014fe82012-12-13 11:16:03 +0100583
Remi Collet4014fe82012-12-13 11:16:03 +0100584 p = strchr(buf, ',');
585 if (p) {
586 *p = '.';
Remi Collet8c847962012-12-13 11:22:31 +0100587 } else {
588 p = strchr(buf, '.');
589 }
Remi Collet32d149c2012-12-13 11:46:04 +0100590 if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
Remi Collet8c847962012-12-13 11:22:31 +0100591 /* last useful digit, always keep 1 zero */
592 p++;
593 for (q=p ; *q ; q++) {
594 if (*q!='0') p=q;
595 }
596 /* drop trailing zeroes */
597 *(++p) = 0;
598 size = p-buf;
Remi Collet4014fe82012-12-13 11:16:03 +0100599 }
600 printbuf_memappend(pb, buf, size);
601 return size;
Michael Clarkf0d08882007-03-13 08:26:18 +0000602}
603
604struct json_object* json_object_new_double(double d)
605{
Eric Haszlakiewicz51993c22013-09-11 20:27:39 -0500606 struct json_object *jso = json_object_new(json_type_double);
607 if (!jso)
608 return NULL;
609 jso->_to_json_string = &json_object_double_to_json_string;
610 jso->o.c_double = d;
611 return jso;
612}
613
614struct json_object* json_object_new_double_s(double d, const char *ds)
615{
616 struct json_object *jso = json_object_new_double(d);
617 if (!jso)
618 return NULL;
619
620 json_object_set_serializer(jso, json_object_userdata_to_json_string,
621 strdup(ds), json_object_free_userdata);
622 return jso;
623}
624
625int json_object_userdata_to_json_string(struct json_object *jso,
626 struct printbuf *pb, int level, int flags)
627{
628 int userdata_len = strlen(jso->_userdata);
629 printbuf_memappend(pb, jso->_userdata, userdata_len);
630 return userdata_len;
631}
632
633void json_object_free_userdata(struct json_object *jso, void *userdata)
634{
635 free(userdata);
Michael Clarkf0d08882007-03-13 08:26:18 +0000636}
637
Michael Clark266a3fd2009-02-25 01:55:31 +0000638double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000639{
640 double cdouble;
Keith Derrickc51b88d2013-10-01 09:18:51 -0700641 char *errPtr = NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000642
Michael Clark266a3fd2009-02-25 01:55:31 +0000643 if(!jso) return 0.0;
644 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000645 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000646 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000647 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000648 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000649 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000650 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000651 case json_type_string:
Keith Derrickc51b88d2013-10-01 09:18:51 -0700652 errno = 0;
653 cdouble = strtod(jso->o.c_string.str,&errPtr);
654
655 /* if conversion stopped at the first character, return 0.0 */
656 if (errPtr == jso->o.c_string.str)
657 return 0.0;
658
659 /*
660 * Check that the conversion terminated on something sensible
661 *
662 * For example, { "pay" : 123AB } would parse as 123.
663 */
664 if (*errPtr != '\0')
665 return 0.0;
666
667 /*
668 * If strtod encounters a string which would exceed the
669 * capacity of a double, it returns +/- HUGE_VAL and sets
670 * errno to ERANGE. But +/- HUGE_VAL is also a valid result
671 * from a conversion, so we need to check errno.
672 *
673 * Underflow also sets errno to ERANGE, but it returns 0 in
674 * that case, which is what we will return anyway.
675 *
676 * See CERT guideline ERR30-C
677 */
678 if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
679 (ERANGE == errno))
680 cdouble = 0.0;
681 return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000682 default:
683 return 0.0;
684 }
685}
686
687
688/* json_object_string */
689
Michael Clark266a3fd2009-02-25 01:55:31 +0000690static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500691 struct printbuf *pb,
692 int level,
693 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000694{
695 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000696 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000697 sprintbuf(pb, "\"");
698 return 0;
699}
700
Michael Clark266a3fd2009-02-25 01:55:31 +0000701static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000702{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000703 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000704 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000705}
706
Michael Clark68cafad2009-01-06 22:56:57 +0000707struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000708{
Michael Clark266a3fd2009-02-25 01:55:31 +0000709 struct json_object *jso = json_object_new(json_type_string);
710 if(!jso) return NULL;
711 jso->_delete = &json_object_string_delete;
712 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000713 jso->o.c_string.str = strdup(s);
714 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000715 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000716}
717
Michael Clark68cafad2009-01-06 22:56:57 +0000718struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000719{
Michael Clark266a3fd2009-02-25 01:55:31 +0000720 struct json_object *jso = json_object_new(json_type_string);
721 if(!jso) return NULL;
722 jso->_delete = &json_object_string_delete;
723 jso->_to_json_string = &json_object_string_to_json_string;
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600724 jso->o.c_string.str = (char*)malloc(len + 1);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000725 memcpy(jso->o.c_string.str, (void *)s, len);
Eric Haszlakiewicz4e4af932012-12-09 16:32:11 -0600726 jso->o.c_string.str[len] = '\0';
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000727 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000728 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000729}
730
Michael Clark266a3fd2009-02-25 01:55:31 +0000731const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000732{
Michael Clark266a3fd2009-02-25 01:55:31 +0000733 if(!jso) return NULL;
734 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000735 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000736 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000737 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000738 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000739 }
740}
741
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000742int json_object_get_string_len(struct json_object *jso) {
743 if(!jso) return 0;
744 switch(jso->o_type) {
745 case json_type_string:
746 return jso->o.c_string.len;
747 default:
748 return 0;
749 }
750}
751
Michael Clarkf0d08882007-03-13 08:26:18 +0000752
753/* json_object_array */
754
Michael Clark266a3fd2009-02-25 01:55:31 +0000755static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500756 struct printbuf *pb,
757 int level,
758 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000759{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500760 int had_children = 0;
761 int ii;
762 sprintbuf(pb, "[");
763 if (flags & JSON_C_TO_STRING_PRETTY)
764 sprintbuf(pb, "\n");
765 for(ii=0; ii < json_object_array_length(jso); ii++)
766 {
767 struct json_object *val;
768 if (had_children)
769 {
770 sprintbuf(pb, ",");
771 if (flags & JSON_C_TO_STRING_PRETTY)
772 sprintbuf(pb, "\n");
773 }
774 had_children = 1;
775 if (flags & JSON_C_TO_STRING_SPACED)
776 sprintbuf(pb, " ");
777 indent(pb, level + 1, flags);
778 val = json_object_array_get_idx(jso, ii);
779 if(val == NULL)
780 sprintbuf(pb, "null");
781 else
782 val->_to_json_string(val, pb, level+1, flags);
783 }
784 if (flags & JSON_C_TO_STRING_PRETTY)
785 {
786 if (had_children)
787 sprintbuf(pb, "\n");
788 indent(pb,level,flags);
789 }
Michael Clark4504df72007-03-13 08:26:20 +0000790
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500791 if (flags & JSON_C_TO_STRING_SPACED)
792 return sprintbuf(pb, " ]");
793 else
794 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000795}
796
797static void json_object_array_entry_free(void *data)
798{
799 json_object_put((struct json_object*)data);
800}
801
Michael Clark266a3fd2009-02-25 01:55:31 +0000802static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000803{
Michael Clark266a3fd2009-02-25 01:55:31 +0000804 array_list_free(jso->o.c_array);
805 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000806}
807
Michael Clarke8de0782009-02-25 01:45:00 +0000808struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000809{
Michael Clark266a3fd2009-02-25 01:55:31 +0000810 struct json_object *jso = json_object_new(json_type_array);
811 if(!jso) return NULL;
812 jso->_delete = &json_object_array_delete;
813 jso->_to_json_string = &json_object_array_to_json_string;
814 jso->o.c_array = array_list_new(&json_object_array_entry_free);
815 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000816}
817
Michael Clark266a3fd2009-02-25 01:55:31 +0000818struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000819{
Michael Clark266a3fd2009-02-25 01:55:31 +0000820 if(!jso) return NULL;
821 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000822 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000823 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000824 default:
825 return NULL;
826 }
827}
828
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200829void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
830{
831 array_list_sort(jso->o.c_array, sort_fn);
832}
833
Michael Clark266a3fd2009-02-25 01:55:31 +0000834int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000835{
Michael Clark266a3fd2009-02-25 01:55:31 +0000836 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000837}
838
Michael Clark266a3fd2009-02-25 01:55:31 +0000839int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000840{
Michael Clark266a3fd2009-02-25 01:55:31 +0000841 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000842}
843
Michael Clark266a3fd2009-02-25 01:55:31 +0000844int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000845 struct json_object *val)
846{
Michael Clark266a3fd2009-02-25 01:55:31 +0000847 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000848}
849
Michael Clark266a3fd2009-02-25 01:55:31 +0000850struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000851 int idx)
852{
Michael Clark266a3fd2009-02-25 01:55:31 +0000853 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000854}
855