Imported Upstream version 0.10
[platform/upstream/json-c.git] / json_object.c
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
20 #include "debug.h"
21 #include "printbuf.h"
22 #include "linkhash.h"
23 #include "arraylist.h"
24 #include "json_inttypes.h"
25 #include "json_object.h"
26 #include "json_object_private.h"
27 #include "json_util.h"
28
29 #if !HAVE_STRNDUP
30   char* strndup(const char* str, size_t n);
31 #endif /* !HAVE_STRNDUP */
32
33 // Don't define this.  It's not thread-safe.
34 /* #define REFCOUNT_DEBUG 1 */
35
36 const char *json_number_chars = "0123456789.+-eE";
37 const char *json_hex_chars = "0123456789abcdefABCDEF";
38
39 static void json_object_generic_delete(struct json_object* jso);
40 static struct json_object* json_object_new(enum json_type o_type);
41
42
43 /* ref count debugging */
44
45 #ifdef REFCOUNT_DEBUG
46
47 static struct lh_table *json_object_table;
48
49 static void json_object_init(void) __attribute__ ((constructor));
50 static void json_object_init(void) {
51   MC_DEBUG("json_object_init: creating object table\n");
52   json_object_table = lh_kptr_table_new(128, "json_object_table", NULL);
53 }
54
55 static void json_object_fini(void) __attribute__ ((destructor));
56 static void json_object_fini(void) {
57   struct lh_entry *ent;
58   if(MC_GET_DEBUG()) {
59     if (json_object_table->count) {
60       MC_DEBUG("json_object_fini: %d referenced objects at exit\n",
61                json_object_table->count);
62       lh_foreach(json_object_table, ent) {
63         struct json_object* obj = (struct json_object*)ent->v;
64         MC_DEBUG("\t%s:%p\n", json_type_to_name(obj->o_type), obj);
65       }
66     }
67   }
68   MC_DEBUG("json_object_fini: freeing object table\n");
69   lh_table_free(json_object_table);
70 }
71 #endif /* REFCOUNT_DEBUG */
72
73
74 /* string escaping */
75
76 static int json_escape_str(struct printbuf *pb, char *str, int len)
77 {
78   int pos = 0, start_offset = 0;
79   unsigned char c;
80   while (len--) {
81     c = str[pos];
82     switch(c) {
83     case '\b':
84     case '\n':
85     case '\r':
86     case '\t':
87     case '"':
88     case '\\':
89     case '/':
90       if(pos - start_offset > 0)
91         printbuf_memappend(pb, str + start_offset, pos - start_offset);
92       if(c == '\b') printbuf_memappend(pb, "\\b", 2);
93       else if(c == '\n') printbuf_memappend(pb, "\\n", 2);
94       else if(c == '\r') printbuf_memappend(pb, "\\r", 2);
95       else if(c == '\t') printbuf_memappend(pb, "\\t", 2);
96       else if(c == '"') printbuf_memappend(pb, "\\\"", 2);
97       else if(c == '\\') printbuf_memappend(pb, "\\\\", 2);
98       else if(c == '/') printbuf_memappend(pb, "\\/", 2);
99       start_offset = ++pos;
100       break;
101     default:
102       if(c < ' ') {
103         if(pos - start_offset > 0)
104           printbuf_memappend(pb, str + start_offset, pos - start_offset);
105         sprintbuf(pb, "\\u00%c%c",
106                   json_hex_chars[c >> 4],
107                   json_hex_chars[c & 0xf]);
108         start_offset = ++pos;
109       } else pos++;
110     }
111   }
112   if(pos - start_offset > 0)
113     printbuf_memappend(pb, str + start_offset, pos - start_offset);
114   return 0;
115 }
116
117
118 /* reference counting */
119
120 extern struct json_object* json_object_get(struct json_object *jso)
121 {
122   if(jso) {
123     jso->_ref_count++;
124   }
125   return jso;
126 }
127
128 extern void json_object_put(struct json_object *jso)
129 {
130   if(jso) {
131     jso->_ref_count--;
132     if(!jso->_ref_count) jso->_delete(jso);
133   }
134 }
135
136
137 /* generic object construction and destruction parts */
138
139 static void json_object_generic_delete(struct json_object* jso)
140 {
141 #ifdef REFCOUNT_DEBUG
142   MC_DEBUG("json_object_delete_%s: %p\n",
143            json_type_to_name(jso->o_type), jso);
144   lh_table_delete(json_object_table, jso);
145 #endif /* REFCOUNT_DEBUG */
146   printbuf_free(jso->_pb);
147   free(jso);
148 }
149
150 static struct json_object* json_object_new(enum json_type o_type)
151 {
152   struct json_object *jso;
153
154   jso = (struct json_object*)calloc(sizeof(struct json_object), 1);
155   if(!jso) return NULL;
156   jso->o_type = o_type;
157   jso->_ref_count = 1;
158   jso->_delete = &json_object_generic_delete;
159 #ifdef REFCOUNT_DEBUG
160   lh_table_insert(json_object_table, jso, jso);
161   MC_DEBUG("json_object_new_%s: %p\n", json_type_to_name(jso->o_type), jso);
162 #endif /* REFCOUNT_DEBUG */
163   return jso;
164 }
165
166
167 /* type checking functions */
168
169 int json_object_is_type(struct json_object *jso, enum json_type type)
170 {
171   if (!jso)
172     return (type == json_type_null);
173   return (jso->o_type == type);
174 }
175
176 enum json_type json_object_get_type(struct json_object *jso)
177 {
178   if (!jso)
179     return json_type_null;
180   return jso->o_type;
181 }
182
183 /* extended conversion to string */
184
185 const char* json_object_to_json_string_ext(struct json_object *jso, int flags)
186 {
187         if (!jso)
188                 return "null";
189
190         if ((!jso->_pb) && !(jso->_pb = printbuf_new()))
191                 return NULL;
192
193         printbuf_reset(jso->_pb);
194
195         if(jso->_to_json_string(jso, jso->_pb, 0, flags) < 0)
196                 return NULL;
197
198         return jso->_pb->buf;
199 }
200
201 /* backwards-compatible conversion to string */
202
203 const char* json_object_to_json_string(struct json_object *jso)
204 {
205         return json_object_to_json_string_ext(jso, JSON_C_TO_STRING_SPACED);
206 }
207
208 static void indent(struct printbuf *pb, int level, int flags)
209 {
210         if (flags & JSON_C_TO_STRING_PRETTY)
211         {
212                 printbuf_memset(pb, -1, ' ', level * 2);
213         }
214 }
215
216 /* json_object_object */
217
218 static int json_object_object_to_json_string(struct json_object* jso,
219                                              struct printbuf *pb,
220                                              int level,
221                                                  int flags)
222 {
223         int had_children = 0;
224         struct json_object_iter iter;
225
226         sprintbuf(pb, "{" /*}*/);
227         if (flags & JSON_C_TO_STRING_PRETTY)
228                 sprintbuf(pb, "\n");
229         json_object_object_foreachC(jso, iter)
230         {
231                 if (had_children)
232                 {
233                         sprintbuf(pb, ",");
234                         if (flags & JSON_C_TO_STRING_PRETTY)
235                                 sprintbuf(pb, "\n");
236                 }
237                 had_children = 1;
238                 if (flags & JSON_C_TO_STRING_SPACED)
239                         sprintbuf(pb, " ");
240                 indent(pb, level+1, flags);
241                 sprintbuf(pb, "\"");
242                 json_escape_str(pb, iter.key, strlen(iter.key));
243                 if (flags & JSON_C_TO_STRING_SPACED)
244                         sprintbuf(pb, "\": ");
245                 else
246                         sprintbuf(pb, "\":");
247                 if(iter.val == NULL)
248                         sprintbuf(pb, "null");
249                 else
250                         iter.val->_to_json_string(iter.val, pb, level+1,flags);
251         }
252         if (flags & JSON_C_TO_STRING_PRETTY)
253         {
254                 if (had_children)
255                         sprintbuf(pb, "\n");
256                 indent(pb,level,flags);
257         }
258         if (flags & JSON_C_TO_STRING_SPACED)
259                 return sprintbuf(pb, /*{*/ " }");
260         else
261                 return sprintbuf(pb, /*{*/ "}");
262 }
263
264
265 static void json_object_lh_entry_free(struct lh_entry *ent)
266 {
267   free(ent->k);
268   json_object_put((struct json_object*)ent->v);
269 }
270
271 static void json_object_object_delete(struct json_object* jso)
272 {
273   lh_table_free(jso->o.c_object);
274   json_object_generic_delete(jso);
275 }
276
277 struct json_object* json_object_new_object(void)
278 {
279   struct json_object *jso = json_object_new(json_type_object);
280   if(!jso) return NULL;
281   jso->_delete = &json_object_object_delete;
282   jso->_to_json_string = &json_object_object_to_json_string;
283   jso->o.c_object = lh_kchar_table_new(JSON_OBJECT_DEF_HASH_ENTRIES,
284                                         NULL, &json_object_lh_entry_free);
285   return jso;
286 }
287
288 struct lh_table* json_object_get_object(struct json_object *jso)
289 {
290   if(!jso) return NULL;
291   switch(jso->o_type) {
292   case json_type_object:
293     return jso->o.c_object;
294   default:
295     return NULL;
296   }
297 }
298
299 void json_object_object_add(struct json_object* jso, const char *key,
300                             struct json_object *val)
301 {
302   lh_table_delete(jso->o.c_object, key);
303   lh_table_insert(jso->o.c_object, strdup(key), val);
304 }
305
306 struct json_object* json_object_object_get(struct json_object* jso, const char *key)
307 {
308   struct json_object *result;
309   json_object_object_get_ex(jso, key, &result);
310   return result;
311 }
312
313 json_bool json_object_object_get_ex(struct json_object* jso, const char *key, struct json_object **value)
314 {
315   if (NULL == jso) return FALSE;
316
317   switch(jso->o_type) {
318   case json_type_object:
319     return lh_table_lookup_ex(jso->o.c_object, (void*)key, (void**)value);
320   default:
321     if (value != NULL) {
322       *value = NULL;
323     }
324     return FALSE;
325   }
326 }
327
328 void json_object_object_del(struct json_object* jso, const char *key)
329 {
330   lh_table_delete(jso->o.c_object, key);
331 }
332
333
334 /* json_object_boolean */
335
336 static int json_object_boolean_to_json_string(struct json_object* jso,
337                                               struct printbuf *pb,
338                                               int level,
339                                                   int flags)
340 {
341   if(jso->o.c_boolean) return sprintbuf(pb, "true");
342   else return sprintbuf(pb, "false");
343 }
344
345 struct json_object* json_object_new_boolean(json_bool b)
346 {
347   struct json_object *jso = json_object_new(json_type_boolean);
348   if(!jso) return NULL;
349   jso->_to_json_string = &json_object_boolean_to_json_string;
350   jso->o.c_boolean = b;
351   return jso;
352 }
353
354 json_bool json_object_get_boolean(struct json_object *jso)
355 {
356   if(!jso) return FALSE;
357   switch(jso->o_type) {
358   case json_type_boolean:
359     return jso->o.c_boolean;
360   case json_type_int:
361     return (jso->o.c_int64 != 0);
362   case json_type_double:
363     return (jso->o.c_double != 0);
364   case json_type_string:
365     return (jso->o.c_string.len != 0);
366   default:
367     return FALSE;
368   }
369 }
370
371
372 /* json_object_int */
373
374 static int json_object_int_to_json_string(struct json_object* jso,
375                                           struct printbuf *pb,
376                                           int level,
377                                           int flags)
378 {
379   return sprintbuf(pb, "%"PRId64, jso->o.c_int64);
380 }
381
382 struct json_object* json_object_new_int(int32_t i)
383 {
384   struct json_object *jso = json_object_new(json_type_int);
385   if(!jso) return NULL;
386   jso->_to_json_string = &json_object_int_to_json_string;
387   jso->o.c_int64 = i;
388   return jso;
389 }
390
391 int32_t json_object_get_int(struct json_object *jso)
392 {
393   int64_t cint64;
394   enum json_type o_type;
395
396   if(!jso) return 0;
397
398   o_type = jso->o_type;
399   cint64 = jso->o.c_int64;
400
401   if (o_type == json_type_string)
402   {
403         /*
404          * Parse strings into 64-bit numbers, then use the
405          * 64-to-32-bit number handling below.
406          */
407         if (json_parse_int64(jso->o.c_string.str, &cint64) != 0)
408                 return 0; /* whoops, it didn't work. */
409         o_type = json_type_int;
410   }
411
412   switch(o_type) {
413   case json_type_int:
414         /* Make sure we return the correct values for out of range numbers. */
415         if (cint64 <= INT32_MIN)
416                 return INT32_MIN;
417         else if (cint64 >= INT32_MAX)
418                 return INT32_MAX;
419         else
420                 return (int32_t)cint64;
421   case json_type_double:
422     return (int32_t)jso->o.c_double;
423   case json_type_boolean:
424     return jso->o.c_boolean;
425   default:
426     return 0;
427   }
428 }
429
430 struct json_object* json_object_new_int64(int64_t i)
431 {
432   struct json_object *jso = json_object_new(json_type_int);
433   if(!jso) return NULL;
434   jso->_to_json_string = &json_object_int_to_json_string;
435   jso->o.c_int64 = i;
436   return jso;
437 }
438
439 int64_t json_object_get_int64(struct json_object *jso)
440 {
441    int64_t cint;
442
443   if(!jso) return 0;
444   switch(jso->o_type) {
445   case json_type_int:
446     return jso->o.c_int64;
447   case json_type_double:
448     return (int64_t)jso->o.c_double;
449   case json_type_boolean:
450     return jso->o.c_boolean;
451   case json_type_string:
452         if (json_parse_int64(jso->o.c_string.str, &cint) == 0) return cint;
453   default:
454     return 0;
455   }
456 }
457
458
459 /* json_object_double */
460
461 static int json_object_double_to_json_string(struct json_object* jso,
462                                              struct printbuf *pb,
463                                              int level,
464                                                  int flags)
465 {
466   return sprintbuf(pb, "%f", jso->o.c_double);
467 }
468
469 struct json_object* json_object_new_double(double d)
470 {
471   struct json_object *jso = json_object_new(json_type_double);
472   if(!jso) return NULL;
473   jso->_to_json_string = &json_object_double_to_json_string;
474   jso->o.c_double = d;
475   return jso;
476 }
477
478 double json_object_get_double(struct json_object *jso)
479 {
480   double cdouble;
481
482   if(!jso) return 0.0;
483   switch(jso->o_type) {
484   case json_type_double:
485     return jso->o.c_double;
486   case json_type_int:
487     return jso->o.c_int64;
488   case json_type_boolean:
489     return jso->o.c_boolean;
490   case json_type_string:
491     if(sscanf(jso->o.c_string.str, "%lf", &cdouble) == 1) return cdouble;
492   default:
493     return 0.0;
494   }
495 }
496
497
498 /* json_object_string */
499
500 static int json_object_string_to_json_string(struct json_object* jso,
501                                              struct printbuf *pb,
502                                              int level,
503                                                  int flags)
504 {
505   sprintbuf(pb, "\"");
506   json_escape_str(pb, jso->o.c_string.str, jso->o.c_string.len);
507   sprintbuf(pb, "\"");
508   return 0;
509 }
510
511 static void json_object_string_delete(struct json_object* jso)
512 {
513   free(jso->o.c_string.str);
514   json_object_generic_delete(jso);
515 }
516
517 struct json_object* json_object_new_string(const char *s)
518 {
519   struct json_object *jso = json_object_new(json_type_string);
520   if(!jso) return NULL;
521   jso->_delete = &json_object_string_delete;
522   jso->_to_json_string = &json_object_string_to_json_string;
523   jso->o.c_string.str = strdup(s);
524   jso->o.c_string.len = strlen(s);
525   return jso;
526 }
527
528 struct json_object* json_object_new_string_len(const char *s, int len)
529 {
530   struct json_object *jso = json_object_new(json_type_string);
531   if(!jso) return NULL;
532   jso->_delete = &json_object_string_delete;
533   jso->_to_json_string = &json_object_string_to_json_string;
534   jso->o.c_string.str = malloc(len);
535   memcpy(jso->o.c_string.str, (void *)s, len);
536   jso->o.c_string.len = len;
537   return jso;
538 }
539
540 const char* json_object_get_string(struct json_object *jso)
541 {
542   if(!jso) return NULL;
543   switch(jso->o_type) {
544   case json_type_string:
545     return jso->o.c_string.str;
546   default:
547     return json_object_to_json_string(jso);
548   }
549 }
550
551 int json_object_get_string_len(struct json_object *jso)  {
552   if(!jso) return 0;
553   switch(jso->o_type) {
554   case json_type_string:
555     return jso->o.c_string.len;
556   default:
557     return 0;
558   }
559 }
560
561
562 /* json_object_array */
563
564 static int json_object_array_to_json_string(struct json_object* jso,
565                                             struct printbuf *pb,
566                                             int level,
567                                             int flags)
568 {
569         int had_children = 0;
570         int ii;
571         sprintbuf(pb, "[");
572         if (flags & JSON_C_TO_STRING_PRETTY)
573                 sprintbuf(pb, "\n");
574         for(ii=0; ii < json_object_array_length(jso); ii++)
575         {
576                 struct json_object *val;
577                 if (had_children)
578                 {
579                         sprintbuf(pb, ",");
580                         if (flags & JSON_C_TO_STRING_PRETTY)
581                                 sprintbuf(pb, "\n");
582                 }
583                 had_children = 1;
584                 if (flags & JSON_C_TO_STRING_SPACED)
585                         sprintbuf(pb, " ");
586                 indent(pb, level + 1, flags);
587                 val = json_object_array_get_idx(jso, ii);
588                 if(val == NULL)
589                         sprintbuf(pb, "null");
590                 else
591                         val->_to_json_string(val, pb, level+1, flags);
592         }
593         if (flags & JSON_C_TO_STRING_PRETTY)
594         {
595                 if (had_children)
596                         sprintbuf(pb, "\n");
597                 indent(pb,level,flags);
598         }
599
600         if (flags & JSON_C_TO_STRING_SPACED)
601                 return sprintbuf(pb, " ]");
602         else
603                 return sprintbuf(pb, "]");
604 }
605
606 static void json_object_array_entry_free(void *data)
607 {
608   json_object_put((struct json_object*)data);
609 }
610
611 static void json_object_array_delete(struct json_object* jso)
612 {
613   array_list_free(jso->o.c_array);
614   json_object_generic_delete(jso);
615 }
616
617 struct json_object* json_object_new_array(void)
618 {
619   struct json_object *jso = json_object_new(json_type_array);
620   if(!jso) return NULL;
621   jso->_delete = &json_object_array_delete;
622   jso->_to_json_string = &json_object_array_to_json_string;
623   jso->o.c_array = array_list_new(&json_object_array_entry_free);
624   return jso;
625 }
626
627 struct array_list* json_object_get_array(struct json_object *jso)
628 {
629   if(!jso) return NULL;
630   switch(jso->o_type) {
631   case json_type_array:
632     return jso->o.c_array;
633   default:
634     return NULL;
635   }
636 }
637
638 void json_object_array_sort(struct json_object *jso, int(*sort_fn)(const void *, const void *))
639 {
640   array_list_sort(jso->o.c_array, sort_fn);
641 }
642
643 int json_object_array_length(struct json_object *jso)
644 {
645   return array_list_length(jso->o.c_array);
646 }
647
648 int json_object_array_add(struct json_object *jso,struct json_object *val)
649 {
650   return array_list_add(jso->o.c_array, val);
651 }
652
653 int json_object_array_put_idx(struct json_object *jso, int idx,
654                               struct json_object *val)
655 {
656   return array_list_put_idx(jso->o.c_array, idx, val);
657 }
658
659 struct json_object* json_object_array_get_idx(struct json_object *jso,
660                                               int idx)
661 {
662   return (struct json_object*)array_list_get_idx(jso->o.c_array, idx);
663 }
664