|
Libparserutils
|
00001 /* 00002 * This file is part of LibParserUtils. 00003 * Licensed under the MIT License, 00004 * http://www.opensource.org/licenses/mit-license.php 00005 * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org> 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 /* Ensure we'll get a valid slot */ 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
1.7.3