aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorLuis Ontanon <luis.ontanon@gmail.com>2005-10-01 10:36:57 +0000
committerLuis Ontanon <luis.ontanon@gmail.com>2005-10-01 10:36:57 +0000
commit9860d26c68a0d54f376bab33c397306ad7c42fb3 (patch)
treee2f92215a02b310d3cd324f2255c1e82240c39b1 /epan
parent6f5e84b2d7c179e574bd413faea17b7f0f8d7240 (diff)
emem.[ch]:
Add a simple stack implememtation that uses ep_alloc Add ep_new() ep_new0() macros tpg.[ch]: use the stack in tpg helpers svn path=/trunk/; revision=16061
Diffstat (limited to 'epan')
-rw-r--r--epan/emem.c41
-rw-r--r--epan/emem.h30
-rw-r--r--epan/tpg.c27
-rw-r--r--epan/tpg.h28
4 files changed, 82 insertions, 44 deletions
diff --git a/epan/emem.c b/epan/emem.c
index e3a8afcac3..8fcfda2429 100644
--- a/epan/emem.c
+++ b/epan/emem.c
@@ -466,6 +466,45 @@ se_free_all(void)
se_init_chunk();
#endif
}
-
+ep_stack_t ep_stack_new(void) {
+ ep_stack_t s = ep_new(struct _ep_stack_frame_t*);
+ *s = ep_new0(struct _ep_stack_frame_t);
+ return s;
+}
+
+/* for ep_stack_t we'll keep the popped frames so we reuse them instead
+of allocating new ones.
+*/
+
+
+void* ep_stack_push(ep_stack_t stack, void* data) {
+ struct _ep_stack_frame_t* frame;
+ struct _ep_stack_frame_t* head = (*stack);
+
+ if (head->above) {
+ frame = head->above;
+ } else {
+ frame = ep_new(struct _ep_stack_frame_t);
+ head->above = frame;
+ frame->below = head;
+ frame->above = NULL;
+ }
+
+ frame->payload = data;
+ (*stack) = frame;
+
+ return data;
+}
+
+void* ep_stack_pop(ep_stack_t stack) {
+
+ if ((*stack)->below) {
+ (*stack) = (*stack)->below;
+ return (*stack)->above->payload;
+ } else {
+ return NULL;
+ }
+}
+
diff --git a/epan/emem.h b/epan/emem.h
index 81f2307294..69fa82c51b 100644
--- a/epan/emem.h
+++ b/epan/emem.h
@@ -46,9 +46,11 @@ void ep_init_chunk(void);
/* Allocate memory with a packet lifetime scope */
void *ep_alloc(size_t size);
+#define ep_new(type) ((type*)ep_alloc(sizeof(type)))
/* Allocate memory with a packet lifetime scope and fill it with zeros*/
void* ep_alloc0(size_t size);
+#define ep_new0(type) ((type*)ep_alloc0(sizeof(type)))
/* Duplicate a string with a packet lifetime scope */
gchar* ep_strdup(const gchar* src);
@@ -79,7 +81,35 @@ gchar** ep_strsplit(const gchar* string, const gchar* delimiter, int max_tokens)
void ep_free_all(void);
+/* a stack implemented using ephemeral allocators */
+typedef struct _ep_stack_frame_t** ep_stack_t;
+
+struct _ep_stack_frame_t {
+ void* payload;
+ struct _ep_stack_frame_t* below;
+ struct _ep_stack_frame_t* above;
+};
+
+/*
+ * creates an empty stack with a packet lifetime scope
+ */
+ep_stack_t ep_stack_new(void);
+
+/*
+ * pushes item into stack, returns item
+ */
+void* ep_stack_push(ep_stack_t stack, void* item);
+
+/*
+ * pops an item from the stack
+ */
+void* ep_stack_pop(ep_stack_t stack);
+
+/*
+ * returns the item on top of the stack without popping it
+ */
+#define ep_stack_peek(stack) ((*(stack))->payload)
/* Functions for handling memory allocation and garbage collection with
diff --git a/epan/tpg.c b/epan/tpg.c
index 21ccf0e2c1..2813b795c0 100644
--- a/epan/tpg.c
+++ b/epan/tpg.c
@@ -52,32 +52,9 @@ extern tpg_parser_data_t* tpg_start(proto_tree* root_tree,
tpg->private_data = private_data;
tpg->tt = tvbparse_init(tvb,offset,len,tpg,NULL);
- tpg->stack = ep_alloc(sizeof(tpg_stack_frame_t));
- tpg->stack->tree = root_tree;
- tpg->stack->down = NULL;
+ tpg->stack = ep_stack_new();
+ ep_stack_push(tpg->stack,root_tree);
return tpg;
}
-
-extern void tpg_push(tpg_parser_data_t* tpg, proto_item* item, gint ett) {
- tpg_stack_frame_t* frame = ep_alloc(sizeof(tpg_stack_frame_t));
-
- frame->tree = proto_item_add_subtree(item,ett);
- frame->down = tpg->stack;
- tpg->stack = frame;
-
-}
-
-
-tpg_stack_frame_t* tpg_pop(tpg_parser_data_t* tpg) {
- tpg_stack_frame_t* frame = tpg->stack;
-
- if (tpg->stack->down) {
- tpg->stack = tpg->stack->down;
- } else {
- DISSECTOR_ASSERT( FALSE && "Error in the TPG infrastructure: trying to pop the end of the stack");
- }
-
- return frame;
-}
diff --git a/epan/tpg.h b/epan/tpg.h
index ee6deddbea..84b3ba02f0 100644
--- a/epan/tpg.h
+++ b/epan/tpg.h
@@ -35,13 +35,8 @@
#include <epan/emem.h>
-typedef struct _tpg_stack_frame_t {
- proto_tree* tree;
- struct _tpg_stack_frame_t* down;
-} tpg_stack_frame_t;
-
typedef struct _tpg_parser_data_t {
- tpg_stack_frame_t* stack;
+ ep_stack_t stack;
tvbparse_t* tt;
void* private_data;
} tpg_parser_data_t;
@@ -71,19 +66,16 @@ extern guint32 tpg_ipv4(tvbparse_elem_t*);
extern guint8* tpg_ipv6(tvbparse_elem_t*);
#define TPG_IPV6(i) tpg_ipv6((i))
-extern void tpg_push(tpg_parser_data_t*, proto_item*, gint ett);
-#define TPG_PUSH(tpg,pi,ett) tpg_push(((tpg_parser_data_t*)tpg),(pi),(ett))
-
-extern tpg_stack_frame_t* tpg_pop(tpg_parser_data_t* tpg);
-#define TPG_POP(tpg) tpg_pop(((tpg_parser_data_t*)tpg))
+#define TPG_PUSH(tpg,pi,ett) ep_stack_push(((tpg_parser_data_t*)(tpg))->stack,proto_item_add_subtree((pi),(ett)))
+#define TPG_POP(tpg) ep_stack_pop(((tpg_parser_data_t*)(tpg))->stack) ;
-#define TPG_ADD_STRING(tpg, hfid, elem) proto_tree_add_item(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, FALSE)
-#define TPG_ADD_BOOLEAN(tpg, hfid, elem) proto_tree_add_boolean(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, TRUE)
-#define TPG_ADD_INT(tpg, hfid, elem, value) proto_tree_add_int(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
-#define TPG_ADD_UINT(tpg, hfid, elem, value) proto_tree_add_uint(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
-#define TPG_ADD_IPV4(tpg, hfid, elem, value) proto_tree_add_ipv4(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
-#define TPG_ADD_IPV6(tpg, hfid, elem, value) proto_tree_add_ipv6(((tpg_parser_data_t*)tpg)->stack->tree, hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
-#define TPG_ADD_TEXT(tpg, elem) proto_tree_add_text(((tpg_parser_data_t*)tpg)->stack->tree, (elem)->tvb, (elem)->offset, (elem)->len, \
+#define TPG_ADD_STRING(tpg, hfid, elem) proto_tree_add_item(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, FALSE)
+#define TPG_ADD_BOOLEAN(tpg, hfid, elem) proto_tree_add_boolean(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, TRUE)
+#define TPG_ADD_INT(tpg, hfid, elem, value) proto_tree_add_int(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
+#define TPG_ADD_UINT(tpg, hfid, elem, value) proto_tree_add_uint(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
+#define TPG_ADD_IPV4(tpg, hfid, elem, value) proto_tree_add_ipv4(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
+#define TPG_ADD_IPV6(tpg, hfid, elem, value) proto_tree_add_ipv6(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), hfid, (elem)->tvb, (elem)->offset, (elem)->len, value)
+#define TPG_ADD_TEXT(tpg, elem) proto_tree_add_text(ep_stack_peek(((tpg_parser_data_t*)tpg)->stack), (elem)->tvb, (elem)->offset, (elem)->len, \
"%s",tvb_format_text((elem)->tvb, (elem)->offset, (elem)->len))
#define TPG_SET_TEXT(pi, elem) proto_item_set_text((pi), "%s",tvb_format_text((elem)->tvb, (elem)->offset, (elem)->len))