Libparserutils
vector.c
Go to the documentation of this file.
1 /*
2  * This file is part of LibParserUtils.
3  * Licensed under the MIT License,
4  * http://www.opensource.org/licenses/mit-license.php
5  * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org>
6  */
7 
8 #include <inttypes.h>
9 #include <string.h>
10 
12 
17 {
18  size_t item_size;
19  size_t chunk_size;
20  size_t items_allocated;
21  int32_t current_item;
22  void *items;
23 };
24 
36  size_t chunk_size, parserutils_vector **vector)
37 {
39 
40  if (item_size == 0 || chunk_size == 0 || vector == NULL)
41  return PARSERUTILS_BADPARM;
42 
43  v = malloc(sizeof(parserutils_vector));
44  if (v == NULL)
45  return PARSERUTILS_NOMEM;
46 
47  v->items = malloc(item_size * chunk_size);
48  if (v->items == NULL) {
49  free(v);
50  return PARSERUTILS_NOMEM;
51  }
52 
53  v->item_size = item_size;
54  v->chunk_size = chunk_size;
55  v->items_allocated = chunk_size;
56  v->current_item = -1;
57 
58  *vector = v;
59 
60  return PARSERUTILS_OK;
61 }
62 
70 {
71  if (vector == NULL)
72  return PARSERUTILS_BADPARM;
73 
74  free(vector->items);
75  free(vector);
76 
77  return PARSERUTILS_OK;
78 }
79 
88  void *item)
89 {
90  int32_t slot;
91 
92  if (vector == NULL || item == NULL)
93  return PARSERUTILS_BADPARM;
94 
95  /* Ensure we'll get a valid slot */
96  if (vector->current_item < -1 || vector->current_item == INT32_MAX)
97  return PARSERUTILS_INVALID;
98 
99  slot = vector->current_item + 1;
100 
101  if ((size_t) slot >= vector->items_allocated) {
102  void *temp = realloc(vector->items,
103  (vector->items_allocated + vector->chunk_size) *
104  vector->item_size);
105  if (temp == NULL)
106  return PARSERUTILS_NOMEM;
107 
108  vector->items = temp;
109  vector->items_allocated += vector->chunk_size;
110  }
111 
112  memcpy((uint8_t *) vector->items + (slot * vector->item_size),
113  item, vector->item_size);
114  vector->current_item = slot;
115 
116  return PARSERUTILS_OK;
117 }
118 
126 {
127  if (vector == NULL)
128  return PARSERUTILS_BADPARM;
129 
130  if (vector->current_item < 0)
131  return PARSERUTILS_INVALID;
132 
133  vector->current_item = -1;
134 
135  return PARSERUTILS_OK;
136 }
137 
145 {
146  if (vector == NULL)
147  return PARSERUTILS_BADPARM;
148 
149  if (vector->current_item < 0)
150  return PARSERUTILS_INVALID;
151 
152  vector->current_item--;
153 
154  return PARSERUTILS_OK;
155 }
156 
165  size_t *length)
166 {
167  if (vector == NULL)
168  return PARSERUTILS_BADPARM;
169 
170  if (length == NULL)
171  return PARSERUTILS_BADPARM;
172 
173  *length = vector->current_item + 1;
174 
175  return PARSERUTILS_OK;
176 }
177 
188  int32_t *ctx)
189 {
190  void *item;
191 
192  if (vector == NULL || ctx == NULL || vector->current_item < 0)
193  return NULL;
194 
195  if ((*ctx) > vector->current_item)
196  return NULL;
197 
198  item = (uint8_t *) vector->items + ((*ctx) * vector->item_size);
199 
200  (*ctx)++;
201 
202  return item;
203 }
204 
212 const void *parserutils_vector_peek(const parserutils_vector *vector,
213  int32_t ctx)
214 {
215  if (vector == NULL || vector->current_item < 0)
216  return NULL;
217 
218  if (ctx > vector->current_item)
219  return NULL;
220 
221  return (uint8_t *) vector->items + (ctx * vector->item_size);
222 }
223 
224 
225 #ifndef NDEBUG
226 #include <stdio.h>
227 
228 extern void parserutils_vector_dump(parserutils_vector *vector,
229  const char *prefix, void (*printer)(void *item));
230 
231 void parserutils_vector_dump(parserutils_vector *vector, const char *prefix,
232  void (*printer)(void *item))
233 {
234  int32_t i;
235 
236  if (vector == NULL || printer == NULL)
237  return;
238 
239  for (i = 0; i <= vector->current_item; i++) {
240  printf("%s %d: ", prefix != NULL ? prefix : "", i);
241  printer((uint8_t *) vector->items + (i * vector->item_size));
242  printf("\n");
243  }
244 }
245 
246 #endif
247 
int32_t current_item
Index of current item.
Definition: vector.c:21
parserutils_error parserutils_vector_clear(parserutils_vector *vector)
Clear a vector.
Definition: vector.c:125
Vector object.
Definition: vector.c:16
parserutils_error parserutils_vector_get_length(parserutils_vector *vector, size_t *length)
Acquire the length (in items) of the vector.
Definition: vector.c:164
parserutils_error parserutils_vector_remove_last(parserutils_vector *vector)
Remove the last item from a vector.
Definition: vector.c:144
void * items
Items in vector.
Definition: vector.c:22
parserutils_error
Definition: errors.h:18
parserutils_error parserutils_vector_append(parserutils_vector *vector, void *item)
Append an item to the vector.
Definition: vector.c:87
const void * parserutils_vector_peek(const parserutils_vector *vector, int32_t ctx)
Peek at an item in a vector.
Definition: vector.c:212
size_t item_size
Size of an item in the vector.
Definition: vector.c:18
size_t items_allocated
Number of slots allocated.
Definition: vector.c:20
size_t chunk_size
Size of a vector chunk.
Definition: vector.c:19
parserutils_error parserutils_vector_destroy(parserutils_vector *vector)
Destroy a vector instance.
Definition: vector.c:69
parserutils_error parserutils_vector_create(size_t item_size, size_t chunk_size, parserutils_vector **vector)
Create a vector.
Definition: vector.c:35
void parserutils_vector_dump(parserutils_vector *vector, const char *prefix, void(*printer)(void *item))
Definition: vector.c:231
const void * parserutils_vector_iterate(const parserutils_vector *vector, int32_t *ctx)
Iterate over a vector.
Definition: vector.c:187