|
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/vector.h> 00012 00016 struct parserutils_vector 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_vector_create(size_t item_size, 00036 size_t chunk_size, parserutils_vector **vector) 00037 { 00038 parserutils_vector *v; 00039 00040 if (item_size == 0 || chunk_size == 0 || vector == NULL) 00041 return PARSERUTILS_BADPARM; 00042 00043 v = malloc(sizeof(parserutils_vector)); 00044 if (v == NULL) 00045 return PARSERUTILS_NOMEM; 00046 00047 v->items = malloc(item_size * chunk_size); 00048 if (v->items == NULL) { 00049 free(v); 00050 return PARSERUTILS_NOMEM; 00051 } 00052 00053 v->item_size = item_size; 00054 v->chunk_size = chunk_size; 00055 v->items_allocated = chunk_size; 00056 v->current_item = -1; 00057 00058 *vector = v; 00059 00060 return PARSERUTILS_OK; 00061 } 00062 00069 parserutils_error parserutils_vector_destroy(parserutils_vector *vector) 00070 { 00071 if (vector == NULL) 00072 return PARSERUTILS_BADPARM; 00073 00074 free(vector->items); 00075 free(vector); 00076 00077 return PARSERUTILS_OK; 00078 } 00079 00087 parserutils_error parserutils_vector_append(parserutils_vector *vector, 00088 void *item) 00089 { 00090 int32_t slot; 00091 00092 if (vector == NULL || item == NULL) 00093 return PARSERUTILS_BADPARM; 00094 00095 /* Ensure we'll get a valid slot */ 00096 if (vector->current_item < -1 || vector->current_item == INT32_MAX) 00097 return PARSERUTILS_INVALID; 00098 00099 slot = vector->current_item + 1; 00100 00101 if ((size_t) slot >= vector->items_allocated) { 00102 void *temp = realloc(vector->items, 00103 (vector->items_allocated + vector->chunk_size) * 00104 vector->item_size); 00105 if (temp == NULL) 00106 return PARSERUTILS_NOMEM; 00107 00108 vector->items = temp; 00109 vector->items_allocated += vector->chunk_size; 00110 } 00111 00112 memcpy((uint8_t *) vector->items + (slot * vector->item_size), 00113 item, vector->item_size); 00114 vector->current_item = slot; 00115 00116 return PARSERUTILS_OK; 00117 } 00118 00125 parserutils_error parserutils_vector_clear(parserutils_vector *vector) 00126 { 00127 if (vector == NULL) 00128 return PARSERUTILS_BADPARM; 00129 00130 if (vector->current_item < 0) 00131 return PARSERUTILS_INVALID; 00132 00133 vector->current_item = -1; 00134 00135 return PARSERUTILS_OK; 00136 } 00137 00144 parserutils_error parserutils_vector_remove_last(parserutils_vector *vector) 00145 { 00146 if (vector == NULL) 00147 return PARSERUTILS_BADPARM; 00148 00149 if (vector->current_item < 0) 00150 return PARSERUTILS_INVALID; 00151 00152 vector->current_item--; 00153 00154 return PARSERUTILS_OK; 00155 } 00156 00164 parserutils_error parserutils_vector_get_length(parserutils_vector *vector, 00165 size_t *length) 00166 { 00167 if (vector == NULL) 00168 return PARSERUTILS_BADPARM; 00169 00170 if (length == NULL) 00171 return PARSERUTILS_BADPARM; 00172 00173 *length = vector->current_item + 1; 00174 00175 return PARSERUTILS_OK; 00176 } 00177 00187 const void *parserutils_vector_iterate(const parserutils_vector *vector, 00188 int32_t *ctx) 00189 { 00190 void *item; 00191 00192 if (vector == NULL || ctx == NULL || vector->current_item < 0) 00193 return NULL; 00194 00195 if ((*ctx) > vector->current_item) 00196 return NULL; 00197 00198 item = (uint8_t *) vector->items + ((*ctx) * vector->item_size); 00199 00200 (*ctx)++; 00201 00202 return item; 00203 } 00204 00212 const void *parserutils_vector_peek(const parserutils_vector *vector, 00213 int32_t ctx) 00214 { 00215 if (vector == NULL || vector->current_item < 0) 00216 return NULL; 00217 00218 if (ctx > vector->current_item) 00219 return NULL; 00220 00221 return (uint8_t *) vector->items + (ctx * vector->item_size); 00222 } 00223 00224 00225 #ifndef NDEBUG 00226 #include <stdio.h> 00227 00228 extern void parserutils_vector_dump(parserutils_vector *vector, 00229 const char *prefix, void (*printer)(void *item)); 00230 00231 void parserutils_vector_dump(parserutils_vector *vector, const char *prefix, 00232 void (*printer)(void *item)) 00233 { 00234 int32_t i; 00235 00236 if (vector == NULL || printer == NULL) 00237 return; 00238 00239 for (i = 0; i <= vector->current_item; i++) { 00240 printf("%s %d: ", prefix != NULL ? prefix : "", i); 00241 printer((uint8_t *) vector->items + (i * vector->item_size)); 00242 printf("\n"); 00243 } 00244 } 00245 00246 #endif 00247
1.7.3