blob: 784863059c8b6d520998721d125dedabe8f2ec08 [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>
6 *
Michael Clarkf6a6e482007-03-13 08:26:23 +00007 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the MIT license. See COPYING for details.
Michael Clarkf0d08882007-03-13 08:26:18 +00009 *
10 */
11
Michael Clark4504df72007-03-13 08:26:20 +000012#include "config.h"
13
Michael Clarkf0d08882007-03-13 08:26:18 +000014#include <stdio.h>
15#include <stdlib.h>
Michael Clarkc8f4a6e2007-12-07 02:44:24 +000016#include <stddef.h>
Michael Clarkf0d08882007-03-13 08:26:18 +000017#include <string.h>
18
19#include "debug.h"
20#include "printbuf.h"
21#include "linkhash.h"
22#include "arraylist.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000023#include "json_inttypes.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000024#include "json_object.h"
25#include "json_object_private.h"
Michael Clarkc4dceae2010-10-06 16:39:20 +000026#include "json_util.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000027
Michael Clark837240f2007-03-13 08:26:25 +000028#if !HAVE_STRNDUP
29 char* strndup(const char* str, size_t n);
30#endif /* !HAVE_STRNDUP */
31
Christopher Watfordc5cbf822009-06-30 03:40:53 +000032/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000033
Michael Clark68cafad2009-01-06 22:56:57 +000034const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010035const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000036
Michael Clark266a3fd2009-02-25 01:55:31 +000037static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000038static struct json_object* json_object_new(enum json_type o_type);
39
40
41/* ref count debugging */
42
43#ifdef REFCOUNT_DEBUG
44
45static struct lh_table *json_object_table;
46
Michael Clark14862b12007-12-07 02:50:42 +000047static void json_object_init(void) __attribute__ ((constructor));
48static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000049 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000050 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
51}
52
Michael Clark14862b12007-12-07 02:50:42 +000053static void json_object_fini(void) __attribute__ ((destructor));
54static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000055 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000056 if(MC_GET_DEBUG()) {
57 if (json_object_table->count) {
58 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
59 json_object_table->count);
60 lh_foreach(json_object_table, ent) {
61 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000062 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000063 }
Michael Clarkf0d08882007-03-13 08:26:18 +000064 }
65 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000066 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000067 lh_table_free(json_object_table);
68}
Michael Clark4504df72007-03-13 08:26:20 +000069#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000070
71
72/* string escaping */
73
Jehiah Czebotarac601b52011-01-14 17:23:06 +000074static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000075{
76 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000077 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000078 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000079 c = str[pos];
80 switch(c) {
81 case '\b':
82 case '\n':
83 case '\r':
84 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +000085 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +000086 case '\\':
87 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +000088 if(pos - start_offset > 0)
89 printbuf_memappend(pb, str + start_offset, pos - start_offset);
90 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
91 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
92 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
93 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +000094 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +000095 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
96 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +000097 start_offset = ++pos;
98 break;
99 default:
Michael Clark837240f2007-03-13 08:26:25 +0000100 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000101 if(pos - start_offset > 0)
102 printbuf_memappend(pb, str + start_offset, pos - start_offset);
103 sprintbuf(pb, "\\u00%c%c",
104 json_hex_chars[c >> 4],
105 json_hex_chars[c & 0xf]);
106 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000107 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000108 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000109 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000110 if(pos - start_offset > 0)
111 printbuf_memappend(pb, str + start_offset, pos - start_offset);
112 return 0;
113}
114
115
116/* reference counting */
117
Michael Clark266a3fd2009-02-25 01:55:31 +0000118extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000119{
Michael Clark266a3fd2009-02-25 01:55:31 +0000120 if(jso) {
121 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000122 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000123 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000124}
125
Michael Clark266a3fd2009-02-25 01:55:31 +0000126extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000127{
Michael Clark266a3fd2009-02-25 01:55:31 +0000128 if(jso) {
129 jso->_ref_count--;
130 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000131 }
132}
133
134
135/* generic object construction and destruction parts */
136
Michael Clark266a3fd2009-02-25 01:55:31 +0000137static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000138{
139#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000140 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000141 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000142 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000143#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000144 printbuf_free(jso->_pb);
145 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000146}
147
148static struct json_object* json_object_new(enum json_type o_type)
149{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000150 struct json_object *jso;
151
152 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000153 if(!jso) return NULL;
154 jso->o_type = o_type;
155 jso->_ref_count = 1;
156 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000157#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000158 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000159 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000160#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000161 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000162}
163
164
165/* type checking functions */
166
Michael Clark266a3fd2009-02-25 01:55:31 +0000167int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000168{
Michael Clark266a3fd2009-02-25 01:55:31 +0000169 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000170}
171
Michael Clark266a3fd2009-02-25 01:55:31 +0000172enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000173{
Michael Clark266a3fd2009-02-25 01:55:31 +0000174 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000175}
176
Michael Clarkf0d08882007-03-13 08:26:18 +0000177/* json_object_to_json_string */
178
Michael Clark266a3fd2009-02-25 01:55:31 +0000179const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000180{
Michael Clark266a3fd2009-02-25 01:55:31 +0000181 if(!jso) return "null";
182 if(!jso->_pb) {
183 if(!(jso->_pb = printbuf_new())) return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000184 } else {
Michael Clark266a3fd2009-02-25 01:55:31 +0000185 printbuf_reset(jso->_pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000186 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000187 if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
188 return jso->_pb->buf;
Michael Clarkf0d08882007-03-13 08:26:18 +0000189}
190
191
192/* json_object_object */
193
Michael Clark266a3fd2009-02-25 01:55:31 +0000194static int json_object_object_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000195 struct printbuf *pb)
196{
197 int i=0;
Michael Clark4504df72007-03-13 08:26:20 +0000198 struct json_object_iter iter;
Michael Clarkf0d08882007-03-13 08:26:18 +0000199 sprintbuf(pb, "{");
Michael Clark4504df72007-03-13 08:26:20 +0000200
201 /* CAW: scope operator to make ANSI correctness */
202 /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
Michael Clark266a3fd2009-02-25 01:55:31 +0000203 json_object_object_foreachC(jso, iter) {
Michael Clark4504df72007-03-13 08:26:20 +0000204 if(i) sprintbuf(pb, ",");
205 sprintbuf(pb, " \"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000206 json_escape_str(pb, iter.key, strlen(iter.key));
Michael Clark4504df72007-03-13 08:26:20 +0000207 sprintbuf(pb, "\": ");
208 if(iter.val == NULL) sprintbuf(pb, "null");
209 else iter.val->_to_json_string(iter.val, pb);
210 i++;
211 }
212
Michael Clarkf0d08882007-03-13 08:26:18 +0000213 return sprintbuf(pb, " }");
214}
215
216static void json_object_lh_entry_free(struct lh_entry *ent)
217{
218 free(ent->k);
219 json_object_put((struct json_object*)ent->v);
220}
221
Michael Clark266a3fd2009-02-25 01:55:31 +0000222static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000223{
Michael Clark266a3fd2009-02-25 01:55:31 +0000224 lh_table_free(jso->o.c_object);
225 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000226}
227
Michael Clarke8de0782009-02-25 01:45:00 +0000228struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000229{
Michael Clark266a3fd2009-02-25 01:55:31 +0000230 struct json_object *jso = json_object_new(json_type_object);
231 if(!jso) return NULL;
232 jso->_delete = &json_object_object_delete;
233 jso->_to_json_string = &json_object_object_to_json_string;
234 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000235 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000236 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000237}
238
Michael Clark266a3fd2009-02-25 01:55:31 +0000239struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000240{
Michael Clark266a3fd2009-02-25 01:55:31 +0000241 if(!jso) return NULL;
242 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000243 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000244 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000245 default:
246 return NULL;
247 }
248}
249
Michael Clark266a3fd2009-02-25 01:55:31 +0000250void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000251 struct json_object *val)
252{
Michael Clark266a3fd2009-02-25 01:55:31 +0000253 lh_table_delete(jso->o.c_object, key);
254 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000255}
256
Michael Clark266a3fd2009-02-25 01:55:31 +0000257struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000258{
Jehiah Czebotar276123e2011-05-26 01:34:52 +0000259 if(!jso) return NULL;
Michael Clark266a3fd2009-02-25 01:55:31 +0000260 return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000261}
262
Michael Clark266a3fd2009-02-25 01:55:31 +0000263void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000264{
Michael Clark266a3fd2009-02-25 01:55:31 +0000265 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000266}
267
268
269/* json_object_boolean */
270
Michael Clark266a3fd2009-02-25 01:55:31 +0000271static int json_object_boolean_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000272 struct printbuf *pb)
273{
Michael Clark266a3fd2009-02-25 01:55:31 +0000274 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000275 else return sprintbuf(pb, "false");
276}
277
Keith Derrick37e74672012-03-26 14:29:31 -0700278struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000279{
Michael Clark266a3fd2009-02-25 01:55:31 +0000280 struct json_object *jso = json_object_new(json_type_boolean);
281 if(!jso) return NULL;
282 jso->_to_json_string = &json_object_boolean_to_json_string;
283 jso->o.c_boolean = b;
284 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000285}
286
Keith Derrick37e74672012-03-26 14:29:31 -0700287json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000288{
Michael Clark266a3fd2009-02-25 01:55:31 +0000289 if(!jso) return FALSE;
290 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000291 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000292 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000293 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000294 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000295 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000296 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000297 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000298 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000299 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000300 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000301 }
302}
303
304
305/* json_object_int */
306
Michael Clark266a3fd2009-02-25 01:55:31 +0000307static int json_object_int_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000308 struct printbuf *pb)
309{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000310 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
311}
312
313struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000314{
Michael Clark266a3fd2009-02-25 01:55:31 +0000315 struct json_object *jso = json_object_new(json_type_int);
316 if(!jso) return NULL;
317 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000318 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000319 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000320}
321
Michael Clarkc4dceae2010-10-06 16:39:20 +0000322int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000323{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100324 int64_t cint64;
325 enum json_type o_type;
326
Michael Clarkc4dceae2010-10-06 16:39:20 +0000327 if(!jso) return 0;
328
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100329 o_type = jso->o_type;
330 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000331
332 if (o_type == json_type_string)
333 {
334 /*
335 * Parse strings into 64-bit numbers, then use the
336 * 64-to-32-bit number handling below.
337 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000338 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000339 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000340 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000341 }
342
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000343 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000344 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000345 /* Make sure we return the correct values for out of range numbers. */
346 if (cint64 <= INT32_MIN)
347 return INT32_MIN;
348 else if (cint64 >= INT32_MAX)
349 return INT32_MAX;
350 else
351 return (int32_t)cint64;
352 case json_type_double:
353 return (int32_t)jso->o.c_double;
354 case json_type_boolean:
355 return jso->o.c_boolean;
356 default:
357 return 0;
358 }
359}
360
361struct json_object* json_object_new_int64(int64_t i)
362{
ehaszla252669c2010-12-07 18:15:35 +0000363 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000364 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000365 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000366 jso->o.c_int64 = i;
367 return jso;
368}
369
370int64_t json_object_get_int64(struct json_object *jso)
371{
372 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000373
Michael Clark266a3fd2009-02-25 01:55:31 +0000374 if(!jso) return 0;
375 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000376 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000377 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000378 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000379 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000380 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000381 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000382 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000383 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000384 default:
385 return 0;
386 }
387}
388
389
390/* json_object_double */
391
Michael Clark266a3fd2009-02-25 01:55:31 +0000392static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000393 struct printbuf *pb)
394{
Michael Clark266a3fd2009-02-25 01:55:31 +0000395 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000396}
397
398struct json_object* json_object_new_double(double d)
399{
Michael Clark266a3fd2009-02-25 01:55:31 +0000400 struct json_object *jso = json_object_new(json_type_double);
401 if(!jso) return NULL;
402 jso->_to_json_string = &json_object_double_to_json_string;
403 jso->o.c_double = d;
404 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000405}
406
Michael Clark266a3fd2009-02-25 01:55:31 +0000407double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000408{
409 double cdouble;
410
Michael Clark266a3fd2009-02-25 01:55:31 +0000411 if(!jso) return 0.0;
412 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000413 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000414 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000415 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000416 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000417 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000418 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000419 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000420 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000421 default:
422 return 0.0;
423 }
424}
425
426
427/* json_object_string */
428
Michael Clark266a3fd2009-02-25 01:55:31 +0000429static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000430 struct printbuf *pb)
431{
432 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000433 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000434 sprintbuf(pb, "\"");
435 return 0;
436}
437
Michael Clark266a3fd2009-02-25 01:55:31 +0000438static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000439{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000440 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000441 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000442}
443
Michael Clark68cafad2009-01-06 22:56:57 +0000444struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000445{
Michael Clark266a3fd2009-02-25 01:55:31 +0000446 struct json_object *jso = json_object_new(json_type_string);
447 if(!jso) return NULL;
448 jso->_delete = &json_object_string_delete;
449 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000450 jso->o.c_string.str = strdup(s);
451 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000452 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000453}
454
Michael Clark68cafad2009-01-06 22:56:57 +0000455struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000456{
Michael Clark266a3fd2009-02-25 01:55:31 +0000457 struct json_object *jso = json_object_new(json_type_string);
458 if(!jso) return NULL;
459 jso->_delete = &json_object_string_delete;
460 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000461 jso->o.c_string.str = malloc(len);
462 memcpy(jso->o.c_string.str, (void *)s, len);
463 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000464 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000465}
466
Michael Clark266a3fd2009-02-25 01:55:31 +0000467const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000468{
Michael Clark266a3fd2009-02-25 01:55:31 +0000469 if(!jso) return NULL;
470 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000471 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000472 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000473 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000474 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000475 }
476}
477
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000478int json_object_get_string_len(struct json_object *jso) {
479 if(!jso) return 0;
480 switch(jso->o_type) {
481 case json_type_string:
482 return jso->o.c_string.len;
483 default:
484 return 0;
485 }
486}
487
Michael Clarkf0d08882007-03-13 08:26:18 +0000488
489/* json_object_array */
490
Michael Clark266a3fd2009-02-25 01:55:31 +0000491static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000492 struct printbuf *pb)
493{
Michael Clark4504df72007-03-13 08:26:20 +0000494 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000495 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000496 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000497 struct json_object *val;
498 if(i) { sprintbuf(pb, ", "); }
499 else { sprintbuf(pb, " "); }
500
Michael Clark266a3fd2009-02-25 01:55:31 +0000501 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000502 if(val == NULL) { sprintbuf(pb, "null"); }
503 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000504 }
505 return sprintbuf(pb, " ]");
506}
507
508static void json_object_array_entry_free(void *data)
509{
510 json_object_put((struct json_object*)data);
511}
512
Michael Clark266a3fd2009-02-25 01:55:31 +0000513static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000514{
Michael Clark266a3fd2009-02-25 01:55:31 +0000515 array_list_free(jso->o.c_array);
516 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000517}
518
Michael Clarke8de0782009-02-25 01:45:00 +0000519struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000520{
Michael Clark266a3fd2009-02-25 01:55:31 +0000521 struct json_object *jso = json_object_new(json_type_array);
522 if(!jso) return NULL;
523 jso->_delete = &json_object_array_delete;
524 jso->_to_json_string = &json_object_array_to_json_string;
525 jso->o.c_array = array_list_new(&json_object_array_entry_free);
526 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000527}
528
Michael Clark266a3fd2009-02-25 01:55:31 +0000529struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000530{
Michael Clark266a3fd2009-02-25 01:55:31 +0000531 if(!jso) return NULL;
532 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000533 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000534 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000535 default:
536 return NULL;
537 }
538}
539
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200540void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
541{
542 array_list_sort(jso->o.c_array, sort_fn);
543}
544
Michael Clark266a3fd2009-02-25 01:55:31 +0000545int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000546{
Michael Clark266a3fd2009-02-25 01:55:31 +0000547 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000548}
549
Michael Clark266a3fd2009-02-25 01:55:31 +0000550int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000551{
Michael Clark266a3fd2009-02-25 01:55:31 +0000552 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000553}
554
Michael Clark266a3fd2009-02-25 01:55:31 +0000555int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000556 struct json_object *val)
557{
Michael Clark266a3fd2009-02-25 01:55:31 +0000558 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000559}
560
Michael Clark266a3fd2009-02-25 01:55:31 +0000561struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000562 int idx)
563{
Michael Clark266a3fd2009-02-25 01:55:31 +0000564 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000565}
566