stack.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008 #include <inttypes.h>
00009 #include <string.h>
00010
00011 #include <parserutils/utils/stack.h>
00012
00016 struct parserutils_stack
00017 {
00018 size_t item_size;
00019 size_t chunk_size;
00020 size_t items_allocated;
00021 int32_t current_item;
00022 void *items;
00023 };
00024
00035 parserutils_error parserutils_stack_create(size_t item_size, size_t chunk_size,
00036 parserutils_stack **stack)
00037 {
00038 parserutils_stack *s;
00039
00040 if (item_size == 0 || chunk_size == 0 || stack == NULL)
00041 return PARSERUTILS_BADPARM;
00042
00043 s = malloc(sizeof(parserutils_stack));
00044 if (s == NULL)
00045 return PARSERUTILS_NOMEM;
00046
00047 s->items = malloc(item_size * chunk_size);
00048 if (s->items == NULL) {
00049 free(s);
00050 return PARSERUTILS_NOMEM;
00051 }
00052
00053 s->item_size = item_size;
00054 s->chunk_size = chunk_size;
00055 s->items_allocated = chunk_size;
00056 s->current_item = -1;
00057
00058 *stack = s;
00059
00060 return PARSERUTILS_OK;
00061 }
00062
00069 parserutils_error parserutils_stack_destroy(parserutils_stack *stack)
00070 {
00071 if (stack == NULL)
00072 return PARSERUTILS_BADPARM;
00073
00074 free(stack->items);
00075 free(stack);
00076
00077 return PARSERUTILS_OK;
00078 }
00079
00087 parserutils_error parserutils_stack_push(parserutils_stack *stack,
00088 const void *item)
00089 {
00090 int32_t slot;
00091
00092 if (stack == NULL || item == NULL)
00093 return PARSERUTILS_BADPARM;
00094
00095
00096 if (stack->current_item < -1 || stack->current_item == INT32_MAX)
00097 return PARSERUTILS_INVALID;
00098
00099 slot = stack->current_item + 1;
00100
00101 if ((size_t) slot >= stack->items_allocated) {
00102 void *temp = realloc(stack->items,
00103 (stack->items_allocated + stack->chunk_size) *
00104 stack->item_size);
00105 if (temp == NULL)
00106 return PARSERUTILS_NOMEM;
00107
00108 stack->items = temp;
00109 stack->items_allocated += stack->chunk_size;
00110 }
00111
00112 memcpy((uint8_t *) stack->items + (slot * stack->item_size),
00113 item, stack->item_size);
00114 stack->current_item = slot;
00115
00116 return PARSERUTILS_OK;
00117 }
00118
00126 parserutils_error parserutils_stack_pop(parserutils_stack *stack, void *item)
00127 {
00128 if (stack == NULL)
00129 return PARSERUTILS_BADPARM;
00130
00131 if (stack->current_item < 0)
00132 return PARSERUTILS_INVALID;
00133
00134 if (item != NULL) {
00135 memcpy(item, (uint8_t *) stack->items +
00136 (stack->current_item * stack->item_size),
00137 stack->item_size);
00138 }
00139
00140 stack->current_item -= 1;
00141
00142 return PARSERUTILS_OK;
00143 }
00144
00151 void *parserutils_stack_get_current(parserutils_stack *stack)
00152 {
00153 if (stack == NULL || stack->current_item < 0)
00154 return NULL;
00155
00156 return (uint8_t *) stack->items +
00157 (stack->current_item * stack->item_size);
00158 }
00159
00160 #ifndef NDEBUG
00161 #include <stdio.h>
00162
00163 extern void parserutils_stack_dump(parserutils_stack *stack, const char *prefix,
00164 void (*printer)(void *item));
00165
00166 void parserutils_stack_dump(parserutils_stack *stack, const char *prefix,
00167 void (*printer)(void *item))
00168 {
00169 int32_t i;
00170
00171 if (stack == NULL || printer == NULL)
00172 return;
00173
00174 for (i = 0; i <= stack->current_item; i++) {
00175 printf("%s %d: ", prefix != NULL ? prefix : "", i);
00176 printer((uint8_t *) stack->items + (i * stack->item_size));
00177 printf("\n");
00178 }
00179 }
00180
00181 #endif
00182