From d487bba75f4719eff8edc5a946596ecb14c28fa2 Mon Sep 17 00:00:00 2001 From: Evan Huus Date: Tue, 18 Jun 2013 21:25:37 +0000 Subject: [PATCH] Add wmem_alloc_array, wmem_strsplit, wmem_strconcat. svn path=/trunk/; revision=50017 --- epan/wmem/wmem_core.h | 21 ++++++++ epan/wmem/wmem_strutl.c | 109 ++++++++++++++++++++++++++++++++++++++++ epan/wmem/wmem_strutl.h | 15 ++++++ epan/wmem/wmem_test.c | 93 +++++++++++++++++++++------------- 4 files changed, 203 insertions(+), 35 deletions(-) diff --git a/epan/wmem/wmem_core.h b/epan/wmem/wmem_core.h index 7e9862a08c..7e22ee8868 100644 --- a/epan/wmem/wmem_core.h +++ b/epan/wmem/wmem_core.h @@ -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 diff --git a/epan/wmem/wmem_strutl.c b/epan/wmem/wmem_strutl.c index 99d13325e8..831d05160f 100644 --- a/epan/wmem/wmem_strutl.c +++ b/epan/wmem/wmem_strutl.c @@ -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 * diff --git a/epan/wmem/wmem_strutl.h b/epan/wmem/wmem_strutl.h index 14f2702b77..55ea5ac5c0 100644 --- a/epan/wmem/wmem_strutl.h +++ b/epan/wmem/wmem_strutl.h @@ -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); + /** @} * @} */ diff --git a/epan/wmem/wmem_test.c b/epan/wmem/wmem_test.c index 5ffb09cf60..d0c1177947 100644 --- a/epan/wmem/wmem_test.c +++ b/epan/wmem/wmem_test.c @@ -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=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=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