aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/emem.c78
-rw-r--r--epan/emem.h14
-rw-r--r--epan/libethereal.def9
-rw-r--r--epan/tvbuff.c32
-rw-r--r--epan/tvbuff.h6
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