blob: 842ca22adca5dd6ef17bc333420f3678ce883e73 [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"
Keith Derrick69175862012-04-12 11:44:13 -070028#include "json_tokener.h"
Michael Clarkf0d08882007-03-13 08:26:18 +000029
Michael Clark837240f2007-03-13 08:26:25 +000030#if !HAVE_STRNDUP
31 char* strndup(const char* str, size_t n);
32#endif /* !HAVE_STRNDUP */
33
Keith Derrick69175862012-04-12 11:44:13 -070034// Don't define this. It's not thread-safe.
Christopher Watfordc5cbf822009-06-30 03:40:53 +000035/* #define REFCOUNT_DEBUG 1 */
Michael Clarkf0d08882007-03-13 08:26:18 +000036
Michael Clark68cafad2009-01-06 22:56:57 +000037const char *json_number_chars = "0123456789.+-eE";
Federico Culloca7ec34c92011-10-30 12:13:15 +010038const char *json_hex_chars = "0123456789abcdefABCDEF";
Michael Clarkf0d08882007-03-13 08:26:18 +000039
Michael Clark266a3fd2009-02-25 01:55:31 +000040static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000041static struct json_object* json_object_new(enum json_type o_type);
42
43
44/* ref count debugging */
45
46#ifdef REFCOUNT_DEBUG
47
48static struct lh_table *json_object_table;
49
Michael Clark14862b12007-12-07 02:50:42 +000050static void json_object_init(void) __attribute__ ((constructor));
51static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000052 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000053 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
54}
55
Michael Clark14862b12007-12-07 02:50:42 +000056static void json_object_fini(void) __attribute__ ((destructor));
57static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000058 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000059 if(MC_GET_DEBUG()) {
60 if (json_object_table->count) {
61 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
62 json_object_table->count);
63 lh_foreach(json_object_table, ent) {
64 struct json_object* obj = (struct json_object*)ent->v;
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +000065 MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
Michael Clarkdfaf6702007-10-25 02:26:00 +000066 }
Michael Clarkf0d08882007-03-13 08:26:18 +000067 }
68 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000069 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000070 lh_table_free(json_object_table);
71}
Michael Clark4504df72007-03-13 08:26:20 +000072#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000073
74
75/* string escaping */
76
Jehiah Czebotarac601b52011-01-14 17:23:06 +000077static int json_escape_str(struct printbuf *pb, char *str, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +000078{
79 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000080 unsigned char c;
Jehiah Czebotarac601b52011-01-14 17:23:06 +000081 while (len--) {
Michael Clarkf0d08882007-03-13 08:26:18 +000082 c = str[pos];
83 switch(c) {
84 case '\b':
85 case '\n':
86 case '\r':
87 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +000088 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +000089 case '\\':
90 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +000091 if(pos - start_offset > 0)
92 printbuf_memappend(pb, str + start_offset, pos - start_offset);
93 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
94 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
95 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
96 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +000097 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +000098 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
99 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000100 start_offset = ++pos;
101 break;
102 default:
Michael Clark837240f2007-03-13 08:26:25 +0000103 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000104 if(pos - start_offset > 0)
105 printbuf_memappend(pb, str + start_offset, pos - start_offset);
106 sprintbuf(pb, "\\u00%c%c",
107 json_hex_chars[c >> 4],
108 json_hex_chars[c & 0xf]);
109 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000110 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000111 }
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000112 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000113 if(pos - start_offset > 0)
114 printbuf_memappend(pb, str + start_offset, pos - start_offset);
115 return 0;
116}
117
118
119/* reference counting */
120
Michael Clark266a3fd2009-02-25 01:55:31 +0000121extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000122{
Michael Clark266a3fd2009-02-25 01:55:31 +0000123 if(jso) {
124 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000125 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000126 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000127}
128
Michael Clark266a3fd2009-02-25 01:55:31 +0000129extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000130{
Michael Clark266a3fd2009-02-25 01:55:31 +0000131 if(jso) {
132 jso->_ref_count--;
133 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000134 }
135}
136
137
138/* generic object construction and destruction parts */
139
Michael Clark266a3fd2009-02-25 01:55:31 +0000140static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000141{
142#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000143 MC_DEBUG("json_object_delete_%s: %p\n",
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000144 json_type_to_name(jso->o_type), jso);
Michael Clark266a3fd2009-02-25 01:55:31 +0000145 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000146#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000147 printbuf_free(jso->_pb);
148 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000149}
150
151static struct json_object* json_object_new(enum json_type o_type)
152{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000153 struct json_object *jso;
154
155 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000156 if(!jso) return NULL;
157 jso->o_type = o_type;
158 jso->_ref_count = 1;
159 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000160#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000161 lh_table_insert(json_object_table, jso, jso);
Eric Haszlakiewicz886c4fb2011-05-03 20:40:49 +0000162 MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
Michael Clark4504df72007-03-13 08:26:20 +0000163#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000164 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000165}
166
167
168/* type checking functions */
169
Michael Clark266a3fd2009-02-25 01:55:31 +0000170int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000171{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500172 if (!jso)
173 return (type == json_type_null);
Michael Clark266a3fd2009-02-25 01:55:31 +0000174 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000175}
176
Michael Clark266a3fd2009-02-25 01:55:31 +0000177enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000178{
Eric Haszlakiewiczaef439a2012-03-31 13:47:28 -0500179 if (!jso)
180 return json_type_null;
Michael Clark266a3fd2009-02-25 01:55:31 +0000181 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000182}
183
Michael Clarkf0d08882007-03-13 08:26:18 +0000184/* json_object_to_json_string */
185
Michael Clark266a3fd2009-02-25 01:55:31 +0000186const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000187{
Michael Clark266a3fd2009-02-25 01:55:31 +0000188 if(!jso) return "null";
189 if(!jso->_pb) {
190 if(!(jso->_pb = printbuf_new())) return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000191 } else {
Michael Clark266a3fd2009-02-25 01:55:31 +0000192 printbuf_reset(jso->_pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000193 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000194 if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
195 return jso->_pb->buf;
Michael Clarkf0d08882007-03-13 08:26:18 +0000196}
197
198
199/* json_object_object */
200
Michael Clark266a3fd2009-02-25 01:55:31 +0000201static int json_object_object_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000202 struct printbuf *pb)
203{
204 int i=0;
Michael Clark4504df72007-03-13 08:26:20 +0000205 struct json_object_iter iter;
Michael Clarkf0d08882007-03-13 08:26:18 +0000206 sprintbuf(pb, "{");
Michael Clark4504df72007-03-13 08:26:20 +0000207
208 /* CAW: scope operator to make ANSI correctness */
209 /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
Michael Clark266a3fd2009-02-25 01:55:31 +0000210 json_object_object_foreachC(jso, iter) {
Michael Clark4504df72007-03-13 08:26:20 +0000211 if(i) sprintbuf(pb, ",");
212 sprintbuf(pb, " \"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000213 json_escape_str(pb, iter.key, strlen(iter.key));
Michael Clark4504df72007-03-13 08:26:20 +0000214 sprintbuf(pb, "\": ");
215 if(iter.val == NULL) sprintbuf(pb, "null");
216 else iter.val->_to_json_string(iter.val, pb);
217 i++;
218 }
219
Michael Clarkf0d08882007-03-13 08:26:18 +0000220 return sprintbuf(pb, " }");
221}
222
223static void json_object_lh_entry_free(struct lh_entry *ent)
224{
225 free(ent->k);
226 json_object_put((struct json_object*)ent->v);
227}
228
Michael Clark266a3fd2009-02-25 01:55:31 +0000229static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000230{
Michael Clark266a3fd2009-02-25 01:55:31 +0000231 lh_table_free(jso->o.c_object);
232 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000233}
234
Michael Clarke8de0782009-02-25 01:45:00 +0000235struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000236{
Michael Clark266a3fd2009-02-25 01:55:31 +0000237 struct json_object *jso = json_object_new(json_type_object);
238 if(!jso) return NULL;
239 jso->_delete = &json_object_object_delete;
240 jso->_to_json_string = &json_object_object_to_json_string;
241 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000242 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000243 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000244}
245
Michael Clark266a3fd2009-02-25 01:55:31 +0000246struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000247{
Michael Clark266a3fd2009-02-25 01:55:31 +0000248 if(!jso) return NULL;
249 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000250 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000251 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000252 default:
253 return NULL;
254 }
255}
256
Michael Clark266a3fd2009-02-25 01:55:31 +0000257void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000258 struct json_object *val)
259{
Michael Clark266a3fd2009-02-25 01:55:31 +0000260 lh_table_delete(jso->o.c_object, key);
261 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000262}
263
Michael Clark266a3fd2009-02-25 01:55:31 +0000264struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000265{
Keith Derrick69175862012-04-12 11:44:13 -0700266 struct json_object *result;
267 json_object_object_get_ex(jso, key, &result);
268 return result;
269}
270
271json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
272{
273 if (NULL == jso) return FALSE;
274
275 switch(jso->o_type) {
276 case json_type_object:
277 return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
278 default:
279 if (value != NULL) {
280 *value = NULL;
281 }
282 return FALSE;
283 }
Michael Clarkf0d08882007-03-13 08:26:18 +0000284}
285
Michael Clark266a3fd2009-02-25 01:55:31 +0000286void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000287{
Michael Clark266a3fd2009-02-25 01:55:31 +0000288 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000289}
290
291
292/* json_object_boolean */
293
Michael Clark266a3fd2009-02-25 01:55:31 +0000294static int json_object_boolean_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000295 struct printbuf *pb)
296{
Michael Clark266a3fd2009-02-25 01:55:31 +0000297 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000298 else return sprintbuf(pb, "false");
299}
300
Keith Derrick37e74672012-03-26 14:29:31 -0700301struct json_object* json_object_new_boolean(json_bool b)
Michael Clarkf0d08882007-03-13 08:26:18 +0000302{
Michael Clark266a3fd2009-02-25 01:55:31 +0000303 struct json_object *jso = json_object_new(json_type_boolean);
304 if(!jso) return NULL;
305 jso->_to_json_string = &json_object_boolean_to_json_string;
306 jso->o.c_boolean = b;
307 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000308}
309
Keith Derrick37e74672012-03-26 14:29:31 -0700310json_bool json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000311{
Michael Clark266a3fd2009-02-25 01:55:31 +0000312 if(!jso) return FALSE;
313 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000314 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000315 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000316 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000317 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000318 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000319 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000320 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000321 return (jso->o.c_string.len != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000322 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000323 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000324 }
325}
326
327
328/* json_object_int */
329
Michael Clark266a3fd2009-02-25 01:55:31 +0000330static int json_object_int_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000331 struct printbuf *pb)
332{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000333 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
334}
335
336struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000337{
Michael Clark266a3fd2009-02-25 01:55:31 +0000338 struct json_object *jso = json_object_new(json_type_int);
339 if(!jso) return NULL;
340 jso->_to_json_string = &json_object_int_to_json_string;
ehaszla252669c2010-12-07 18:15:35 +0000341 jso->o.c_int64 = i;
Michael Clark266a3fd2009-02-25 01:55:31 +0000342 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000343}
344
Michael Clarkc4dceae2010-10-06 16:39:20 +0000345int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000346{
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100347 int64_t cint64;
348 enum json_type o_type;
349
Michael Clarkc4dceae2010-10-06 16:39:20 +0000350 if(!jso) return 0;
351
John Arbash Meinel6a231e42012-02-01 09:27:49 +0100352 o_type = jso->o_type;
353 cint64 = jso->o.c_int64;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000354
355 if (o_type == json_type_string)
356 {
357 /*
358 * Parse strings into 64-bit numbers, then use the
359 * 64-to-32-bit number handling below.
360 */
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000361 if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
Michael Clarkc4dceae2010-10-06 16:39:20 +0000362 return 0; /* whoops, it didn't work. */
ehaszla252669c2010-12-07 18:15:35 +0000363 o_type = json_type_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000364 }
365
Eric Haszlakiewicze2e16012011-05-03 20:39:07 +0000366 switch(o_type) {
Michael Clarkc4dceae2010-10-06 16:39:20 +0000367 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000368 /* Make sure we return the correct values for out of range numbers. */
369 if (cint64 <= INT32_MIN)
370 return INT32_MIN;
371 else if (cint64 >= INT32_MAX)
372 return INT32_MAX;
373 else
374 return (int32_t)cint64;
375 case json_type_double:
376 return (int32_t)jso->o.c_double;
377 case json_type_boolean:
378 return jso->o.c_boolean;
379 default:
380 return 0;
381 }
382}
383
384struct json_object* json_object_new_int64(int64_t i)
385{
ehaszla252669c2010-12-07 18:15:35 +0000386 struct json_object *jso = json_object_new(json_type_int);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000387 if(!jso) return NULL;
ehaszla252669c2010-12-07 18:15:35 +0000388 jso->_to_json_string = &json_object_int_to_json_string;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000389 jso->o.c_int64 = i;
390 return jso;
391}
392
393int64_t json_object_get_int64(struct json_object *jso)
394{
395 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000396
Michael Clark266a3fd2009-02-25 01:55:31 +0000397 if(!jso) return 0;
398 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000399 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000400 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000401 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000402 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000403 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000404 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000405 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000406 if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000407 default:
408 return 0;
409 }
410}
411
412
413/* json_object_double */
414
Michael Clark266a3fd2009-02-25 01:55:31 +0000415static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000416 struct printbuf *pb)
417{
Michael Clark266a3fd2009-02-25 01:55:31 +0000418 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000419}
420
421struct json_object* json_object_new_double(double d)
422{
Michael Clark266a3fd2009-02-25 01:55:31 +0000423 struct json_object *jso = json_object_new(json_type_double);
424 if(!jso) return NULL;
425 jso->_to_json_string = &json_object_double_to_json_string;
426 jso->o.c_double = d;
427 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000428}
429
Michael Clark266a3fd2009-02-25 01:55:31 +0000430double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000431{
432 double cdouble;
433
Michael Clark266a3fd2009-02-25 01:55:31 +0000434 if(!jso) return 0.0;
435 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000436 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000437 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000438 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000439 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000440 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000441 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000442 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000443 if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000444 default:
445 return 0.0;
446 }
447}
448
449
450/* json_object_string */
451
Michael Clark266a3fd2009-02-25 01:55:31 +0000452static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000453 struct printbuf *pb)
454{
455 sprintbuf(pb, "\"");
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000456 json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
Michael Clarkf0d08882007-03-13 08:26:18 +0000457 sprintbuf(pb, "\"");
458 return 0;
459}
460
Michael Clark266a3fd2009-02-25 01:55:31 +0000461static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000462{
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000463 free(jso->o.c_string.str);
Michael Clark266a3fd2009-02-25 01:55:31 +0000464 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000465}
466
Michael Clark68cafad2009-01-06 22:56:57 +0000467struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000468{
Michael Clark266a3fd2009-02-25 01:55:31 +0000469 struct json_object *jso = json_object_new(json_type_string);
470 if(!jso) return NULL;
471 jso->_delete = &json_object_string_delete;
472 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000473 jso->o.c_string.str = strdup(s);
474 jso->o.c_string.len = strlen(s);
Michael Clark266a3fd2009-02-25 01:55:31 +0000475 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000476}
477
Michael Clark68cafad2009-01-06 22:56:57 +0000478struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000479{
Michael Clark266a3fd2009-02-25 01:55:31 +0000480 struct json_object *jso = json_object_new(json_type_string);
481 if(!jso) return NULL;
482 jso->_delete = &json_object_string_delete;
483 jso->_to_json_string = &json_object_string_to_json_string;
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000484 jso->o.c_string.str = malloc(len);
485 memcpy(jso->o.c_string.str, (void *)s, len);
486 jso->o.c_string.len = len;
Michael Clark266a3fd2009-02-25 01:55:31 +0000487 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000488}
489
Michael Clark266a3fd2009-02-25 01:55:31 +0000490const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000491{
Michael Clark266a3fd2009-02-25 01:55:31 +0000492 if(!jso) return NULL;
493 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000494 case json_type_string:
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000495 return jso->o.c_string.str;
Michael Clarkf0d08882007-03-13 08:26:18 +0000496 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000497 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000498 }
499}
500
Jehiah Czebotarac601b52011-01-14 17:23:06 +0000501int json_object_get_string_len(struct json_object *jso) {
502 if(!jso) return 0;
503 switch(jso->o_type) {
504 case json_type_string:
505 return jso->o.c_string.len;
506 default:
507 return 0;
508 }
509}
510
Michael Clarkf0d08882007-03-13 08:26:18 +0000511
512/* json_object_array */
513
Michael Clark266a3fd2009-02-25 01:55:31 +0000514static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000515 struct printbuf *pb)
516{
Michael Clark4504df72007-03-13 08:26:20 +0000517 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000518 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000519 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000520 struct json_object *val;
521 if(i) { sprintbuf(pb, ", "); }
522 else { sprintbuf(pb, " "); }
523
Michael Clark266a3fd2009-02-25 01:55:31 +0000524 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000525 if(val == NULL) { sprintbuf(pb, "null"); }
526 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000527 }
528 return sprintbuf(pb, " ]");
529}
530
531static void json_object_array_entry_free(void *data)
532{
533 json_object_put((struct json_object*)data);
534}
535
Michael Clark266a3fd2009-02-25 01:55:31 +0000536static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000537{
Michael Clark266a3fd2009-02-25 01:55:31 +0000538 array_list_free(jso->o.c_array);
539 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000540}
541
Michael Clarke8de0782009-02-25 01:45:00 +0000542struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000543{
Michael Clark266a3fd2009-02-25 01:55:31 +0000544 struct json_object *jso = json_object_new(json_type_array);
545 if(!jso) return NULL;
546 jso->_delete = &json_object_array_delete;
547 jso->_to_json_string = &json_object_array_to_json_string;
548 jso->o.c_array = array_list_new(&json_object_array_entry_free);
549 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000550}
551
Michael Clark266a3fd2009-02-25 01:55:31 +0000552struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000553{
Michael Clark266a3fd2009-02-25 01:55:31 +0000554 if(!jso) return NULL;
555 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000556 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000557 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000558 default:
559 return NULL;
560 }
561}
562
Frederik Deweerdtc43871c2011-10-07 21:07:18 +0200563void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
564{
565 array_list_sort(jso->o.c_array, sort_fn);
566}
567
Michael Clark266a3fd2009-02-25 01:55:31 +0000568int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000569{
Michael Clark266a3fd2009-02-25 01:55:31 +0000570 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000571}
572
Michael Clark266a3fd2009-02-25 01:55:31 +0000573int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000574{
Michael Clark266a3fd2009-02-25 01:55:31 +0000575 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000576}
577
Michael Clark266a3fd2009-02-25 01:55:31 +0000578int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000579 struct json_object *val)
580{
Michael Clark266a3fd2009-02-25 01:55:31 +0000581 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000582}
583
Michael Clark266a3fd2009-02-25 01:55:31 +0000584struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000585 int idx)
586{
Michael Clark266a3fd2009-02-25 01:55:31 +0000587 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000588}
589