diff options
-rw-r--r-- | epan/emem.c | 78 | ||||
-rw-r--r-- | epan/emem.h | 14 | ||||
-rw-r--r-- | epan/libethereal.def | 9 | ||||
-rw-r--r-- | epan/tvbuff.c | 32 | ||||
-rw-r--r-- | epan/tvbuff.h | 6 |
5 files changed, 136 insertions, 3 deletions
diff --git a/epan/emem.c b/epan/emem.c index bbe1347fe4..1b77023a1e 100644 --- a/epan/emem.c +++ b/epan/emem.c @@ -120,7 +120,9 @@ ep_alloc(size_t size) return buf; } - +void* ep_alloc0(size_t size) { + return memset(ep_alloc(size),'\0',size); +} gchar* ep_strdup(const gchar* src) { guint len = strlen(src); @@ -166,6 +168,80 @@ gchar* ep_strdup_printf(const gchar* fmt, ...) { return dst; } +gchar** ep_strsplit(const gchar* string, const gchar* sep, int max_tokens) { + gchar* splitted; + gchar* s; + guint tokens; + guint str_len = strlen(splitted); + guint sep_len = strlen(sep); + guint i; + gchar** vec; + enum { AT_START, IN_PAD, IN_TOKEN } state; + guint curr_tok = 0; + + if ( ! string + || ! sep + || ! sep[0]) + return NULL; + + s = splitted = ep_strdup(string); + str_len = strlen(splitted); + sep_len = strlen(sep); + + if (max_tokens < 1) max_tokens = INT_MAX; + + tokens = 1; + + + while (tokens <= (guint)max_tokens && ( s = strstr(s,sep) )) { + tokens++; + + for(i=0; i < sep_len; i++ ) + s[i] = '\0'; + + s += sep_len; + + } + + vec = ep_alloc_array(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; +} /* release all allocated memory back to the pool. */ diff --git a/epan/emem.h b/epan/emem.h index c40efd3100..af10c7e637 100644 --- a/epan/emem.h +++ b/epan/emem.h @@ -45,6 +45,9 @@ void ep_init_chunk(void); /* Allocate memory with a packet lifetime scope */ void *ep_alloc(size_t size); +/* Allocate memory with a packet lifetime scope and fill it with zeros*/ +void* ep_alloc0(size_t size); + /* Duplicate a string with a packet lifetime scope */ gchar* ep_strdup(const gchar* src); @@ -57,6 +60,17 @@ guint8* ep_memdup(const guint8* src, size_t len); /* Create a formated string with a packet lifetime scope */ gchar* ep_strdup_printf(const gchar* fmt, ...); +/* allocates with a packet lifetime scope a array of type made of num elements */ +#define ep_alloc_array(type,num) (type*)ep_alloc(sizeof(type)*(num)) + +/* + * 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. + * the vector and all the strings are allocated with packet lifetime scope + */ +gchar** ep_strsplit(const gchar* string, const gchar* delimiter, int max_tokens); + /* release all memory allocated in the previous packet dissector */ void ep_free_all(void); diff --git a/epan/libethereal.def b/epan/libethereal.def index e18f750779..814715af3b 100644 --- a/epan/libethereal.def +++ b/epan/libethereal.def @@ -184,6 +184,15 @@ dtbl_entry_get_initial_handle EBCDIC_to_ASCII EBCDIC_to_ASCII1 ep_init_chunk +ep_alloc +ep_alloc0 +ep_strdup +ep_strdup_printf +ep_strndup +ep_strsplit +ep_memdup +ep_tvb_get_string +ep_tvb_memdup epan_cleanup epan_dissect_fill_in_columns epan_dissect_free diff --git a/epan/tvbuff.c b/epan/tvbuff.c index b63f568f69..ab6bd7896f 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -1002,13 +1002,41 @@ tvb_memdup(tvbuff_t *tvb, gint offset, gint length) { guint abs_offset, abs_length; guint8 *duped; - + check_offset_length(tvb, offset, length, &abs_offset, &abs_length); - + duped = g_malloc(abs_length); return tvb_memcpy(tvb, duped, abs_offset, abs_length); } +/* + * XXX - this doesn't treat a length of -1 as an error. + * If it did, this could replace some code that calls + * "tvb_ensure_bytes_exist()" and then allocates a buffer and copies + * data to it. + * + * "composite_ensure_contiguous_no_exception()" depends on -1 not being + * an error; does anything else depend on this routine treating -1 as + * meaning "to the end of the buffer"? + * + * This function allocates memory from a buffer with packet lifetime. + * You do not have to free this buffer, it will be automatically freed + * when ethereal starts decoding the next packet. + * Do not use this function if you want the allocated memory to be persistent + * after the current packet has been dissected. + */ +guint8* +ep_tvb_memdup(tvbuff_t *tvb, gint offset, gint length) +{ + guint abs_offset, abs_length; + guint8 *duped; + + check_offset_length(tvb, offset, length, &abs_offset, &abs_length); + + duped = ep_alloc(abs_length); + return tvb_memcpy(tvb, duped, abs_offset, abs_length); +} + const guint8* diff --git a/epan/tvbuff.h b/epan/tvbuff.h index 82c76a569d..064391d191 100644 --- a/epan/tvbuff.h +++ b/epan/tvbuff.h @@ -332,6 +332,12 @@ extern guint8* tvb_memcpy(tvbuff_t*, guint8* target, gint offset, gint length); * tvb_memdup(). Calls tvb_memcpy() */ extern guint8* tvb_memdup(tvbuff_t*, gint offset, gint length); +/* Same as above but the buffer returned from this function does not have to +* be freed. It will be automatically freed after the packet is dissected. +* Buffers allocated by this function are NOT persistent. +*/ +extern guint8* ep_tvb_memdup(tvbuff_t *tvb, gint offset, gint length); + /** WARNING! This function is possibly expensive, temporarily allocating * another copy of the packet data. Furthermore, it's dangerous because once * this pointer is given to the user, there's no guarantee that the user will |