• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $Id: json_object.c,v 1.17 2006/07/25 03:24:50 mclark Exp $
3  *
4  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5  * Michael Clark <michael@metaparadigm.com>
6  * Copyright (c) 2009 Hewlett-Packard Development Company, L.P.
7  *
8  * 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.
10  *
11  */
12 
13 #include "config.h"
14 
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <stddef.h>
18 #include <string.h>
19 #include <math.h>
20 #include <errno.h>
21 
22 #include "debug.h"
23 #include "printbuf.h"
24 #include "linkhash.h"
25 #include "arraylist.h"
26 #include "json_inttypes.h"
27 #include "json_object.h"
28 #include "json_object_private.h"
29 #include "json_util.h"
30 #include "math_compat.h"
31 
32 #if !defined(HAVE_STRDUP) && defined(_MSC_VER)
33   /* MSC has the version as _strdup */
34 # define strdup _strdup
35 #elif !defined(HAVE_STRDUP)
36 # error You do not have strdup on your system.
37 #endif /* HAVE_STRDUP */
38 
39 #if !defined(HAVE_SNPRINTF) && defined(_MSC_VER)
40   /* MSC has the version as _snprintf */
41 # define snprintf _snprintf
42 #elif !defined(HAVE_SNPRINTF)
43 # error You do not have snprintf on your system.
44 #endif /* HAVE_SNPRINTF */
45 
46 // Don't define this.  It's not thread-safe.
47 /* #define REFCOUNT_DEBUG 1 */
48 
49 const char *json_number_chars = "0123456789.+-eE";
50 const char *json_hex_chars = "0123456789abcdefABCDEF";
51 
52 static void json_object_generic_delete(struct json_object* jso);
53 static struct json_object* json_object_new(enum json_type o_type);
54 
55 static json_object_to_json_string_fn json_object_object_to_json_string;
56 static json_object_to_json_string_fn json_object_boolean_to_json_string;
57 static json_object_to_json_string_fn json_object_int_to_json_string;
58 static json_object_to_json_string_fn json_object_double_to_json_string;
59 static json_object_to_json_string_fn json_object_string_to_json_string;
60 static json_object_to_json_string_fn json_object_array_to_json_string;
61 
62 
63 /* ref count debugging */
64 
65 #ifdef REFCOUNT_DEBUG
66 
67 static struct lh_table *json_object_table;
68 
69 static void json_object_init(void) __attribute__ ((constructor));
json_object_init(void)70 static void json_object_init(void) {
71 	MC_DEBUG("json_object_init: creating object table\n");
72 	json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
73 }
74 
75 static void json_object_fini(void) __attribute__ ((destructor));
json_object_fini(void)76 static void json_object_fini(void)
77 {
78 	struct lh_entry *ent;
79 	if (MC_GET_DEBUG())
80 	{
81 		if (json_object_table->count)
82 		{
83 			MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
84 			   json_object_table->count);
85 			lh_foreach(json_object_table, ent)
86 			{
87 				struct json_object* obj = (struct json_object*)ent->v;
88 				MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
89 			}
90 		}
91 	}
92 	MC_DEBUG("json_object_fini: freeing object table\n");
93 	lh_table_free(json_object_table);
94 }
95 #endif /* REFCOUNT_DEBUG */
96 
97 
98 /* string escaping */
99 
json_escape_str(struct printbuf * pb,char * str,int len)100 static int json_escape_str(struct printbuf *pb, char *str, int len)
101 {
102 	int pos = 0, start_offset = 0;
103 	unsigned char c;
104 	while (len--)
105 	{
106 		c = str[pos];
107 		switch(c)
108 		{
109 		case '\b':
110 		case '\n':
111 		case '\r':
112 		case '\t':
113 		case '\f':
114 		case '"':
115 		case '\\':
116 		case '/':
117 			if(pos - start_offset > 0)
118 				printbuf_memappend(pb, str + start_offset, pos - start_offset);
119 
120 			if(c == '\b') printbuf_memappend(pb, "\\b", 2);
121 			else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
122 			else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
123 			else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
124 			else if(c == '\f') printbuf_memappend(pb, "\\f", 2);
125 			else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
126 			else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
127 			else if(c == '/') printbuf_memappend(pb, "\\/", 2);
128 
129 			start_offset = ++pos;
130 			break;
131 		default:
132 			if(c < ' ')
133 			{
134 				if(pos - start_offset > 0)
135 				printbuf_memappend(pb, str + start_offset, pos - start_offset);
136 				sprintbuf(pb, "\\u00%c%c",
137 				json_hex_chars[c >> 4],
138 				json_hex_chars[c & 0xf]);
139 				start_offset = ++pos;
140 			} else
141 				pos++;
142 		}
143 	}
144 	if (pos - start_offset > 0)
145 		printbuf_memappend(pb, str + start_offset, pos - start_offset);
146 	return 0;
147 }
148 
149 
150 /* reference counting */
151 
json_object_get(struct json_object * jso)152 extern struct json_object* json_object_get(struct json_object *jso)
153 {
154 	if (jso)
155 		jso->_ref_count++;
156 	return jso;
157 }
158 
json_object_put(struct json_object * jso)159 int json_object_put(struct json_object *jso)
160 {
161 	if(jso)
162 	{
163 		jso->_ref_count--;
164 		if(!jso->_ref_count)
165 		{
166 			if (jso->_user_delete)
167 				jso->_user_delete(jso, jso->_userdata);
168 			jso->_delete(jso);
169 			return 1;
170 		}
171 	}
172 	return 0;
173 }
174 
175 
176 /* generic object construction and destruction parts */
177 
json_object_generic_delete(struct json_object * jso)178 static void json_object_generic_delete(struct json_object* jso)
179 {
180 #ifdef REFCOUNT_DEBUG
181 	MC_DEBUG("json_object_delete_%s: %p\n",
182 	   json_type_to_name(jso->o_type), jso);
183 	lh_table_delete(json_object_table, jso);
184 #endif /* REFCOUNT_DEBUG */
185 	printbuf_free(jso->_pb);
186 	free(jso);
187 }
188 
json_object_new(enum json_type o_type)189 static struct json_object* json_object_new(enum json_type o_type)
190 {
191 	struct json_object *jso;
192 
193 	jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
194 	if (!jso)
195 		return NULL;
196 	jso->o_type = o_type;
197 	jso->_ref_count = 1;
198 	jso->_delete = &json_object_generic_delete;
199 #ifdef REFCOUNT_DEBUG
200 	lh_table_insert(json_object_table, jso, jso);
201 	MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
202 #endif /* REFCOUNT_DEBUG */
203 	return jso;
204 }
205 
206 
207 /* type checking functions */
208 
json_object_is_type(struct json_object * jso,enum json_type type)209 int json_object_is_type(struct json_object *jso, enum json_type type)
210 {
211 	if (!jso)
212 		return (type == json_type_null);
213 	return (jso->o_type == type);
214 }
215 
json_object_get_type(struct json_object * jso)216 enum json_type json_object_get_type(struct json_object *jso)
217 {
218 	if (!jso)
219 		return json_type_null;
220 	return jso->o_type;
221 }
222 
223 /* set a custom conversion to string */
224 
json_object_set_serializer(json_object * jso,json_object_to_json_string_fn to_string_func,void * userdata,json_object_delete_fn * user_delete)225 void json_object_set_serializer(json_object *jso,
226 	json_object_to_json_string_fn to_string_func,
227 	void *userdata,
228 	json_object_delete_fn *user_delete)
229 {
230 	// First, clean up any previously existing user info
231 	if (jso->_user_delete)
232 	{
233 		jso->_user_delete(jso, jso->_userdata);
234 	}
235 	jso->_userdata = NULL;
236 	jso->_user_delete = NULL;
237 
238 	if (to_string_func == NULL)
239 	{
240 		// Reset to the standard serialization function
241 		switch(jso->o_type)
242 		{
243 		case json_type_null:
244 			jso->_to_json_string = NULL;
245 			break;
246 		case json_type_boolean:
247 			jso->_to_json_string = &json_object_boolean_to_json_string;
248 			break;
249 		case json_type_double:
250 			jso->_to_json_string = &json_object_double_to_json_string;
251 			break;
252 		case json_type_int:
253 			jso->_to_json_string = &json_object_int_to_json_string;
254 			break;
255 		case json_type_object:
256 			jso->_to_json_string = &json_object_object_to_json_string;
257 			break;
258 		case json_type_array:
259 			jso->_to_json_string = &json_object_array_to_json_string;
260 			break;
261 		case json_type_string:
262 			jso->_to_json_string = &json_object_string_to_json_string;
263 			break;
264 		}
265 		return;
266 	}
267 
268 	jso->_to_json_string = to_string_func;
269 	jso->_userdata = userdata;
270 	jso->_user_delete = user_delete;
271 }
272 
273 
274 /* extended conversion to string */
275 
json_object_to_json_string_ext(struct json_object * jso,int flags)276 const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
277 {
278 	if (!jso)
279 		return "null";
280 
281 	if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
282 		return NULL;
283 
284 	printbuf_reset(jso->_pb);
285 
286 	if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
287 		return NULL;
288 
289 	return jso->_pb->buf;
290 }
291 
292 /* backwards-compatible conversion to string */
293 
json_object_to_json_string(struct json_object * jso)294 const char* json_object_to_json_string(struct json_object *jso)
295 {
296 	return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
297 }
298 
indent(struct printbuf * pb,int level,int flags)299 static void indent(struct printbuf *pb, int level, int flags)
300 {
301 	if (flags & JSON_C_TO_STRING_PRETTY)
302 	{
303 		printbuf_memset(pb, -1, ' ', level * 2);
304 	}
305 }
306 
307 /* json_object_object */
308 
json_object_object_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)309 static int json_object_object_to_json_string(struct json_object* jso,
310 					     struct printbuf *pb,
311 					     int level,
312 						 int flags)
313 {
314 	int had_children = 0;
315 	struct json_object_iter iter;
316 
317 	sprintbuf(pb, "{" /*}*/);
318 	if (flags & JSON_C_TO_STRING_PRETTY)
319 		sprintbuf(pb, "\n");
320 	json_object_object_foreachC(jso, iter)
321 	{
322 		if (had_children)
323 		{
324 			sprintbuf(pb, ",");
325 			if (flags & JSON_C_TO_STRING_PRETTY)
326 				sprintbuf(pb, "\n");
327 		}
328 		had_children = 1;
329 		if (flags & JSON_C_TO_STRING_SPACED)
330 			sprintbuf(pb, " ");
331 		indent(pb, level+1, flags);
332 		sprintbuf(pb, "\"");
333 		json_escape_str(pb, iter.key, strlen(iter.key));
334 		if (flags & JSON_C_TO_STRING_SPACED)
335 			sprintbuf(pb, "\": ");
336 		else
337 			sprintbuf(pb, "\":");
338 		if(iter.val == NULL)
339 			sprintbuf(pb, "null");
340 		else
341 			iter.val->_to_json_string(iter.val, pb, level+1,flags);
342 	}
343 	if (flags & JSON_C_TO_STRING_PRETTY)
344 	{
345 		if (had_children)
346 			sprintbuf(pb, "\n");
347 		indent(pb,level,flags);
348 	}
349 	if (flags & JSON_C_TO_STRING_SPACED)
350 		return sprintbuf(pb, /*{*/ " }");
351 	else
352 		return sprintbuf(pb, /*{*/ "}");
353 }
354 
355 
json_object_lh_entry_free(struct lh_entry * ent)356 static void json_object_lh_entry_free(struct lh_entry *ent)
357 {
358 	free(ent->k);
359 	json_object_put((struct json_object*)ent->v);
360 }
361 
json_object_object_delete(struct json_object * jso)362 static void json_object_object_delete(struct json_object* jso)
363 {
364 	lh_table_free(jso->o.c_object);
365 	json_object_generic_delete(jso);
366 }
367 
json_object_new_object(void)368 struct json_object* json_object_new_object(void)
369 {
370 	struct json_object *jso = json_object_new(json_type_object);
371 	if (!jso)
372 		return NULL;
373 	jso->_delete = &json_object_object_delete;
374 	jso->_to_json_string = &json_object_object_to_json_string;
375 	jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
376 					NULL, &json_object_lh_entry_free);
377 	if (!jso->o.c_object)
378 	{
379 		json_object_generic_delete(jso);
380 		errno = ENOMEM;
381 		return NULL;
382 	}
383 	return jso;
384 }
385 
json_object_get_object(struct json_object * jso)386 struct lh_table* json_object_get_object(struct json_object *jso)
387 {
388 	if (!jso)
389 		return NULL;
390 	switch(jso->o_type)
391 	{
392 	case json_type_object:
393 		return jso->o.c_object;
394 	default:
395 		return NULL;
396 	}
397 }
398 
json_object_object_add(struct json_object * jso,const char * key,struct json_object * val)399 void json_object_object_add(struct json_object* jso, const char *key,
400 			    struct json_object *val)
401 {
402 	// We lookup the entry and replace the value, rather than just deleting
403 	// and re-adding it, so the existing key remains valid.
404 	json_object *existing_value = NULL;
405 	struct lh_entry *existing_entry;
406 	existing_entry = lh_table_lookup_entry(jso->o.c_object, (void*)key);
407 	if (!existing_entry)
408 	{
409 		lh_table_insert(jso->o.c_object, strdup(key), val);
410 		return;
411 	}
412 	existing_value = (void *)existing_entry->v;
413 	if (existing_value)
414 		json_object_put(existing_value);
415 	existing_entry->v = val;
416 }
417 
json_object_object_length(struct json_object * jso)418 int json_object_object_length(struct json_object *jso)
419 {
420 	return lh_table_length(jso->o.c_object);
421 }
422 
json_object_object_get(struct json_object * jso,const char * key)423 struct json_object* json_object_object_get(struct json_object* jso, const char *key)
424 {
425 	struct json_object *result = NULL;
426 	json_object_object_get_ex(jso, key, &result);
427 	return result;
428 }
429 
json_object_object_get_ex(struct json_object * jso,const char * key,struct json_object ** value)430 json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
431 {
432 	if (value != NULL)
433 		*value = NULL;
434 
435 	if (NULL == jso)
436 		return FALSE;
437 
438 	switch(jso->o_type)
439 	{
440 	case json_type_object:
441 		return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
442 	default:
443 		if (value != NULL)
444 			*value = NULL;
445 		return FALSE;
446 	}
447 }
448 
json_object_object_del(struct json_object * jso,const char * key)449 void json_object_object_del(struct json_object* jso, const char *key)
450 {
451 	lh_table_delete(jso->o.c_object, key);
452 }
453 
454 
455 /* json_object_boolean */
456 
json_object_boolean_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)457 static int json_object_boolean_to_json_string(struct json_object* jso,
458 					      struct printbuf *pb,
459 					      int level,
460 						  int flags)
461 {
462 	if (jso->o.c_boolean)
463 		return sprintbuf(pb, "true");
464 	else
465 		return sprintbuf(pb, "false");
466 }
467 
json_object_new_boolean(json_bool b)468 struct json_object* json_object_new_boolean(json_bool b)
469 {
470 	struct json_object *jso = json_object_new(json_type_boolean);
471 	if (!jso)
472 		return NULL;
473 	jso->_to_json_string = &json_object_boolean_to_json_string;
474 	jso->o.c_boolean = b;
475 	return jso;
476 }
477 
json_object_get_boolean(struct json_object * jso)478 json_bool json_object_get_boolean(struct json_object *jso)
479 {
480 	if (!jso)
481 		return FALSE;
482 	switch(jso->o_type)
483 	{
484 	case json_type_boolean:
485 		return jso->o.c_boolean;
486 	case json_type_int:
487 		return (jso->o.c_int64 != 0);
488 	case json_type_double:
489 		return (jso->o.c_double != 0);
490 	case json_type_string:
491 		return (jso->o.c_string.len != 0);
492 	default:
493 		return FALSE;
494 	}
495 }
496 
497 
498 /* json_object_int */
499 
json_object_int_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)500 static int json_object_int_to_json_string(struct json_object* jso,
501 					  struct printbuf *pb,
502 					  int level,
503 					  int flags)
504 {
505 	return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
506 }
507 
json_object_new_int(int32_t i)508 struct json_object* json_object_new_int(int32_t i)
509 {
510 	struct json_object *jso = json_object_new(json_type_int);
511 	if (!jso)
512 		return NULL;
513 	jso->_to_json_string = &json_object_int_to_json_string;
514 	jso->o.c_int64 = i;
515 	return jso;
516 }
517 
json_object_get_int(struct json_object * jso)518 int32_t json_object_get_int(struct json_object *jso)
519 {
520   int64_t cint64;
521   enum json_type o_type;
522 
523   if(!jso) return 0;
524 
525   o_type = jso->o_type;
526   cint64 = jso->o.c_int64;
527 
528   if (o_type == json_type_string)
529   {
530 	/*
531 	 * Parse strings into 64-bit numbers, then use the
532 	 * 64-to-32-bit number handling below.
533 	 */
534 	if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
535 		return 0; /* whoops, it didn't work. */
536 	o_type = json_type_int;
537   }
538 
539   switch(o_type) {
540   case json_type_int:
541 	/* Make sure we return the correct values for out of range numbers. */
542 	if (cint64 <= INT32_MIN)
543 		return INT32_MIN;
544 	else if (cint64 >= INT32_MAX)
545 		return INT32_MAX;
546 	else
547 		return (int32_t)cint64;
548   case json_type_double:
549     return (int32_t)jso->o.c_double;
550   case json_type_boolean:
551     return jso->o.c_boolean;
552   default:
553     return 0;
554   }
555 }
556 
json_object_new_int64(int64_t i)557 struct json_object* json_object_new_int64(int64_t i)
558 {
559 	struct json_object *jso = json_object_new(json_type_int);
560 	if (!jso)
561 		return NULL;
562 	jso->_to_json_string = &json_object_int_to_json_string;
563 	jso->o.c_int64 = i;
564 	return jso;
565 }
566 
json_object_get_int64(struct json_object * jso)567 int64_t json_object_get_int64(struct json_object *jso)
568 {
569 	int64_t cint;
570 
571 	if (!jso)
572 		return 0;
573 	switch(jso->o_type)
574 	{
575 	case json_type_int:
576 		return jso->o.c_int64;
577 	case json_type_double:
578 		return (int64_t)jso->o.c_double;
579 	case json_type_boolean:
580 		return jso->o.c_boolean;
581 	case json_type_string:
582 		if (json_parse_int64(jso->o.c_string.str, &cint) == 0)
583 			return cint;
584 	default:
585 		return 0;
586 	}
587 }
588 
589 
590 /* json_object_double */
591 
json_object_double_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)592 static int json_object_double_to_json_string(struct json_object* jso,
593 					     struct printbuf *pb,
594 					     int level,
595 						 int flags)
596 {
597   char buf[128], *p, *q;
598   int size;
599   /* Although JSON RFC does not support
600      NaN or Infinity as numeric values
601      ECMA 262 section 9.8.1 defines
602      how to handle these cases as strings */
603   if(isnan(jso->o.c_double))
604     size = snprintf(buf, sizeof(buf), "NaN");
605   else if(isinf(jso->o.c_double))
606     if(jso->o.c_double > 0)
607       size = snprintf(buf, sizeof(buf), "Infinity");
608     else
609       size = snprintf(buf, sizeof(buf), "-Infinity");
610   else
611     size = snprintf(buf, sizeof(buf), "%.17g", jso->o.c_double);
612 
613   p = strchr(buf, ',');
614   if (p) {
615     *p = '.';
616   } else {
617     p = strchr(buf, '.');
618   }
619   if (p && (flags & JSON_C_TO_STRING_NOZERO)) {
620     /* last useful digit, always keep 1 zero */
621     p++;
622     for (q=p ; *q ; q++) {
623       if (*q!='0') p=q;
624     }
625     /* drop trailing zeroes */
626     *(++p) = 0;
627     size = p-buf;
628   }
629   printbuf_memappend(pb, buf, size);
630   return size;
631 }
632 
json_object_new_double(double d)633 struct json_object* json_object_new_double(double d)
634 {
635 	struct json_object *jso = json_object_new(json_type_double);
636 	if (!jso)
637 		return NULL;
638 	jso->_to_json_string = &json_object_double_to_json_string;
639 	jso->o.c_double = d;
640 	return jso;
641 }
642 
json_object_new_double_s(double d,const char * ds)643 struct json_object* json_object_new_double_s(double d, const char *ds)
644 {
645 	struct json_object *jso = json_object_new_double(d);
646 	if (!jso)
647 		return NULL;
648 
649 	char *new_ds = strdup(ds);
650 	if (!new_ds)
651 	{
652 		json_object_generic_delete(jso);
653 		errno = ENOMEM;
654 		return NULL;
655 	}
656 	json_object_set_serializer(jso, json_object_userdata_to_json_string,
657 	    new_ds, json_object_free_userdata);
658 	return jso;
659 }
660 
json_object_userdata_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)661 int json_object_userdata_to_json_string(struct json_object *jso,
662 	struct printbuf *pb, int level, int flags)
663 {
664 	int userdata_len = strlen(jso->_userdata);
665 	printbuf_memappend(pb, jso->_userdata, userdata_len);
666 	return userdata_len;
667 }
668 
json_object_free_userdata(struct json_object * jso,void * userdata)669 void json_object_free_userdata(struct json_object *jso, void *userdata)
670 {
671 	free(userdata);
672 }
673 
json_object_get_double(struct json_object * jso)674 double json_object_get_double(struct json_object *jso)
675 {
676   double cdouble;
677   char *errPtr = NULL;
678 
679   if(!jso) return 0.0;
680   switch(jso->o_type) {
681   case json_type_double:
682     return jso->o.c_double;
683   case json_type_int:
684     return jso->o.c_int64;
685   case json_type_boolean:
686     return jso->o.c_boolean;
687   case json_type_string:
688     errno = 0;
689     cdouble = strtod(jso->o.c_string.str,&errPtr);
690 
691     /* if conversion stopped at the first character, return 0.0 */
692     if (errPtr == jso->o.c_string.str)
693         return 0.0;
694 
695     /*
696      * Check that the conversion terminated on something sensible
697      *
698      * For example, { "pay" : 123AB } would parse as 123.
699      */
700     if (*errPtr != '\0')
701         return 0.0;
702 
703     /*
704      * If strtod encounters a string which would exceed the
705      * capacity of a double, it returns +/- HUGE_VAL and sets
706      * errno to ERANGE. But +/- HUGE_VAL is also a valid result
707      * from a conversion, so we need to check errno.
708      *
709      * Underflow also sets errno to ERANGE, but it returns 0 in
710      * that case, which is what we will return anyway.
711      *
712      * See CERT guideline ERR30-C
713      */
714     if ((HUGE_VAL == cdouble || -HUGE_VAL == cdouble) &&
715         (ERANGE == errno))
716             cdouble = 0.0;
717     return cdouble;
718   default:
719     return 0.0;
720   }
721 }
722 
723 
724 /* json_object_string */
725 
json_object_string_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)726 static int json_object_string_to_json_string(struct json_object* jso,
727 					     struct printbuf *pb,
728 					     int level,
729 						 int flags)
730 {
731 	sprintbuf(pb, "\"");
732 	json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
733 	sprintbuf(pb, "\"");
734 	return 0;
735 }
736 
json_object_string_delete(struct json_object * jso)737 static void json_object_string_delete(struct json_object* jso)
738 {
739 	free(jso->o.c_string.str);
740 	json_object_generic_delete(jso);
741 }
742 
json_object_new_string(const char * s)743 struct json_object* json_object_new_string(const char *s)
744 {
745 	struct json_object *jso = json_object_new(json_type_string);
746 	if (!jso)
747 		return NULL;
748 	jso->_delete = &json_object_string_delete;
749 	jso->_to_json_string = &json_object_string_to_json_string;
750 	jso->o.c_string.str = strdup(s);
751 	if (!jso->o.c_string.str)
752 	{
753 		json_object_generic_delete(jso);
754 		errno = ENOMEM;
755 		return NULL;
756 	}
757 	jso->o.c_string.len = strlen(s);
758 	return jso;
759 }
760 
json_object_new_string_len(const char * s,int len)761 struct json_object* json_object_new_string_len(const char *s, int len)
762 {
763 	struct json_object *jso = json_object_new(json_type_string);
764 	if (!jso)
765 		return NULL;
766 	jso->_delete = &json_object_string_delete;
767 	jso->_to_json_string = &json_object_string_to_json_string;
768 	jso->o.c_string.str = (char*)malloc(len + 1);
769 	if (!jso->o.c_string.str)
770 	{
771 		json_object_generic_delete(jso);
772 		errno = ENOMEM;
773 		return NULL;
774 	}
775 	memcpy(jso->o.c_string.str, (void *)s, len);
776 	jso->o.c_string.str[len] = '\0';
777 	jso->o.c_string.len = len;
778 	return jso;
779 }
780 
json_object_get_string(struct json_object * jso)781 const char* json_object_get_string(struct json_object *jso)
782 {
783 	if (!jso)
784 		return NULL;
785 	switch(jso->o_type)
786 	{
787 	case json_type_string:
788 		return jso->o.c_string.str;
789 	default:
790 		return json_object_to_json_string(jso);
791 	}
792 }
793 
json_object_get_string_len(struct json_object * jso)794 int json_object_get_string_len(struct json_object *jso)
795 {
796 	if (!jso)
797 		return 0;
798 	switch(jso->o_type)
799 	{
800 	case json_type_string:
801 		return jso->o.c_string.len;
802 	default:
803 		return 0;
804 	}
805 }
806 
807 
808 /* json_object_array */
809 
json_object_array_to_json_string(struct json_object * jso,struct printbuf * pb,int level,int flags)810 static int json_object_array_to_json_string(struct json_object* jso,
811                                             struct printbuf *pb,
812                                             int level,
813                                             int flags)
814 {
815 	int had_children = 0;
816 	int ii;
817 	sprintbuf(pb, "[");
818 	if (flags & JSON_C_TO_STRING_PRETTY)
819 		sprintbuf(pb, "\n");
820 	for(ii=0; ii < json_object_array_length(jso); ii++)
821 	{
822 		struct json_object *val;
823 		if (had_children)
824 		{
825 			sprintbuf(pb, ",");
826 			if (flags & JSON_C_TO_STRING_PRETTY)
827 				sprintbuf(pb, "\n");
828 		}
829 		had_children = 1;
830 		if (flags & JSON_C_TO_STRING_SPACED)
831 			sprintbuf(pb, " ");
832 		indent(pb, level + 1, flags);
833 		val = json_object_array_get_idx(jso, ii);
834 		if(val == NULL)
835 			sprintbuf(pb, "null");
836 		else
837 			val->_to_json_string(val, pb, level+1, flags);
838 	}
839 	if (flags & JSON_C_TO_STRING_PRETTY)
840 	{
841 		if (had_children)
842 			sprintbuf(pb, "\n");
843 		indent(pb,level,flags);
844 	}
845 
846 	if (flags & JSON_C_TO_STRING_SPACED)
847 		return sprintbuf(pb, " ]");
848 	else
849 		return sprintbuf(pb, "]");
850 }
851 
json_object_array_entry_free(void * data)852 static void json_object_array_entry_free(void *data)
853 {
854 	json_object_put((struct json_object*)data);
855 }
856 
json_object_array_delete(struct json_object * jso)857 static void json_object_array_delete(struct json_object* jso)
858 {
859 	array_list_free(jso->o.c_array);
860 	json_object_generic_delete(jso);
861 }
862 
json_object_new_array(void)863 struct json_object* json_object_new_array(void)
864 {
865 	struct json_object *jso = json_object_new(json_type_array);
866 	if (!jso)
867 		return NULL;
868 	jso->_delete = &json_object_array_delete;
869 	jso->_to_json_string = &json_object_array_to_json_string;
870 	jso->o.c_array = array_list_new(&json_object_array_entry_free);
871 	return jso;
872 }
873 
json_object_get_array(struct json_object * jso)874 struct array_list* json_object_get_array(struct json_object *jso)
875 {
876 	if (!jso)
877 		return NULL;
878 	switch(jso->o_type)
879 	{
880 	case json_type_array:
881 		return jso->o.c_array;
882 	default:
883 		return NULL;
884 	}
885 }
886 
json_object_array_sort(struct json_object * jso,int (* sort_fn)(const void *,const void *))887 void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
888 {
889 	array_list_sort(jso->o.c_array, sort_fn);
890 }
891 
json_object_array_length(struct json_object * jso)892 int json_object_array_length(struct json_object *jso)
893 {
894 	return array_list_length(jso->o.c_array);
895 }
896 
json_object_array_add(struct json_object * jso,struct json_object * val)897 int json_object_array_add(struct json_object *jso,struct json_object *val)
898 {
899 	return array_list_add(jso->o.c_array, val);
900 }
901 
json_object_array_put_idx(struct json_object * jso,int idx,struct json_object * val)902 int json_object_array_put_idx(struct json_object *jso, int idx,
903 			      struct json_object *val)
904 {
905 	return array_list_put_idx(jso->o.c_array, idx, val);
906 }
907 
json_object_array_get_idx(struct json_object * jso,int idx)908 struct json_object* json_object_array_get_idx(struct json_object *jso,
909 					      int idx)
910 {
911 	return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
912 }
913 
914