Initial Import
[profile/ivi/json-glib.git] / json-glib / json-object.c
1 /* json-object.c - JSON object implementation
2  * 
3  * This file is part of JSON-GLib
4  * Copyright (C) 2007  OpenedHand Ltd.
5  * Copyright (C) 2009  Intel Corp.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19  *
20  * Author:
21  *   Emmanuele Bassi  <ebassi@linux.intel.com>
22  */
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include <string.h>
29
30 #include <glib.h>
31
32 #include "json-types-private.h"
33
34 /**
35  * SECTION:json-object
36  * @short_description: a JSON object representation
37  *
38  * #JsonObject is the representation of the object type inside JSON. It contains
39  * #JsonNode<!-- -->s, which may contain fundamental types, arrays or other
40  * objects. Each member of an object is accessed using its name.
41  *
42  * Since objects can be expensive, they are reference counted. You can control
43  * the lifetime of a #JsonObject using json_object_ref() and json_object_unref().
44  *
45  * To add or overwrite a member with a given name, use json_object_set_member().
46  * To extract a member with a given name, use json_object_get_member().
47  * To retrieve the list of members, use json_object_get_members().
48  * To retrieve the size of the object (that is, the number of members it has),
49  * use json_object_get_size().
50  */
51
52 G_DEFINE_BOXED_TYPE (JsonObject, json_object, json_object_ref, json_object_unref);
53
54 /**
55  * json_object_new:
56  * 
57  * Creates a new #JsonObject, an JSON object type representation.
58  *
59  * Return value: the newly created #JsonObject
60  */
61 JsonObject *
62 json_object_new (void)
63 {
64   JsonObject *object;
65
66   object = g_slice_new (JsonObject);
67   
68   object->ref_count = 1;
69   object->members = g_hash_table_new_full (g_str_hash, g_str_equal,
70                                            g_free,
71                                            (GDestroyNotify) json_node_free);
72   object->members_ordered = NULL;
73
74   return object;
75 }
76
77 /**
78  * json_object_ref:
79  * @object: a #JsonObject
80  *
81  * Increase by one the reference count of a #JsonObject.
82  *
83  * Return value: the passed #JsonObject, with the reference count
84  *   increased by one.
85  */
86 JsonObject *
87 json_object_ref (JsonObject *object)
88 {
89   g_return_val_if_fail (object != NULL, NULL);
90   g_return_val_if_fail (object->ref_count > 0, NULL);
91
92   g_atomic_int_add (&object->ref_count, 1);
93
94   return object;
95 }
96
97 /**
98  * json_object_unref:
99  * @object: a #JsonObject
100  *
101  * Decreases by one the reference count of a #JsonObject. If the
102  * reference count reaches zero, the object is destroyed and all
103  * its allocated resources are freed.
104  */
105 void
106 json_object_unref (JsonObject *object)
107 {
108   g_return_if_fail (object != NULL);
109   g_return_if_fail (object->ref_count > 0);
110
111   if (g_atomic_int_dec_and_test (&object->ref_count))
112     {
113       g_list_free (object->members_ordered);
114       g_hash_table_destroy (object->members);
115       object->members_ordered = NULL;
116       object->members = NULL;
117
118       g_slice_free (JsonObject, object);
119     }
120 }
121
122 static inline void
123 object_set_member_internal (JsonObject  *object,
124                             const gchar *member_name,
125                             JsonNode    *node)
126 {
127   gchar *name = g_strdup (member_name);
128
129   if (g_hash_table_lookup (object->members, name) == NULL)
130     object->members_ordered = g_list_prepend (object->members_ordered, name);
131   else
132     {
133       GList *l;
134
135       /* if the member already exists then we need to replace the
136        * pointer to its name, to avoid keeping invalid pointers
137        * once we replace the key in the hash table
138        */
139       l = g_list_find_custom (object->members_ordered, name, (GCompareFunc) strcmp);
140       if (l != NULL)
141         l->data = name;
142     }
143
144   g_hash_table_replace (object->members, name, node);
145 }
146
147 /**
148  * json_object_add_member:
149  * @object: a #JsonObject
150  * @member_name: the name of the member
151  * @node: (transfer full): the value of the member
152  *
153  * Adds a member named @member_name and containing @node into a #JsonObject.
154  * The object will take ownership of the #JsonNode.
155  *
156  * This function will return if the @object already contains a member
157  * @member_name.
158  *
159  * Deprecated: 0.8: Use json_object_set_member() instead
160  */
161 void
162 json_object_add_member (JsonObject  *object,
163                         const gchar *member_name,
164                         JsonNode    *node)
165 {
166   g_return_if_fail (object != NULL);
167   g_return_if_fail (member_name != NULL);
168   g_return_if_fail (node != NULL);
169
170   if (json_object_has_member (object, member_name))
171     {
172       g_warning ("JsonObject already has a `%s' member of type `%s'",
173                  member_name,
174                  json_node_type_name (node));
175       return;
176     }
177
178   object_set_member_internal (object, member_name, node);
179 }
180
181 /**
182  * json_object_set_member:
183  * @object: a #JsonObject
184  * @member_name: the name of the member
185  * @node: (transfer full): the value of the member
186  *
187  * Sets @node as the value of @member_name inside @object.
188  *
189  * If @object already contains a member called @member_name then
190  * the member's current value is overwritten. Otherwise, a new
191  * member is added to @object.
192  *
193  * Since: 0.8
194  */
195 void
196 json_object_set_member (JsonObject  *object,
197                         const gchar *member_name,
198                         JsonNode    *node)
199 {
200   JsonNode *old_node;
201
202   g_return_if_fail (object != NULL);
203   g_return_if_fail (member_name != NULL);
204   g_return_if_fail (node != NULL);
205
206   old_node = g_hash_table_lookup (object->members, member_name);
207   if (old_node == NULL)
208     goto set_member;
209
210   if (old_node == node)
211     return;
212
213 set_member:
214   object_set_member_internal (object, member_name, node);
215 }
216
217 /**
218  * json_object_set_int_member:
219  * @object: a #JsonObject
220  * @member_name: the name of the member
221  * @value: the value of the member
222  *
223  * Convenience function for setting an integer @value of
224  * @member_name inside @object.
225  *
226  * See also: json_object_set_member()
227  *
228  * Since: 0.8
229  */
230 void
231 json_object_set_int_member (JsonObject  *object,
232                             const gchar *member_name,
233                             gint64       value)
234 {
235   JsonNode *node;
236
237   g_return_if_fail (object != NULL);
238   g_return_if_fail (member_name != NULL);
239
240   node = json_node_new (JSON_NODE_VALUE);
241   json_node_set_int (node, value);
242   object_set_member_internal (object, member_name, node);
243 }
244
245 /**
246  * json_object_set_double_member:
247  * @object: a #JsonObject
248  * @member_name: the name of the member
249  * @value: the value of the member
250  *
251  * Convenience function for setting a floating point @value
252  * of @member_name inside @object.
253  *
254  * See also: json_object_set_member()
255  *
256  * Since: 0.8
257  */
258 void
259 json_object_set_double_member (JsonObject  *object,
260                                const gchar *member_name,
261                                gdouble      value)
262 {
263   JsonNode *node;
264
265   g_return_if_fail (object != NULL);
266   g_return_if_fail (member_name != NULL);
267
268   node = json_node_new (JSON_NODE_VALUE);
269   json_node_set_double (node, value);
270   object_set_member_internal (object, member_name, node);
271 }
272
273 /**
274  * json_object_set_boolean_member:
275  * @object: a #JsonObject
276  * @member_name: the name of the member
277  * @value: the value of the member
278  *
279  * Convenience function for setting a boolean @value of
280  * @member_name inside @object.
281  *
282  * See also: json_object_set_member()
283  *
284  * Since: 0.8
285  */
286 void
287 json_object_set_boolean_member (JsonObject  *object,
288                                 const gchar *member_name,
289                                 gboolean     value)
290 {
291   JsonNode *node;
292
293   g_return_if_fail (object != NULL);
294   g_return_if_fail (member_name != NULL);
295
296   node = json_node_new (JSON_NODE_VALUE);
297   json_node_set_boolean (node, value);
298   object_set_member_internal (object, member_name, node);
299 }
300
301 /**
302  * json_object_set_string_member:
303  * @object: a #JsonObject
304  * @member_name: the name of the member
305  * @value: the value of the member
306  *
307  * Convenience function for setting a string @value of
308  * @member_name inside @object.
309  *
310  * See also: json_object_set_member()
311  *
312  * Since: 0.8
313  */
314 void
315 json_object_set_string_member (JsonObject  *object,
316                                const gchar *member_name,
317                                const gchar *value)
318 {
319   JsonNode *node;
320
321   g_return_if_fail (object != NULL);
322   g_return_if_fail (member_name != NULL);
323
324   if (value != NULL)
325     {
326       node = json_node_new (JSON_NODE_VALUE);
327       json_node_set_string (node, value);
328     }
329   else
330     node = json_node_new (JSON_NODE_NULL);
331
332   object_set_member_internal (object, member_name, node);
333 }
334
335 /**
336  * json_object_set_null_member:
337  * @object: a #JsonObject
338  * @member_name: the name of the member
339  *
340  * Convenience function for setting a null @value of
341  * @member_name inside @object.
342  *
343  * See also: json_object_set_member()
344  *
345  * Since: 0.8
346  */
347 void
348 json_object_set_null_member (JsonObject  *object,
349                              const gchar *member_name)
350 {
351   JsonNode *node;
352
353   g_return_if_fail (object != NULL);
354   g_return_if_fail (member_name != NULL);
355
356   node = json_node_new (JSON_NODE_NULL);
357   object_set_member_internal (object, member_name, node);
358 }
359
360 /**
361  * json_object_set_array_member:
362  * @object: a #JsonObject
363  * @member_name: the name of the member
364  * @value: (transfer full): the value of the member
365  *
366  * Convenience function for setting an array @value of
367  * @member_name inside @object.
368  *
369  * The @object will take ownership of the passed #JsonArray
370  *
371  * See also: json_object_set_member()
372  *
373  * Since: 0.8
374  */
375 void
376 json_object_set_array_member (JsonObject  *object,
377                               const gchar *member_name,
378                               JsonArray   *value)
379 {
380   JsonNode *node;
381
382   g_return_if_fail (object != NULL);
383   g_return_if_fail (member_name != NULL);
384
385   if (value != NULL)
386     {
387       node = json_node_new (JSON_NODE_ARRAY);
388       json_node_take_array (node, value);
389     }
390   else
391     node = json_node_new (JSON_NODE_NULL);
392
393   object_set_member_internal (object, member_name, node);
394 }
395
396 /**
397  * json_object_set_object_member:
398  * @object: a #JsonObject
399  * @member_name: the name of the member
400  * @value: (transfer full): the value of the member
401  *
402  * Convenience function for setting an object @value of
403  * @member_name inside @object.
404  *
405  * The @object will take ownership of the passed #JsonObject
406  *
407  * See also: json_object_set_member()
408  *
409  * Since: 0.8
410  */
411 void
412 json_object_set_object_member (JsonObject  *object,
413                                const gchar *member_name,
414                                JsonObject  *value)
415 {
416   JsonNode *node;
417
418   g_return_if_fail (object != NULL);
419   g_return_if_fail (member_name != NULL);
420
421   if (value != NULL)
422     {
423       node = json_node_new (JSON_NODE_OBJECT);
424       json_node_take_object (node, value);
425     }
426   else
427     node = json_node_new (JSON_NODE_NULL);
428
429   object_set_member_internal (object, member_name, node);
430 }
431
432 /**
433  * json_object_get_members:
434  * @object: a #JsonObject
435  *
436  * Retrieves all the names of the members of a #JsonObject. You can
437  * obtain the value for each member using json_object_get_member().
438  *
439  * Return value: (element-type utf8) (transfer container): a #GList
440  *   of member names. The content of the list is owned by the #JsonObject
441  *   and should never be modified or freed. When you have finished using
442  *   the returned list, use g_list_free() to free the resources it has
443  *   allocated.
444  */
445 GList *
446 json_object_get_members (JsonObject *object)
447 {
448   GList *copy;
449
450   g_return_val_if_fail (object != NULL, NULL);
451
452   copy = g_list_copy (object->members_ordered);
453
454   return g_list_reverse (copy);
455 }
456
457 /**
458  * json_object_get_values:
459  * @object: a #JsonObject
460  *
461  * Retrieves all the values of the members of a #JsonObject.
462  *
463  * Return value: (element-type JsonNode) (transfer container): a #GList of
464  *   #JsonNode<!-- -->s. The content of the list is owned by the #JsonObject
465  *   and should never be modified or freed. When you have finished using the
466  *   returned list, use g_list_free() to free the resources it has allocated.
467  */
468 GList *
469 json_object_get_values (JsonObject *object)
470 {
471   GList *values, *l;
472
473   g_return_val_if_fail (object != NULL, NULL);
474
475   values = NULL;
476   for (l = object->members_ordered; l != NULL; l = l->next)
477     values = g_list_prepend (values, g_hash_table_lookup (object->members, l->data));
478
479   return values;
480 }
481
482 /**
483  * json_object_dup_member:
484  * @object: a #JsonObject
485  * @member_name: the name of the JSON object member to access
486  *
487  * Retrieves a copy of the #JsonNode containing the value of @member_name
488  * inside a #JsonObject
489  *
490  * Return value: (transfer full): a copy of the node for the requested
491  *   object member or %NULL. Use json_node_free() when done.
492  *
493  * Since: 0.6
494  */
495 JsonNode *
496 json_object_dup_member (JsonObject  *object,
497                         const gchar *member_name)
498 {
499   JsonNode *retval;
500
501   g_return_val_if_fail (object != NULL, NULL);
502   g_return_val_if_fail (member_name != NULL, NULL);
503
504   retval = json_object_get_member (object, member_name);
505   if (!retval)
506     return NULL;
507
508   return json_node_copy (retval);
509 }
510
511 static inline JsonNode *
512 object_get_member_internal (JsonObject  *object,
513                             const gchar *member_name)
514 {
515   return g_hash_table_lookup (object->members, member_name);
516 }
517
518 /**
519  * json_object_get_member:
520  * @object: a #JsonObject
521  * @member_name: the name of the JSON object member to access
522  *
523  * Retrieves the #JsonNode containing the value of @member_name inside
524  * a #JsonObject.
525  *
526  * Return value: (transfer none): a pointer to the node for the requested object
527  *   member, or %NULL
528  */
529 JsonNode *
530 json_object_get_member (JsonObject  *object,
531                         const gchar *member_name)
532 {
533   g_return_val_if_fail (object != NULL, NULL);
534   g_return_val_if_fail (member_name != NULL, NULL);
535
536   return object_get_member_internal (object, member_name);
537 }
538
539 /**
540  * json_object_get_int_member:
541  * @object: a #JsonObject
542  * @member_name: the name of the member
543  *
544  * Convenience function that retrieves the integer value
545  * stored in @member_name of @object
546  *
547  * See also: json_object_get_member()
548  *
549  * Return value: the integer value of the object's member
550  *
551  * Since: 0.8
552  */
553 gint64
554 json_object_get_int_member (JsonObject  *object,
555                             const gchar *member_name)
556 {
557   JsonNode *node;
558
559   g_return_val_if_fail (object != NULL, 0);
560   g_return_val_if_fail (member_name != NULL, 0);
561
562   node = object_get_member_internal (object, member_name);
563   g_return_val_if_fail (node != NULL, 0);
564   g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0);
565
566   return json_node_get_int (node);
567 }
568
569 /**
570  * json_object_get_double_member:
571  * @object: a #JsonObject
572  * @member_name: the name of the member
573  *
574  * Convenience function that retrieves the floating point value
575  * stored in @member_name of @object
576  *
577  * See also: json_object_get_member()
578  *
579  * Return value: the floating point value of the object's member
580  *
581  * Since: 0.8
582  */
583 gdouble
584 json_object_get_double_member (JsonObject  *object,
585                                const gchar *member_name)
586 {
587   JsonNode *node;
588
589   g_return_val_if_fail (object != NULL, 0.0);
590   g_return_val_if_fail (member_name != NULL, 0.0);
591
592   node = object_get_member_internal (object, member_name);
593   g_return_val_if_fail (node != NULL, 0.0);
594   g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, 0.0);
595
596   return json_node_get_double (node);
597 }
598
599 /**
600  * json_object_get_boolean_member:
601  * @object: a #JsonObject
602  * @member_name: the name of the member
603  *
604  * Convenience function that retrieves the boolean value
605  * stored in @member_name of @object
606  *
607  * See also: json_object_get_member()
608  *
609  * Return value: the boolean value of the object's member
610  *
611  * Since: 0.8
612  */
613 gboolean
614 json_object_get_boolean_member (JsonObject  *object,
615                                 const gchar *member_name)
616 {
617   JsonNode *node;
618
619   g_return_val_if_fail (object != NULL, FALSE);
620   g_return_val_if_fail (member_name != NULL, FALSE);
621
622   node = object_get_member_internal (object, member_name);
623   g_return_val_if_fail (node != NULL, FALSE);
624   g_return_val_if_fail (JSON_NODE_TYPE (node) == JSON_NODE_VALUE, FALSE);
625
626   return json_node_get_boolean (node);
627 }
628
629 /**
630  * json_object_get_null_member:
631  * @object: a #JsonObject
632  * @member_name: the name of the member
633  *
634  * Convenience function that checks whether the value
635  * stored in @member_name of @object is null
636  *
637  * See also: json_object_get_member()
638  *
639  * Return value: %TRUE if the value is null
640  *
641  * Since: 0.8
642  */
643 gboolean
644 json_object_get_null_member (JsonObject  *object,
645                              const gchar *member_name)
646 {
647   JsonNode *node;
648
649   g_return_val_if_fail (object != NULL, FALSE);
650   g_return_val_if_fail (member_name != NULL, FALSE);
651
652   node = object_get_member_internal (object, member_name);
653   g_return_val_if_fail (node != NULL, FALSE);
654
655   return JSON_NODE_TYPE (node) == JSON_NODE_NULL;
656 }
657
658 /**
659  * json_object_get_string_member:
660  * @object: a #JsonObject
661  * @member_name: the name of the member
662  *
663  * Convenience function that retrieves the string value
664  * stored in @member_name of @object
665  *
666  * See also: json_object_get_member()
667  *
668  * Return value: the string value of the object's member
669  *
670  * Since: 0.8
671  */
672 const gchar *
673 json_object_get_string_member (JsonObject  *object,
674                                const gchar *member_name)
675 {
676   JsonNode *node;
677
678   g_return_val_if_fail (object != NULL, NULL);
679   g_return_val_if_fail (member_name != NULL, NULL);
680
681   node = object_get_member_internal (object, member_name);
682   g_return_val_if_fail (node != NULL, NULL);
683   g_return_val_if_fail (JSON_NODE_HOLDS_VALUE (node) || JSON_NODE_HOLDS_NULL (node), NULL);
684
685   if (JSON_NODE_HOLDS_NULL (node))
686     return NULL;
687
688   return json_node_get_string (node);
689 }
690
691 /**
692  * json_object_get_array_member:
693  * @object: a #JsonObject
694  * @member_name: the name of the member
695  *
696  * Convenience function that retrieves the array
697  * stored in @member_name of @object
698  *
699  * See also: json_object_get_member()
700  *
701  * Return value: (transfer none): the array inside the object's member
702  *
703  * Since: 0.8
704  */
705 JsonArray *
706 json_object_get_array_member (JsonObject  *object,
707                               const gchar *member_name)
708 {
709   JsonNode *node;
710
711   g_return_val_if_fail (object != NULL, NULL);
712   g_return_val_if_fail (member_name != NULL, NULL);
713
714   node = object_get_member_internal (object, member_name);
715   g_return_val_if_fail (node != NULL, NULL);
716   g_return_val_if_fail (JSON_NODE_HOLDS_ARRAY (node) || JSON_NODE_HOLDS_NULL (node), NULL);
717
718   if (JSON_NODE_HOLDS_NULL (node))
719     return NULL;
720
721   return json_node_get_array (node);
722 }
723
724 /**
725  * json_object_get_object_member:
726  * @object: a #JsonObject
727  * @member_name: the name of the member
728  *
729  * Convenience function that retrieves the object
730  * stored in @member_name of @object
731  *
732  * See also: json_object_get_member()
733  *
734  * Return value: (transfer none): the object inside the object's member
735  *
736  * Since: 0.8
737  */
738 JsonObject *
739 json_object_get_object_member (JsonObject  *object,
740                                const gchar *member_name)
741 {
742   JsonNode *node;
743
744   g_return_val_if_fail (object != NULL, NULL);
745   g_return_val_if_fail (member_name != NULL, NULL);
746
747   node = object_get_member_internal (object, member_name);
748   g_return_val_if_fail (node != NULL, NULL);
749   g_return_val_if_fail (JSON_NODE_HOLDS_OBJECT (node) || JSON_NODE_HOLDS_NULL (node), NULL);
750
751   if (JSON_NODE_HOLDS_NULL (node))
752     return NULL;
753
754   return json_node_get_object (node);
755 }
756
757 /**
758  * json_object_has_member:
759  * @object: a #JsonObject
760  * @member_name: the name of a JSON object member
761  *
762  * Checks whether @object has a member named @member_name.
763  *
764  * Return value: %TRUE if the JSON object has the requested member
765  */
766 gboolean
767 json_object_has_member (JsonObject *object,
768                         const gchar *member_name)
769 {
770   g_return_val_if_fail (object != NULL, FALSE);
771   g_return_val_if_fail (member_name != NULL, FALSE);
772
773   return (g_hash_table_lookup (object->members, member_name) != NULL);
774 }
775
776 /**
777  * json_object_get_size:
778  * @object: a #JsonObject
779  *
780  * Retrieves the number of members of a #JsonObject.
781  *
782  * Return value: the number of members
783  */
784 guint
785 json_object_get_size (JsonObject *object)
786 {
787   g_return_val_if_fail (object != NULL, 0);
788
789   return g_hash_table_size (object->members);
790 }
791
792 /**
793  * json_object_remove_member:
794  * @object: a #JsonObject
795  * @member_name: the name of the member to remove
796  *
797  * Removes @member_name from @object, freeing its allocated resources.
798  */
799 void
800 json_object_remove_member (JsonObject  *object,
801                            const gchar *member_name)
802 {
803   GList *l;
804
805   g_return_if_fail (object != NULL);
806   g_return_if_fail (member_name != NULL);
807
808   for (l = object->members_ordered; l != NULL; l = l->next)
809     {
810       const gchar *name = l->data;
811
812       if (g_strcmp0 (name, member_name) == 0)
813         {
814           object->members_ordered = g_list_delete_link (object->members_ordered, l);
815           break;
816         }
817     }
818
819   g_hash_table_remove (object->members, member_name);
820 }
821
822 /**
823  * json_object_foreach_member:
824  * @object: a #JsonObject
825  * @func: (scope call): the function to be called on each member
826  * @data: (closure): data to be passed to the function
827  *
828  * Iterates over all members of @object and calls @func on
829  * each one of them.
830  *
831  * It is safe to change the value of a #JsonNode of the @object
832  * from within the iterator @func, but it is not safe to add or
833  * remove members from the @object.
834  *
835  * Since: 0.8
836  */
837 void
838 json_object_foreach_member (JsonObject        *object,
839                             JsonObjectForeach  func,
840                             gpointer           data)
841 {
842   GList *members, *l;
843
844   g_return_if_fail (object != NULL);
845   g_return_if_fail (func != NULL);
846
847   /* the list is stored in reverse order to have constant time additions */
848   members = g_list_last (object->members_ordered);
849   for (l = members; l != NULL; l = l->prev)
850     {
851       const gchar *member_name = l->data;
852       JsonNode *member_node = g_hash_table_lookup (object->members, member_name);
853
854       func (object, member_name, member_node, data);
855     }
856 }