blob: f52445c901163e2da6fb015d1d30767ce02393b0 [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
Christopher Watfordc5cbf822009-06-30 03:40:53 +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 Clarkaaec1ef2009-02-25 02:31:32 +0000162 struct json_object *jso;
163
164 jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
Michael Clark266a3fd2009-02-25 01:55:31 +0000165 if(!jso) return NULL;
166 jso->o_type = o_type;
167 jso->_ref_count = 1;
168 jso->_delete = &json_object_generic_delete;
Michael Clarkf0d08882007-03-13 08:26:18 +0000169#ifdef REFCOUNT_DEBUG
Michael Clark266a3fd2009-02-25 01:55:31 +0000170 lh_table_insert(json_object_table, jso, jso);
171 MC_DEBUG("json_object_new_%s: %p\n", json_type_name[jso->o_type], jso);
Michael Clark4504df72007-03-13 08:26:20 +0000172#endif /* REFCOUNT_DEBUG */
Michael Clark266a3fd2009-02-25 01:55:31 +0000173 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000174}
175
176
177/* type checking functions */
178
Michael Clark266a3fd2009-02-25 01:55:31 +0000179int json_object_is_type(struct json_object *jso, enum json_type type)
Michael Clarkf0d08882007-03-13 08:26:18 +0000180{
Michael Clark266a3fd2009-02-25 01:55:31 +0000181 return (jso->o_type == type);
Michael Clarkf0d08882007-03-13 08:26:18 +0000182}
183
Michael Clark266a3fd2009-02-25 01:55:31 +0000184enum json_type json_object_get_type(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000185{
Michael Clark266a3fd2009-02-25 01:55:31 +0000186 return jso->o_type;
Michael Clarkf0d08882007-03-13 08:26:18 +0000187}
188
189
190/* json_object_to_json_string */
191
Michael Clark266a3fd2009-02-25 01:55:31 +0000192const char* json_object_to_json_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000193{
Michael Clark266a3fd2009-02-25 01:55:31 +0000194 if(!jso) return "null";
195 if(!jso->_pb) {
196 if(!(jso->_pb = printbuf_new())) return NULL;
Michael Clarkf0d08882007-03-13 08:26:18 +0000197 } else {
Michael Clark266a3fd2009-02-25 01:55:31 +0000198 printbuf_reset(jso->_pb);
Michael Clarkf0d08882007-03-13 08:26:18 +0000199 }
Michael Clark266a3fd2009-02-25 01:55:31 +0000200 if(jso->_to_json_string(jso, jso->_pb) < 0) return NULL;
201 return jso->_pb->buf;
Michael Clarkf0d08882007-03-13 08:26:18 +0000202}
203
204
205/* json_object_object */
206
Michael Clark266a3fd2009-02-25 01:55:31 +0000207static int json_object_object_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000208 struct printbuf *pb)
209{
210 int i=0;
Michael Clark4504df72007-03-13 08:26:20 +0000211 struct json_object_iter iter;
Michael Clarkf0d08882007-03-13 08:26:18 +0000212 sprintbuf(pb, "{");
Michael Clark4504df72007-03-13 08:26:20 +0000213
214 /* CAW: scope operator to make ANSI correctness */
215 /* CAW: switched to json_object_object_foreachC which uses an iterator struct */
Michael Clark266a3fd2009-02-25 01:55:31 +0000216 json_object_object_foreachC(jso, iter) {
Michael Clark4504df72007-03-13 08:26:20 +0000217 if(i) sprintbuf(pb, ",");
218 sprintbuf(pb, " \"");
219 json_escape_str(pb, iter.key);
220 sprintbuf(pb, "\": ");
221 if(iter.val == NULL) sprintbuf(pb, "null");
222 else iter.val->_to_json_string(iter.val, pb);
223 i++;
224 }
225
Michael Clarkf0d08882007-03-13 08:26:18 +0000226 return sprintbuf(pb, " }");
227}
228
229static void json_object_lh_entry_free(struct lh_entry *ent)
230{
231 free(ent->k);
232 json_object_put((struct json_object*)ent->v);
233}
234
Michael Clark266a3fd2009-02-25 01:55:31 +0000235static void json_object_object_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000236{
Michael Clark266a3fd2009-02-25 01:55:31 +0000237 lh_table_free(jso->o.c_object);
238 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000239}
240
Michael Clarke8de0782009-02-25 01:45:00 +0000241struct json_object* json_object_new_object(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000242{
Michael Clark266a3fd2009-02-25 01:55:31 +0000243 struct json_object *jso = json_object_new(json_type_object);
244 if(!jso) return NULL;
245 jso->_delete = &json_object_object_delete;
246 jso->_to_json_string = &json_object_object_to_json_string;
247 jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
Michael Clarkf0d08882007-03-13 08:26:18 +0000248 NULL, &json_object_lh_entry_free);
Michael Clark266a3fd2009-02-25 01:55:31 +0000249 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000250}
251
Michael Clark266a3fd2009-02-25 01:55:31 +0000252struct lh_table* json_object_get_object(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000253{
Michael Clark266a3fd2009-02-25 01:55:31 +0000254 if(!jso) return NULL;
255 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000256 case json_type_object:
Michael Clark266a3fd2009-02-25 01:55:31 +0000257 return jso->o.c_object;
Michael Clarkf0d08882007-03-13 08:26:18 +0000258 default:
259 return NULL;
260 }
261}
262
Michael Clark266a3fd2009-02-25 01:55:31 +0000263void json_object_object_add(struct json_object* jso, const char *key,
Michael Clarkf0d08882007-03-13 08:26:18 +0000264 struct json_object *val)
265{
Michael Clark266a3fd2009-02-25 01:55:31 +0000266 lh_table_delete(jso->o.c_object, key);
267 lh_table_insert(jso->o.c_object, strdup(key), val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000268}
269
Michael Clark266a3fd2009-02-25 01:55:31 +0000270struct json_object* json_object_object_get(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000271{
Michael Clark266a3fd2009-02-25 01:55:31 +0000272 return (struct json_object*) lh_table_lookup(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000273}
274
Michael Clark266a3fd2009-02-25 01:55:31 +0000275void json_object_object_del(struct json_object* jso, const char *key)
Michael Clarkf0d08882007-03-13 08:26:18 +0000276{
Michael Clark266a3fd2009-02-25 01:55:31 +0000277 lh_table_delete(jso->o.c_object, key);
Michael Clarkf0d08882007-03-13 08:26:18 +0000278}
279
280
281/* json_object_boolean */
282
Michael Clark266a3fd2009-02-25 01:55:31 +0000283static int json_object_boolean_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000284 struct printbuf *pb)
285{
Michael Clark266a3fd2009-02-25 01:55:31 +0000286 if(jso->o.c_boolean) return sprintbuf(pb, "true");
Michael Clarkf0d08882007-03-13 08:26:18 +0000287 else return sprintbuf(pb, "false");
288}
289
290struct json_object* json_object_new_boolean(boolean b)
291{
Michael Clark266a3fd2009-02-25 01:55:31 +0000292 struct json_object *jso = json_object_new(json_type_boolean);
293 if(!jso) return NULL;
294 jso->_to_json_string = &json_object_boolean_to_json_string;
295 jso->o.c_boolean = b;
296 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000297}
298
Michael Clark266a3fd2009-02-25 01:55:31 +0000299boolean json_object_get_boolean(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000300{
Michael Clark266a3fd2009-02-25 01:55:31 +0000301 if(!jso) return FALSE;
302 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000303 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000304 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000305 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000306 return (jso->o.c_int != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000307 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000308 return (jso->o.c_double != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000309 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000310 return (strlen(jso->o.c_string) != 0);
Michael Clarkf0d08882007-03-13 08:26:18 +0000311 default:
Michael Clark6f70e442009-04-27 08:19:27 +0000312 return FALSE;
Michael Clarkf0d08882007-03-13 08:26:18 +0000313 }
314}
315
316
317/* json_object_int */
318
Michael Clark266a3fd2009-02-25 01:55:31 +0000319static int json_object_int_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000320 struct printbuf *pb)
321{
Michael Clark266a3fd2009-02-25 01:55:31 +0000322 return sprintbuf(pb, "%d", jso->o.c_int);
Michael Clarkf0d08882007-03-13 08:26:18 +0000323}
324
325struct json_object* json_object_new_int(int i)
326{
Michael Clark266a3fd2009-02-25 01:55:31 +0000327 struct json_object *jso = json_object_new(json_type_int);
328 if(!jso) return NULL;
329 jso->_to_json_string = &json_object_int_to_json_string;
330 jso->o.c_int = i;
331 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000332}
333
Michael Clark266a3fd2009-02-25 01:55:31 +0000334int json_object_get_int(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000335{
336 int cint;
337
Michael Clark266a3fd2009-02-25 01:55:31 +0000338 if(!jso) return 0;
339 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000340 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000341 return jso->o.c_int;
Michael Clarkf0d08882007-03-13 08:26:18 +0000342 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000343 return (int)jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000344 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000345 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000346 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000347 if(sscanf(jso->o.c_string, "%d", &cint) == 1) return cint;
Michael Clarkf0d08882007-03-13 08:26:18 +0000348 default:
349 return 0;
350 }
351}
352
353
354/* json_object_double */
355
Michael Clark266a3fd2009-02-25 01:55:31 +0000356static int json_object_double_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000357 struct printbuf *pb)
358{
Michael Clark266a3fd2009-02-25 01:55:31 +0000359 return sprintbuf(pb, "%lf", jso->o.c_double);
Michael Clarkf0d08882007-03-13 08:26:18 +0000360}
361
362struct json_object* json_object_new_double(double d)
363{
Michael Clark266a3fd2009-02-25 01:55:31 +0000364 struct json_object *jso = json_object_new(json_type_double);
365 if(!jso) return NULL;
366 jso->_to_json_string = &json_object_double_to_json_string;
367 jso->o.c_double = d;
368 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000369}
370
Michael Clark266a3fd2009-02-25 01:55:31 +0000371double json_object_get_double(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000372{
373 double cdouble;
374
Michael Clark266a3fd2009-02-25 01:55:31 +0000375 if(!jso) return 0.0;
376 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000377 case json_type_double:
Michael Clark266a3fd2009-02-25 01:55:31 +0000378 return jso->o.c_double;
Michael Clarkf0d08882007-03-13 08:26:18 +0000379 case json_type_int:
Michael Clark266a3fd2009-02-25 01:55:31 +0000380 return jso->o.c_int;
Michael Clarkf0d08882007-03-13 08:26:18 +0000381 case json_type_boolean:
Michael Clark266a3fd2009-02-25 01:55:31 +0000382 return jso->o.c_boolean;
Michael Clarkf0d08882007-03-13 08:26:18 +0000383 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000384 if(sscanf(jso->o.c_string, "%lf", &cdouble) == 1) return cdouble;
Michael Clarkf0d08882007-03-13 08:26:18 +0000385 default:
386 return 0.0;
387 }
388}
389
390
391/* json_object_string */
392
Michael Clark266a3fd2009-02-25 01:55:31 +0000393static int json_object_string_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000394 struct printbuf *pb)
395{
396 sprintbuf(pb, "\"");
Michael Clark266a3fd2009-02-25 01:55:31 +0000397 json_escape_str(pb, jso->o.c_string);
Michael Clarkf0d08882007-03-13 08:26:18 +0000398 sprintbuf(pb, "\"");
399 return 0;
400}
401
Michael Clark266a3fd2009-02-25 01:55:31 +0000402static void json_object_string_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000403{
Michael Clark266a3fd2009-02-25 01:55:31 +0000404 free(jso->o.c_string);
405 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000406}
407
Michael Clark68cafad2009-01-06 22:56:57 +0000408struct json_object* json_object_new_string(const char *s)
Michael Clarkf0d08882007-03-13 08:26:18 +0000409{
Michael Clark266a3fd2009-02-25 01:55:31 +0000410 struct json_object *jso = json_object_new(json_type_string);
411 if(!jso) return NULL;
412 jso->_delete = &json_object_string_delete;
413 jso->_to_json_string = &json_object_string_to_json_string;
414 jso->o.c_string = strdup(s);
415 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000416}
417
Michael Clark68cafad2009-01-06 22:56:57 +0000418struct json_object* json_object_new_string_len(const char *s, int len)
Michael Clarkf0d08882007-03-13 08:26:18 +0000419{
Michael Clark266a3fd2009-02-25 01:55:31 +0000420 struct json_object *jso = json_object_new(json_type_string);
421 if(!jso) return NULL;
422 jso->_delete = &json_object_string_delete;
423 jso->_to_json_string = &json_object_string_to_json_string;
424 jso->o.c_string = strndup(s, len);
425 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000426}
427
Michael Clark266a3fd2009-02-25 01:55:31 +0000428const char* json_object_get_string(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000429{
Michael Clark266a3fd2009-02-25 01:55:31 +0000430 if(!jso) return NULL;
431 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000432 case json_type_string:
Michael Clark266a3fd2009-02-25 01:55:31 +0000433 return jso->o.c_string;
Michael Clarkf0d08882007-03-13 08:26:18 +0000434 default:
Michael Clark266a3fd2009-02-25 01:55:31 +0000435 return json_object_to_json_string(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000436 }
437}
438
439
440/* json_object_array */
441
Michael Clark266a3fd2009-02-25 01:55:31 +0000442static int json_object_array_to_json_string(struct json_object* jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000443 struct printbuf *pb)
444{
Michael Clark4504df72007-03-13 08:26:20 +0000445 int i;
Michael Clarkf0d08882007-03-13 08:26:18 +0000446 sprintbuf(pb, "[");
Michael Clark266a3fd2009-02-25 01:55:31 +0000447 for(i=0; i < json_object_array_length(jso); i++) {
Michael Clark4504df72007-03-13 08:26:20 +0000448 struct json_object *val;
449 if(i) { sprintbuf(pb, ", "); }
450 else { sprintbuf(pb, " "); }
451
Michael Clark266a3fd2009-02-25 01:55:31 +0000452 val = json_object_array_get_idx(jso, i);
Michael Clark4504df72007-03-13 08:26:20 +0000453 if(val == NULL) { sprintbuf(pb, "null"); }
454 else { val->_to_json_string(val, pb); }
Michael Clarkf0d08882007-03-13 08:26:18 +0000455 }
456 return sprintbuf(pb, " ]");
457}
458
459static void json_object_array_entry_free(void *data)
460{
461 json_object_put((struct json_object*)data);
462}
463
Michael Clark266a3fd2009-02-25 01:55:31 +0000464static void json_object_array_delete(struct json_object* jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000465{
Michael Clark266a3fd2009-02-25 01:55:31 +0000466 array_list_free(jso->o.c_array);
467 json_object_generic_delete(jso);
Michael Clarkf0d08882007-03-13 08:26:18 +0000468}
469
Michael Clarke8de0782009-02-25 01:45:00 +0000470struct json_object* json_object_new_array(void)
Michael Clarkf0d08882007-03-13 08:26:18 +0000471{
Michael Clark266a3fd2009-02-25 01:55:31 +0000472 struct json_object *jso = json_object_new(json_type_array);
473 if(!jso) return NULL;
474 jso->_delete = &json_object_array_delete;
475 jso->_to_json_string = &json_object_array_to_json_string;
476 jso->o.c_array = array_list_new(&json_object_array_entry_free);
477 return jso;
Michael Clarkf0d08882007-03-13 08:26:18 +0000478}
479
Michael Clark266a3fd2009-02-25 01:55:31 +0000480struct array_list* json_object_get_array(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000481{
Michael Clark266a3fd2009-02-25 01:55:31 +0000482 if(!jso) return NULL;
483 switch(jso->o_type) {
Michael Clarkf0d08882007-03-13 08:26:18 +0000484 case json_type_array:
Michael Clark266a3fd2009-02-25 01:55:31 +0000485 return jso->o.c_array;
Michael Clarkf0d08882007-03-13 08:26:18 +0000486 default:
487 return NULL;
488 }
489}
490
Michael Clark266a3fd2009-02-25 01:55:31 +0000491int json_object_array_length(struct json_object *jso)
Michael Clarkf0d08882007-03-13 08:26:18 +0000492{
Michael Clark266a3fd2009-02-25 01:55:31 +0000493 return array_list_length(jso->o.c_array);
Michael Clarkf0d08882007-03-13 08:26:18 +0000494}
495
Michael Clark266a3fd2009-02-25 01:55:31 +0000496int json_object_array_add(struct json_object *jso,struct json_object *val)
Michael Clarkf0d08882007-03-13 08:26:18 +0000497{
Michael Clark266a3fd2009-02-25 01:55:31 +0000498 return array_list_add(jso->o.c_array, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000499}
500
Michael Clark266a3fd2009-02-25 01:55:31 +0000501int json_object_array_put_idx(struct json_object *jso, int idx,
Michael Clarkf0d08882007-03-13 08:26:18 +0000502 struct json_object *val)
503{
Michael Clark266a3fd2009-02-25 01:55:31 +0000504 return array_list_put_idx(jso->o.c_array, idx, val);
Michael Clarkf0d08882007-03-13 08:26:18 +0000505}
506
Michael Clark266a3fd2009-02-25 01:55:31 +0000507struct json_object* json_object_array_get_idx(struct json_object *jso,
Michael Clarkf0d08882007-03-13 08:26:18 +0000508 int idx)
509{
Michael Clark266a3fd2009-02-25 01:55:31 +0000510 return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
Michael Clarkf0d08882007-03-13 08:26:18 +0000511}
512