stack.c

Go to the documentation of this file.
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 

Generated on Wed Jul 29 11:59:21 2015 for Libparserutils by  doxygen 1.5.6