blob: 5a359381d9acda84f324b1497e5b94806d77c7af [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
Michael Clark837240f2007-03-13 08:26:25 +000029#if !HAVE_STRNDUP
30 char* strndup(const char* str, size_t n);
31#endif /* !HAVE_STRNDUP */
32
Keith Derrick69175862012-04-12 11:44:13 -070033// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000034/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000035
Michael Clark68cafad2009-01-06 22:56:57 +000036const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010037const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000038
Michael Clark266a3fd2009-02-25 01:55:31 +000039static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000040static struct json_object* json_object_new(enum json_type o_type);
41
42
43/* ref count debugging */
44
45#ifdef REFCOUNT_DEBUG
46
47static struct lh_table *json_object_table;
48
Michael Clark14862b12007-12-07 02:50:42 +000049static void json_object_init(void) __attribute__ ((constructor));
50static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000051 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000052 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
53}
54
Michael Clark14862b12007-12-07 02:50:42 +000055static void json_object_fini(void) __attribute__ ((destructor));
56static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000057 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000058 if(MC_GET_DEBUG()) {
59 if (json_object_table->count) {
60 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
61 json_object_table->count);
62 lh_foreach(json_object_table, ent) {
63 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000064 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000065 }
Michael Clarkf0d08882007-03-13 08:26:18 +000066 }
67 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000068 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000069 lh_table_free(json_object_table);
70}
Michael Clark4504df72007-03-13 08:26:20 +000071#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000072
73
74/* string escaping */
75
Jehiah Czebotarac601b52011-01-14 17:23:06 +000076static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000077{
78 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000079 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000080 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000081 c = str[pos];
82 switch(c) {
83 case '\b':
84 case '\n':
85 case '\r':
86 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +000087 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +000088 case '\\':
89 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +000090 if(pos - start_offset > 0)
91 printbuf_memappend(pb, str + start_offset, pos - start_offset);
92 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
93 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
94 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
95 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +000096 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +000097 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
98 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +000099 start_offset = ++pos;
100 break;
101 default:
Michael Clark837240f2007-03-13 08:26:25 +0000102 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000103 if(pos - start_offset > 0)
104 printbuf_memappend(pb, str + start_offset, pos - start_offset);
105 sprintbuf(pb, "\\u00%c%c",
106 json_hex_chars[c >> 4],
107 json_hex_chars[c & 0xf]);
108 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000109 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000110 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000111 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000112 if(pos - start_offset > 0)
113 printbuf_memappend(pb, str + start_offset, pos - start_offset);
114 return 0;
115}
116
117
118/* reference counting */
119
Michael Clark266a3fd2009-02-25 01:55:31 +0000120extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000121{
Michael Clark266a3fd2009-02-25 01:55:31 +0000122 if(jso) {
123 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000124 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000125 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000126}
127
Michael Clark266a3fd2009-02-25 01:55:31 +0000128extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000129{
Michael Clark266a3fd2009-02-25 01:55:31 +0000130 if(jso) {
131 jso->_ref_count--;
132 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000133 }
134}
135
136
137/* generic object construction and destruction parts */
138
Michael Clark266a3fd2009-02-25 01:55:31 +0000139static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000140{
141#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000142 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000143 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000144 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000145#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000146 printbuf_free(jso->_pb);
147 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000148}
149
150static struct json_object* json_object_new(enum json_type o_type)
151{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000152 struct json_object *jso;
153
154 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000155 if(!jso) return NULL;
156 jso->o_type = o_type;
157 jso->_ref_count = 1;
158 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000159#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000160 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000161 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000162#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000163 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000164}
165
166
167/* type checking functions */
168
Michael Clark266a3fd2009-02-25 01:55:31 +0000169int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000170{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500171 if (!jso)
172 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000173 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000174}
175
Michael Clark266a3fd2009-02-25 01:55:31 +0000176enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000177{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500178 if (!jso)
179 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000180 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000181}
182
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500183/* extended conversion to string */
184
185const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
186{
187 if (!jso)
188 return "null";
189
190 if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
191 return NULL;
192
193 printbuf_reset(jso->_pb);
194
195 if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
196 return NULL;
197
198 return jso->_pb->buf;
199}
200
201/* backwards-compatible conversion to string */
Michael Clarkf0d08882007-03-13 08:26:18 +0000202
Michael Clark266a3fd2009-02-25 01:55:31 +0000203const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000204{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500205 return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
Michael Clarkf0d08882007-03-13 08:26:18 +0000206}
207
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500208static void indent(struct printbuf *pb, int level, int flags)
209{
210 if (flags & JSON_C_TO_STRING_PRETTY)
211 {
212 printbuf_memset(pb, -1, ' ', level * 2);
213 }
214}
Michael Clarkf0d08882007-03-13 08:26:18 +0000215
216/* json_object_object */
217
Michael Clark266a3fd2009-02-25 01:55:31 +0000218static int json_object_object_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500219 struct printbuf *pb,
220 int level,
221 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000222{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500223 int had_children = 0;
224 struct json_object_iter iter;
Michael Clark4504df72007-03-13 08:26:20 +0000225
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500226 sprintbuf(pb, "{" /*}*/);
227 if (flags & JSON_C_TO_STRING_PRETTY)
228 sprintbuf(pb, "\n");
229 json_object_object_foreachC(jso, iter)
230 {
231 if (had_children)
232 {
233 sprintbuf(pb, ",");
234 if (flags & JSON_C_TO_STRING_PRETTY)
235 sprintbuf(pb, "\n");
236 }
237 had_children = 1;
238 if (flags & JSON_C_TO_STRING_SPACED)
239 sprintbuf(pb, " ");
240 indent(pb, level+1, flags);
241 sprintbuf(pb, "\"");
242 json_escape_str(pb, iter.key, strlen(iter.key));
243 if (flags & JSON_C_TO_STRING_SPACED)
Michael Clark4504df72007-03-13 08:26:20 +0000244 sprintbuf(pb, "\": ");
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500245 else
246 sprintbuf(pb, "\":");
247 if(iter.val == NULL)
248 sprintbuf(pb, "null");
249 else
250 iter.val->_to_json_string(iter.val, pb, level+1,flags);
Michael Clark4504df72007-03-13 08:26:20 +0000251 }
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500252 if (flags & JSON_C_TO_STRING_PRETTY)
253 {
254 if (had_children)
255 sprintbuf(pb, "\n");
256 indent(pb,level,flags);
257 }
258 if (flags & JSON_C_TO_STRING_SPACED)
259 return sprintbuf(pb, /*{*/ " }");
260 else
261 return sprintbuf(pb, /*{*/ "}");
Michael Clarkf0d08882007-03-13 08:26:18 +0000262}
263
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500264
Michael Clarkf0d08882007-03-13 08:26:18 +0000265static void json_object_lh_entry_free(struct lh_entry *ent)
266{
267 free(ent->k);
268 json_object_put((struct json_object*)ent->v);
269}
270
Michael Clark266a3fd2009-02-25 01:55:31 +0000271static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000272{
Michael Clark266a3fd2009-02-25 01:55:31 +0000273 lh_table_free(jso->o.c_object);
274 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000275}
276
Michael Clarke8de0782009-02-25 01:45:00 +0000277struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000278{
Michael Clark266a3fd2009-02-25 01:55:31 +0000279 struct json_object *jso = json_object_new(json_type_object);
280 if(!jso) return NULL;
281 jso->_delete = &json_object_object_delete;
282 jso->_to_json_string = &json_object_object_to_json_string;
283 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000284 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000285 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000286}
287
Michael Clark266a3fd2009-02-25 01:55:31 +0000288struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000289{
Michael Clark266a3fd2009-02-25 01:55:31 +0000290 if(!jso) return NULL;
291 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000292 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000293 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000294 default:
295 return NULL;
296 }
297}
298
Michael Clark266a3fd2009-02-25 01:55:31 +0000299void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000300 struct json_object *val)
301{
Michael Clark266a3fd2009-02-25 01:55:31 +0000302 lh_table_delete(jso->o.c_object, key);
303 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000304}
305
Michael Clark266a3fd2009-02-25 01:55:31 +0000306struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000307{
Keith Derrick69175862012-04-12 11:44:13 -0700308 struct json_object *result;
309 json_object_object_get_ex(jso, key, &result);
310 return result;
311}
312
313json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
314{
315 if (NULL == jso) return FALSE;
316
317 switch(jso->o_type) {
318 case json_type_object:
319 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
320 default:
321 if (value != NULL) {
322 *value = NULL;
323 }
324 return FALSE;
325 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000326}
327
Michael Clark266a3fd2009-02-25 01:55:31 +0000328void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000329{
Michael Clark266a3fd2009-02-25 01:55:31 +0000330 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000331}
332
333
334/* json_object_boolean */
335
Michael Clark266a3fd2009-02-25 01:55:31 +0000336static int json_object_boolean_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500337 struct printbuf *pb,
338 int level,
339 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000340{
Michael Clark266a3fd2009-02-25 01:55:31 +0000341 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000342 else return sprintbuf(pb, "false");
343}
344
Keith Derrick37e74672012-03-26 14:29:31 -0700345struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000346{
Michael Clark266a3fd2009-02-25 01:55:31 +0000347 struct json_object *jso = json_object_new(json_type_boolean);
348 if(!jso) return NULL;
349 jso->_to_json_string = &json_object_boolean_to_json_string;
350 jso->o.c_boolean = b;
351 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000352}
353
Keith Derrick37e74672012-03-26 14:29:31 -0700354json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000355{
Michael Clark266a3fd2009-02-25 01:55:31 +0000356 if(!jso) return FALSE;
357 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000358 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000359 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000360 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000361 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000362 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000363 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000364 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000365 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000366 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000367 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000368 }
369}
370
371
372/* json_object_int */
373
Michael Clark266a3fd2009-02-25 01:55:31 +0000374static int json_object_int_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500375 struct printbuf *pb,
376 int level,
377 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000378{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000379 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
380}
381
382struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000383{
Michael Clark266a3fd2009-02-25 01:55:31 +0000384 struct json_object *jso = json_object_new(json_type_int);
385 if(!jso) return NULL;
386 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000387 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000388 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000389}
390
Michael Clarkc4dceae2010-10-06 16:39:20 +0000391int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000392{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100393 int64_t cint64;
394 enum json_type o_type;
395
Michael Clarkc4dceae2010-10-06 16:39:20 +0000396 if(!jso) return 0;
397
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100398 o_type = jso->o_type;
399 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000400
401 if (o_type == json_type_string)
402 {
403 /*
404 * Parse strings into 64-bit numbers, then use the
405 * 64-to-32-bit number handling below.
406 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000407 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000408 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000409 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000410 }
411
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000412 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000413 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000414 /* Make sure we return the correct values for out of range numbers. */
415 if (cint64 <= INT32_MIN)
416 return INT32_MIN;
417 else if (cint64 >= INT32_MAX)
418 return INT32_MAX;
419 else
420 return (int32_t)cint64;
421 case json_type_double:
422 return (int32_t)jso->o.c_double;
423 case json_type_boolean:
424 return jso->o.c_boolean;
425 default:
426 return 0;
427 }
428}
429
430struct json_object* json_object_new_int64(int64_t i)
431{
ehaszla252669c2010-12-07 18:15:35 +0000432 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000433 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000434 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000435 jso->o.c_int64 = i;
436 return jso;
437}
438
439int64_t json_object_get_int64(struct json_object *jso)
440{
441 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000442
Michael Clark266a3fd2009-02-25 01:55:31 +0000443 if(!jso) return 0;
444 switch(jso->o_type) {
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;
Michael Clarkf0d08882007-03-13 08:26:18 +0000447 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000448 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000449 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000450 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000451 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000452 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000453 default:
454 return 0;
455 }
456}
457
458
459/* json_object_double */
460
Michael Clark266a3fd2009-02-25 01:55:31 +0000461static int json_object_double_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500462 struct printbuf *pb,
463 int level,
464 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000465{
Eric Haszlakiewicz0cc1db62012-04-29 11:04:33 -0500466 return sprintbuf(pb, "%f", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000467}
468
469struct json_object* json_object_new_double(double d)
470{
Michael Clark266a3fd2009-02-25 01:55:31 +0000471 struct json_object *jso = json_object_new(json_type_double);
472 if(!jso) return NULL;
473 jso->_to_json_string = &json_object_double_to_json_string;
474 jso->o.c_double = d;
475 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000476}
477
Michael Clark266a3fd2009-02-25 01:55:31 +0000478double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000479{
480 double cdouble;
481
Michael Clark266a3fd2009-02-25 01:55:31 +0000482 if(!jso) return 0.0;
483 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000484 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000485 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000486 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000487 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000488 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000489 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000490 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000491 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000492 default:
493 return 0.0;
494 }
495}
496
497
498/* json_object_string */
499
Michael Clark266a3fd2009-02-25 01:55:31 +0000500static int json_object_string_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500501 struct printbuf *pb,
502 int level,
503 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000504{
505 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000506 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000507 sprintbuf(pb, "\"");
508 return 0;
509}
510
Michael Clark266a3fd2009-02-25 01:55:31 +0000511static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000512{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000513 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000514 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000515}
516
Michael Clark68cafad2009-01-06 22:56:57 +0000517struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000518{
Michael Clark266a3fd2009-02-25 01:55:31 +0000519 struct json_object *jso = json_object_new(json_type_string);
520 if(!jso) return NULL;
521 jso->_delete = &json_object_string_delete;
522 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000523 jso->o.c_string.str = strdup(s);
524 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000525 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000526}
527
Michael Clark68cafad2009-01-06 22:56:57 +0000528struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000529{
Michael Clark266a3fd2009-02-25 01:55:31 +0000530 struct json_object *jso = json_object_new(json_type_string);
531 if(!jso) return NULL;
532 jso->_delete = &json_object_string_delete;
533 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000534 jso->o.c_string.str = malloc(len);
535 memcpy(jso->o.c_string.str, (void *)s, len);
536 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000537 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000538}
539
Michael Clark266a3fd2009-02-25 01:55:31 +0000540const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000541{
Michael Clark266a3fd2009-02-25 01:55:31 +0000542 if(!jso) return NULL;
543 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000544 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000545 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000546 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000547 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000548 }
549}
550
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000551int json_object_get_string_len(struct json_object *jso) {
552 if(!jso) return 0;
553 switch(jso->o_type) {
554 case json_type_string:
555 return jso->o.c_string.len;
556 default:
557 return 0;
558 }
559}
560
Michael Clarkf0d08882007-03-13 08:26:18 +0000561
562/* json_object_array */
563
Michael Clark266a3fd2009-02-25 01:55:31 +0000564static int json_object_array_to_json_string(struct json_object* jso,
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500565 struct printbuf *pb,
566 int level,
567 int flags)
Michael Clarkf0d08882007-03-13 08:26:18 +0000568{
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500569 int had_children = 0;
570 int ii;
571 sprintbuf(pb, "[");
572 if (flags & JSON_C_TO_STRING_PRETTY)
573 sprintbuf(pb, "\n");
574 for(ii=0; ii < json_object_array_length(jso); ii++)
575 {
576 struct json_object *val;
577 if (had_children)
578 {
579 sprintbuf(pb, ",");
580 if (flags & JSON_C_TO_STRING_PRETTY)
581 sprintbuf(pb, "\n");
582 }
583 had_children = 1;
584 if (flags & JSON_C_TO_STRING_SPACED)
585 sprintbuf(pb, " ");
586 indent(pb, level + 1, flags);
587 val = json_object_array_get_idx(jso, ii);
588 if(val == NULL)
589 sprintbuf(pb, "null");
590 else
591 val->_to_json_string(val, pb, level+1, flags);
592 }
593 if (flags & JSON_C_TO_STRING_PRETTY)
594 {
595 if (had_children)
596 sprintbuf(pb, "\n");
597 indent(pb,level,flags);
598 }
Michael Clark4504df72007-03-13 08:26:20 +0000599
Eric Haszlakiewicz3fcffe12012-04-28 13:26:09 -0500600 if (flags & JSON_C_TO_STRING_SPACED)
601 return sprintbuf(pb, " ]");
602 else
603 return sprintbuf(pb, "]");
Michael Clarkf0d08882007-03-13 08:26:18 +0000604}
605
606static void json_object_array_entry_free(void *data)
607{
608 json_object_put((struct json_object*)data);
609}
610
Michael Clark266a3fd2009-02-25 01:55:31 +0000611static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000612{
Michael Clark266a3fd2009-02-25 01:55:31 +0000613 array_list_free(jso->o.c_array);
614 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000615}
616
Michael Clarke8de0782009-02-25 01:45:00 +0000617struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000618{
Michael Clark266a3fd2009-02-25 01:55:31 +0000619 struct json_object *jso = json_object_new(json_type_array);
620 if(!jso) return NULL;
621 jso->_delete = &json_object_array_delete;
622 jso->_to_json_string = &json_object_array_to_json_string;
623 jso->o.c_array = array_list_new(&json_object_array_entry_free);
624 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000625}
626
Michael Clark266a3fd2009-02-25 01:55:31 +0000627struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000628{
Michael Clark266a3fd2009-02-25 01:55:31 +0000629 if(!jso) return NULL;
630 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000631 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000632 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000633 default:
634 return NULL;
635 }
636}
637
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200638void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
639{
640 array_list_sort(jso->o.c_array, sort_fn);
641}
642
Michael Clark266a3fd2009-02-25 01:55:31 +0000643int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000644{
Michael Clark266a3fd2009-02-25 01:55:31 +0000645 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000646}
647
Michael Clark266a3fd2009-02-25 01:55:31 +0000648int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000649{
Michael Clark266a3fd2009-02-25 01:55:31 +0000650 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000651}
652
Michael Clark266a3fd2009-02-25 01:55:31 +0000653int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000654 struct json_object *val)
655{
Michael Clark266a3fd2009-02-25 01:55:31 +0000656 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000657}
658
Michael Clark266a3fd2009-02-25 01:55:31 +0000659struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000660 int idx)
661{
Michael Clark266a3fd2009-02-25 01:55:31 +0000662 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000663}
664