+/**
+ @file osrf_list.h
+ @brief Header for osrfList, like a vector class in C
+
+ An osrfList manages an array of void pointers, allocating additional memory as
+ needed when the array needs to grow. Optionally, it may call a designated callback
+ function as a destructor when one of the void pointers is removed, or when the
+ array itself is destroyed.
+
+ The callback function must be of type void and accept a void pointer as its parameter.
+ There is no specific function for installing or uninstalling such a callback; just assign
+ directly to the freeItem member of the osrfList structure.
+
+ Unlike a typical vector class in, or example, C++, an osrfList does NOT shift items
+ around to fill in the gap when you remove an item. Items stay put.
+
+ The use of void pointers involves the usual risk of type errors, so be careful.
+
+ NULL pointers are a special case. On the one hand an osrfList will happily store
+ a NULL if you ask it to. On the other hand it may overwrite a NULL pointer previously
+ stored, treating it as disposable. Conclusion: you can store NULLs in an osrfList, but
+ not safely, unless you are familiar with the internal details of the implementation and
+ work around them accordingly.
+ */
+
#ifndef OSRF_LIST_H
#define OSRF_LIST_H
extern "C" {
#endif
+/**
+ @brief Macro version of osrfListGetIndex().
+ @param l A pointer to the osrfList.
+ @param i The zero-based index of the requested pointer.
+*/
#define OSRF_LIST_GET_INDEX(l, i) (!(l) || (i) >= (l)->size) ? NULL: (l)->arrlist[(i)]
/**
- Items are stored as void*'s so it's up to the user to
- manage the data wisely. Also, if the 'freeItem' callback is defined for the list,
- then, it will be used on any item that needs to be freed, so don't mix data
- types in the list if you want magic freeing */
-
+ @brief Structure for managing an array of pointers.
+*/
struct _osrfListStruct {
- unsigned int size; /* how many items in the list including NULL items between non-NULL items */
- void (*freeItem) (void* item); /* callback for freeing stored items */
+ /** @brief How many slots are in use (possibly including some NULLs). */
+ unsigned int size;
+ /** @brief Callback function pointer for freeing stored items. */
+ void (*freeItem) (void* item);
+ /** @brief Pointer to array of void pointers. */
void** arrlist;
- int arrsize; /* how big is the currently allocated array */
+ /** @brief Capacity of the currently allocated array. */
+ int arrsize;
};
typedef struct _osrfListStruct osrfList;
+/**
+ @brief Iterator for traversing an osrfList.
+*/
struct _osrfListIteratorStruct {
+ /** @brief Pointer to the associated osrfList. */
const osrfList* list;
+ /** @brief Index of the next pointer to be returned by osrfListIteratorNext(). */
unsigned int current;
};
typedef struct _osrfListIteratorStruct osrfListIterator;
osrfList* osrfNewListSize( unsigned int size );
-
-/**
- Creates a new list iterator with the given list
- */
osrfListIterator* osrfNewListIterator( const osrfList* list );
-/**
- Returns the next non-NULL item in the list, return NULL when
- the end of the list has been reached
- */
void* osrfListIteratorNext( osrfListIterator* itr );
-/**
- Deallocates the given list
- */
void osrfListIteratorFree( osrfListIterator* itr );
void osrfListIteratorReset( osrfListIterator* itr );
-
-/**
- Allocates a new list
- @return The allocated list
- */
osrfList* osrfNewList();
-/**
- Pushes an item onto the end of the list. This always finds the highest index
- in the list and pushes the new item into the list after it.
- @param list The list
- @param item The item to push
- @return 0 on success, -1 on failure
- */
int osrfListPush( osrfList* list, void* item );
-
-/**
- * Removes the last item in the list
- * See osrfListRemove for details on how the removed item is handled
- * @return The item, unless 'freeItem' exists, then returns NULL
- */
void* osrfListPop( osrfList* list );
-/**
- Puts the given item into the list at the specified position. If there
- is already an item at the given position and the list has its
- "freeItem" function defined, then it will be used to free said item.
- If no 'freeItem' callback is defined, then the displaced item will
- be returned;
- @param list The list
- @param item The item to put into the list
- @param position The position to place the item in
- @return NULL in successfully inserting the new item and freeing
- any displaced items. Returns the displaced item if no "freeItem"
- callback is defined.
- */
void* osrfListSet( osrfList* list, void* item, unsigned int position );
-/**
- Returns the item at the given position
- @param list The list
- @param postiont the position
- */
void* osrfListGetIndex( const osrfList* list, unsigned int position );
-/**
- Frees the list and all list items (if the list has a "freeItem" function defined )
- @param list The list
- */
void osrfListFree( osrfList* list );
-/**
- Removes the list item at the given index
- @param list The list
- @param position The position of the item to remove
- @return A pointer to the item removed if "freeItem" is not defined
- for this list, returns NULL if it is.
- */
void* osrfListRemove( osrfList* list, unsigned int position );
-/**
- Removes the list item at the given index, without freeing it
- @param list The list
- @param position The position of the item to remove
- @return A pointer to the item extracted, or NULL
- if there is nothing to extract
- */
void* osrfListExtract( osrfList* list, unsigned int position );
-/**
- Finds the list item whose void* is the same as the one passed in
- @param list The list
- @param addr The pointer connected to the list item we're to find
- @return the index of the item, or -1 if the item was not found
- */
int osrfListFind( const osrfList* list, void* addr );
-/**
- @return The number of non-null items in the list
- */
unsigned int osrfListGetCount( const osrfList* list );
-/**
- * May be used as a default memory freeing call
- * Just calls free() on list items
- */
-void osrfListVanillaFree( void* item );
-
-/**
- * Tells the list to just call 'free()' on each item when
- * an item or the whole list is destroyed
- */
void osrfListSetDefaultFree( osrfList* list );
-/**
- * Inserts the new item at the first free (null) slot
- * in the array. Item is shoved onto the end of the
- * list if there are no null slots */
int osrfListPushFirst( osrfList* list, void* item );
#ifdef __cplusplus
/**
@file osrf_list.c
@brief Implementation of osrfList, sort of like a vector class.
-
- An osrfList manages an array of void pointers, allocating additional memory as
- needed when the array needs to grow. Optionally, it may call a designated callback
- function as a destructor when one of the void pointers is removed, or when the
- array itself is destroyed.
-
- The callback function must be of type void and accept a void pointer as its parameter.
- There is no specific function for installing or uninstalling such a callback; just assign
- directly to the freeItem member of the osrfList structure.
-
- Unlike a typical vector class in, or example, C++, an osrfList does NOT shift items
- around to fill in the gap when you remove an item. Items stay put.
-
- The use of void pointers involves the usual risk of type errors, so be careful.
-
- NULL pointers are a special case. On the one hand an osrfList will happily store
- a NULL if you ask it to. On the other hand it may overwrite a NULL pointer previously
- stored, treating it as disposable. Conclusion: you can store NULLs in an osrfList, but
- not safely, unless you are familiar with the internal details of the implementation and
- work around them accordingly.
*/
#include <opensrf/osrf_list.h>
@brief Create and initialize an osrfListIterator for a given osrfList.
@param list A pointer to an osrfList.
@return A pointer to the newly constructed osrfListIterator.
+
+ The calling code is responsible for freeing the osrfListIterator by calling
+ osrfListIteratorFree().
*/
osrfListIterator* osrfNewListIterator( const osrfList* list ) {
if(!list) return NULL;