blob: 8dd13b0d665c94fab860c785aeba4844a10fcc51 [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
49
50/* ref count debugging */
51
52#ifdef REFCOUNT_DEBUG
53
54static struct lh_table *json_object_table;
55
Michael Clark14862b12007-12-07 02:50:42 +000056static void json_object_init(void) __attribute__ ((constructor));
57static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000058 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000059 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
60}
61
Michael Clark14862b12007-12-07 02:50:42 +000062static void json_object_fini(void) __attribute__ ((destructor));
63static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000064 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000065 if(MC_GET_DEBUG()) {
66 if (json_object_table->count) {
67 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
68 json_object_table->count);
69 lh_foreach(json_object_table, ent) {
70 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000071 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000072 }
Michael Clarkf0d08882007-03-13 08:26:18 +000073 }
74 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000075 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000076 lh_table_free(json_object_table);
77}
Michael Clark4504df72007-03-13 08:26:20 +000078#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000079
80
81/* string escaping */
82
Jehiah Czebotarac601b52011-01-14 17:23:06 +000083static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000084{
85 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000086 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000087 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000088 c = str[pos];
89 switch(c) {
90 case '\b':
91 case '\n':
92 case '\r':
93 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +000094 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +000095 case '\\':
96 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +000097 if(pos - start_offset > 0)
98 printbuf_memappend(pb, str + start_offset, pos - start_offset);
99 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
100 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
101 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
102 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000103 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000104 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
105 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000106 start_offset = ++pos;
107 break;
108 default:
Michael Clark837240f2007-03-13 08:26:25 +0000109 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000110 if(pos - start_offset > 0)
111 printbuf_memappend(pb, str + start_offset, pos - start_offset);
112 sprintbuf(pb, "\\u00%c%c",
113 json_hex_chars[c >> 4],
114 json_hex_chars[c & 0xf]);
115 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000116 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000117 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000118 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000119 if(pos - start_offset > 0)
120 printbuf_memappend(pb, str + start_offset, pos - start_offset);
121 return 0;
122}
123
124
125/* reference counting */
126
Michael Clark266a3fd2009-02-25 01:55:31 +0000127extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000128{
Michael Clark266a3fd2009-02-25 01:55:31 +0000129 if(jso) {
130 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000131 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000132 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000133}
134
Michael Clark266a3fd2009-02-25 01:55:31 +0000135extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000136{
Michael Clark266a3fd2009-02-25 01:55:31 +0000137 if(jso) {
138 jso->_ref_count--;
139 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000140 }
141}
142
143
144/* generic object construction and destruction parts */
145
Michael Clark266a3fd2009-02-25 01:55:31 +0000146static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000147{
148#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000149 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000150 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000151 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000152#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000153 printbuf_free(jso->_pb);
154 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000155}
156
157static struct json_object* json_object_new(enum json_type o_type)
158{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000159 struct json_object *jso;
160
161 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000162 if(!jso) return NULL;
163 jso->o_type = o_type;
164 jso->_ref_count = 1;
165 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000166#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000167 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000168 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000169#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000170 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000171}
172
173
174/* type checking functions */
175
Michael Clark266a3fd2009-02-25 01:55:31 +0000176int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000177{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500178 if (!jso)
179 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000180 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000181}
182
Michael Clark266a3fd2009-02-25 01:55:31 +0000183enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000184{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500185 if (!jso)
186 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000187 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000188}
189
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500190/* extended conversion to string */
191
192const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
193{
194 if (!jso)
195 return "null";
196
197 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
198 return NULL;
199
200 printbuf_reset(jso->_pb);
201
202 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
203 return NULL;
204
205 return jso->_pb->buf;
206}
207
208/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000209
Michael Clark266a3fd2009-02-25 01:55:31 +0000210const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000211{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500212 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000213}
214
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500215static void indent(struct printbuf *pb, int level, int flags)
216{
217 if (flags & JSON_C_TO_STRING_PRETTY)
218 {
219 printbuf_memset(pb, -1, ' ', level * 2);
220 }
221}
Michael Clarkf0d08882007-03-13 08:26:18 +0000222
223/* json_object_object */
224
Michael Clark266a3fd2009-02-25 01:55:31 +0000225static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500226 struct printbuf *pb,
227 int level,
228 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000229{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500230 int had_children = 0;
231 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000232
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500233 sprintbuf(pb, "{" /*}*/);
234 if (flags & JSON_C_TO_STRING_PRETTY)
235 sprintbuf(pb, "\n");
236 json_object_object_foreachC(jso, iter)
237 {
238 if (had_children)
239 {
240 sprintbuf(pb, ",");
241 if (flags & JSON_C_TO_STRING_PRETTY)
242 sprintbuf(pb, "\n");
243 }
244 had_children = 1;
245 if (flags & JSON_C_TO_STRING_SPACED)
246 sprintbuf(pb, " ");
247 indent(pb, level+1, flags);
248 sprintbuf(pb, "\"");
249 json_escape_str(pb, iter.key, strlen(iter.key));
250 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000251 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500252 else
253 sprintbuf(pb, "\":");
254 if(iter.val == NULL)
255 sprintbuf(pb, "null");
256 else
257 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000258 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500259 if (flags & JSON_C_TO_STRING_PRETTY)
260 {
261 if (had_children)
262 sprintbuf(pb, "\n");
263 indent(pb,level,flags);
264 }
265 if (flags & JSON_C_TO_STRING_SPACED)
266 return sprintbuf(pb, /*{*/ " }");
267 else
268 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000269}
270
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500271
Michael Clarkf0d08882007-03-13 08:26:18 +0000272static void json_object_lh_entry_free(struct lh_entry *ent)
273{
274 free(ent->k);
275 json_object_put((struct json_object*)ent->v);
276}
277
Michael Clark266a3fd2009-02-25 01:55:31 +0000278static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000279{
Michael Clark266a3fd2009-02-25 01:55:31 +0000280 lh_table_free(jso->o.c_object);
281 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000282}
283
Michael Clarke8de0782009-02-25 01:45:00 +0000284struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000285{
Michael Clark266a3fd2009-02-25 01:55:31 +0000286 struct json_object *jso = json_object_new(json_type_object);
287 if(!jso) return NULL;
288 jso->_delete = &json_object_object_delete;
289 jso->_to_json_string = &json_object_object_to_json_string;
290 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000291 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000292 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000293}
294
Michael Clark266a3fd2009-02-25 01:55:31 +0000295struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000296{
Michael Clark266a3fd2009-02-25 01:55:31 +0000297 if(!jso) return NULL;
298 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000299 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000300 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000301 default:
302 return NULL;
303 }
304}
305
Michael Clark266a3fd2009-02-25 01:55:31 +0000306void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000307 struct json_object *val)
308{
Eric Haszlakiewicz6988f532012-07-24 23:27:41 -0500309 // We lookup the entry and replace the value, rather than just deleting
310 // and re-adding it, so the existing key remains valid.
311 json_object *existing_value = NULL;
312 struct lh_entry *existing_entry;
313 existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
314 if (!existing_entry)
315 {
316 lh_table_insert(jso->o.c_object, strdup(key), val);
317 return;
318 }
319 existing_value = (void *)existing_entry->v;
320 if (existing_value)
321 json_object_put(existing_value);
322 existing_entry->v = val;
Michael Clarkf0d08882007-03-13 08:26:18 +0000323}
324
Michael Clark266a3fd2009-02-25 01:55:31 +0000325struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000326{
Keith Derrick69175862012-04-12 11:44:13 -0700327 struct json_object *result;
328 json_object_object_get_ex(jso, key, &result);
329 return result;
330}
331
332json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
333{
334 if (NULL == jso) return FALSE;
335
336 switch(jso->o_type) {
337 case json_type_object:
338 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
339 default:
340 if (value != NULL) {
341 *value = NULL;
342 }
343 return FALSE;
344 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000345}
346
Michael Clark266a3fd2009-02-25 01:55:31 +0000347void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000348{
Michael Clark266a3fd2009-02-25 01:55:31 +0000349 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000350}
351
352
353/* json_object_boolean */
354
Michael Clark266a3fd2009-02-25 01:55:31 +0000355static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500356 struct printbuf *pb,
357 int level,
358 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000359{
Michael Clark266a3fd2009-02-25 01:55:31 +0000360 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000361 else return sprintbuf(pb, "false");
362}
363
Keith Derrick37e74672012-03-26 14:29:31 -0700364struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000365{
Michael Clark266a3fd2009-02-25 01:55:31 +0000366 struct json_object *jso = json_object_new(json_type_boolean);
367 if(!jso) return NULL;
368 jso->_to_json_string = &json_object_boolean_to_json_string;
369 jso->o.c_boolean = b;
370 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000371}
372
Keith Derrick37e74672012-03-26 14:29:31 -0700373json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000374{
Michael Clark266a3fd2009-02-25 01:55:31 +0000375 if(!jso) return FALSE;
376 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000377 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000378 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000379 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000380 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000381 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000382 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000383 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000384 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000385 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000386 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000387 }
388}
389
390
391/* json_object_int */
392
Michael Clark266a3fd2009-02-25 01:55:31 +0000393static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500394 struct printbuf *pb,
395 int level,
396 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000397{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000398 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
399}
400
401struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000402{
Michael Clark266a3fd2009-02-25 01:55:31 +0000403 struct json_object *jso = json_object_new(json_type_int);
404 if(!jso) return NULL;
405 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000406 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000407 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000408}
409
Michael Clarkc4dceae2010-10-06 16:39:20 +0000410int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000411{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100412 int64_t cint64;
413 enum json_type o_type;
414
Michael Clarkc4dceae2010-10-06 16:39:20 +0000415 if(!jso) return 0;
416
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100417 o_type = jso->o_type;
418 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000419
420 if (o_type == json_type_string)
421 {
422 /*
423 * Parse strings into 64-bit numbers, then use the
424 * 64-to-32-bit number handling below.
425 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000426 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000427 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000428 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000429 }
430
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000431 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000432 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000433 /* Make sure we return the correct values for out of range numbers. */
434 if (cint64 <= INT32_MIN)
435 return INT32_MIN;
436 else if (cint64 >= INT32_MAX)
437 return INT32_MAX;
438 else
439 return (int32_t)cint64;
440 case json_type_double:
441 return (int32_t)jso->o.c_double;
442 case json_type_boolean:
443 return jso->o.c_boolean;
444 default:
445 return 0;
446 }
447}
448
449struct json_object* json_object_new_int64(int64_t i)
450{
ehaszla252669c2010-12-07 18:15:35 +0000451 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000452 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000453 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000454 jso->o.c_int64 = i;
455 return jso;
456}
457
458int64_t json_object_get_int64(struct json_object *jso)
459{
460 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000461
Michael Clark266a3fd2009-02-25 01:55:31 +0000462 if(!jso) return 0;
463 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000464 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000465 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000466 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000467 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000468 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000469 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000470 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000471 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000472 default:
473 return 0;
474 }
475}
476
477
478/* json_object_double */
479
Michael Clark266a3fd2009-02-25 01:55:31 +0000480static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500481 struct printbuf *pb,
482 int level,
483 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000484{
Eric Haszlakiewicz0cc1db62012-04-29 11:04:33 -0500485 return sprintbuf(pb, "%f", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000486}
487
488struct json_object* json_object_new_double(double d)
489{
Michael Clark266a3fd2009-02-25 01:55:31 +0000490 struct json_object *jso = json_object_new(json_type_double);
491 if(!jso) return NULL;
492 jso->_to_json_string = &json_object_double_to_json_string;
493 jso->o.c_double = d;
494 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000495}
496
Michael Clark266a3fd2009-02-25 01:55:31 +0000497double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000498{
499 double cdouble;
500
Michael Clark266a3fd2009-02-25 01:55:31 +0000501 if(!jso) return 0.0;
502 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000503 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000504 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000505 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000506 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000507 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000508 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000509 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000510 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000511 default:
512 return 0.0;
513 }
514}
515
516
517/* json_object_string */
518
Michael Clark266a3fd2009-02-25 01:55:31 +0000519static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500520 struct printbuf *pb,
521 int level,
522 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000523{
524 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000525 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000526 sprintbuf(pb, "\"");
527 return 0;
528}
529
Michael Clark266a3fd2009-02-25 01:55:31 +0000530static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000531{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000532 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000533 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000534}
535
Michael Clark68cafad2009-01-06 22:56:57 +0000536struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000537{
Michael Clark266a3fd2009-02-25 01:55:31 +0000538 struct json_object *jso = json_object_new(json_type_string);
539 if(!jso) return NULL;
540 jso->_delete = &json_object_string_delete;
541 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000542 jso->o.c_string.str = strdup(s);
543 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000544 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000545}
546
Michael Clark68cafad2009-01-06 22:56:57 +0000547struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000548{
Michael Clark266a3fd2009-02-25 01:55:31 +0000549 struct json_object *jso = json_object_new(json_type_string);
550 if(!jso) return NULL;
551 jso->_delete = &json_object_string_delete;
552 jso->_to_json_string = &json_object_string_to_json_string;
Mateusz Loskot271c53e2012-05-22 23:51:44 +0100553 jso->o.c_string.str = (char*)malloc(len);
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000554 memcpy(jso->o.c_string.str, (void *)s, len);
555 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000556 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000557}
558
Michael Clark266a3fd2009-02-25 01:55:31 +0000559const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000560{
Michael Clark266a3fd2009-02-25 01:55:31 +0000561 if(!jso) return NULL;
562 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000563 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000564 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000565 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000566 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000567 }
568}
569
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000570int json_object_get_string_len(struct json_object *jso) {
571 if(!jso) return 0;
572 switch(jso->o_type) {
573 case json_type_string:
574 return jso->o.c_string.len;
575 default:
576 return 0;
577 }
578}
579
Michael Clarkf0d08882007-03-13 08:26:18 +0000580
581/* json_object_array */
582
Michael Clark266a3fd2009-02-25 01:55:31 +0000583static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500584 struct printbuf *pb,
585 int level,
586 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000587{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500588 int had_children = 0;
589 int ii;
590 sprintbuf(pb, "[");
591 if (flags & JSON_C_TO_STRING_PRETTY)
592 sprintbuf(pb, "\n");
593 for(ii=0; ii < json_object_array_length(jso); ii++)
594 {
595 struct json_object *val;
596 if (had_children)
597 {
598 sprintbuf(pb, ",");
599 if (flags & JSON_C_TO_STRING_PRETTY)
600 sprintbuf(pb, "\n");
601 }
602 had_children = 1;
603 if (flags & JSON_C_TO_STRING_SPACED)
604 sprintbuf(pb, " ");
605 indent(pb, level + 1, flags);
606 val = json_object_array_get_idx(jso, ii);
607 if(val == NULL)
608 sprintbuf(pb, "null");
609 else
610 val->_to_json_string(val, pb, level+1, flags);
611 }
612 if (flags & JSON_C_TO_STRING_PRETTY)
613 {
614 if (had_children)
615 sprintbuf(pb, "\n");
616 indent(pb,level,flags);
617 }
Michael Clark4504df72007-03-13 08:26:20 +0000618
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500619 if (flags & JSON_C_TO_STRING_SPACED)
620 return sprintbuf(pb, " ]");
621 else
622 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000623}
624
625static void json_object_array_entry_free(void *data)
626{
627 json_object_put((struct json_object*)data);
628}
629
Michael Clark266a3fd2009-02-25 01:55:31 +0000630static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000631{
Michael Clark266a3fd2009-02-25 01:55:31 +0000632 array_list_free(jso->o.c_array);
633 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000634}
635
Michael Clarke8de0782009-02-25 01:45:00 +0000636struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000637{
Michael Clark266a3fd2009-02-25 01:55:31 +0000638 struct json_object *jso = json_object_new(json_type_array);
639 if(!jso) return NULL;
640 jso->_delete = &json_object_array_delete;
641 jso->_to_json_string = &json_object_array_to_json_string;
642 jso->o.c_array = array_list_new(&json_object_array_entry_free);
643 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000644}
645
Michael Clark266a3fd2009-02-25 01:55:31 +0000646struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000647{
Michael Clark266a3fd2009-02-25 01:55:31 +0000648 if(!jso) return NULL;
649 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000650 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000651 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000652 default:
653 return NULL;
654 }
655}
656
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200657void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
658{
659 array_list_sort(jso->o.c_array, sort_fn);
660}
661
Michael Clark266a3fd2009-02-25 01:55:31 +0000662int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000663{
Michael Clark266a3fd2009-02-25 01:55:31 +0000664 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000665}
666
Michael Clark266a3fd2009-02-25 01:55:31 +0000667int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000668{
Michael Clark266a3fd2009-02-25 01:55:31 +0000669 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000670}
671
Michael Clark266a3fd2009-02-25 01:55:31 +0000672int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000673 struct json_object *val)
674{
Michael Clark266a3fd2009-02-25 01:55:31 +0000675 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000676}
677
Michael Clark266a3fd2009-02-25 01:55:31 +0000678struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000679 int idx)
680{
Michael Clark266a3fd2009-02-25 01:55:31 +0000681 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000682}
683