[json-glib] Make JSON to GVariant conversion handle some string to number conversions.



commit 64b4f936617e781e9a3677cf98b2abde94b8ef2a
Author: Joseph Artsimovich <joseph artsimovich youview com>
Date:   Tue Sep 3 11:30:08 2013 +0100

    Make JSON to GVariant conversion handle some string to number conversions.
    
    Consider the following JSON: ["123"]
    Trying to convert it to GVariant with signature "(i)" would previously fail,
    as string-to-number conversions weren't implemented. This patch implements
    string-to-number and string-to-boolean conversions.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=707382

 json-glib/json-gvariant.c  |   24 ++++++++++++++++++++++++
 json-glib/tests/gvariant.c |   37 ++++++++++++++++++++++++++++++-------
 2 files changed, 54 insertions(+), 7 deletions(-)
---
diff --git a/json-glib/json-gvariant.c b/json-glib/json-gvariant.c
index 932914a..99b2b8f 100644
--- a/json-glib/json-gvariant.c
+++ b/json-glib/json-gvariant.c
@@ -1138,6 +1138,30 @@ json_to_gvariant_recurse (JsonNode      *json_node,
       goto out;
     }
 
+  if (JSON_NODE_TYPE (json_node) == JSON_NODE_VALUE &&
+      json_node_get_value_type (json_node) == G_TYPE_STRING)
+    {
+      const gchar* str = json_node_get_string (json_node);
+      switch (class)
+        {
+        case G_VARIANT_CLASS_BOOLEAN:
+        case G_VARIANT_CLASS_BYTE:
+        case G_VARIANT_CLASS_INT16:
+        case G_VARIANT_CLASS_UINT16:
+        case G_VARIANT_CLASS_INT32:
+        case G_VARIANT_CLASS_UINT32:
+        case G_VARIANT_CLASS_INT64:
+        case G_VARIANT_CLASS_UINT64:
+        case G_VARIANT_CLASS_HANDLE:
+        case G_VARIANT_CLASS_DOUBLE:
+        case G_VARIANT_CLASS_STRING:
+          variant = gvariant_simple_from_string (str, class, error);
+          goto out;
+        default:
+          break;
+        }
+    }
+
   switch (class)
     {
     case G_VARIANT_CLASS_BOOLEAN:
diff --git a/json-glib/tests/gvariant.c b/json-glib/tests/gvariant.c
index acb7f69..3ef4b98 100644
--- a/json-glib/tests/gvariant.c
+++ b/json-glib/tests/gvariant.c
@@ -12,7 +12,7 @@ typedef struct
 
 /* each entry in this list spawns to a GVariant-to-JSON and
    JSON-to-GVariant test */
-const TestCase test_cases[] =
+const TestCase two_way_test_cases[] =
   {
     /* boolean */
     { "/boolean", "(b)", "(true,)", "[true]" },
@@ -145,6 +145,18 @@ const TestCase test_cases[] =
       "[{\"true\":1,\"false\":0},[\"do\",null,\"did\"],[],null,{\"10000\":[\"yes\",\"august\"],\"0\":null}]" 
},
   };
 
+const TestCase json_to_gvariant_test_cases[] =
+  {
+    { "/string-to-boolean", "(b)", "(true,)", "[\"true\"]" },
+    { "/string-to-byte", "(y)", "(byte 0xff,)", "[\"255\"]" },
+    { "/string-to-int16", "(n)", "(int16 -12345,)", "[\"-12345\"]" },
+    { "/string-to-uint16", "(q)", "(uint16 40001,)", "[\"40001\"]" },
+    { "/string-to-int32", "(i)", "(-7654321,)", "[\"-7654321\"]" },
+    { "/string-to-int64", "(x)", "(int64 -666999666999,)", "[\"-666999666999\"]" },
+    { "/string-to-uint64", "(t)", "(uint64 1999999999999999,)", "[\"1999999999999999\"]" },
+    { "/string-to-double", "(d)", "(1.23,)", "[\"1.23\"]" },
+  };
+
 static void
 test_gvariant_to_json (gconstpointer test_data)
 {
@@ -207,23 +219,34 @@ main (gint argc, gchar *argv[])
   g_test_init (&argc, &argv, NULL);
 
   /* GVariant to JSON */
-  for (i = 0; i < sizeof (test_cases) / sizeof (TestCase); i++)
+  for (i = 0; i < sizeof (two_way_test_cases) / sizeof (TestCase); i++)
     {
-      test_case = test_cases[i];
+      test_case = two_way_test_cases[i];
       test_name = g_strdup_printf ("/gvariant/to-json/%s", test_case.test_name);
 
-      g_test_add_data_func (test_name, &test_cases[i], test_gvariant_to_json);
+      g_test_add_data_func (test_name, &two_way_test_cases[i], test_gvariant_to_json);
 
       g_free (test_name);
     }
 
   /* JSON to GVariant */
-  for (i = 0; i < sizeof (test_cases) / sizeof (TestCase); i++)
+  for (i = 0; i < sizeof (two_way_test_cases) / sizeof (TestCase); i++)
+    {
+      test_case = two_way_test_cases[i];
+      test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name);
+
+      g_test_add_data_func (test_name, &two_way_test_cases[i], test_json_to_gvariant);
+
+      g_free (test_name);
+    }
+
+  /* JSON to GVariant one way tests */
+  for (i = 0; i < sizeof (json_to_gvariant_test_cases) / sizeof (TestCase); i++)
     {
-      test_case = test_cases[i];
+      test_case = json_to_gvariant_test_cases[i];
       test_name = g_strdup_printf ("/gvariant/from-json/%s", test_case.test_name);
 
-      g_test_add_data_func (test_name, &test_cases[i], test_json_to_gvariant);
+      g_test_add_data_func (test_name, &json_to_gvariant_test_cases[i], test_json_to_gvariant);
 
       g_free (test_name);
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]