262 lines · 6.2 KB · C
RawDownload
/* * This file is part of LibParserUtils. * Licensed under the MIT License, *                http://www.opensource.org/licenses/mit-license.php * Copyright 2008 John-Mark Bell <jmb@netsurf-browser.org> */ #if defined PLAN9#include <limits.h>#define INT32_MAX INT_MAX#endif #include <inttypes.h>#include <string.h> #include <parserutils/utils/vector.h> /** * Vector object */struct parserutils_vector{	size_t item_size;		/**< Size of an item in the vector */	size_t chunk_size;		/**< Size of a vector chunk */	size_t items_allocated;		/**< Number of slots allocated */	int32_t current_item;		/**< Index of current item */	void *items;			/**< Items in vector */ 	parserutils_alloc alloc;	/**< Memory (de)allocation function */	void *pw;			/**< Client-specific data */}; /** * Create a vector * * \param item_size   Length, in bytes, of an item in the vector * \param chunk_size  Number of vector slots in a chunk * \param alloc       Memory (de)allocation function * \param pw          Pointer to client-specific private data * \param vector      Pointer to location to receive vector instance * \return PARSERUTILS_OK on success, *         PARSERUTILS_BADPARM on bad parameters, *         PARSERUTILS_NOMEM on memory exhaustion */parserutils_error parserutils_vector_create(size_t item_size, 		size_t chunk_size, parserutils_alloc alloc, void *pw,		parserutils_vector **vector){	parserutils_vector *v; 	if (item_size == 0 || chunk_size == 0 || alloc == NULL || 			vector == NULL)		return PARSERUTILS_BADPARM; 	v = alloc(NULL, sizeof(parserutils_vector), pw);	if (v == NULL)		return PARSERUTILS_NOMEM; 	v->items = alloc(NULL, item_size * chunk_size, pw);	if (v->items == NULL) {		alloc(v, 0, pw);		return PARSERUTILS_NOMEM;	} 	v->item_size = item_size;	v->chunk_size = chunk_size;	v->items_allocated = chunk_size;	v->current_item = -1; 	v->alloc = alloc;	v->pw = pw; 	*vector = v; 	return PARSERUTILS_OK;} /** * Destroy a vector instance * * \param vector  The vector to destroy * \return PARSERUTILS_OK on success, appropriate error otherwise. */parserutils_error parserutils_vector_destroy(parserutils_vector *vector){	if (vector == NULL)		return PARSERUTILS_BADPARM; 	vector->alloc(vector->items, 0, vector->pw);	vector->alloc(vector, 0, vector->pw); 	return PARSERUTILS_OK;} /** * Append an item to the vector * * \param vector  The vector to append to * \param item    The item to append * \return PARSERUTILS_OK on success, appropriate error otherwise */parserutils_error parserutils_vector_append(parserutils_vector *vector, 		void *item){	int32_t slot; 	if (vector == NULL || item == NULL)		return PARSERUTILS_BADPARM; 	/* Ensure we'll get a valid slot */	if (vector->current_item < -1 || vector->current_item == INT32_MAX)		return PARSERUTILS_INVALID; 	slot = vector->current_item + 1; 	if ((size_t) slot >= vector->items_allocated) {		void *temp = vector->alloc(vector->items,				(vector->items_allocated + vector->chunk_size) *				vector->item_size, vector->pw);		if (temp == NULL)			return PARSERUTILS_NOMEM; 		vector->items = temp;		vector->items_allocated += vector->chunk_size;	} 	memcpy((uint8_t *) vector->items + (slot * vector->item_size), 			item, vector->item_size);	vector->current_item = slot; 	return PARSERUTILS_OK;} /** * Clear a vector * * \param vector  The vector to clear * \return PARSERUTILS_OK on success, appropriate error otherwise. */parserutils_error parserutils_vector_clear(parserutils_vector *vector){	if (vector == NULL)		return PARSERUTILS_BADPARM; 	if (vector->current_item < 0)		return PARSERUTILS_INVALID; 	vector->current_item = -1; 	return PARSERUTILS_OK;} /** * Remove the last item from a vector * * \param vector  The vector to remove from * \return PARSERUTILS_OK on success, appropriate error otherwise */parserutils_error parserutils_vector_remove_last(parserutils_vector *vector){	if (vector == NULL)		return PARSERUTILS_BADPARM; 	if (vector->current_item < 0)		return PARSERUTILS_INVALID; 	vector->current_item--; 	return PARSERUTILS_OK;} /** * Acquire the length (in items) of the vector. * * \param vector  The vector to interrogate. * \param length  Pointer to location to receive length information. * \return PARSERUTILS_OK on success, appropriate error otherwise */parserutils_error parserutils_vector_get_length(parserutils_vector *vector,                                                size_t *length){        if (vector == NULL)                return PARSERUTILS_BADPARM;                if (length == NULL)                return PARSERUTILS_BADPARM;                *length = vector->current_item + 1;                return PARSERUTILS_OK;} /** * Iterate over a vector * * \param vector  The vector to iterate over * \param ctx     Pointer to an integer for the iterator to use as context. * \return Pointer to current item, or NULL if no more * * \note The value pointed to by \a ctx must be zero to begin the iteration. */const void *parserutils_vector_iterate(const parserutils_vector *vector, 		int32_t *ctx){	void *item; 	if (vector == NULL || ctx == NULL || vector->current_item < 0)		return NULL; 	if ((*ctx) > vector->current_item)		return NULL; 	item = (uint8_t *) vector->items + ((*ctx) * vector->item_size); 	(*ctx)++; 	return item;} /** * Peek at an item in a vector * * \param vector  The vector to iterate over * \param ctx     Integer for the iterator to use as context. * \return Pointer to item, or NULL if no more */const void *parserutils_vector_peek(const parserutils_vector *vector, 		int32_t ctx){	if (vector == NULL || vector->current_item < 0)		return NULL; 	if (ctx > vector->current_item)		return NULL; 	return (uint8_t *) vector->items + (ctx * vector->item_size);}  #ifndef NDEBUG#include <stdio.h> extern void parserutils_vector_dump(parserutils_vector *vector, 		const char *prefix, void (*printer)(void *item)); void parserutils_vector_dump(parserutils_vector *vector, const char *prefix,		void (*printer)(void *item)){	int32_t i; 	if (vector == NULL || printer == NULL)		return; 	for (i = 0; i <= vector->current_item; i++) {		printf("%s %d: ", prefix != NULL ? prefix : "", i);		printer((uint8_t *) vector->items + (i * vector->item_size));		printf("\n");	}} #endif 

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t