blob: c2b6fe2c885a70d221c6168c6b5fba0e84a3bdb7 [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
37#ifdef REFCOUNT_DEBUG
Michael Clark68cafad2009-01-06 22:56:57 +000038static const char* json_type_name[] = {
Michael Clarkf0d08882007-03-13 08:26:18 +000039 "null",
40 "boolean",
41 "double",
42 "int",
43 "object",
44 "array",
45 "string",
Michael Clarkc4dceae2010-10-06 16:39:20 +000046 "int64",
Michael Clarkf0d08882007-03-13 08:26:18 +000047};
Michael Clark4504df72007-03-13 08:26:20 +000048#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000049
Michael Clark266a3fd2009-02-25 01:55:31 +000050static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000051static struct json_object* json_object_new(enum json_type o_type);
52
53
54/* ref count debugging */
55
56#ifdef REFCOUNT_DEBUG
57
58static struct lh_table *json_object_table;
59
Michael Clark14862b12007-12-07 02:50:42 +000060static void json_object_init(void) __attribute__ ((constructor));
61static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000062 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000063 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
64}
65
Michael Clark14862b12007-12-07 02:50:42 +000066static void json_object_fini(void) __attribute__ ((destructor));
67static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000068 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000069 if(MC_GET_DEBUG()) {
70 if (json_object_table->count) {
71 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
72 json_object_table->count);
73 lh_foreach(json_object_table, ent) {
74 struct json_object* obj = (struct json_object*)ent->v;
75 MC_DEBUG("\t%s:%p\n", json_type_name[obj->o_type], obj);
76 }
Michael Clarkf0d08882007-03-13 08:26:18 +000077 }
78 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000079 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000080 lh_table_free(json_object_table);
81}
Michael Clark4504df72007-03-13 08:26:20 +000082#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000083
84
85/* string escaping */
86
87static int json_escape_str(struct printbuf *pb, char *str)
88{
89 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000090 unsigned char c;
Michael Clarkf0d08882007-03-13 08:26:18 +000091 do {
92 c = str[pos];
93 switch(c) {
Michael Clark837240f2007-03-13 08:26:25 +000094 case '\0':
95 break;
Michael Clarkf0d08882007-03-13 08:26:18 +000096 case '\b':
97 case '\n':
98 case '\r':
99 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +0000100 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +0000101 case '\\':
102 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000103 if(pos - start_offset > 0)
104 printbuf_memappend(pb, str + start_offset, pos - start_offset);
105 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
106 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
107 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
108 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000109 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000110 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
111 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000112 start_offset = ++pos;
113 break;
114 default:
Michael Clark837240f2007-03-13 08:26:25 +0000115 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000116 if(pos - start_offset > 0)
117 printbuf_memappend(pb, str + start_offset, pos - start_offset);
118 sprintbuf(pb, "\\u00%c%c",
119 json_hex_chars[c >> 4],
120 json_hex_chars[c & 0xf]);
121 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000122 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000123 }
124 } while(c);
125 if(pos - start_offset > 0)
126 printbuf_memappend(pb, str + start_offset, pos - start_offset);
127 return 0;
128}
129
130
131/* reference counting */
132
Michael Clark266a3fd2009-02-25 01:55:31 +0000133extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000134{
Michael Clark266a3fd2009-02-25 01:55:31 +0000135 if(jso) {
136 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000137 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000138 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000139}
140
Michael Clark266a3fd2009-02-25 01:55:31 +0000141extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000142{
Michael Clark266a3fd2009-02-25 01:55:31 +0000143 if(jso) {
144 jso->_ref_count--;
145 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000146 }
147}
148
149
150/* generic object construction and destruction parts */
151
Michael Clark266a3fd2009-02-25 01:55:31 +0000152static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000153{
154#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000155 MC_DEBUG("json_object_delete_%s: %p\n",
Michael Clark266a3fd2009-02-25 01:55:31 +0000156 json_type_name[jso->o_type], jso);
157 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000158#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000159 printbuf_free(jso->_pb);
160 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000161}
162
163static struct json_object* json_object_new(enum json_type o_type)
164{
Michael Clarkaaec1ef2009-02-25 02:31:32 +0000165 struct json_object *jso;
166
167 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000168 if(!jso) return NULL;
169 jso->o_type = o_type;
170 jso->_ref_count = 1;
171 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000172#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000173 lh_table_insert(json_object_table, jso, jso);
174 MC_DEBUG("json_object_new_%s: %p\n", json_type_name[jso->o_type], jso);
Michael Clark4504df72007-03-13 08:26:20 +0000175#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000176 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000177}
178
179
180/* type checking functions */
181
Michael Clark266a3fd2009-02-25 01:55:31 +0000182int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000183{
Michael Clark266a3fd2009-02-25 01:55:31 +0000184 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000185}
186
Michael Clark266a3fd2009-02-25 01:55:31 +0000187enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000188{
Michael Clark266a3fd2009-02-25 01:55:31 +0000189 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000190}
191
192
193/* json_object_to_json_string */
194
Michael Clark266a3fd2009-02-25 01:55:31 +0000195const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000196{
Michael Clark266a3fd2009-02-25 01:55:31 +0000197 if(!jso) return "null";
198 if(!jso->_pb) {
199 if(!(jso->_pb = printbuf_new())) return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000200 } else {
Michael Clark266a3fd2009-02-25 01:55:31 +0000201 printbuf_reset(jso->_pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000202 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000203 if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
204 return jso->_pb->buf;
Michael Clarkf0d08882007-03-13 08:26:18 +0000205}
206
207
208/* json_object_object */
209
Michael Clark266a3fd2009-02-25 01:55:31 +0000210static int json_object_object_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000211 struct printbuf *pb)
212{
213 int i=0;
Michael Clark4504df72007-03-13 08:26:20 +0000214 struct json_object_iter iter;
Michael Clarkf0d08882007-03-13 08:26:18 +0000215 sprintbuf(pb, "{");
Michael Clark4504df72007-03-13 08:26:20 +0000216
217 /* CAW: scope operator to make ANSI correctness */
218 /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
Michael Clark266a3fd2009-02-25 01:55:31 +0000219 json_object_object_foreachC(jso, iter) {
Michael Clark4504df72007-03-13 08:26:20 +0000220 if(i) sprintbuf(pb, ",");
221 sprintbuf(pb, " \"");
222 json_escape_str(pb, iter.key);
223 sprintbuf(pb, "\": ");
224 if(iter.val == NULL) sprintbuf(pb, "null");
225 else iter.val->_to_json_string(iter.val, pb);
226 i++;
227 }
228
Michael Clarkf0d08882007-03-13 08:26:18 +0000229 return sprintbuf(pb, " }");
230}
231
232static void json_object_lh_entry_free(struct lh_entry *ent)
233{
234 free(ent->k);
235 json_object_put((struct json_object*)ent->v);
236}
237
Michael Clark266a3fd2009-02-25 01:55:31 +0000238static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000239{
Michael Clark266a3fd2009-02-25 01:55:31 +0000240 lh_table_free(jso->o.c_object);
241 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000242}
243
Michael Clarke8de0782009-02-25 01:45:00 +0000244struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000245{
Michael Clark266a3fd2009-02-25 01:55:31 +0000246 struct json_object *jso = json_object_new(json_type_object);
247 if(!jso) return NULL;
248 jso->_delete = &json_object_object_delete;
249 jso->_to_json_string = &json_object_object_to_json_string;
250 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000251 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000252 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000253}
254
Michael Clark266a3fd2009-02-25 01:55:31 +0000255struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000256{
Michael Clark266a3fd2009-02-25 01:55:31 +0000257 if(!jso) return NULL;
258 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000259 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000260 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000261 default:
262 return NULL;
263 }
264}
265
Michael Clark266a3fd2009-02-25 01:55:31 +0000266void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000267 struct json_object *val)
268{
Michael Clark266a3fd2009-02-25 01:55:31 +0000269 lh_table_delete(jso->o.c_object, key);
270 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000271}
272
Michael Clark266a3fd2009-02-25 01:55:31 +0000273struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000274{
Michael Clark266a3fd2009-02-25 01:55:31 +0000275 return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000276}
277
Michael Clark266a3fd2009-02-25 01:55:31 +0000278void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000279{
Michael Clark266a3fd2009-02-25 01:55:31 +0000280 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000281}
282
283
284/* json_object_boolean */
285
Michael Clark266a3fd2009-02-25 01:55:31 +0000286static int json_object_boolean_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000287 struct printbuf *pb)
288{
Michael Clark266a3fd2009-02-25 01:55:31 +0000289 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000290 else return sprintbuf(pb, "false");
291}
292
293struct json_object* json_object_new_boolean(boolean b)
294{
Michael Clark266a3fd2009-02-25 01:55:31 +0000295 struct json_object *jso = json_object_new(json_type_boolean);
296 if(!jso) return NULL;
297 jso->_to_json_string = &json_object_boolean_to_json_string;
298 jso->o.c_boolean = b;
299 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000300}
301
Michael Clark266a3fd2009-02-25 01:55:31 +0000302boolean json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000303{
Michael Clark266a3fd2009-02-25 01:55:31 +0000304 if(!jso) return FALSE;
305 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000306 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000307 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000308 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000309 return (jso->o.c_int != 0);
Michael Clarkc4dceae2010-10-06 16:39:20 +0000310 case json_type_int64:
311 return (jso->o.c_int64 != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000312 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000313 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000314 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000315 return (strlen(jso->o.c_string) != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000316 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000317 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000318 }
319}
320
321
322/* json_object_int */
323
Michael Clark266a3fd2009-02-25 01:55:31 +0000324static int json_object_int_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000325 struct printbuf *pb)
326{
Michael Clark266a3fd2009-02-25 01:55:31 +0000327 return sprintbuf(pb, "%d", jso->o.c_int);
Michael Clarkf0d08882007-03-13 08:26:18 +0000328}
329
Michael Clarkc4dceae2010-10-06 16:39:20 +0000330static int json_object_int64_to_json_string(struct json_object* jso, struct printbuf *pb) {
331 return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
332}
333
334struct json_object* json_object_new_int(int32_t i)
Michael Clarkf0d08882007-03-13 08:26:18 +0000335{
Michael Clark266a3fd2009-02-25 01:55:31 +0000336 struct json_object *jso = json_object_new(json_type_int);
337 if(!jso) return NULL;
338 jso->_to_json_string = &json_object_int_to_json_string;
339 jso->o.c_int = i;
340 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000341}
342
Michael Clarkc4dceae2010-10-06 16:39:20 +0000343int32_t json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000344{
Michael Clarkc4dceae2010-10-06 16:39:20 +0000345 if(!jso) return 0;
346
347 enum json_type o_type = jso->o_type;
348 int64_t cint64 = jso->o.c_int64;
349
350 if (o_type == json_type_string)
351 {
352 /*
353 * Parse strings into 64-bit numbers, then use the
354 * 64-to-32-bit number handling below.
355 */
356 if (json_parse_int64(jso->o.c_string, &cint64) != 0)
357 return 0; /* whoops, it didn't work. */
358 o_type = json_type_int64;
359 }
360
361 switch(jso->o_type) {
362 case json_type_int:
363 return jso->o.c_int;
364 case json_type_int64:
365 /* Make sure we return the correct values for out of range numbers. */
366 if (cint64 <= INT32_MIN)
367 return INT32_MIN;
368 else if (cint64 >= INT32_MAX)
369 return INT32_MAX;
370 else
371 return (int32_t)cint64;
372 case json_type_double:
373 return (int32_t)jso->o.c_double;
374 case json_type_boolean:
375 return jso->o.c_boolean;
376 default:
377 return 0;
378 }
379}
380
381struct json_object* json_object_new_int64(int64_t i)
382{
383 struct json_object *jso = json_object_new(json_type_int64);
384 if(!jso) return NULL;
385 jso->_to_json_string = &json_object_int64_to_json_string;
386 jso->o.c_int64 = i;
387 return jso;
388}
389
390int64_t json_object_get_int64(struct json_object *jso)
391{
392 int64_t cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000393
Michael Clark266a3fd2009-02-25 01:55:31 +0000394 if(!jso) return 0;
395 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000396 case json_type_int:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000397 return (int64_t)jso->o.c_int;
398 case json_type_int64:
399 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000400 case json_type_double:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000401 return (int64_t)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000402 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000403 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000404 case json_type_string:
Michael Clarkc4dceae2010-10-06 16:39:20 +0000405 if (json_parse_int64(jso->o.c_string, &cint) == 0) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000406 default:
407 return 0;
408 }
409}
410
411
412/* json_object_double */
413
Michael Clark266a3fd2009-02-25 01:55:31 +0000414static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000415 struct printbuf *pb)
416{
Michael Clark266a3fd2009-02-25 01:55:31 +0000417 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000418}
419
420struct json_object* json_object_new_double(double d)
421{
Michael Clark266a3fd2009-02-25 01:55:31 +0000422 struct json_object *jso = json_object_new(json_type_double);
423 if(!jso) return NULL;
424 jso->_to_json_string = &json_object_double_to_json_string;
425 jso->o.c_double = d;
426 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000427}
428
Michael Clark266a3fd2009-02-25 01:55:31 +0000429double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000430{
431 double cdouble;
432
Michael Clark266a3fd2009-02-25 01:55:31 +0000433 if(!jso) return 0.0;
434 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000435 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000436 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000437 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000438 return jso->o.c_int;
Michael Clarkc4dceae2010-10-06 16:39:20 +0000439 case json_type_int64:
440 return jso->o.c_int64;
Michael Clarkf0d08882007-03-13 08:26:18 +0000441 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000442 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000443 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000444 if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000445 default:
446 return 0.0;
447 }
448}
449
450
451/* json_object_string */
452
Michael Clark266a3fd2009-02-25 01:55:31 +0000453static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000454 struct printbuf *pb)
455{
456 sprintbuf(pb, "\"");
Michael Clark266a3fd2009-02-25 01:55:31 +0000457 json_escape_str(pb, jso->o.c_string);
Michael Clarkf0d08882007-03-13 08:26:18 +0000458 sprintbuf(pb, "\"");
459 return 0;
460}
461
Michael Clark266a3fd2009-02-25 01:55:31 +0000462static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000463{
Michael Clark266a3fd2009-02-25 01:55:31 +0000464 free(jso->o.c_string);
465 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000466}
467
Michael Clark68cafad2009-01-06 22:56:57 +0000468struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000469{
Michael Clark266a3fd2009-02-25 01:55:31 +0000470 struct json_object *jso = json_object_new(json_type_string);
471 if(!jso) return NULL;
472 jso->_delete = &json_object_string_delete;
473 jso->_to_json_string = &json_object_string_to_json_string;
474 jso->o.c_string = strdup(s);
475 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;
484 jso->o.c_string = strndup(s, len);
485 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000486}
487
Michael Clark266a3fd2009-02-25 01:55:31 +0000488const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000489{
Michael Clark266a3fd2009-02-25 01:55:31 +0000490 if(!jso) return NULL;
491 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000492 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000493 return jso->o.c_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000494 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000495 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000496 }
497}
498
499
500/* json_object_array */
501
Michael Clark266a3fd2009-02-25 01:55:31 +0000502static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000503 struct printbuf *pb)
504{
Michael Clark4504df72007-03-13 08:26:20 +0000505 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000506 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000507 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000508 struct json_object *val;
509 if(i) { sprintbuf(pb, ", "); }
510 else { sprintbuf(pb, " "); }
511
Michael Clark266a3fd2009-02-25 01:55:31 +0000512 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000513 if(val == NULL) { sprintbuf(pb, "null"); }
514 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000515 }
516 return sprintbuf(pb, " ]");
517}
518
519static void json_object_array_entry_free(void *data)
520{
521 json_object_put((struct json_object*)data);
522}
523
Michael Clark266a3fd2009-02-25 01:55:31 +0000524static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000525{
Michael Clark266a3fd2009-02-25 01:55:31 +0000526 array_list_free(jso->o.c_array);
527 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000528}
529
Michael Clarke8de0782009-02-25 01:45:00 +0000530struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000531{
Michael Clark266a3fd2009-02-25 01:55:31 +0000532 struct json_object *jso = json_object_new(json_type_array);
533 if(!jso) return NULL;
534 jso->_delete = &json_object_array_delete;
535 jso->_to_json_string = &json_object_array_to_json_string;
536 jso->o.c_array = array_list_new(&json_object_array_entry_free);
537 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000538}
539
Michael Clark266a3fd2009-02-25 01:55:31 +0000540struct array_list* json_object_get_array(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_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000545 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000546 default:
547 return NULL;
548 }
549}
550
Michael Clark266a3fd2009-02-25 01:55:31 +0000551int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000552{
Michael Clark266a3fd2009-02-25 01:55:31 +0000553 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000554}
555
Michael Clark266a3fd2009-02-25 01:55:31 +0000556int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000557{
Michael Clark266a3fd2009-02-25 01:55:31 +0000558 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000559}
560
Michael Clark266a3fd2009-02-25 01:55:31 +0000561int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000562 struct json_object *val)
563{
Michael Clark266a3fd2009-02-25 01:55:31 +0000564 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000565}
566
Michael Clark266a3fd2009-02-25 01:55:31 +0000567struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000568 int idx)
569{
Michael Clark266a3fd2009-02-25 01:55:31 +0000570 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000571}
572