[glib: 1/2] Adding a function g_array_copy() to glib/garray.c



commit 46f70e9901ad8ee996a746d1f5f830618d200901
Author: Emmanuel Fleury <emmanuel fleury u-bordeaux fr>
Date:   Tue May 28 09:46:20 2019 +0200

    Adding a function g_array_copy() to glib/garray.c
    
    Original code from Simon van der Linden
    
    Close issue #236

 docs/reference/glib/glib-sections.txt |  1 +
 glib/garray.c                         | 28 ++++++++++++++++++
 glib/garray.h                         |  2 ++
 glib/tests/array-test.c               | 53 +++++++++++++++++++++++++++++++++++
 4 files changed, 84 insertions(+)
---
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index 058000e16..2ab5b17fa 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -2611,6 +2611,7 @@ g_string_chunk_free
 GArray
 g_array_new
 g_array_sized_new
+g_array_copy
 g_array_ref
 g_array_unref
 g_array_get_element_size
diff --git a/glib/garray.c b/glib/garray.c
index 2b7957a92..2b35a9e0e 100644
--- a/glib/garray.c
+++ b/glib/garray.c
@@ -999,6 +999,34 @@ g_ptr_array_sized_new (guint reserved_size)
   return (GPtrArray*) array;  
 }
 
+/**
+ * g_array_copy:
+ * @array: A #GArray.
+ *
+ * Create a shallow copy of a #GArray. If the array elements consist of
+ * pointers to data, the pointers are copied but the actual data is not.
+ *
+ * Returns: (transfer container): A copy of @array.
+ *
+ * Since: 2.62
+ **/
+GArray *
+g_array_copy (GArray *array)
+{
+  GRealArray *rarray = (GRealArray *) array;
+  GRealArray *new_rarray;
+
+  g_return_val_if_fail (rarray != NULL, NULL);
+
+  new_rarray =
+    (GRealArray *) g_array_sized_new (rarray->zero_terminated, rarray->clear,
+                                      rarray->elt_size, rarray->len);
+  new_rarray->len = rarray->len;
+  memcpy (new_rarray->data, rarray->data, rarray->alloc);
+
+  return (GArray *) new_rarray;
+}
+
 /**
  * g_ptr_array_new_with_free_func:
  * @element_free_func: (nullable): A function to free elements with
diff --git a/glib/garray.h b/glib/garray.h
index e97718b74..c4ec4aeaa 100644
--- a/glib/garray.h
+++ b/glib/garray.h
@@ -75,6 +75,8 @@ GArray* g_array_sized_new         (gboolean          zero_terminated,
                                   gboolean          clear_,
                                   guint             element_size,
                                   guint             reserved_size);
+GLIB_AVAILABLE_IN_2_62
+GArray* g_array_copy              (GArray           *array);
 GLIB_AVAILABLE_IN_ALL
 gchar*  g_array_free              (GArray           *array,
                                   gboolean          free_segment);
diff --git a/glib/tests/array-test.c b/glib/tests/array-test.c
index 217ef9274..b896b2d16 100644
--- a/glib/tests/array-test.c
+++ b/glib/tests/array-test.c
@@ -466,6 +466,58 @@ int_compare (gconstpointer p1, gconstpointer p2)
   return *i1 - *i2;
 }
 
+static void
+array_copy (gconstpointer test_data)
+{
+  GArray *array, *array_copy;
+  gsize i;
+  const ArrayTestData *config = test_data;
+  const gsize array_size = 100;
+
+  /* Testing degenerated cases */
+  if (g_test_undefined ())
+    {
+      g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
+                             "*assertion*!= NULL*");
+      array = g_array_copy (NULL);
+      g_test_assert_expected_messages ();
+
+      g_assert_null (array);
+    }
+
+  /* Testing simple copy */
+  array = g_array_new (config->zero_terminated, config->clear_, sizeof (gint));
+
+  for (i = 0; i < array_size; i++)
+    g_array_append_val (array, i);
+
+  array_copy = g_array_copy (array);
+
+  /* Check internal data */
+  for (i = 0; i < array_size; i++)
+    g_assert_cmpuint (g_array_index (array, gint, i), ==,
+                      g_array_index (array_copy, gint, i));
+
+  /* Check internal parameters ('zero_terminated' flag) */
+  if (config->zero_terminated)
+    {
+      const gint *data = (const gint *) array_copy->data;
+      g_assert_cmpint (data[array_copy->len], ==, 0);
+    }
+
+  /* Check internal parameters ('clear' flag) */
+  if (config->clear_)
+    {
+      g_array_set_size (array_copy, array_copy->len + 5);
+      for (i = array_copy->len; i < array_copy->len + 5; i++)
+        g_assert_cmpint (g_array_index (array_copy, gint, i), ==, 0);
+    }
+
+  /* Clean-up */
+  g_array_unref (array);
+  g_array_unref (array_copy);
+}
+
 static int
 int_compare_data (gconstpointer p1, gconstpointer p2, gpointer data)
 {
@@ -1506,6 +1558,7 @@ main (int argc, char *argv[])
       add_array_test ("/array/remove-index", &array_configurations[i], array_remove_index);
       add_array_test ("/array/remove-index-fast", &array_configurations[i], array_remove_index_fast);
       add_array_test ("/array/remove-range", &array_configurations[i], array_remove_range);
+      add_array_test ("/array/copy", &array_configurations[i], array_copy);
       add_array_test ("/array/sort", &array_configurations[i], array_sort);
       add_array_test ("/array/sort-with-data", &array_configurations[i], array_sort_with_data);
     }


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