[pango/serialize-attrs-and-tabs: 4/4] Add pango_tab_array_to/from_string




commit 5da2ada3e7c032d3671b0faf95e75f2b46dc0078
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Nov 14 00:12:34 2021 -0500

    Add pango_tab_array_to/from_string

 pango/pango-tabs.c    | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++
 pango/pango-tabs.h    |   4 ++
 tests/testserialize.c |  48 ++++++++++++++++++++++++
 3 files changed, 154 insertions(+)
---
diff --git a/pango/pango-tabs.c b/pango/pango-tabs.c
index 28027454..c126ec91 100644
--- a/pango/pango-tabs.c
+++ b/pango/pango-tabs.c
@@ -371,3 +371,105 @@ pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array)
 
   return tab_array->positions_in_pixels;
 }
+
+/**
+ * pango_tab_array_to_string:
+ * @tab_array: a `PangoTabArray`
+ *
+ * Serializes a `PangoTabArray` to a string.
+ *
+ * No guarantees are made about the format of the string,
+ * it may change between Pango versions.
+ *
+ * The intended use of this function is testing and
+ * debugging. The format is not meant as a permanent
+ * storage format.
+ *
+ * Returns: (transfer full): a newly allocated string
+ * Since: 1.50
+ */
+char *
+pango_tab_array_to_string (PangoTabArray *tab_array)
+{
+  GString *s;
+
+  s = g_string_new ("");
+
+  for (int i = 0; i < tab_array->size; i++)
+    {
+      if (i > 0)
+        g_string_append_c (s, ' ');
+      g_string_append_printf (s, "%d", tab_array->tabs[i].location);
+      if (tab_array->positions_in_pixels)
+        g_string_append (s, "px");
+    }
+
+  return g_string_free (s, FALSE);
+}
+
+static const char *
+skip_whitespace (const char *p)
+{
+  while (g_ascii_isspace (*p))
+    p++;
+  return p;
+}
+
+/**
+ * pango_tab_array_from_string:
+ * @text: a string
+ *
+ * Deserializes a `PangoTabArray` from a string.
+ *
+ * This is the counterpart to [func@Pango.TabArray.to_string].
+ * See that functions for details about the format.
+ *
+ * Returns: (transfer full) (nullable): a new `PangoTabArray`
+ * Since: 1.50
+ */
+PangoTabArray *
+pango_tab_array_from_string (const char *text)
+{
+  PangoTabArray *array;
+  gboolean pixels;
+  const char *p;
+  int i;
+
+  pixels = strstr (text, "px") != NULL;
+
+  array = pango_tab_array_new (0, pixels);
+
+  p = skip_whitespace (text);
+
+  i = 0;
+  while (*p)
+    {
+      char *endp;
+      gint64 pos;
+
+      pos = g_ascii_strtoll (p, &endp, 10);
+      if (pos < 0 ||
+          (pixels && *endp != 'p') ||
+          (!pixels && !g_ascii_isspace (*endp) && *endp != '\0')) goto fail;
+
+      pango_tab_array_set_tab (array, i, PANGO_TAB_LEFT, pos);
+      i++;
+
+      p = (const char *)endp;
+      if (pixels)
+        {
+          if (p[0] != 'p' || p[1] != 'x') goto fail;
+          p += 2;
+        }
+      p = skip_whitespace (p);
+    }
+
+  goto success;
+
+fail:
+  pango_tab_array_free (array);
+  array = NULL;
+
+success:
+  return array;
+}
diff --git a/pango/pango-tabs.h b/pango/pango-tabs.h
index 893132ed..e8ce1b97 100644
--- a/pango/pango-tabs.h
+++ b/pango/pango-tabs.h
@@ -87,6 +87,10 @@ void            pango_tab_array_get_tabs            (PangoTabArray *tab_array,
 PANGO_AVAILABLE_IN_ALL
 gboolean        pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array);
 
+PANGO_AVAILABLE_IN_1_50
+char *          pango_tab_array_to_string           (PangoTabArray *tab_array);
+PANGO_AVAILABLE_IN_1_50
+PangoTabArray * pango_tab_array_from_string         (const char    *text);
 
 G_END_DECLS
 
diff --git a/tests/testserialize.c b/tests/testserialize.c
index 8135b60c..bf8caab0 100644
--- a/tests/testserialize.c
+++ b/tests/testserialize.c
@@ -74,12 +74,60 @@ test_serialize_attr_list (void)
     }
 }
 
+static void
+test_serialize_tab_array (void)
+{
+  const char *valid[] = {
+    "0 10 100 200 400",
+    "0px 10px 100px 200px 400px",
+    "  0    10   ",
+    "20 10",
+    ""
+  };
+  const char *roundtripped[] = {
+    "0 10 100 200 400",
+    "0px 10px 100px 200px 400px",
+    "0 10",
+    "20 10",
+    ""
+  };
+  const char *invalid[] = {
+    "not a tabarray",
+    "-10\n-20",
+    "10ps 20pu",
+    "10, 20",
+    "10 20px 30",
+  };
+
+  for (int i = 0; i < G_N_ELEMENTS (valid); i++)
+    {
+      PangoTabArray *tabs;
+      char *str;
+
+      tabs = pango_tab_array_from_string (valid[i]);
+      g_assert_nonnull (tabs);
+      str = pango_tab_array_to_string (tabs);
+      g_assert_cmpstr (str, ==, roundtripped[i]);
+      g_free (str);
+      pango_tab_array_free (tabs);
+    }
+
+  for (int i = 0; i < G_N_ELEMENTS (invalid); i++)
+    {
+      PangoTabArray *tabs;
+
+      tabs = pango_tab_array_from_string (invalid[i]);
+      g_assert_null (tabs);
+    }
+}
+
 int
 main (int argc, char *argv[])
 {
   g_test_init (&argc, &argv, NULL);
 
   g_test_add_func ("/serialize/attr-list", test_serialize_attr_list);
+  g_test_add_func ("/serialize/tab-array", test_serialize_tab_array);
 
   return g_test_run ();
 }


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