blob: 482c5e3d947d1d1c7a25389a624c7fdd0fa52a2e [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";
35const char *json_hex_chars = "0123456789abcdef";
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
278struct json_object* json_object_new_boolean(boolean b)
279{
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
Michael Clark266a3fd2009-02-25 01:55:31 +0000287boolean 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{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000324 if(!jso) return 0;
325
326 enum json_type o_type = jso->o_type;
327 int64_t cint64 = jso->o.c_int64;
328
329 if (o_type == json_type_string)
330 {
331 /*
332 * Parse strings into 64-bit numbers, then use the
333 * 64-to-32-bit number handling below.
334 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000335 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000336 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000337 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000338 }
339
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000340 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000341 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000342 /* Make sure we return the correct values for out of range numbers. */
343 if (cint64 <= INT32_MIN)
344 return INT32_MIN;
345 else if (cint64 >= INT32_MAX)
346 return INT32_MAX;
347 else
348 return (int32_t)cint64;
349 case json_type_double:
350 return (int32_t)jso->o.c_double;
351 case json_type_boolean:
352 return jso->o.c_boolean;
353 default:
354 return 0;
355 }
356}
357
358struct json_object* json_object_new_int64(int64_t i)
359{
ehaszla252669c2010-12-07 18:15:35 +0000360 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000361 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000362 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000363 jso->o.c_int64 = i;
364 return jso;
365}
366
367int64_t json_object_get_int64(struct json_object *jso)
368{
369 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000370
Michael Clark266a3fd2009-02-25 01:55:31 +0000371 if(!jso) return 0;
372 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000373 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000374 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000375 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000376 return (int64_t)jso->o.c_double;
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_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000380 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000381 default:
382 return 0;
383 }
384}
385
386
387/* json_object_double */
388
Michael Clark266a3fd2009-02-25 01:55:31 +0000389static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000390 struct printbuf *pb)
391{
Michael Clark266a3fd2009-02-25 01:55:31 +0000392 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000393}
394
395struct json_object* json_object_new_double(double d)
396{
Michael Clark266a3fd2009-02-25 01:55:31 +0000397 struct json_object *jso = json_object_new(json_type_double);
398 if(!jso) return NULL;
399 jso->_to_json_string = &json_object_double_to_json_string;
400 jso->o.c_double = d;
401 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000402}
403
Michael Clark266a3fd2009-02-25 01:55:31 +0000404double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000405{
406 double cdouble;
407
Michael Clark266a3fd2009-02-25 01:55:31 +0000408 if(!jso) return 0.0;
409 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000410 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000411 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000412 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000413 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000414 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000415 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000416 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000417 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000418 default:
419 return 0.0;
420 }
421}
422
423
424/* json_object_string */
425
Michael Clark266a3fd2009-02-25 01:55:31 +0000426static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000427 struct printbuf *pb)
428{
429 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000430 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000431 sprintbuf(pb, "\"");
432 return 0;
433}
434
Michael Clark266a3fd2009-02-25 01:55:31 +0000435static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000436{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000437 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000438 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000439}
440
Michael Clark68cafad2009-01-06 22:56:57 +0000441struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000442{
Michael Clark266a3fd2009-02-25 01:55:31 +0000443 struct json_object *jso = json_object_new(json_type_string);
444 if(!jso) return NULL;
445 jso->_delete = &json_object_string_delete;
446 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000447 jso->o.c_string.str = strdup(s);
448 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000449 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000450}
451
Michael Clark68cafad2009-01-06 22:56:57 +0000452struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000453{
Michael Clark266a3fd2009-02-25 01:55:31 +0000454 struct json_object *jso = json_object_new(json_type_string);
455 if(!jso) return NULL;
456 jso->_delete = &json_object_string_delete;
457 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000458 jso->o.c_string.str = malloc(len);
459 memcpy(jso->o.c_string.str, (void *)s, len);
460 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000461 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000462}
463
Michael Clark266a3fd2009-02-25 01:55:31 +0000464const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000465{
Michael Clark266a3fd2009-02-25 01:55:31 +0000466 if(!jso) return NULL;
467 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000468 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000469 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000470 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000471 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000472 }
473}
474
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000475int json_object_get_string_len(struct json_object *jso) {
476 if(!jso) return 0;
477 switch(jso->o_type) {
478 case json_type_string:
479 return jso->o.c_string.len;
480 default:
481 return 0;
482 }
483}
484
Michael Clarkf0d08882007-03-13 08:26:18 +0000485
486/* json_object_array */
487
Michael Clark266a3fd2009-02-25 01:55:31 +0000488static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000489 struct printbuf *pb)
490{
Michael Clark4504df72007-03-13 08:26:20 +0000491 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000492 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000493 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000494 struct json_object *val;
495 if(i) { sprintbuf(pb, ", "); }
496 else { sprintbuf(pb, " "); }
497
Michael Clark266a3fd2009-02-25 01:55:31 +0000498 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000499 if(val == NULL) { sprintbuf(pb, "null"); }
500 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000501 }
502 return sprintbuf(pb, " ]");
503}
504
505static void json_object_array_entry_free(void *data)
506{
507 json_object_put((struct json_object*)data);
508}
509
Michael Clark266a3fd2009-02-25 01:55:31 +0000510static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000511{
Michael Clark266a3fd2009-02-25 01:55:31 +0000512 array_list_free(jso->o.c_array);
513 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000514}
515
Michael Clarke8de0782009-02-25 01:45:00 +0000516struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000517{
Michael Clark266a3fd2009-02-25 01:55:31 +0000518 struct json_object *jso = json_object_new(json_type_array);
519 if(!jso) return NULL;
520 jso->_delete = &json_object_array_delete;
521 jso->_to_json_string = &json_object_array_to_json_string;
522 jso->o.c_array = array_list_new(&json_object_array_entry_free);
523 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000524}
525
Michael Clark266a3fd2009-02-25 01:55:31 +0000526struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000527{
Michael Clark266a3fd2009-02-25 01:55:31 +0000528 if(!jso) return NULL;
529 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000530 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000531 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000532 default:
533 return NULL;
534 }
535}
536
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200537void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
538{
539 array_list_sort(jso->o.c_array, sort_fn);
540}
541
Michael Clark266a3fd2009-02-25 01:55:31 +0000542int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000543{
Michael Clark266a3fd2009-02-25 01:55:31 +0000544 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000545}
546
Michael Clark266a3fd2009-02-25 01:55:31 +0000547int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000548{
Michael Clark266a3fd2009-02-25 01:55:31 +0000549 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000550}
551
Michael Clark266a3fd2009-02-25 01:55:31 +0000552int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000553 struct json_object *val)
554{
Michael Clark266a3fd2009-02-25 01:55:31 +0000555 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000556}
557
Michael Clark266a3fd2009-02-25 01:55:31 +0000558struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000559 int idx)
560{
Michael Clark266a3fd2009-02-25 01:55:31 +0000561 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000562}
563