blob: 28ca10264f86cd6fb70837b17e76dd6ec4f2a5f0 [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"
23#include "json_object.h"
24#include "json_object_private.h"
25
Michael Clark837240f2007-03-13 08:26:25 +000026#if !HAVE_STRNDUP
27 char* strndup(const char* str, size_t n);
28#endif /* !HAVE_STRNDUP */
29
Michael Clarkdfaf6702007-10-25 02:26:00 +000030#define REFCOUNT_DEBUG 1
Michael Clarkf0d08882007-03-13 08:26:18 +000031
Michael Clark68cafad2009-01-06 22:56:57 +000032const char *json_number_chars = "0123456789.+-eE";
33const char *json_hex_chars = "0123456789abcdef";
Michael Clarkf0d08882007-03-13 08:26:18 +000034
35#ifdef REFCOUNT_DEBUG
Michael Clark68cafad2009-01-06 22:56:57 +000036static const char* json_type_name[] = {
Michael Clarkf0d08882007-03-13 08:26:18 +000037 "null",
38 "boolean",
39 "double",
40 "int",
41 "object",
42 "array",
43 "string",
44};
Michael Clark4504df72007-03-13 08:26:20 +000045#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000046
Michael Clark266a3fd2009-02-25 01:55:31 +000047static void json_object_generic_delete(struct json_object* jso);
Michael Clarkf0d08882007-03-13 08:26:18 +000048static struct json_object* json_object_new(enum json_type o_type);
49
50
51/* ref count debugging */
52
53#ifdef REFCOUNT_DEBUG
54
55static struct lh_table *json_object_table;
56
Michael Clark14862b12007-12-07 02:50:42 +000057static void json_object_init(void) __attribute__ ((constructor));
58static void json_object_init(void) {
Michael Clarkdfaf6702007-10-25 02:26:00 +000059 MC_DEBUG("json_object_init: creating object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000060 json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
61}
62
Michael Clark14862b12007-12-07 02:50:42 +000063static void json_object_fini(void) __attribute__ ((destructor));
64static void json_object_fini(void) {
Michael Clarkf0d08882007-03-13 08:26:18 +000065 struct lh_entry *ent;
Michael Clarkdfaf6702007-10-25 02:26:00 +000066 if(MC_GET_DEBUG()) {
67 if (json_object_table->count) {
68 MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
69 json_object_table->count);
70 lh_foreach(json_object_table, ent) {
71 struct json_object* obj = (struct json_object*)ent->v;
72 MC_DEBUG("\t%s:%p\n", json_type_name[obj->o_type], obj);
73 }
Michael Clarkf0d08882007-03-13 08:26:18 +000074 }
75 }
Michael Clarkdfaf6702007-10-25 02:26:00 +000076 MC_DEBUG("json_object_fini: freeing object table\n");
Michael Clarkf0d08882007-03-13 08:26:18 +000077 lh_table_free(json_object_table);
78}
Michael Clark4504df72007-03-13 08:26:20 +000079#endif /* REFCOUNT_DEBUG */
Michael Clarkf0d08882007-03-13 08:26:18 +000080
81
82/* string escaping */
83
84static int json_escape_str(struct printbuf *pb, char *str)
85{
86 int pos = 0, start_offset = 0;
Michael Clark837240f2007-03-13 08:26:25 +000087 unsigned char c;
Michael Clarkf0d08882007-03-13 08:26:18 +000088 do {
89 c = str[pos];
90 switch(c) {
Michael Clark837240f2007-03-13 08:26:25 +000091 case '\0':
92 break;
Michael Clarkf0d08882007-03-13 08:26:18 +000093 case '\b':
94 case '\n':
95 case '\r':
96 case '\t':
Michael Clark4504df72007-03-13 08:26:20 +000097 case '"':
Michael Clarka850f8e2007-03-13 08:26:26 +000098 case '\\':
99 case '/':
Michael Clarkf0d08882007-03-13 08:26:18 +0000100 if(pos - start_offset > 0)
101 printbuf_memappend(pb, str + start_offset, pos - start_offset);
102 if(c == '\b') printbuf_memappend(pb, "\\b", 2);
103 else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
104 else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
105 else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
Michael Clark4504df72007-03-13 08:26:20 +0000106 else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
Michael Clarka850f8e2007-03-13 08:26:26 +0000107 else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
108 else if(c == '/') printbuf_memappend(pb, "\\/", 2);
Michael Clarkf0d08882007-03-13 08:26:18 +0000109 start_offset = ++pos;
110 break;
111 default:
Michael Clark837240f2007-03-13 08:26:25 +0000112 if(c < ' ') {
Michael Clarkf0d08882007-03-13 08:26:18 +0000113 if(pos - start_offset > 0)
114 printbuf_memappend(pb, str + start_offset, pos - start_offset);
115 sprintbuf(pb, "\\u00%c%c",
116 json_hex_chars[c >> 4],
117 json_hex_chars[c & 0xf]);
118 start_offset = ++pos;
Michael Clark837240f2007-03-13 08:26:25 +0000119 } else pos++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000120 }
121 } while(c);
122 if(pos - start_offset > 0)
123 printbuf_memappend(pb, str + start_offset, pos - start_offset);
124 return 0;
125}
126
127
128/* reference counting */
129
Michael Clark266a3fd2009-02-25 01:55:31 +0000130extern struct json_object* json_object_get(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000131{
Michael Clark266a3fd2009-02-25 01:55:31 +0000132 if(jso) {
133 jso->_ref_count++;
Michael Clarkf0d08882007-03-13 08:26:18 +0000134 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000135 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000136}
137
Michael Clark266a3fd2009-02-25 01:55:31 +0000138extern void json_object_put(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000139{
Michael Clark266a3fd2009-02-25 01:55:31 +0000140 if(jso) {
141 jso->_ref_count--;
142 if(!jso->_ref_count) jso->_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000143 }
144}
145
146
147/* generic object construction and destruction parts */
148
Michael Clark266a3fd2009-02-25 01:55:31 +0000149static void json_object_generic_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000150{
151#ifdef REFCOUNT_DEBUG
Michael Clarkdfaf6702007-10-25 02:26:00 +0000152 MC_DEBUG("json_object_delete_%s: %p\n",
Michael Clark266a3fd2009-02-25 01:55:31 +0000153 json_type_name[jso->o_type], jso);
154 lh_table_delete(json_object_table, jso);
Michael Clark4504df72007-03-13 08:26:20 +0000155#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000156 printbuf_free(jso->_pb);
157 free(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000158}
159
160static struct json_object* json_object_new(enum json_type o_type)
161{
Michael Clark266a3fd2009-02-25 01:55:31 +0000162 struct json_object *jso = calloc(sizeof(struct json_object), 1);
163 if(!jso) return NULL;
164 jso->o_type = o_type;
165 jso->_ref_count = 1;
166 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000167#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000168 lh_table_insert(json_object_table, jso, jso);
169 MC_DEBUG("json_object_new_%s: %p\n", json_type_name[jso->o_type], jso);
Michael Clark4504df72007-03-13 08:26:20 +0000170#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000171 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000172}
173
174
175/* type checking functions */
176
Michael Clark266a3fd2009-02-25 01:55:31 +0000177int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000178{
Michael Clark266a3fd2009-02-25 01:55:31 +0000179 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000180}
181
Michael Clark266a3fd2009-02-25 01:55:31 +0000182enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000183{
Michael Clark266a3fd2009-02-25 01:55:31 +0000184 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000185}
186
187
188/* json_object_to_json_string */
189
Michael Clark266a3fd2009-02-25 01:55:31 +0000190const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000191{
Michael Clark266a3fd2009-02-25 01:55:31 +0000192 if(!jso) return "null";
193 if(!jso->_pb) {
194 if(!(jso->_pb = printbuf_new())) return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000195 } else {
Michael Clark266a3fd2009-02-25 01:55:31 +0000196 printbuf_reset(jso->_pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000197 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000198 if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
199 return jso->_pb->buf;
Michael Clarkf0d08882007-03-13 08:26:18 +0000200}
201
202
203/* json_object_object */
204
Michael Clark266a3fd2009-02-25 01:55:31 +0000205static int json_object_object_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000206 struct printbuf *pb)
207{
208 int i=0;
Michael Clark4504df72007-03-13 08:26:20 +0000209 struct json_object_iter iter;
Michael Clarkf0d08882007-03-13 08:26:18 +0000210 sprintbuf(pb, "{");
Michael Clark4504df72007-03-13 08:26:20 +0000211
212 /* CAW: scope operator to make ANSI correctness */
213 /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
Michael Clark266a3fd2009-02-25 01:55:31 +0000214 json_object_object_foreachC(jso, iter) {
Michael Clark4504df72007-03-13 08:26:20 +0000215 if(i) sprintbuf(pb, ",");
216 sprintbuf(pb, " \"");
217 json_escape_str(pb, iter.key);
218 sprintbuf(pb, "\": ");
219 if(iter.val == NULL) sprintbuf(pb, "null");
220 else iter.val->_to_json_string(iter.val, pb);
221 i++;
222 }
223
Michael Clarkf0d08882007-03-13 08:26:18 +0000224 return sprintbuf(pb, " }");
225}
226
227static void json_object_lh_entry_free(struct lh_entry *ent)
228{
229 free(ent->k);
230 json_object_put((struct json_object*)ent->v);
231}
232
Michael Clark266a3fd2009-02-25 01:55:31 +0000233static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000234{
Michael Clark266a3fd2009-02-25 01:55:31 +0000235 lh_table_free(jso->o.c_object);
236 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000237}
238
Michael Clarke8de0782009-02-25 01:45:00 +0000239struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000240{
Michael Clark266a3fd2009-02-25 01:55:31 +0000241 struct json_object *jso = json_object_new(json_type_object);
242 if(!jso) return NULL;
243 jso->_delete = &json_object_object_delete;
244 jso->_to_json_string = &json_object_object_to_json_string;
245 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000246 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000247 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000248}
249
Michael Clark266a3fd2009-02-25 01:55:31 +0000250struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000251{
Michael Clark266a3fd2009-02-25 01:55:31 +0000252 if(!jso) return NULL;
253 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000254 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000255 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000256 default:
257 return NULL;
258 }
259}
260
Michael Clark266a3fd2009-02-25 01:55:31 +0000261void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000262 struct json_object *val)
263{
Michael Clark266a3fd2009-02-25 01:55:31 +0000264 lh_table_delete(jso->o.c_object, key);
265 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000266}
267
Michael Clark266a3fd2009-02-25 01:55:31 +0000268struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000269{
Michael Clark266a3fd2009-02-25 01:55:31 +0000270 return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000271}
272
Michael Clark266a3fd2009-02-25 01:55:31 +0000273void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000274{
Michael Clark266a3fd2009-02-25 01:55:31 +0000275 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000276}
277
278
279/* json_object_boolean */
280
Michael Clark266a3fd2009-02-25 01:55:31 +0000281static int json_object_boolean_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000282 struct printbuf *pb)
283{
Michael Clark266a3fd2009-02-25 01:55:31 +0000284 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000285 else return sprintbuf(pb, "false");
286}
287
288struct json_object* json_object_new_boolean(boolean b)
289{
Michael Clark266a3fd2009-02-25 01:55:31 +0000290 struct json_object *jso = json_object_new(json_type_boolean);
291 if(!jso) return NULL;
292 jso->_to_json_string = &json_object_boolean_to_json_string;
293 jso->o.c_boolean = b;
294 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000295}
296
Michael Clark266a3fd2009-02-25 01:55:31 +0000297boolean json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000298{
Michael Clark266a3fd2009-02-25 01:55:31 +0000299 if(!jso) return FALSE;
300 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000301 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000302 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000303 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000304 return (jso->o.c_int != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000305 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000306 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000307 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000308 return (strlen(jso->o.c_string) != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000309 default:
310 return TRUE;
311 }
312}
313
314
315/* json_object_int */
316
Michael Clark266a3fd2009-02-25 01:55:31 +0000317static int json_object_int_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000318 struct printbuf *pb)
319{
Michael Clark266a3fd2009-02-25 01:55:31 +0000320 return sprintbuf(pb, "%d", jso->o.c_int);
Michael Clarkf0d08882007-03-13 08:26:18 +0000321}
322
323struct json_object* json_object_new_int(int i)
324{
Michael Clark266a3fd2009-02-25 01:55:31 +0000325 struct json_object *jso = json_object_new(json_type_int);
326 if(!jso) return NULL;
327 jso->_to_json_string = &json_object_int_to_json_string;
328 jso->o.c_int = i;
329 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000330}
331
Michael Clark266a3fd2009-02-25 01:55:31 +0000332int json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000333{
334 int cint;
335
Michael Clark266a3fd2009-02-25 01:55:31 +0000336 if(!jso) return 0;
337 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000338 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000339 return jso->o.c_int;
Michael Clarkf0d08882007-03-13 08:26:18 +0000340 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000341 return (int)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000342 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000343 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000344 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000345 if(sscanf(jso->o.c_string, "%d", &cint) == 1) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000346 default:
347 return 0;
348 }
349}
350
351
352/* json_object_double */
353
Michael Clark266a3fd2009-02-25 01:55:31 +0000354static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000355 struct printbuf *pb)
356{
Michael Clark266a3fd2009-02-25 01:55:31 +0000357 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000358}
359
360struct json_object* json_object_new_double(double d)
361{
Michael Clark266a3fd2009-02-25 01:55:31 +0000362 struct json_object *jso = json_object_new(json_type_double);
363 if(!jso) return NULL;
364 jso->_to_json_string = &json_object_double_to_json_string;
365 jso->o.c_double = d;
366 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000367}
368
Michael Clark266a3fd2009-02-25 01:55:31 +0000369double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000370{
371 double cdouble;
372
Michael Clark266a3fd2009-02-25 01:55:31 +0000373 if(!jso) return 0.0;
374 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000375 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000376 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000377 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000378 return jso->o.c_int;
Michael Clarkf0d08882007-03-13 08:26:18 +0000379 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000380 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000381 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000382 if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000383 default:
384 return 0.0;
385 }
386}
387
388
389/* json_object_string */
390
Michael Clark266a3fd2009-02-25 01:55:31 +0000391static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000392 struct printbuf *pb)
393{
394 sprintbuf(pb, "\"");
Michael Clark266a3fd2009-02-25 01:55:31 +0000395 json_escape_str(pb, jso->o.c_string);
Michael Clarkf0d08882007-03-13 08:26:18 +0000396 sprintbuf(pb, "\"");
397 return 0;
398}
399
Michael Clark266a3fd2009-02-25 01:55:31 +0000400static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000401{
Michael Clark266a3fd2009-02-25 01:55:31 +0000402 free(jso->o.c_string);
403 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000404}
405
Michael Clark68cafad2009-01-06 22:56:57 +0000406struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000407{
Michael Clark266a3fd2009-02-25 01:55:31 +0000408 struct json_object *jso = json_object_new(json_type_string);
409 if(!jso) return NULL;
410 jso->_delete = &json_object_string_delete;
411 jso->_to_json_string = &json_object_string_to_json_string;
412 jso->o.c_string = strdup(s);
413 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000414}
415
Michael Clark68cafad2009-01-06 22:56:57 +0000416struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000417{
Michael Clark266a3fd2009-02-25 01:55:31 +0000418 struct json_object *jso = json_object_new(json_type_string);
419 if(!jso) return NULL;
420 jso->_delete = &json_object_string_delete;
421 jso->_to_json_string = &json_object_string_to_json_string;
422 jso->o.c_string = strndup(s, len);
423 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000424}
425
Michael Clark266a3fd2009-02-25 01:55:31 +0000426const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000427{
Michael Clark266a3fd2009-02-25 01:55:31 +0000428 if(!jso) return NULL;
429 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000430 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000431 return jso->o.c_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000432 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000433 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000434 }
435}
436
437
438/* json_object_array */
439
Michael Clark266a3fd2009-02-25 01:55:31 +0000440static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000441 struct printbuf *pb)
442{
Michael Clark4504df72007-03-13 08:26:20 +0000443 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000444 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000445 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000446 struct json_object *val;
447 if(i) { sprintbuf(pb, ", "); }
448 else { sprintbuf(pb, " "); }
449
Michael Clark266a3fd2009-02-25 01:55:31 +0000450 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000451 if(val == NULL) { sprintbuf(pb, "null"); }
452 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000453 }
454 return sprintbuf(pb, " ]");
455}
456
457static void json_object_array_entry_free(void *data)
458{
459 json_object_put((struct json_object*)data);
460}
461
Michael Clark266a3fd2009-02-25 01:55:31 +0000462static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000463{
Michael Clark266a3fd2009-02-25 01:55:31 +0000464 array_list_free(jso->o.c_array);
465 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000466}
467
Michael Clarke8de0782009-02-25 01:45:00 +0000468struct json_object* json_object_new_array(void)
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_array);
471 if(!jso) return NULL;
472 jso->_delete = &json_object_array_delete;
473 jso->_to_json_string = &json_object_array_to_json_string;
474 jso->o.c_array = array_list_new(&json_object_array_entry_free);
475 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000476}
477
Michael Clark266a3fd2009-02-25 01:55:31 +0000478struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000479{
Michael Clark266a3fd2009-02-25 01:55:31 +0000480 if(!jso) return NULL;
481 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000482 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000483 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000484 default:
485 return NULL;
486 }
487}
488
Michael Clark266a3fd2009-02-25 01:55:31 +0000489int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000490{
Michael Clark266a3fd2009-02-25 01:55:31 +0000491 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000492}
493
Michael Clark266a3fd2009-02-25 01:55:31 +0000494int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000495{
Michael Clark266a3fd2009-02-25 01:55:31 +0000496 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000497}
498
Michael Clark266a3fd2009-02-25 01:55:31 +0000499int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000500 struct json_object *val)
501{
Michael Clark266a3fd2009-02-25 01:55:31 +0000502 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000503}
504
Michael Clark266a3fd2009-02-25 01:55:31 +0000505struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000506 int idx)
507{
Michael Clark266a3fd2009-02-25 01:55:31 +0000508 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000509}
510