summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-04-21 13:47:04 +0200
committerChristian Grothoff <christian@grothoff.org>2020-04-21 13:47:04 +0200
commit13ceb583b892ecbe1094e473c058a6ff18ad0efb (patch)
treeb11e8b3bfea52a94d77d948b169a031dc8378228
parent3776e3a77bff3f3d7091e91aac2e1b6b3425b28d (diff)
defining GNUNET_array_concatenate() for #6190
-rw-r--r--src/include/gnunet_common.h50
-rw-r--r--src/util/test_common_allocation.c26
2 files changed, 67 insertions, 9 deletions
diff --git a/src/include/gnunet_common.h b/src/include/gnunet_common.h
index fcc510ec9..033a68894 100644
--- a/src/include/gnunet_common.h
+++ b/src/include/gnunet_common.h
@@ -1392,22 +1392,58 @@ GNUNET_is_zero_ (const void *a,
/**
* @ingroup memory
- * Append an element to a list (growing the list by one).
+ * Append an element to an array (growing the array by one).
*
- * @param arr base-pointer of the vector, may be NULL if size is 0;
+ * @param arr base-pointer of the vector, may be NULL if @a len is 0;
* will be updated to reflect the new address. The TYPE of
* arr is important since size is the number of elements and
* not the size in bytes
- * @param size the number of elements in the existing vector (number
+ * @param len the number of elements in the existing vector (number
* of elements to copy over), will be updated with the new
- * array size
+ * array length
* @param element the element that will be appended to the array
*/
-#define GNUNET_array_append(arr, size, element) \
+#define GNUNET_array_append(arr, len, element) \
+ do \
+ { \
+ GNUNET_assert ((len) + 1 > (len)); \
+ GNUNET_array_grow (arr, len, len + 1); \
+ (arr) [len - 1] = element; \
+ } while (0)
+
+
+/**
+ * @ingroup memory
+ * Append @a arr2 to @a arr1 (growing @a arr1
+ * as needed). The @a arr2 array is left unchanged. Naturally
+ * this function performs a shallow copy. Both arrays must have
+ * the same type for their elements.
+ *
+ * @param arr1 base-pointer of the vector, may be NULL if @a len is 0;
+ * will be updated to reflect the new address. The TYPE of
+ * arr is important since size is the number of elements and
+ * not the size in bytes
+ * @param len1 the number of elements in the existing vector (number
+ * of elements to copy over), will be updated with the new
+ * array size
+ * @param arr2 base-pointer a second array to concatenate, may be NULL if @a len2 is 0;
+ * will be updated to reflect the new address. The TYPE of
+ * arr is important since size is the number of elements and
+ * not the size in bytes
+ * @param len the number of elements in the existing vector (number
+ * of elements to copy over), will be updated with the new
+ * array size
+
+ */
+#define GNUNET_array_concatenate(arr1, len1, arr2, len2) \
do \
{ \
- GNUNET_array_grow (arr, size, size + 1); \
- (arr) [size - 1] = element; \
+ const typeof (*arr2) * _a1 = (arr1); \
+ const typeof (*arr1) * _a2 = (arr2); \
+ GNUNET_assert ((len1) + (len2) >= (len1)); \
+ GNUNET_assert (SIZE_MAX / sizeof (*_a1) >= ((len1) + (len2))); \
+ GNUNET_array_grow (arr1, len1, (len1) + (len2)); \
+ memcpy (&(arr1) [(len1) - (len2)], _a2, (len2) * sizeof (*arr1)); \
} while (0)
/**
diff --git a/src/util/test_common_allocation.c b/src/util/test_common_allocation.c
index e2fc29e82..a24af7124 100644
--- a/src/util/test_common_allocation.c
+++ b/src/util/test_common_allocation.c
@@ -27,7 +27,7 @@
static int
-check ()
+check (void)
{
#define MAX_TESTVAL 1024
char *ptrs[MAX_TESTVAL];
@@ -134,6 +134,28 @@ check ()
}
+static int
+check2 (void)
+{
+ char *a1 = NULL;
+ unsigned int a1_len = 0;
+ const char *a2 = "test";
+
+ GNUNET_array_append (a1,
+ a1_len,
+ 'x');
+ GNUNET_array_concatenate (a1,
+ a1_len,
+ a2,
+ 4);
+ GNUNET_assert (0 == strncmp ("xtest",
+ a1,
+ 5));
+ GNUNET_assert (5 == a1_len);
+ return 0;
+}
+
+
int
main (int argc, char *argv[])
{
@@ -142,7 +164,7 @@ main (int argc, char *argv[])
GNUNET_log_setup ("test-common-allocation",
"WARNING",
NULL);
- ret = check ();
+ ret = check () | check2 ();
if (ret != 0)
fprintf (stderr,
"ERROR %d.\n",