forked from osmocom/wireshark
Add wmem_alloc_array, wmem_strsplit, wmem_strconcat.
svn path=/trunk/; revision=50017
This commit is contained in:
parent
ece132a5ce
commit
d487bba75f
|
@ -85,6 +85,16 @@ G_GNUC_MALLOC;
|
|||
#define wmem_new(allocator, type) \
|
||||
((type*)wmem_alloc((allocator), sizeof(type)))
|
||||
|
||||
/** Allocate memory sufficient to hold n objects of the given type.
|
||||
*
|
||||
* @param allocator The allocator object to use to allocate the memory.
|
||||
* @param type The type that the newly allocated memory will hold.
|
||||
* @param num The number of objects that the newly allocated memory will hold.
|
||||
* @return A void pointer to the newly allocated memory.
|
||||
*/
|
||||
#define wmem_alloc_array(allocator, type, num) \
|
||||
((type*)wmem_alloc((allocator), sizeof(type) * (num)))
|
||||
|
||||
/** Allocate the requested amount of memory in the given pool. Initializes the
|
||||
* allocated memory with zeroes.
|
||||
*
|
||||
|
@ -107,6 +117,17 @@ G_GNUC_MALLOC;
|
|||
#define wmem_new0(allocator, type) \
|
||||
((type*)wmem_alloc0((allocator), sizeof(type)))
|
||||
|
||||
/** Allocate memory sufficient to hold n objects of the given type.
|
||||
* Initializes the allocated memory with zeroes.
|
||||
*
|
||||
* @param allocator The allocator object to use to allocate the memory.
|
||||
* @param type The type that the newly allocated memory will hold.
|
||||
* @param num The number of objects that the newly allocated memory will hold.
|
||||
* @return A void pointer to the newly allocated and zeroed memory.
|
||||
*/
|
||||
#define wmem_alloc0_array(allocator, type, num) \
|
||||
((type*)wmem_alloc0((allocator), sizeof(type) * (num)))
|
||||
|
||||
/** Returns the allocated memory to the allocator. This function should only
|
||||
* be called directly by allocators when the allocated block is sufficiently
|
||||
* large that the reduced memory usage is worth the cost of the extra function
|
||||
|
|
|
@ -98,6 +98,115 @@ wmem_strdup_vprintf(wmem_allocator_t *allocator, const gchar *fmt, va_list ap)
|
|||
return dst;
|
||||
}
|
||||
|
||||
gchar *
|
||||
wmem_strconcat(wmem_allocator_t *allocator, const gchar *first, ...)
|
||||
{
|
||||
gsize len;
|
||||
va_list args;
|
||||
gchar *s;
|
||||
gchar *concat;
|
||||
gchar *ptr;
|
||||
|
||||
if (!first)
|
||||
return NULL;
|
||||
|
||||
len = 1 + strlen(first);
|
||||
va_start(args, first);
|
||||
while ((s = va_arg(args, gchar*))) {
|
||||
len += strlen(s);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
ptr = concat = (gchar *)wmem_alloc(allocator, len);
|
||||
|
||||
ptr = g_stpcpy(ptr, first);
|
||||
va_start(args, first);
|
||||
while ((s = va_arg(args, gchar*))) {
|
||||
ptr = g_stpcpy(ptr, s);
|
||||
}
|
||||
va_end(args);
|
||||
|
||||
return concat;
|
||||
}
|
||||
|
||||
gchar **
|
||||
wmem_strsplit(wmem_allocator_t *allocator, const gchar *src,
|
||||
const gchar *delimiter, int max_tokens)
|
||||
{
|
||||
gchar* splitted;
|
||||
gchar* s;
|
||||
guint tokens;
|
||||
guint str_len;
|
||||
guint sep_len;
|
||||
guint i;
|
||||
gchar** vec;
|
||||
enum { AT_START, IN_PAD, IN_TOKEN } state;
|
||||
guint curr_tok = 0;
|
||||
|
||||
if ( ! src
|
||||
|| ! delimiter
|
||||
|| ! delimiter[0])
|
||||
return NULL;
|
||||
|
||||
s = splitted = wmem_strdup(allocator, src);
|
||||
str_len = (guint) strlen(splitted);
|
||||
sep_len = (guint) strlen(delimiter);
|
||||
|
||||
if (max_tokens < 1) max_tokens = INT_MAX;
|
||||
|
||||
tokens = 1;
|
||||
|
||||
|
||||
while (tokens <= (guint)max_tokens && ( s = strstr(s,delimiter) )) {
|
||||
tokens++;
|
||||
|
||||
for(i=0; i < sep_len; i++ )
|
||||
s[i] = '\0';
|
||||
|
||||
s += sep_len;
|
||||
|
||||
}
|
||||
|
||||
vec = wmem_alloc_array(allocator, gchar*,tokens+1);
|
||||
state = AT_START;
|
||||
|
||||
for (i=0; i< str_len; i++) {
|
||||
switch(state) {
|
||||
case AT_START:
|
||||
switch(splitted[i]) {
|
||||
case '\0':
|
||||
state = IN_PAD;
|
||||
continue;
|
||||
default:
|
||||
vec[curr_tok] = &(splitted[i]);
|
||||
curr_tok++;
|
||||
state = IN_TOKEN;
|
||||
continue;
|
||||
}
|
||||
case IN_TOKEN:
|
||||
switch(splitted[i]) {
|
||||
case '\0':
|
||||
state = IN_PAD;
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
case IN_PAD:
|
||||
switch(splitted[i]) {
|
||||
default:
|
||||
vec[curr_tok] = &(splitted[i]);
|
||||
curr_tok++;
|
||||
state = IN_TOKEN;
|
||||
case '\0':
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vec[curr_tok] = NULL;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - http://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
|
|
@ -63,6 +63,21 @@ gchar *
|
|||
wmem_strdup_vprintf(wmem_allocator_t *allocator, const gchar *fmt, va_list ap)
|
||||
G_GNUC_MALLOC;
|
||||
|
||||
WS_DLL_PUBLIC
|
||||
gchar *
|
||||
wmem_strconcat(wmem_allocator_t *allocator, const gchar *first, ...)
|
||||
G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
|
||||
|
||||
/**
|
||||
* Splits a string into a maximum of max_tokens pieces, using the given
|
||||
* delimiter. If max_tokens is reached, the remainder of string is appended
|
||||
* to the last token. Consecutive delimiters are treated as a single delimiter.
|
||||
*/
|
||||
WS_DLL_PUBLIC
|
||||
gchar **
|
||||
wmem_strsplit(wmem_allocator_t *allocator, const gchar *src,
|
||||
const gchar *delimiter, int max_tokens);
|
||||
|
||||
/** @}
|
||||
* @} */
|
||||
|
||||
|
|
|
@ -186,6 +186,36 @@ wmem_test_allocator_callbacks(void)
|
|||
g_assert(cb_called_count == 3);
|
||||
}
|
||||
|
||||
static void
|
||||
wmem_test_allocator_det(wmem_allocator_t *allocator, wmem_verify_func verify,
|
||||
guint len)
|
||||
{
|
||||
int i;
|
||||
char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
|
||||
|
||||
/* we use wmem_alloc0 in part because it tests slightly more code, but
|
||||
* primarily so that if the allocator doesn't give us enough memory or
|
||||
* gives us memory that includes its own metadata, we write to it and
|
||||
* things go wrong, causing the tests to fail */
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
ptrs[i] = (char *)wmem_alloc0(allocator, len);
|
||||
}
|
||||
for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) {
|
||||
/* no wmem_realloc0 so just use memset manually */
|
||||
ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len);
|
||||
memset(ptrs[i], 0, 4*len);
|
||||
}
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
wmem_free(allocator, ptrs[i]);
|
||||
}
|
||||
|
||||
if (verify) (*verify)(allocator);
|
||||
wmem_free_all(allocator);
|
||||
wmem_gc(allocator);
|
||||
if (verify) (*verify)(allocator);
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify)
|
||||
{
|
||||
|
@ -199,44 +229,14 @@ wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify)
|
|||
|
||||
/* start with some fairly simple deterministic tests */
|
||||
|
||||
/* we use wmem_alloc0 in part because it tests slightly more code, but
|
||||
* primarily so that if the allocator doesn't give us enough memory or
|
||||
* gives us memory that includes its own metadata, we write to it and
|
||||
* things go wrong, causing the tests to fail */
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
ptrs[i] = (char *)wmem_alloc0(allocator, 8);
|
||||
}
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
wmem_free(allocator, ptrs[i]);
|
||||
}
|
||||
wmem_test_allocator_det(allocator, verify, 8);
|
||||
|
||||
if (verify) (*verify)(allocator);
|
||||
wmem_free_all(allocator);
|
||||
wmem_gc(allocator);
|
||||
if (verify) (*verify)(allocator);
|
||||
wmem_test_allocator_det(allocator, verify, 64);
|
||||
|
||||
wmem_test_allocator_det(allocator, verify, 512);
|
||||
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
ptrs[i] = (char *)wmem_alloc0(allocator, 64);
|
||||
}
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
wmem_free(allocator, ptrs[i]);
|
||||
}
|
||||
|
||||
if (verify) (*verify)(allocator);
|
||||
wmem_free_all(allocator);
|
||||
wmem_gc(allocator);
|
||||
if (verify) (*verify)(allocator);
|
||||
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
ptrs[i] = (char *)wmem_alloc0(allocator, 512);
|
||||
}
|
||||
for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) {
|
||||
/* no wmem_realloc0 so just use memset manually */
|
||||
ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], MAX_ALLOC_SIZE);
|
||||
memset(ptrs[i], 0, MAX_ALLOC_SIZE);
|
||||
}
|
||||
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
|
||||
wmem_free(allocator, ptrs[i]);
|
||||
ptrs[i] = wmem_alloc0_array(allocator, char, 32);
|
||||
}
|
||||
|
||||
if (verify) (*verify)(allocator);
|
||||
|
@ -362,6 +362,7 @@ wmem_test_strutls(void)
|
|||
wmem_allocator_t *allocator;
|
||||
const char *orig_str;
|
||||
char *new_str;
|
||||
char **split_str;
|
||||
|
||||
allocator = wmem_allocator_force_new(WMEM_ALLOCATOR_STRICT);
|
||||
|
||||
|
@ -384,6 +385,28 @@ wmem_test_strutls(void)
|
|||
g_assert_cmpstr(new_str, ==, "abc boo % 23");
|
||||
wmem_strict_check_canaries(allocator);
|
||||
|
||||
new_str = wmem_strconcat(allocator, "ABC", NULL);
|
||||
g_assert_cmpstr(new_str, ==, "ABC");
|
||||
new_str = wmem_strconcat(allocator, "ABC", "DEF", NULL);
|
||||
g_assert_cmpstr(new_str, ==, "ABCDEF");
|
||||
wmem_strict_check_canaries(allocator);
|
||||
new_str = wmem_strconcat(allocator, "", "", "ABCDEF", "", "GH", NULL);
|
||||
g_assert_cmpstr(new_str, ==, "ABCDEFGH");
|
||||
wmem_strict_check_canaries(allocator);
|
||||
|
||||
split_str = wmem_strsplit(allocator, "A-C", "-", 2);
|
||||
g_assert_cmpstr(split_str[0], ==, "A");
|
||||
g_assert_cmpstr(split_str[1], ==, "C");
|
||||
split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 10);
|
||||
g_assert_cmpstr(split_str[0], ==, "aslkf");
|
||||
g_assert_cmpstr(split_str[1], ==, "asio");
|
||||
g_assert_cmpstr(split_str[2], ==, "asfj");
|
||||
g_assert_cmpstr(split_str[3], ==, "as");
|
||||
split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 4);
|
||||
g_assert_cmpstr(split_str[0], ==, "aslkf");
|
||||
g_assert_cmpstr(split_str[1], ==, "asio");
|
||||
g_assert_cmpstr(split_str[2], ==, "-asfj-as--");
|
||||
|
||||
wmem_destroy_allocator(allocator);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue