Adding a function g_array_copy() to glib/garray.c

Original code from Simon van der Linden

Close issue #236
This commit is contained in:
Emmanuel Fleury 2019-05-28 09:46:20 +02:00
parent 75614a0972
commit 46f70e9901
4 changed files with 84 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);
}