Initial Import
[profile/ivi/json-glib.git] / json-glib / json-gvariant.c
1 /* json-gvariant.c - JSON GVariant integration
2  *
3  * This file is part of JSON-GLib
4  * Copyright (C) 2007  OpenedHand Ltd.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * Author:
17  *   Eduardo Lima Mitev  <elima@igalia.com>
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <errno.h>
27
28 #include <glib/gi18n-lib.h>
29
30 #include "json-gvariant.h"
31
32 /**
33  * SECTION:json-gvariant
34  * @short_description: Serialize and deserialize GVariant types
35  * @Title: JSON GVariant Integration
36  *
37  * Use json_gvariant_serialize() and json_gvariant_serialize_data() to
38  * convert from any #GVariant value to a #JsonNode tree or its string
39  * representation.
40  *
41  * Use json_gvariant_deserialize() and json_gvariant_deserialize_data() to
42  * obtain the #GVariant value from a #JsonNode tree or directly from a JSON
43  * string.
44  * Since many #GVariant data types cannot be directly represented as
45  * JSON, a #GVariant type string (signature) should be provided to these
46  * methods in order to obtain a correct, type-contrained result.
47  * If no signature is provided, conversion can still be done, but the
48  * resulting #GVariant value will be "guessed" from the JSON data types,
49  * according to the following table:
50  *
51  * <table frame='all'><title>Default JSON to GVariant conversion (without signature constrains)</title>
52  *  <tgroup cols='2' align='left' colsep='1' rowsep='1'>
53  *   <thead>
54  *     <row>
55  *       <entry>JSON</entry>
56  *       <entry>GVariant</entry>
57  *     </row>
58  *   </thead>
59  *   <tfoot>
60  *    <row>
61  *     <entry>string</entry>
62  *     <entry>string (s)</entry>
63  *    </row>
64  *    <row>
65  *     <entry>int64</entry>
66  *     <entry>int64 (x)</entry>
67  *    </row>
68  *    <row>
69  *     <entry>boolean</entry>
70  *     <entry>boolean (b)</entry>
71  *    </row>
72  *    <row>
73  *     <entry>double</entry>
74  *     <entry>double (d)</entry>
75  *    </row>
76  *    <row>
77  *     <entry>array</entry>
78  *     <entry>array of variants (av)</entry>
79  *    </row>
80  *    <row>
81  *     <entry>object</entry>
82  *     <entry>dictionary of string-variant (a{sv})</entry>
83  *    </row>
84  *    <row>
85  *     <entry>null</entry>
86  *     <entry>maybe variant (mv)</entry>
87  *    </row>
88  *   </tfoot>
89  *  </tgroup>
90  * </table>
91  */
92
93 /* custom extension to the GVariantClass enumeration to differentiate
94  * a single dictionary entry from an array of dictionary entries
95  */
96 #define JSON_G_VARIANT_CLASS_DICTIONARY 'c'
97
98 typedef void (* GVariantForeachFunc) (GVariant *variant_child,
99                                       gpointer  user_data);
100
101 static GVariant * json_to_gvariant_recurse (JsonNode      *json_node,
102                                             const gchar  **signature,
103                                             GError       **error);
104
105 /* ========================================================================== */
106 /* GVariant to JSON */
107 /* ========================================================================== */
108
109 static void
110 gvariant_foreach (GVariant            *variant,
111                   GVariantForeachFunc  func,
112                   gpointer             user_data)
113 {
114   GVariantIter iter;
115   GVariant *variant_child;
116
117   g_variant_iter_init (&iter, variant);
118   while ((variant_child = g_variant_iter_next_value (&iter)) != NULL)
119     {
120       func (variant_child, user_data);
121       g_variant_unref (variant_child);
122     }
123 }
124
125 static void
126 gvariant_to_json_array_foreach (GVariant *variant_child,
127                                 gpointer  user_data)
128 {
129   JsonArray *array = user_data;
130   JsonNode *json_child;
131
132   json_child = json_gvariant_serialize (variant_child);
133   json_array_add_element (array, json_child);
134 }
135
136 static JsonNode *
137 gvariant_to_json_array (GVariant *variant)
138 {
139   JsonArray *array;
140   JsonNode *json_node;
141
142   array = json_array_new ();
143   json_node = json_node_new (JSON_NODE_ARRAY);
144   json_node_set_array (json_node, array);
145   json_array_unref (array);
146
147   gvariant_foreach (variant,
148                     gvariant_to_json_array_foreach,
149                     array);
150
151   return json_node;
152 }
153
154 static gchar *
155 gvariant_simple_to_string (GVariant *variant)
156 {
157   GVariantClass class;
158   gchar *str;
159
160   class = g_variant_classify (variant);
161   switch (class)
162     {
163     case G_VARIANT_CLASS_BOOLEAN:
164       if (g_variant_get_boolean (variant))
165         str = g_strdup ("true");
166       else
167         str = g_strdup ("false");
168       break;
169
170     case G_VARIANT_CLASS_BYTE:
171       str = g_strdup_printf ("%u", g_variant_get_byte (variant));
172       break;
173     case G_VARIANT_CLASS_INT16:
174       str = g_strdup_printf ("%d", g_variant_get_int16 (variant));
175       break;
176     case G_VARIANT_CLASS_UINT16:
177       str = g_strdup_printf ("%u", g_variant_get_uint16 (variant));
178       break;
179     case G_VARIANT_CLASS_INT32:
180       str = g_strdup_printf ("%d", g_variant_get_int32 (variant));
181       break;
182     case G_VARIANT_CLASS_UINT32:
183       str = g_strdup_printf ("%u", g_variant_get_uint32 (variant));
184       break;
185     case G_VARIANT_CLASS_INT64:
186       str = g_strdup_printf ("%" G_GINT64_FORMAT,
187                              g_variant_get_int64 (variant));
188       break;
189     case G_VARIANT_CLASS_UINT64:
190       str = g_strdup_printf ("%" G_GUINT64_FORMAT,
191                              g_variant_get_uint64 (variant));
192       break;
193     case G_VARIANT_CLASS_HANDLE:
194       str = g_strdup_printf ("%d", g_variant_get_handle (variant));
195       break;
196
197     case G_VARIANT_CLASS_DOUBLE:
198       {
199         gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
200
201         g_ascii_formatd (buf,
202                          G_ASCII_DTOSTR_BUF_SIZE,
203                          "%f",
204                          g_variant_get_double (variant));
205
206         str = g_strdup (buf);
207         break;
208       }
209
210     case G_VARIANT_CLASS_STRING:
211     case G_VARIANT_CLASS_OBJECT_PATH:
212     case G_VARIANT_CLASS_SIGNATURE:
213       str = g_strdup (g_variant_get_string (variant, NULL));
214       break;
215
216     default:
217       g_assert_not_reached ();
218       break;
219     }
220
221   return str;
222 }
223
224 static JsonNode *
225 gvariant_dict_entry_to_json (GVariant  *variant, gchar **member_name)
226 {
227   GVariant *member;
228   GVariant *value;
229   JsonNode *json_node;
230
231   member = g_variant_get_child_value (variant, 0);
232   *member_name = gvariant_simple_to_string (member);
233
234   value = g_variant_get_child_value (variant, 1);
235   json_node = json_gvariant_serialize (value);
236
237   g_variant_unref (member);
238   g_variant_unref (value);
239
240   return json_node;
241 }
242
243 static void
244 gvariant_to_json_object_foreach (GVariant *variant_child, gpointer  user_data)
245 {
246   gchar *member_name;
247   JsonNode *json_child;
248   JsonObject *object = (JsonObject *) user_data;
249
250   json_child = gvariant_dict_entry_to_json (variant_child, &member_name);
251   json_object_set_member (object, member_name, json_child);
252   g_free (member_name);
253 }
254
255 static JsonNode *
256 gvariant_to_json_object (GVariant *variant)
257 {
258   JsonNode *json_node;
259   JsonObject *object;
260
261   json_node = json_node_new (JSON_NODE_OBJECT);
262   object = json_object_new ();
263   json_node_set_object (json_node, object);
264   json_object_unref (object);
265
266   gvariant_foreach (variant,
267                     gvariant_to_json_object_foreach,
268                     object);
269
270   return json_node;
271 }
272
273 /**
274  * json_gvariant_serialize:
275  * @variant: A #GVariant to convert
276  *
277  * Converts @variant to a JSON tree.
278  *
279  * Return value: (transfer full): A #JsonNode representing the root of the
280  *   JSON data structure obtained from @variant
281  *
282  * Since: 0.14
283  */
284 JsonNode *
285 json_gvariant_serialize (GVariant *variant)
286 {
287   JsonNode *json_node = NULL;
288   GVariantClass class;
289
290   g_return_val_if_fail (variant != NULL, NULL);
291
292   class = g_variant_classify (variant);
293
294   if (! g_variant_is_container (variant))
295     {
296       json_node = json_node_new (JSON_NODE_VALUE);
297
298       switch (class)
299         {
300         case G_VARIANT_CLASS_BOOLEAN:
301           json_node_set_boolean (json_node, g_variant_get_boolean (variant));
302           break;
303
304         case G_VARIANT_CLASS_BYTE:
305           json_node_set_int (json_node, g_variant_get_byte (variant));
306           break;
307         case G_VARIANT_CLASS_INT16:
308           json_node_set_int (json_node, g_variant_get_int16 (variant));
309           break;
310         case G_VARIANT_CLASS_UINT16:
311           json_node_set_int (json_node, g_variant_get_uint16 (variant));
312           break;
313         case G_VARIANT_CLASS_INT32:
314           json_node_set_int (json_node, g_variant_get_int32 (variant));
315           break;
316         case G_VARIANT_CLASS_UINT32:
317           json_node_set_int (json_node, g_variant_get_uint32 (variant));
318           break;
319         case G_VARIANT_CLASS_INT64:
320           json_node_set_int (json_node, g_variant_get_int64 (variant));
321           break;
322         case G_VARIANT_CLASS_UINT64:
323           json_node_set_int (json_node, g_variant_get_uint64 (variant));
324           break;
325         case G_VARIANT_CLASS_HANDLE:
326           json_node_set_int (json_node, g_variant_get_handle (variant));
327           break;
328
329         case G_VARIANT_CLASS_DOUBLE:
330           json_node_set_double (json_node, g_variant_get_double (variant));
331           break;
332
333         case G_VARIANT_CLASS_STRING:
334         case G_VARIANT_CLASS_OBJECT_PATH:
335         case G_VARIANT_CLASS_SIGNATURE:
336           json_node_set_string (json_node, g_variant_get_string (variant, NULL));
337           break;
338
339         default:
340           break;
341         }
342     }
343   else
344     {
345       switch (class)
346         {
347         case G_VARIANT_CLASS_MAYBE:
348           {
349             GVariant *value;
350
351             value = g_variant_get_maybe (variant);
352             if (value == NULL)
353               {
354                 json_node = json_node_new (JSON_NODE_NULL);
355               }
356             else
357               {
358                 json_node = json_gvariant_serialize (value);
359                 g_variant_unref (value);
360               }
361
362             break;
363           }
364
365         case G_VARIANT_CLASS_VARIANT:
366           {
367             GVariant *value;
368
369             value = g_variant_get_variant (variant);
370             json_node = json_gvariant_serialize (value);
371             g_variant_unref (value);
372
373             break;
374           }
375
376         case G_VARIANT_CLASS_ARRAY:
377           {
378             const gchar *type;
379
380             type = g_variant_get_type_string (variant);
381
382             if (type[1] == G_VARIANT_CLASS_DICT_ENTRY)
383               {
384                 /* array of dictionary entries => JsonObject */
385                 json_node = gvariant_to_json_object (variant);
386               }
387             else
388               {
389                 /* array of anything else => JsonArray */
390                 json_node = gvariant_to_json_array (variant);
391               }
392
393             break;
394           }
395
396         case G_VARIANT_CLASS_DICT_ENTRY:
397           {
398             gchar *member_name;
399             JsonObject *object;
400             JsonNode *child;
401
402             /* a single dictionary entry => JsonObject */
403             json_node = json_node_new (JSON_NODE_OBJECT);
404             object = json_object_new ();
405             json_node_set_object (json_node, object);
406             json_object_unref (object);
407
408             child = gvariant_dict_entry_to_json (variant, &member_name);
409
410             json_object_set_member (object, member_name, child);
411             g_free (member_name);
412
413             break;
414           }
415
416         case G_VARIANT_CLASS_TUPLE:
417           json_node = gvariant_to_json_array (variant);
418           break;
419
420         default:
421           break;
422         }
423     }
424
425   return json_node;
426 }
427
428 /**
429  * json_gvariant_serialize_data:
430  * @variant: A #GVariant to convert
431  * @length: (out) (allow-none): Return location for the length of the returned
432  *   string, or %NULL
433  *
434  * Converts @variant to its JSON encoded string representation. This method
435  * is actually a helper function. It uses json_gvariant_serialize() to obtain the
436  * JSON tree, and then #JsonGenerator to stringify it.
437  *
438  * Return value: (transfer full): The JSON encoded string corresponding to
439  *   @variant
440  *
441  * Since: 0.14
442  */
443 gchar *
444 json_gvariant_serialize_data (GVariant *variant, gsize *length)
445 {
446   JsonNode *json_node;
447   JsonGenerator *generator;
448   gchar *json;
449
450   json_node = json_gvariant_serialize (variant);
451
452   generator = json_generator_new ();
453
454   json_generator_set_root (generator, json_node);
455   json = json_generator_to_data (generator, length);
456
457   g_object_unref (generator);
458
459   json_node_free (json_node);
460
461   return json;
462 }
463
464 /* ========================================================================== */
465 /* JSON to GVariant */
466 /* ========================================================================== */
467
468 static GVariantClass
469 json_to_gvariant_get_next_class (JsonNode     *json_node,
470                                  const gchar **signature)
471 {
472   if (signature == NULL)
473     {
474       GVariantClass class = 0;
475
476       switch (json_node_get_node_type (json_node))
477         {
478         case JSON_NODE_VALUE:
479           switch (json_node_get_value_type (json_node))
480             {
481             case G_TYPE_BOOLEAN:
482               class = G_VARIANT_CLASS_BOOLEAN;
483               break;
484
485             case G_TYPE_INT64:
486               class = G_VARIANT_CLASS_INT64;
487               break;
488
489             case G_TYPE_DOUBLE:
490               class = G_VARIANT_CLASS_DOUBLE;
491               break;
492
493             case G_TYPE_STRING:
494               class = G_VARIANT_CLASS_STRING;
495               break;
496             }
497
498           break;
499
500         case JSON_NODE_ARRAY:
501           class = G_VARIANT_CLASS_ARRAY;
502           break;
503
504         case JSON_NODE_OBJECT:
505           class = JSON_G_VARIANT_CLASS_DICTIONARY;
506           break;
507
508         case JSON_NODE_NULL:
509           class = G_VARIANT_CLASS_MAYBE;
510           break;
511         }
512
513       return class;
514     }
515   else
516     {
517       if ((*signature)[0] == G_VARIANT_CLASS_ARRAY &&
518           (*signature)[1] == G_VARIANT_CLASS_DICT_ENTRY)
519         return JSON_G_VARIANT_CLASS_DICTIONARY;
520       else
521         return (*signature)[0];
522     }
523 }
524
525 static gboolean
526 json_node_assert_type (JsonNode       *json_node,
527                        JsonNodeType    type,
528                        GType           sub_type,
529                        GError        **error)
530 {
531   if (JSON_NODE_TYPE (json_node) != type ||
532       (type == JSON_NODE_VALUE &&
533        (json_node_get_value_type (json_node) != sub_type)))
534     {
535       /* translators: the '%s' is the type name */
536       g_set_error (error,
537                    G_IO_ERROR,
538                    G_IO_ERROR_INVALID_DATA,
539                    _("Unexpected type '%s' in JSON node"),
540                    g_type_name (json_node_get_value_type (json_node)));
541       return FALSE;
542     }
543   else
544     {
545       return TRUE;
546     }
547 }
548
549 static void
550 json_to_gvariant_foreach_add (gpointer data, gpointer user_data)
551 {
552   GVariantBuilder *builder = (GVariantBuilder *) user_data;
553   GVariant *child = (GVariant *) data;
554
555   g_variant_builder_add_value (builder, child);
556 }
557
558 static void
559 json_to_gvariant_foreach_free (gpointer data, gpointer user_data)
560 {
561   GVariant *child = (GVariant *) data;
562
563   g_variant_unref (child);
564 }
565
566 static GVariant *
567 json_to_gvariant_build_from_glist (GList *list, const gchar *signature)
568 {
569   GVariantBuilder *builder;
570   GVariant *result;
571
572   builder = g_variant_builder_new (G_VARIANT_TYPE (signature));
573
574   g_list_foreach (list, json_to_gvariant_foreach_add, builder);
575   result = g_variant_builder_end (builder);
576
577   g_variant_builder_unref (builder);
578
579   return result;
580 }
581
582 static GVariant *
583 json_to_gvariant_tuple (JsonNode     *json_node,
584                         const gchar **signature,
585                         GError      **error)
586 {
587   GVariant *variant = NULL;
588   JsonArray *array;
589   gint i;
590   GList *children = NULL;
591   gboolean roll_back = FALSE;
592   const gchar *initial_signature;
593
594   array = json_node_get_array (json_node);
595
596   initial_signature = *signature;
597   (*signature)++;
598   i = 1;
599   while ((*signature)[0] != ')' && (*signature)[0] != '\0')
600     {
601       JsonNode *json_child;
602       GVariant *variant_child;
603
604       if (i - 1 >= json_array_get_length (array))
605         {
606           g_set_error_literal (error,
607                                G_IO_ERROR,
608                                G_IO_ERROR_INVALID_DATA,
609                                _("Missing elements in JSON array to conform to a tuple"));
610           roll_back = TRUE;
611           break;
612         }
613
614       json_child = json_array_get_element (array, i - 1);
615
616       variant_child = json_to_gvariant_recurse (json_child, signature, error);
617       if (variant_child != NULL)
618         {
619           children = g_list_append (children, variant_child);
620         }
621       else
622         {
623           roll_back = TRUE;
624           break;
625         }
626
627       i++;
628     }
629
630   if (! roll_back)
631     {
632       if ( (*signature)[0] != ')')
633         {
634           g_set_error_literal (error,
635                                G_IO_ERROR,
636                                G_IO_ERROR_INVALID_DATA,
637                                _("Missing closing symbol ')' in the GVariant tuple type"));
638           roll_back = TRUE;
639         }
640       else if (json_array_get_length (array) >= i)
641         {
642           g_set_error_literal (error,
643                                G_IO_ERROR,
644                                G_IO_ERROR_INVALID_DATA,
645                                _("Unexpected extra elements in JSON array"));
646           roll_back = TRUE;
647         }
648       else
649         {
650           gchar *tuple_type;
651
652           tuple_type = g_strndup (initial_signature,
653                                   (*signature) - initial_signature + 1);
654
655           variant = json_to_gvariant_build_from_glist (children, tuple_type);
656
657           g_free (tuple_type);
658         }
659     }
660
661   if (roll_back)
662     g_list_foreach (children, json_to_gvariant_foreach_free, NULL);
663
664   g_list_free (children);
665
666   return variant;
667 }
668
669 static gchar *
670 signature_get_next_complete_type (const gchar **signature)
671 {
672   GVariantClass class;
673   const gchar *initial_signature;
674   gchar *result;
675
676   /* here it is assumed that 'signature' is a valid type string */
677
678   initial_signature = *signature;
679   class = (*signature)[0];
680
681   if (class == G_VARIANT_CLASS_TUPLE || class == G_VARIANT_CLASS_DICT_ENTRY)
682     {
683       gchar stack[256] = {0};
684       guint stack_len = 0;
685
686       do
687         {
688           if ( (*signature)[0] == G_VARIANT_CLASS_TUPLE)
689             {
690               stack[stack_len] = ')';
691               stack_len++;
692             }
693           else if ( (*signature)[0] == G_VARIANT_CLASS_DICT_ENTRY)
694             {
695               stack[stack_len] = '}';
696               stack_len++;
697             }
698
699           (*signature)++;
700
701           if ( (*signature)[0] == stack[stack_len - 1])
702             stack_len--;
703         }
704       while (stack_len > 0);
705
706       (*signature)++;
707     }
708   else if (class == G_VARIANT_CLASS_ARRAY || class == G_VARIANT_CLASS_MAYBE)
709     {
710       gchar *tmp_sig;
711
712       (*signature)++;
713       tmp_sig = signature_get_next_complete_type (signature);
714       g_free (tmp_sig);
715     }
716   else
717     {
718       (*signature)++;
719     }
720
721   result = g_strndup (initial_signature, (*signature) - initial_signature);
722
723   return result;
724 }
725
726 static GVariant *
727 json_to_gvariant_maybe (JsonNode     *json_node,
728                         const gchar **signature,
729                         GError      **error)
730 {
731   GVariant *variant = NULL;
732   GVariant *value;
733   gchar *maybe_signature;
734
735   if (signature)
736     {
737       (*signature)++;
738       maybe_signature = signature_get_next_complete_type (signature);
739     }
740   else
741     {
742       maybe_signature = g_strdup ("v");
743     }
744
745   if (json_node_get_node_type (json_node) == JSON_NODE_NULL)
746     {
747       variant = g_variant_new_maybe (G_VARIANT_TYPE (maybe_signature), NULL);
748     }
749   else
750     {
751       const gchar *tmp_signature;
752
753       tmp_signature = maybe_signature;
754       value = json_to_gvariant_recurse (json_node,
755                                         &tmp_signature,
756                                         error);
757
758       if (value != NULL)
759         variant = g_variant_new_maybe (G_VARIANT_TYPE (maybe_signature), value);
760     }
761
762   g_free (maybe_signature);
763
764   /* compensate the (*signature)++ call at the end of 'recurse()' */
765   if (signature)
766     (*signature)--;
767
768   return variant;
769 }
770
771 static GVariant *
772 json_to_gvariant_array (JsonNode     *json_node,
773                         const gchar **signature,
774                         GError      **error)
775 {
776   GVariant *variant = NULL;
777   JsonArray *array;
778   GList *children = NULL;
779   gboolean roll_back = FALSE;
780   const gchar *orig_signature;
781   gchar *child_signature;
782
783   array = json_node_get_array (json_node);
784
785   if (signature != NULL)
786     {
787       orig_signature = *signature;
788
789       (*signature)++;
790       child_signature = signature_get_next_complete_type (signature);
791     }
792   else
793     child_signature = g_strdup ("v");
794
795   if (json_array_get_length (array) > 0)
796     {
797       gint i;
798       guint len;
799
800       len = json_array_get_length (array);
801       for (i = 0; i < len; i++)
802         {
803           JsonNode *json_child;
804           GVariant *variant_child;
805           const gchar *tmp_signature;
806
807           json_child = json_array_get_element (array, i);
808
809           tmp_signature = child_signature;
810           variant_child = json_to_gvariant_recurse (json_child,
811                                                     &tmp_signature,
812                                                     error);
813           if (variant_child != NULL)
814             {
815               children = g_list_append (children, variant_child);
816             }
817           else
818             {
819               roll_back = TRUE;
820               break;
821             }
822         }
823     }
824
825   if (!roll_back)
826     {
827       gchar *array_signature;
828
829       if (signature)
830         array_signature = g_strndup (orig_signature, (*signature) - orig_signature);
831       else
832         array_signature = g_strdup ("av");
833
834       variant = json_to_gvariant_build_from_glist (children, array_signature);
835
836       g_free (array_signature);
837
838       /* compensate the (*signature)++ call at the end of 'recurse()' */
839       if (signature)
840         (*signature)--;
841     }
842   else
843     g_list_foreach (children, json_to_gvariant_foreach_free, NULL);
844
845   g_list_free (children);
846   g_free (child_signature);
847
848   return variant;
849 }
850
851 static GVariant *
852 gvariant_simple_from_string (const gchar    *st,
853                              GVariantClass   class,
854                              GError        **error)
855 {
856   GVariant *variant = NULL;
857   gchar *nptr = NULL;
858
859   errno = 0;
860
861   switch (class)
862     {
863     case G_VARIANT_CLASS_BOOLEAN:
864       if (g_strcmp0 (st, "true") == 0)
865         variant = g_variant_new_boolean (TRUE);
866       else if (g_strcmp0 (st, "false") == 0)
867         variant = g_variant_new_boolean (FALSE);
868       else
869         errno = 1;
870       break;
871
872     case G_VARIANT_CLASS_BYTE:
873       variant = g_variant_new_byte (g_ascii_strtoll (st, &nptr, 10));
874       break;
875
876     case G_VARIANT_CLASS_INT16:
877       variant = g_variant_new_int16 (g_ascii_strtoll (st, &nptr, 10));
878       break;
879
880     case G_VARIANT_CLASS_UINT16:
881       variant = g_variant_new_uint16 (g_ascii_strtoll (st, &nptr, 10));
882       break;
883
884     case G_VARIANT_CLASS_INT32:
885       variant = g_variant_new_int32 (g_ascii_strtoll (st, &nptr, 10));
886       break;
887
888     case G_VARIANT_CLASS_UINT32:
889       variant = g_variant_new_uint32 (g_ascii_strtoull (st, &nptr, 10));
890       break;
891
892     case G_VARIANT_CLASS_INT64:
893       variant = g_variant_new_int64 (g_ascii_strtoll (st, &nptr, 10));
894       break;
895
896     case G_VARIANT_CLASS_UINT64:
897       variant = g_variant_new_uint64 (g_ascii_strtoull (st, &nptr, 10));
898       break;
899
900     case G_VARIANT_CLASS_HANDLE:
901       variant = g_variant_new_handle (strtol (st, &nptr, 10));
902       break;
903
904     case G_VARIANT_CLASS_DOUBLE:
905       variant = g_variant_new_double (g_ascii_strtod (st, &nptr));
906       break;
907
908     case G_VARIANT_CLASS_STRING:
909     case G_VARIANT_CLASS_OBJECT_PATH:
910     case G_VARIANT_CLASS_SIGNATURE:
911       variant = g_variant_new_string (st);
912       break;
913
914     default:
915       g_assert_not_reached ();
916       break;
917     }
918
919   if (errno != 0 || nptr == st)
920     {
921       g_set_error_literal (error,
922                            G_IO_ERROR,
923                            G_IO_ERROR_INVALID_DATA,
924                            _("Invalid string value converting to GVariant"));
925       if (variant != NULL)
926         {
927           g_variant_unref (variant);
928           variant = NULL;
929         }
930     }
931
932   return variant;
933 }
934
935 static void
936 parse_dict_entry_signature (const gchar **signature,
937                             gchar       **entry_signature,
938                             gchar       **key_signature,
939                             gchar       **value_signature)
940 {
941   const gchar *tmp_sig;
942
943   if (signature != NULL)
944     *entry_signature = signature_get_next_complete_type (signature);
945   else
946     *entry_signature = g_strdup ("{sv}");
947
948   tmp_sig = (*entry_signature) + 1;
949   *key_signature = signature_get_next_complete_type (&tmp_sig);
950   *value_signature = signature_get_next_complete_type (&tmp_sig);
951 }
952
953 static GVariant *
954 json_to_gvariant_dict_entry (JsonNode     *json_node,
955                              const gchar **signature,
956                              GError      **error)
957 {
958   GVariant *variant = NULL;
959   JsonObject *obj;
960
961   gchar *entry_signature;
962   gchar *key_signature;
963   gchar *value_signature;
964   const gchar *tmp_signature;
965
966   GList *member;
967
968   const gchar *json_member;
969   JsonNode *json_value;
970   GVariant *variant_member;
971   GVariant *variant_value;
972
973   obj = json_node_get_object (json_node);
974
975   if (json_object_get_size (obj) != 1)
976     {
977       g_set_error_literal (error,
978                            G_IO_ERROR,
979                            G_IO_ERROR_INVALID_DATA,
980                            _("A GVariant dictionary entry expects a JSON object with exactly one member"));
981       return NULL;
982     }
983
984   parse_dict_entry_signature (signature,
985                               &entry_signature,
986                               &key_signature,
987                               &value_signature);
988
989   member = json_object_get_members (obj);
990
991   json_member = (const gchar *) member->data;
992   variant_member = gvariant_simple_from_string (json_member,
993                                                 key_signature[0],
994                                                 error);
995   if (variant_member != NULL)
996     {
997       json_value = json_object_get_member (obj, json_member);
998
999       tmp_signature = value_signature;
1000       variant_value = json_to_gvariant_recurse (json_value,
1001                                                 &tmp_signature,
1002                                                 error);
1003
1004       if (variant_value != NULL)
1005         {
1006           GVariantBuilder *builder;
1007
1008           builder = g_variant_builder_new (G_VARIANT_TYPE (entry_signature));
1009           g_variant_builder_add_value (builder, variant_member);
1010           g_variant_builder_add_value (builder, variant_value);
1011           variant = g_variant_builder_end (builder);
1012
1013           g_variant_builder_unref (builder);
1014         }
1015     }
1016
1017   g_list_free (member);
1018   g_free (value_signature);
1019   g_free (key_signature);
1020   g_free (entry_signature);
1021
1022   /* compensate the (*signature)++ call at the end of 'recurse()' */
1023   if (signature)
1024     (*signature)--;
1025
1026   return variant;
1027 }
1028
1029 static GVariant *
1030 json_to_gvariant_dictionary (JsonNode     *json_node,
1031                              const gchar **signature,
1032                              GError      **error)
1033 {
1034   GVariant *variant = NULL;
1035   JsonObject *obj;
1036   gboolean roll_back = FALSE;
1037
1038   gchar *dict_signature;
1039   gchar *entry_signature;
1040   gchar *key_signature;
1041   gchar *value_signature;
1042   const gchar *tmp_signature;
1043
1044   GVariantBuilder *builder;
1045   GList *members;
1046   GList *member;
1047
1048   obj = json_node_get_object (json_node);
1049
1050   if (signature != NULL)
1051     (*signature)++;
1052
1053   parse_dict_entry_signature (signature,
1054                               &entry_signature,
1055                               &key_signature,
1056                               &value_signature);
1057
1058   dict_signature = g_strdup_printf ("a%s", entry_signature);
1059
1060   builder = g_variant_builder_new (G_VARIANT_TYPE (dict_signature));
1061
1062   members = json_object_get_members (obj);
1063
1064   member = members;
1065   while (member != NULL)
1066     {
1067       const gchar *json_member;
1068       JsonNode *json_value;
1069       GVariant *variant_member;
1070       GVariant *variant_value;
1071
1072       json_member = (const gchar *) member->data;
1073       variant_member = gvariant_simple_from_string (json_member,
1074                                                     key_signature[0],
1075                                                     error);
1076       if (variant_member == NULL)
1077         {
1078           roll_back = TRUE;
1079           break;
1080         }
1081
1082       json_value = json_object_get_member (obj, json_member);
1083
1084       tmp_signature = value_signature;
1085       variant_value = json_to_gvariant_recurse (json_value,
1086                                                 &tmp_signature,
1087                                                 error);
1088
1089       if (variant_value != NULL)
1090         {
1091           g_variant_builder_open (builder, G_VARIANT_TYPE (entry_signature));
1092           g_variant_builder_add_value (builder, variant_member);
1093           g_variant_builder_add_value (builder, variant_value);
1094           g_variant_builder_close (builder);
1095         }
1096       else
1097         {
1098           roll_back = TRUE;
1099           break;
1100         }
1101
1102       member = member->next;
1103     }
1104
1105   if (! roll_back)
1106     variant = g_variant_builder_end (builder);
1107
1108   g_variant_builder_unref (builder);
1109   g_list_free (members);
1110   g_free (value_signature);
1111   g_free (key_signature);
1112   g_free (entry_signature);
1113   g_free (dict_signature);
1114
1115   /* compensate the (*signature)++ call at the end of 'recurse()' */
1116   if (signature != NULL)
1117     (*signature)--;
1118
1119   return variant;
1120 }
1121
1122 static GVariant *
1123 json_to_gvariant_recurse (JsonNode      *json_node,
1124                           const gchar  **signature,
1125                           GError       **error)
1126 {
1127   GVariant *variant = NULL;
1128   GVariantClass class;
1129
1130   class = json_to_gvariant_get_next_class (json_node, signature);
1131
1132   if (class == JSON_G_VARIANT_CLASS_DICTIONARY)
1133     {
1134       if (json_node_assert_type (json_node, JSON_NODE_OBJECT, 0, error))
1135         variant = json_to_gvariant_dictionary (json_node, signature, error);
1136
1137       goto out;
1138     }
1139
1140   switch (class)
1141     {
1142     case G_VARIANT_CLASS_BOOLEAN:
1143       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_BOOLEAN, error))
1144         variant = g_variant_new_boolean (json_node_get_boolean (json_node));
1145       break;
1146
1147     case G_VARIANT_CLASS_BYTE:
1148       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1149         variant = g_variant_new_byte (json_node_get_int (json_node));
1150       break;
1151
1152     case G_VARIANT_CLASS_INT16:
1153       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1154         variant = g_variant_new_int16 (json_node_get_int (json_node));
1155       break;
1156
1157     case G_VARIANT_CLASS_UINT16:
1158       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1159         variant = g_variant_new_uint16 (json_node_get_int (json_node));
1160       break;
1161
1162     case G_VARIANT_CLASS_INT32:
1163       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1164         variant = g_variant_new_int32 (json_node_get_int (json_node));
1165       break;
1166
1167     case G_VARIANT_CLASS_UINT32:
1168       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1169         variant = g_variant_new_uint32 (json_node_get_int (json_node));
1170       break;
1171
1172     case G_VARIANT_CLASS_INT64:
1173       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1174         variant = g_variant_new_int64 (json_node_get_int (json_node));
1175       break;
1176
1177     case G_VARIANT_CLASS_UINT64:
1178       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1179         variant = g_variant_new_uint64 (json_node_get_int (json_node));
1180       break;
1181
1182     case G_VARIANT_CLASS_HANDLE:
1183       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_INT64, error))
1184         variant = g_variant_new_handle (json_node_get_int (json_node));
1185       break;
1186
1187     case G_VARIANT_CLASS_DOUBLE:
1188       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_DOUBLE, error))
1189         variant = g_variant_new_double (json_node_get_double (json_node));
1190       break;
1191
1192     case G_VARIANT_CLASS_STRING:
1193       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error))
1194         variant = g_variant_new_string (json_node_get_string (json_node));
1195       break;
1196
1197     case G_VARIANT_CLASS_OBJECT_PATH:
1198       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error))
1199         variant = g_variant_new_object_path (json_node_get_string (json_node));
1200       break;
1201
1202     case G_VARIANT_CLASS_SIGNATURE:
1203       if (json_node_assert_type (json_node, JSON_NODE_VALUE, G_TYPE_STRING, error))
1204         variant = g_variant_new_signature (json_node_get_string (json_node));
1205       break;
1206
1207     case G_VARIANT_CLASS_VARIANT:
1208       variant = g_variant_new_variant (json_to_gvariant_recurse (json_node,
1209                                                                  NULL,
1210                                                                  error));
1211       break;
1212
1213     case G_VARIANT_CLASS_MAYBE:
1214       variant = json_to_gvariant_maybe (json_node, signature, error);
1215       break;
1216
1217     case G_VARIANT_CLASS_ARRAY:
1218       if (json_node_assert_type (json_node, JSON_NODE_ARRAY, 0, error))
1219         variant = json_to_gvariant_array (json_node, signature, error);
1220       break;
1221
1222     case G_VARIANT_CLASS_TUPLE:
1223       if (json_node_assert_type (json_node, JSON_NODE_ARRAY, 0, error))
1224         variant = json_to_gvariant_tuple (json_node, signature, error);
1225       break;
1226
1227     case G_VARIANT_CLASS_DICT_ENTRY:
1228       if (json_node_assert_type (json_node, JSON_NODE_OBJECT, 0, error))
1229         variant = json_to_gvariant_dict_entry (json_node, signature, error);
1230       break;
1231
1232     default:
1233       g_set_error (error,
1234                    G_IO_ERROR,
1235                    G_IO_ERROR_INVALID_DATA,
1236                    _("GVariant class '%c' not supported"), class);
1237       break;
1238     }
1239
1240 out:
1241   if (signature)
1242     (*signature)++;
1243
1244   return variant;
1245 }
1246
1247 /**
1248  * json_gvariant_deserialize:
1249  * @json_node: A #JsonNode to convert
1250  * @signature: (allow-none): A valid #GVariant type string, or %NULL
1251  * @error: A pointer to a #GError
1252  *
1253  * Converts a JSON data structure to a GVariant value using @signature to
1254  * resolve ambiguous data types. If no error occurs, the resulting #GVariant
1255  * is guaranteed to conform to @signature.
1256  *
1257  * If @signature is not %NULL but does not represent a valid GVariant type
1258  * string, %NULL is returned and error is set to %G_IO_ERROR_INVALID_ARGUMENT.
1259  * If a @signature is provided but the JSON structure cannot be mapped to it,
1260  * %NULL is returned and error is set to %G_IO_ERROR_INVALID_DATA.
1261  * If @signature is %NULL, the conversion is done based strictly on the types
1262  * in the JSON nodes.
1263  *
1264  * Return value: (transfer full): A newly created #GVariant compliant with
1265  *   @signature, or %NULL on error
1266  *
1267  * Since: 0.14
1268  */
1269 GVariant *
1270 json_gvariant_deserialize (JsonNode     *json_node,
1271                            const gchar  *signature,
1272                            GError      **error)
1273 {
1274   g_return_val_if_fail (json_node != NULL, NULL);
1275
1276   if (signature != NULL && ! g_variant_type_string_is_valid (signature))
1277     {
1278       g_set_error_literal (error,
1279                            G_IO_ERROR,
1280                            G_IO_ERROR_INVALID_ARGUMENT,
1281                            _("Invalid GVariant signature"));
1282       return NULL;
1283     }
1284
1285   return json_to_gvariant_recurse (json_node, signature ? &signature : NULL, error);
1286 }
1287
1288 /**
1289  * json_gvariant_deserialize_data:
1290  * @json: A JSON data string
1291  * @length: The length of @json, or -1 if %NULL-terminated
1292  * @signature: (allow-none): A valid #GVariant type string, or %NULL
1293  * @error: A pointer to a #GError
1294  *
1295  * Converts a JSON string to a #GVariant value. This method works exactly
1296  * like json_gvariant_deserialize(), but takes a JSON encoded string instead.
1297  * The string is first converted to a #JsonNode using #JsonParser, and then
1298  * json_gvariant_deserialize() is called.
1299  *
1300  * Returns: (transfer full): A newly created #GVariant compliant with
1301  *   @signature, or %NULL on error
1302  *
1303  * Since: 0.14
1304  */
1305 GVariant *
1306 json_gvariant_deserialize_data (const gchar  *json,
1307                                 gssize        length,
1308                                 const gchar  *signature,
1309                                 GError      **error)
1310 {
1311   JsonParser *parser;
1312   GVariant *variant = NULL;
1313   JsonNode *root;
1314
1315   parser = json_parser_new ();
1316
1317   if (! json_parser_load_from_data (parser, json, length, error))
1318     return NULL;
1319
1320   root = json_parser_get_root (parser);
1321   if (root == NULL)
1322     {
1323       g_set_error_literal (error,
1324                            G_IO_ERROR,
1325                            G_IO_ERROR_INVALID_DATA,
1326                            _("JSON data is empty"));
1327     }
1328   else
1329     {
1330       variant =
1331         json_gvariant_deserialize (json_parser_get_root (parser), signature, error);
1332     }
1333
1334   g_object_unref (parser);
1335
1336   return variant;
1337 }