[glib/gvariant] add new format string operator: ^



commit 7768204bb0ddb18dd64f264404f725bbaa7a6bb1
Author: Ryan Lortie <desrt desrt ca>
Date:   Fri Aug 14 15:27:07 2009 -0400

    add new format string operator: ^
    
    '^' will convert from GVariant to C types.  Currently only supported for
    ^as (gchar **) and ^a&s (const gchar **).

 glib/gvariant-valist.c |  157 ++++++++++++++++++++++++++++--------------------
 1 files changed, 92 insertions(+), 65 deletions(-)
---
diff --git a/glib/gvariant-valist.c b/glib/gvariant-valist.c
index c212cdf..cc79d46 100644
--- a/glib/gvariant-valist.c
+++ b/glib/gvariant-valist.c
@@ -44,9 +44,9 @@
  * Additionally, any array of fixed-width types may be prefixed with a
  * '&'.
  *
- * Additionally, '&s', '&as' and '&a&s' may appear.
+ * Additionally, '&s', '^as' and '^a&s' may appear.
  *
- * No '@' or '&' character, however, may appear as part of an array
+ * No '@', '&' or '^' character, however, may appear as part of an array
  * type.
  *
  * Currently, there are no other permissible format strings.  Others
@@ -118,19 +118,6 @@ g_variant_format_string_scan (const gchar **format_string)
             *format_string = start + 1;
             return TRUE;
           }
-        else if (start[0] == 'a')
-          {
-            if (start[1] == 's')  /* '&as' */
-              {
-                *format_string = start + 2;
-                return TRUE;
-              }
-            else if (start[1] == '&' && start[2] == 's') /* '&a&s' */
-              {
-                *format_string = start + 3;
-                return TRUE;
-              }
-          }
 
         if (!g_variant_type_string_scan (format_string, NULL))
           return FALSE;
@@ -145,6 +132,17 @@ g_variant_format_string_scan (const gchar **format_string)
         return TRUE;
       }
 
+    case '^':
+      {
+        if (*((*format_string)++) != 'a')
+          return FALSE;
+
+        if (**format_string == '&')
+          (*format_string)++;
+
+        return *((*format_string)++) == 's';
+      }
+
     case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
     case 'x': case 't': case 'd': case 's': case 'o': case 'g':
     case 'v': case '*': case '?': case 'r':
@@ -178,7 +176,7 @@ g_variant_format_string_get_type (const gchar **format_string)
   dest = new = g_malloc (*format_string - src + 1);
   while (src != *format_string)
     {
-      if (*src != '@' && *src != '&')
+      if (*src != '@' && *src != '&' && *src != '^')
         *dest++ = *src;
       src++;
     }
@@ -252,6 +250,27 @@ g_variant_valist_new (const gchar **format_string,
       g_variant_format_string_scan (format_string);
       return va_arg (*app, GVariant *);
 
+    case '^':
+      {
+        const gchar *string = (*format_string + 1);
+
+        if (string[0] == 'a' &&
+            (string[1] == 's' ||
+             (string[1] == '&' && string[2] == 's')))
+          {
+            gconstpointer ptr;
+            gint n_items;
+
+            *format_string += 3 + (string[1] == '&');
+            ptr = va_arg (*app, gconstpointer);
+            n_items = va_arg (*app, gint);
+
+            return g_variant_new_strv ((const gchar **) ptr, n_items);
+          }
+
+        g_error ("Currently, only ^as and ^a&s are supported");
+      }
+
     case '&':
       {
         const gchar *string = (*format_string + 1);
@@ -270,18 +289,6 @@ g_variant_valist_new (const gchar **format_string,
           case 'a':
             n_items = va_arg (*app, gint);
 
-            if (string[1] == 's') /* '&as' */
-              {
-                *format_string += 3;
-                return g_variant_new_strv (va_arg (*app, const gchar **), n_items);
-              }
-
-            if (string[1] == '&' && string[2] == 's') /* '&a&s' */
-              {
-                *format_string += 4;
-                return g_variant_new_strv (va_arg (*app, const gchar **), n_items);
-              }
-
             if (n_items < 0)
               g_error ("size of -1 can only be specified for string arrays");
 
@@ -674,15 +681,58 @@ g_variant_valist_get (GVariant     *value,
         return;
       }
 
+    case '^':
+      {
+        const gchar *string = (*format_string + 1);
+
+        if (string[0] == 'a')
+          {
+            gpointer *ptr;
+            gint *n_items;
+
+            ptr = va_arg (*app, gpointer *);
+            n_items = va_arg (*app, gint *);
+
+            if (string[1] == 's')
+              {
+                *format_string += 3;
+
+                if (free && *ptr)
+                  g_strfreev (*ptr);
+
+                if (value)
+                  *ptr = g_variant_dup_strv (value, n_items);
+                else
+                  *ptr = NULL;
+
+                return;
+              }
+
+            if (string[1] == '&' && string[2] == 's')
+              {
+                *format_string += 4;
+
+                if (free && *ptr)
+                  g_free (*ptr);
+
+                if (value)
+                  *ptr = g_variant_get_strv (value, n_items);
+                else
+                  *ptr = NULL;
+
+                return;
+              }
+          }
+
+        g_error ("Currently, only ^as and ^a&s are supported");
+      }
+
+
     case '&':
       {
-        /* this can be 'const gchar *' but also 'gchar **' so
-         * we lose a little type safety here...
-         * but srsly, it's varargs!
-         */
-        gpointer *ptr;
+        gconstpointer *ptr;
 
-        ptr = va_arg (*app, gpointer *);
+        ptr = va_arg (*app, gconstpointer *);
 
         if ((*format_string)[1] == 's') /* '&s' */
           {
@@ -691,13 +741,16 @@ g_variant_valist_get (GVariant     *value,
             if (ptr)
               {
                 if (value)
-                  *ptr = (gpointer) g_variant_get_string (value, NULL);
+                  *ptr = g_variant_get_string (value, NULL);
                 else
                   *ptr = NULL;
               }
+
+            (*format_string) += 2;
+            return;
           }
 
-        else if ((*format_string)[1] == 'a') /* '&a..' */
+        if ((*format_string)[1] == 'a') /* '&a..' */
           {
             gint *n_items = va_arg (*app, gint *);
 
@@ -712,36 +765,10 @@ g_variant_valist_get (GVariant     *value,
 
         if (ptr)
           {
-            if ((*format_string)[1] == 'a' &&
-                (*format_string)[2] == 's')
-              {
-                if (free && *ptr)
-                  g_strfreev (*ptr);
-
-                if (value)
-                  *ptr = g_variant_dup_strv (value, NULL);
-                else
-                  *ptr = NULL;
-              }
-            else if ((*format_string)[1] == 'a' &&
-                     (*format_string)[2] == '&' &&
-                     (*format_string)[3] == 's')
-              {
-                if (free && *ptr)
-                  g_free (*ptr);
-
-                if (value)
-                  *ptr = g_variant_get_strv (value, NULL);
-                else
-                  *ptr = NULL;
-              }
+            if (value)
+              *ptr = g_variant_get_data (value);
             else
-              {
-                if (value)
-                  *ptr = (gpointer) g_variant_get_data (value);
-                else
-                  *ptr = NULL;
-              }
+              *ptr = NULL;
           }
 
         g_variant_format_string_scan (format_string);



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