mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 23:16:14 +01:00
Add g_array_steal(), g_ptr_array_steal() and g_byte_array_steal()
Closes issue #285
This commit is contained in:
parent
c08e7b9364
commit
7bada8394d
@ -2805,6 +2805,7 @@ g_string_chunk_free
|
|||||||
<FILE>arrays</FILE>
|
<FILE>arrays</FILE>
|
||||||
GArray
|
GArray
|
||||||
g_array_new
|
g_array_new
|
||||||
|
g_array_steal
|
||||||
g_array_sized_new
|
g_array_sized_new
|
||||||
g_array_copy
|
g_array_copy
|
||||||
g_array_ref
|
g_array_ref
|
||||||
@ -2833,6 +2834,7 @@ g_array_free
|
|||||||
<FILE>arrays_pointer</FILE>
|
<FILE>arrays_pointer</FILE>
|
||||||
GPtrArray
|
GPtrArray
|
||||||
g_ptr_array_new
|
g_ptr_array_new
|
||||||
|
g_ptr_array_steal
|
||||||
g_ptr_array_sized_new
|
g_ptr_array_sized_new
|
||||||
g_ptr_array_new_with_free_func
|
g_ptr_array_new_with_free_func
|
||||||
g_ptr_array_copy
|
g_ptr_array_copy
|
||||||
@ -2868,6 +2870,7 @@ g_ptr_array_find_with_equal_func
|
|||||||
<SUBSECTION>
|
<SUBSECTION>
|
||||||
GByteArray
|
GByteArray
|
||||||
g_byte_array_new
|
g_byte_array_new
|
||||||
|
g_byte_array_steal
|
||||||
g_byte_array_new_take
|
g_byte_array_new_take
|
||||||
g_byte_array_sized_new
|
g_byte_array_sized_new
|
||||||
g_byte_array_ref
|
g_byte_array_ref
|
||||||
|
113
glib/garray.c
113
glib/garray.c
@ -165,6 +165,57 @@ g_array_new (gboolean zero_terminated,
|
|||||||
return g_array_sized_new (zero_terminated, clear, elt_size, 0);
|
return g_array_sized_new (zero_terminated, clear, elt_size, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_array_steal:
|
||||||
|
* @array: a #GArray.
|
||||||
|
* @len: (optional) (out caller-allocates): pointer to retrieve the number of
|
||||||
|
* elements of the original array
|
||||||
|
*
|
||||||
|
* Frees the data in the array and resets the size to zero, while
|
||||||
|
* the underlying array is preserved for use elsewhere and returned
|
||||||
|
* to the caller.
|
||||||
|
*
|
||||||
|
* If the array was created with the @zero_terminate property
|
||||||
|
* set to %TRUE, the returned data is zero terminated too.
|
||||||
|
*
|
||||||
|
* If array elements contain dynamically-allocated memory,
|
||||||
|
* the array elements should also be freed by the caller.
|
||||||
|
*
|
||||||
|
* A short example of use:
|
||||||
|
* |[<!-- language="C" -->
|
||||||
|
* ...
|
||||||
|
* gpointer data;
|
||||||
|
* gsize data_len;
|
||||||
|
* data = g_array_steal (some_array, &data_len);
|
||||||
|
* ...
|
||||||
|
* ]|
|
||||||
|
|
||||||
|
* Returns: (transfer full): the element data, which should be
|
||||||
|
* freed using g_free().
|
||||||
|
*
|
||||||
|
* Since: 2.64
|
||||||
|
*/
|
||||||
|
gpointer
|
||||||
|
g_array_steal (GArray *array,
|
||||||
|
gsize *len)
|
||||||
|
{
|
||||||
|
GRealArray *rarray;
|
||||||
|
gpointer segment;
|
||||||
|
|
||||||
|
g_return_val_if_fail (array != NULL, NULL);
|
||||||
|
|
||||||
|
rarray = (GRealArray *) array;
|
||||||
|
segment = (gpointer) rarray->data;
|
||||||
|
|
||||||
|
if (len != NULL)
|
||||||
|
*len = rarray->len;
|
||||||
|
|
||||||
|
rarray->data = NULL;
|
||||||
|
rarray->len = 0;
|
||||||
|
rarray->alloc = 0;
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_array_sized_new:
|
* g_array_sized_new:
|
||||||
* @zero_terminated: %TRUE if the array should have an extra element at
|
* @zero_terminated: %TRUE if the array should have an extra element at
|
||||||
@ -1013,6 +1064,46 @@ g_ptr_array_new (void)
|
|||||||
return g_ptr_array_sized_new (0);
|
return g_ptr_array_sized_new (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_ptr_array_steal:
|
||||||
|
* @array: a #GPtrArray.
|
||||||
|
* @len: (optional) (out caller-allocates): pointer to retrieve the number of
|
||||||
|
* elements of the original array
|
||||||
|
*
|
||||||
|
* Frees the data in the array and resets the size to zero, while
|
||||||
|
* the underlying array is preserved for use elsewhere and returned
|
||||||
|
* to the caller.
|
||||||
|
*
|
||||||
|
* Even if set, the #GDestroyNotify function will never be called
|
||||||
|
* on the current contents of the array and the caller is
|
||||||
|
* responsible for freeing the array elements.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the element data, which should be
|
||||||
|
* freed using g_free().
|
||||||
|
*
|
||||||
|
* Since: 2.64
|
||||||
|
*/
|
||||||
|
gpointer *
|
||||||
|
g_ptr_array_steal (GPtrArray *array,
|
||||||
|
gsize *len)
|
||||||
|
{
|
||||||
|
GRealPtrArray *rarray;
|
||||||
|
gpointer *segment;
|
||||||
|
|
||||||
|
g_return_val_if_fail (array != NULL, NULL);
|
||||||
|
|
||||||
|
rarray = (GRealPtrArray *) array;
|
||||||
|
segment = (gpointer *) rarray->pdata;
|
||||||
|
|
||||||
|
if (len != NULL)
|
||||||
|
*len = rarray->len;
|
||||||
|
|
||||||
|
rarray->pdata = NULL;
|
||||||
|
rarray->len = 0;
|
||||||
|
rarray->alloc = 0;
|
||||||
|
return segment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_ptr_array_copy:
|
* g_ptr_array_copy:
|
||||||
* @array: #GPtrArray to duplicate
|
* @array: #GPtrArray to duplicate
|
||||||
@ -2002,6 +2093,28 @@ g_byte_array_new (void)
|
|||||||
return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
|
return (GByteArray *)g_array_sized_new (FALSE, FALSE, 1, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* g_byte_array_steal:
|
||||||
|
* @array: a #GByteArray.
|
||||||
|
* @len: (optional) (out caller-allocates): pointer to retrieve the number of
|
||||||
|
* elements of the original array
|
||||||
|
*
|
||||||
|
* Frees the data in the array and resets the size to zero, while
|
||||||
|
* the underlying array is preserved for use elsewhere and returned
|
||||||
|
* to the caller.
|
||||||
|
*
|
||||||
|
* Returns: (transfer full): the element data, which should be
|
||||||
|
* freed using g_free().
|
||||||
|
*
|
||||||
|
* Since: 2.64
|
||||||
|
*/
|
||||||
|
guint8 *
|
||||||
|
g_byte_array_steal (GByteArray *array,
|
||||||
|
gsize *len)
|
||||||
|
{
|
||||||
|
return (guint8 *) g_array_steal ((GArray *) array, len);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_byte_array_new_take:
|
* g_byte_array_new_take:
|
||||||
* @data: (transfer full) (array length=len): byte data for the array
|
* @data: (transfer full) (array length=len): byte data for the array
|
||||||
|
@ -70,6 +70,9 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
GArray* g_array_new (gboolean zero_terminated,
|
GArray* g_array_new (gboolean zero_terminated,
|
||||||
gboolean clear_,
|
gboolean clear_,
|
||||||
guint element_size);
|
guint element_size);
|
||||||
|
GLIB_AVAILABLE_IN_2_64
|
||||||
|
gpointer g_array_steal (GArray *array,
|
||||||
|
gsize *len);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GArray* g_array_sized_new (gboolean zero_terminated,
|
GArray* g_array_sized_new (gboolean zero_terminated,
|
||||||
gboolean clear_,
|
gboolean clear_,
|
||||||
@ -137,6 +140,9 @@ GLIB_AVAILABLE_IN_ALL
|
|||||||
GPtrArray* g_ptr_array_new (void);
|
GPtrArray* g_ptr_array_new (void);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func);
|
GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify element_free_func);
|
||||||
|
GLIB_AVAILABLE_IN_2_64
|
||||||
|
gpointer* g_ptr_array_steal (GPtrArray *array,
|
||||||
|
gsize *len);
|
||||||
GLIB_AVAILABLE_IN_2_62
|
GLIB_AVAILABLE_IN_2_62
|
||||||
GPtrArray *g_ptr_array_copy (GPtrArray *array,
|
GPtrArray *g_ptr_array_copy (GPtrArray *array,
|
||||||
GCopyFunc func,
|
GCopyFunc func,
|
||||||
@ -227,6 +233,9 @@ GByteArray* g_byte_array_new (void);
|
|||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GByteArray* g_byte_array_new_take (guint8 *data,
|
GByteArray* g_byte_array_new_take (guint8 *data,
|
||||||
gsize len);
|
gsize len);
|
||||||
|
GLIB_AVAILABLE_IN_2_64
|
||||||
|
guint8* g_byte_array_steal (GByteArray *array,
|
||||||
|
gsize *len);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
GByteArray* g_byte_array_sized_new (guint reserved_size);
|
GByteArray* g_byte_array_sized_new (guint reserved_size);
|
||||||
GLIB_AVAILABLE_IN_ALL
|
GLIB_AVAILABLE_IN_ALL
|
||||||
|
@ -140,6 +140,57 @@ array_new_zero_terminated (void)
|
|||||||
g_free (out_str);
|
g_free (out_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check g_array_steal() function */
|
||||||
|
static void
|
||||||
|
array_steal (void)
|
||||||
|
{
|
||||||
|
const guint array_size = 10000;
|
||||||
|
GArray *garray;
|
||||||
|
gint *adata;
|
||||||
|
guint i;
|
||||||
|
gsize len, past_len;
|
||||||
|
|
||||||
|
garray = g_array_new (FALSE, FALSE, sizeof (gint));
|
||||||
|
adata = (gint *) g_array_steal (garray, NULL);
|
||||||
|
g_assert_null (adata);
|
||||||
|
|
||||||
|
adata = (gint *) g_array_steal (garray, &len);
|
||||||
|
g_assert_null (adata);
|
||||||
|
g_assert_cmpint (len, ==, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_array_append_val (garray, i);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_assert_cmpint (g_array_index (garray, gint, i), ==, i);
|
||||||
|
|
||||||
|
|
||||||
|
past_len = garray->len;
|
||||||
|
adata = (gint *) g_array_steal (garray, &len);
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_assert_cmpint (adata[i], ==, i);
|
||||||
|
|
||||||
|
g_assert_cmpint (past_len, ==, len);
|
||||||
|
g_assert_cmpint (garray->len, ==, 0);
|
||||||
|
|
||||||
|
g_array_append_val (garray, i);
|
||||||
|
|
||||||
|
g_assert_cmpint (adata[0], ==, 0);
|
||||||
|
g_assert_cmpint (g_array_index (garray, gint, 0), ==, array_size);
|
||||||
|
g_assert_cmpint (garray->len, ==, 1);
|
||||||
|
|
||||||
|
g_array_remove_index (garray, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_array_append_val (garray, i);
|
||||||
|
|
||||||
|
g_assert_cmpint (garray->len, ==, array_size);
|
||||||
|
g_assert_cmpmem (adata, array_size * sizeof (gint),
|
||||||
|
garray->data, array_size * sizeof (gint));
|
||||||
|
g_free (adata);
|
||||||
|
g_array_free (garray, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check that g_array_append_val() works correctly for various #GArray
|
/* Check that g_array_append_val() works correctly for various #GArray
|
||||||
* configurations. */
|
* configurations. */
|
||||||
static void
|
static void
|
||||||
@ -760,6 +811,49 @@ test_array_binary_search (void)
|
|||||||
g_array_free (garray, TRUE);
|
g_array_free (garray, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check g_ptr_array_steal() function */
|
||||||
|
static void
|
||||||
|
pointer_array_steal (void)
|
||||||
|
{
|
||||||
|
const guint array_size = 10000;
|
||||||
|
GPtrArray *gparray;
|
||||||
|
gpointer *pdata;
|
||||||
|
guint i;
|
||||||
|
gsize len, past_len;
|
||||||
|
|
||||||
|
gparray = g_ptr_array_new ();
|
||||||
|
pdata = g_ptr_array_steal (gparray, NULL);
|
||||||
|
g_assert_null (pdata);
|
||||||
|
|
||||||
|
pdata = g_ptr_array_steal (gparray, &len);
|
||||||
|
g_assert_null (pdata);
|
||||||
|
g_assert_cmpint (len, ==, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_ptr_array_add (gparray, GINT_TO_POINTER (i));
|
||||||
|
|
||||||
|
past_len = gparray->len;
|
||||||
|
pdata = g_ptr_array_steal (gparray, &len);
|
||||||
|
g_assert_cmpint (gparray->len, ==, 0);
|
||||||
|
g_assert_cmpint (past_len, ==, len);
|
||||||
|
g_ptr_array_add (gparray, GINT_TO_POINTER (10));
|
||||||
|
|
||||||
|
g_assert_cmpint ((gsize) pdata[0], ==, (gsize) GINT_TO_POINTER (0));
|
||||||
|
g_assert_cmpint ((gsize) g_ptr_array_index (gparray, 0), ==,
|
||||||
|
(gsize) GINT_TO_POINTER (10));
|
||||||
|
g_assert_cmpint (gparray->len, ==, 1);
|
||||||
|
|
||||||
|
g_ptr_array_remove_index (gparray, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_ptr_array_add (gparray, GINT_TO_POINTER (i));
|
||||||
|
g_assert_cmpmem (pdata, array_size * sizeof (gpointer),
|
||||||
|
gparray->pdata, array_size * sizeof (gpointer));
|
||||||
|
g_free (pdata);
|
||||||
|
|
||||||
|
g_ptr_array_free (gparray, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
pointer_array_add (void)
|
pointer_array_add (void)
|
||||||
{
|
{
|
||||||
@ -1318,7 +1412,7 @@ steal_destroy_notify (gpointer data)
|
|||||||
/* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
|
/* Test that g_ptr_array_steal_index() and g_ptr_array_steal_index_fast() can
|
||||||
* remove elements from a pointer array without the #GDestroyNotify being called. */
|
* remove elements from a pointer array without the #GDestroyNotify being called. */
|
||||||
static void
|
static void
|
||||||
pointer_array_steal (void)
|
pointer_array_steal_index (void)
|
||||||
{
|
{
|
||||||
guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
|
guint i1 = 0, i2 = 0, i3 = 0, i4 = 0;
|
||||||
gpointer out1, out2;
|
gpointer out1, out2;
|
||||||
@ -1361,6 +1455,41 @@ pointer_array_steal (void)
|
|||||||
g_assert_cmpuint (i4, ==, 1);
|
g_assert_cmpuint (i4, ==, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
byte_array_steal (void)
|
||||||
|
{
|
||||||
|
const guint array_size = 10000;
|
||||||
|
GByteArray *gbarray;
|
||||||
|
guint8 *bdata;
|
||||||
|
guint i;
|
||||||
|
gsize len, past_len;
|
||||||
|
|
||||||
|
gbarray = g_byte_array_new ();
|
||||||
|
bdata = g_byte_array_steal (gbarray, NULL);
|
||||||
|
g_assert_cmpint ((gsize) bdata, ==, (gsize) gbarray->data);
|
||||||
|
g_free (bdata);
|
||||||
|
|
||||||
|
for (i = 0; i < array_size; i++)
|
||||||
|
g_byte_array_append (gbarray, (guint8 *) "abcd", 4);
|
||||||
|
|
||||||
|
past_len = gbarray->len;
|
||||||
|
bdata = g_byte_array_steal (gbarray, &len);
|
||||||
|
|
||||||
|
g_assert_cmpint (len, ==, past_len);
|
||||||
|
g_assert_cmpint (gbarray->len, ==, 0);
|
||||||
|
|
||||||
|
g_byte_array_append (gbarray, (guint8 *) "@", 1);
|
||||||
|
|
||||||
|
g_assert_cmpint (bdata[0], ==, 'a');
|
||||||
|
g_assert_cmpint (gbarray->data[0], ==, '@');
|
||||||
|
g_assert_cmpint (gbarray->len, ==, 1);
|
||||||
|
|
||||||
|
g_byte_array_remove_index (gbarray, 0);
|
||||||
|
|
||||||
|
g_free (bdata);
|
||||||
|
g_byte_array_free (gbarray, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
byte_array_append (void)
|
byte_array_append (void)
|
||||||
{
|
{
|
||||||
@ -1679,6 +1808,7 @@ main (int argc, char *argv[])
|
|||||||
/* array tests */
|
/* array tests */
|
||||||
g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
|
g_test_add_func ("/array/new/zero-terminated", array_new_zero_terminated);
|
||||||
g_test_add_func ("/array/ref-count", array_ref_count);
|
g_test_add_func ("/array/ref-count", array_ref_count);
|
||||||
|
g_test_add_func ("/array/steal", array_steal);
|
||||||
g_test_add_func ("/array/clear-func", array_clear_func);
|
g_test_add_func ("/array/clear-func", array_clear_func);
|
||||||
g_test_add_func ("/array/binary-search", test_array_binary_search);
|
g_test_add_func ("/array/binary-search", test_array_binary_search);
|
||||||
|
|
||||||
@ -1711,8 +1841,10 @@ main (int argc, char *argv[])
|
|||||||
g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
|
g_test_add_func ("/pointerarray/find/empty", pointer_array_find_empty);
|
||||||
g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
|
g_test_add_func ("/pointerarray/find/non-empty", pointer_array_find_non_empty);
|
||||||
g_test_add_func ("/pointerarray/steal", pointer_array_steal);
|
g_test_add_func ("/pointerarray/steal", pointer_array_steal);
|
||||||
|
g_test_add_func ("/pointerarray/steal_index", pointer_array_steal_index);
|
||||||
|
|
||||||
/* byte arrays */
|
/* byte arrays */
|
||||||
|
g_test_add_func ("/bytearray/steal", byte_array_steal);
|
||||||
g_test_add_func ("/bytearray/append", byte_array_append);
|
g_test_add_func ("/bytearray/append", byte_array_append);
|
||||||
g_test_add_func ("/bytearray/prepend", byte_array_prepend);
|
g_test_add_func ("/bytearray/prepend", byte_array_prepend);
|
||||||
g_test_add_func ("/bytearray/remove", byte_array_remove);
|
g_test_add_func ("/bytearray/remove", byte_array_remove);
|
||||||
|
Loading…
Reference in New Issue
Block a user