[template-glib: 1/4] Allow for to iterate over strv stored as either a boxed value or variant



commit 57e3c77d7704db068989c63cbd4b3ca95b725e03
Author: Zander Brown <ajhb2001 outlook com>
Date:   Sat Feb 3 22:43:58 2018 +0000

    Allow for to iterate over strv stored as either a boxed value or variant
    
    Various parts of this implementation are potentially a little naive
    
    Also adds type annotation to `tmpl_symbol_assign_object` allowing
    introspection based languages to throw appropriate errors when passing
    non-gobjects

 src/tmpl-iterator.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/tmpl-scope.c    | 40 ++++++++++++++++++++++++++++++++++
 src/tmpl-scope.h    | 11 ++++++++++
 src/tmpl-symbol.c   | 42 ++++++++++++++++++++++++++++++++++++
 src/tmpl-symbol.h   |  8 +++++++
 5 files changed, 163 insertions(+)
---
diff --git a/src/tmpl-iterator.c b/src/tmpl-iterator.c
index 04252e8..f7cc97d 100644
--- a/src/tmpl-iterator.c
+++ b/src/tmpl-iterator.c
@@ -57,6 +57,42 @@ string_get_value (TmplIterator *iter,
   return FALSE;
 }
 
+static gboolean
+strv_move_next (TmplIterator *iter)
+{
+  guint index = GPOINTER_TO_INT (iter->data1);
+  index++;
+  
+  if (iter->instance)
+    {
+      gchar **strv = iter->instance;
+      iter->data1 = GINT_TO_POINTER (index);
+      return strv[index] != 0;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+strv_get_value (TmplIterator *iter,
+                GValue       *value)
+{
+  guint index = GPOINTER_TO_INT (iter->data1);
+
+  if (iter->instance)
+    {
+      gchar **strv = iter->instance;
+      gchar *str = strv[index];
+
+      g_value_init (value, G_TYPE_STRING);
+      g_value_set_string (value, str);
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
 static gboolean
 list_model_move_next (TmplIterator *iter)
 {
@@ -127,6 +163,32 @@ tmpl_iterator_init (TmplIterator *iter,
           iter->data2 = GUINT_TO_POINTER (n_items);
         }
     }
+  else if (G_VALUE_HOLDS_VARIANT(value) &&
+            g_variant_is_of_type (
+              g_value_get_variant(value), G_VARIANT_TYPE_STRING_ARRAY))
+    {
+      iter->instance = (const gchar **) g_variant_get_strv (
+        g_value_get_variant (value), NULL);
+      iter->move_next = strv_move_next;
+      iter->get_value = strv_get_value;
+      iter->destroy = NULL;
+      iter->data1 = GINT_TO_POINTER (-1);
+    }
+  else if (G_VALUE_HOLDS_BOXED(value))
+    {
+      // TODO: On the basis more than just strv can be boxed there
+      // should be more checks here
+      iter->instance = (const gchar **) g_value_get_boxed (value);
+      iter->move_next = strv_move_next;
+      iter->get_value = strv_get_value;
+      iter->destroy = NULL;
+      iter->data1 = GINT_TO_POINTER (-1);
+    }
+  else
+    {
+      g_critical ("Don't know how to iterate %s",
+        g_strdup_value_contents (value));
+    }
 
   /* TODO: More iter types */
 }
diff --git a/src/tmpl-scope.c b/src/tmpl-scope.c
index 2cc04fc..7488ab2 100644
--- a/src/tmpl-scope.c
+++ b/src/tmpl-scope.c
@@ -300,6 +300,46 @@ tmpl_scope_set_object (TmplScope   *self,
   tmpl_symbol_assign_object (tmpl_scope_get_full (self, name, TRUE), value);
 }
 
+/**
+ * tmpl_scope_set_variant:
+ * @self: A #TmplScope
+ * @name: a name for the symbol
+ * @value: (nullable): the variant to set it to, or %NULL
+ *
+ * Sets the value of the symbol named @name to the variant @value.
+ */
+void
+tmpl_scope_set_variant (TmplScope   *self,
+                        const gchar *name,
+                        GVariant    *value)
+{
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (name != NULL);
+
+  tmpl_symbol_assign_variant (tmpl_scope_get_full (self, name, TRUE),
+    value);
+}
+
+/**
+ * tmpl_scope_set_strv:
+ * @self: A #TmplScope
+ * @name: a name for the symbol
+ * @value: (nullable) (array zero-terminated=1): the value to set it to, or %NULL
+ *
+ * Sets the value of the symbol named @name to the strv @value.
+ */
+void
+tmpl_scope_set_strv (TmplScope   *self,
+                     const gchar *name,
+                     const gchar **value)
+{
+  g_return_if_fail (self != NULL);
+  g_return_if_fail (name != NULL);
+
+  tmpl_symbol_assign_variant (tmpl_scope_get_full (self, name, TRUE),
+    g_variant_new_strv (value, -1));
+}
+
 /**
  * tmpl_scope_set_string:
  * @self: A #TmplScope
diff --git a/src/tmpl-scope.h b/src/tmpl-scope.h
index 7f788df..dde37cd 100644
--- a/src/tmpl-scope.h
+++ b/src/tmpl-scope.h
@@ -76,6 +76,17 @@ TMPL_AVAILABLE_IN_ALL
 void        tmpl_scope_set_object      (TmplScope         *self,
                                         const gchar       *name,
                                         gpointer           value);
+
+TMPL_AVAILABLE_IN_3_28
+void        tmpl_scope_set_strv        (TmplScope   *self,
+                                        const gchar *name,
+                                        const gchar **value);
+
+TMPL_AVAILABLE_IN_3_28
+void        tmpl_scope_set_variant     (TmplScope   *self,
+                                        const gchar *name,
+                                        GVariant    *value);
+
 TMPL_AVAILABLE_IN_ALL
 void        tmpl_scope_set_resolver    (TmplScope         *self,
                                         TmplScopeResolver  resolver,
diff --git a/src/tmpl-symbol.c b/src/tmpl-symbol.c
index 78339c7..2dd05d1 100644
--- a/src/tmpl-symbol.c
+++ b/src/tmpl-symbol.c
@@ -222,6 +222,13 @@ tmpl_symbol_assign_string (TmplSymbol  *self,
   g_value_unset (&value);
 }
 
+/**
+ * tmpl_symbol_assign_object:
+ * @self: A #TmplSymbol
+ * @v_object: (type GObject.Object) (nullable): a #GObject or %NULL.
+ *
+ * Sets the value to the object @v_object.
+ */
 void
 tmpl_symbol_assign_object (TmplSymbol *self,
                            gpointer    v_object)
@@ -235,3 +242,38 @@ tmpl_symbol_assign_object (TmplSymbol *self,
   tmpl_symbol_assign_value (self, &value);
   g_value_unset (&value);
 }
+
+void
+tmpl_symbol_assign_variant (TmplSymbol *self,
+                            GVariant   *v_variant)
+{
+  GValue value = G_VALUE_INIT;
+
+  g_return_if_fail (self != NULL);
+
+  g_value_init (&value, G_TYPE_VARIANT);
+  g_value_set_variant (&value, v_variant);
+  tmpl_symbol_assign_value (self, &value);
+  g_value_unset (&value);
+}
+
+/**
+ * tmpl_symbol_assign_strv:
+ * @self: A #TmplSymbol
+ * @strv: (nullable) (array zero-terminated=1): the value to set, or %NULL
+ *
+ * Sets the value to the strv @strv.
+ */
+void
+tmpl_symbol_assign_strv (TmplSymbol *self,
+                         const gchar **strv)
+{
+  GValue value = G_VALUE_INIT;
+
+  g_return_if_fail (self != NULL);
+
+  g_value_init (&value, G_TYPE_VARIANT);
+  g_value_set_variant (&value, g_variant_new_strv (strv, -1));
+  tmpl_symbol_assign_value (self, &value);
+  g_value_unset (&value);
+}
diff --git a/src/tmpl-symbol.h b/src/tmpl-symbol.h
index 4ae2177..78c6b1d 100644
--- a/src/tmpl-symbol.h
+++ b/src/tmpl-symbol.h
@@ -58,6 +58,14 @@ void            tmpl_symbol_assign_string   (TmplSymbol   *self,
 TMPL_AVAILABLE_IN_ALL
 void            tmpl_symbol_assign_object   (TmplSymbol   *self,
                                              gpointer      v_object);
+TMPL_AVAILABLE_IN_3_28
+void            tmpl_symbol_assign_variant (TmplSymbol *self,
+                                            GVariant   *v_variant);
+
+TMPL_AVAILABLE_IN_3_28
+void            tmpl_symbol_assign_strv    (TmplSymbol *self,
+                                            const gchar **strv);
+
 TMPL_AVAILABLE_IN_ALL
 void            tmpl_symbol_assign_expr     (TmplSymbol   *self,
                                              TmplExpr     *expr,


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