Skip to content

Commit

Permalink
[glibutil] Added gutil_memdup()
Browse files Browse the repository at this point in the history
Similar to g_memdup but takes gsize as the number of bytes to copy,
guint can overflow on 64-bit platforms.
  • Loading branch information
monich committed Apr 18, 2021
1 parent c74f100 commit eafeea3
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
5 changes: 5 additions & 0 deletions include/gutil_misc.h
Expand Up @@ -125,6 +125,11 @@ void
gutil_ptrv_free(
void** ptrv); /* Since 1.0.51 */

void*
gutil_memdup(
const void* ptr,
gsize size); /* Since 1.0.52 */

G_END_DECLS

#endif /* GUTIL_MISC_H */
Expand Down
15 changes: 8 additions & 7 deletions src/gutil_ints.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2017-2020 Jolla Ltd.
* Copyright (C) 2017-2020 Slava Monich <slava.monich@jolla.com>
* Copyright (C) 2017-2021 Jolla Ltd.
* Copyright (C) 2017-2021 Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of BSD license as follows:
*
Expand Down Expand Up @@ -32,6 +32,7 @@

#include "gutil_intarray.h"
#include "gutil_ints.h"
#include "gutil_misc.h"
#include "gutil_macros.h"

struct gutil_ints {
Expand All @@ -45,10 +46,10 @@ struct gutil_ints {
GUtilInts*
gutil_ints_new(
const int* data,
guint count)
guint n)
{
if (data && count) {
return gutil_ints_new_take(g_memdup(data, count*sizeof(int)), count);
if (data && n) {
return gutil_ints_new_take(gutil_memdup(data, n * sizeof(int)), n);
} else {
return NULL;
}
Expand Down Expand Up @@ -155,12 +156,12 @@ gutil_ints_unref_to_data(
/* We can allow the caller to free the data */
result = (int*)ints->data;
} else {
result = g_memdup(ints->data, ints->count * sizeof(int));
result = gutil_memdup(ints->data, ints->count * sizeof(int));
ints->free_func(ints->user_data);
}
gutil_slice_free(ints);
} else {
result = g_memdup(ints->data, ints->count * sizeof(int));
result = gutil_memdup(ints->data, ints->count * sizeof(int));
}
return result;
} else {
Expand Down
16 changes: 16 additions & 0 deletions src/gutil_misc.c
Expand Up @@ -444,6 +444,22 @@ gutil_ptrv_free(
}
}

/* Similar to g_memdup but takes gsize as the number of bytes to copy */
void*
gutil_memdup(
const void* ptr,
gsize size) /* Since 1.0.52 */
{
if (G_LIKELY(ptr) && G_LIKELY(size)) {
void* copy = g_malloc(size);

memcpy(copy, ptr, size);
return copy;
} else {
return NULL;
}
}

/*
* Local Variables:
* mode: C
Expand Down
22 changes: 22 additions & 0 deletions test/test_misc/test_misc.c
Expand Up @@ -519,6 +519,27 @@ test_ptrv_free(
gutil_ptrv_free(ptrv1);
}

/*==========================================================================*
* memdup
*==========================================================================*/

static
void
test_memdup(
void)
{
static const guint8 data[] = { 0x01, 0x02, 0x03 };
void* copy = gutil_memdup(data, sizeof(data));

g_assert(copy);
g_assert(!memcmp(copy, data, sizeof(data)));
g_free(copy);

g_assert(!gutil_memdup(data, 0));
g_assert(!gutil_memdup(NULL, 0));
g_assert(!gutil_memdup(NULL, 1));
}

/*==========================================================================*
* Common
*==========================================================================*/
Expand Down Expand Up @@ -550,6 +571,7 @@ int main(int argc, char* argv[])
g_test_add_func(TEST_("bytes_equal"), test_bytes_equal);
g_test_add_func(TEST_("ptrv_lenght"), test_ptrv_length);
g_test_add_func(TEST_("ptrv_free"), test_ptrv_free);
g_test_add_func(TEST_("memdup"), test_memdup);
test_init(&test_opt, argc, argv);
return g_test_run();
}
Expand Down

0 comments on commit eafeea3

Please sign in to comment.