Go to the source code of this file.
Data Structures | |
struct | handle_table |
Defines | |
#define | HANDLE_TABLE_INITIAL_SIZE 16 |
Functions | |
struct handle_table * | handle_table_create (void) |
void | handle_table_set_destroy (struct handle_table *ht, void(*destroy)(void *object)) |
Set an optional destructor callback. | |
static int | handle_table_resize (struct handle_table *ht, unsigned minimum_size) |
Resize the table if necessary. | |
static void | handle_table_clear (struct handle_table *ht, unsigned index) |
unsigned | handle_table_add (struct handle_table *ht, void *object) |
Add a new object. | |
unsigned | handle_table_set (struct handle_table *ht, unsigned handle, void *object) |
Returns zero on failure (out of memory). | |
void * | handle_table_get (struct handle_table *ht, unsigned handle) |
Fetch an existing object. | |
void | handle_table_remove (struct handle_table *ht, unsigned handle) |
unsigned | handle_table_get_next_handle (struct handle_table *ht, unsigned handle) |
unsigned | handle_table_get_first_handle (struct handle_table *ht) |
void | handle_table_destroy (struct handle_table *ht) |
Definition in file u_handle_table.c.
#define HANDLE_TABLE_INITIAL_SIZE 16 |
Definition at line 43 of file u_handle_table.c.
unsigned handle_table_add | ( | struct handle_table * | ht, | |
void * | object | |||
) |
Add a new object.
Returns a zero handle on failure (out of memory).
Definition at line 150 of file u_handle_table.c.
References assert, handle_table::filled, handle_table_resize(), handle_table::objects, and handle_table::size.
00152 { 00153 unsigned index; 00154 unsigned handle; 00155 00156 assert(ht); 00157 assert(object); 00158 if(!object) 00159 return 0; 00160 00161 /* linear search for an empty handle */ 00162 while(ht->filled < ht->size) { 00163 if(!ht->objects[ht->filled]) 00164 break; 00165 ++ht->filled; 00166 } 00167 00168 index = ht->filled; 00169 handle = index + 1; 00170 00171 /* check integer overflow */ 00172 if(!handle) 00173 return 0; 00174 00175 /* grow the table if necessary */ 00176 if(!handle_table_resize(ht, index)) 00177 return 0; 00178 00179 assert(!ht->objects[index]); 00180 ht->objects[index] = object; 00181 ++ht->filled; 00182 00183 return handle; 00184 }
static void handle_table_clear | ( | struct handle_table * | ht, | |
unsigned | index | |||
) | [static] |
Definition at line 128 of file u_handle_table.c.
References handle_table::destroy, and handle_table::objects.
00130 { 00131 void *object; 00132 00133 /* The order here is important so that the object being destroyed is not 00134 * present in the table when seen by the destroy callback, because the 00135 * destroy callback may directly or indirectly call the other functions in 00136 * this module. 00137 */ 00138 00139 object = ht->objects[index]; 00140 if(object) { 00141 ht->objects[index] = NULL; 00142 00143 if(ht->destroy) 00144 ht->destroy(object); 00145 } 00146 }
struct handle_table* handle_table_create | ( | void | ) | [read] |
Definition at line 62 of file u_handle_table.c.
References CALLOC, handle_table::destroy, handle_table::filled, FREE, HANDLE_TABLE_INITIAL_SIZE, MALLOC_STRUCT, handle_table::objects, and handle_table::size.
00063 { 00064 struct handle_table *ht; 00065 00066 ht = MALLOC_STRUCT(handle_table); 00067 if(!ht) 00068 return NULL; 00069 00070 ht->objects = (void **)CALLOC(HANDLE_TABLE_INITIAL_SIZE, sizeof(void *)); 00071 if(!ht->objects) { 00072 FREE(ht); 00073 return NULL; 00074 } 00075 00076 ht->size = HANDLE_TABLE_INITIAL_SIZE; 00077 ht->filled = 0; 00078 00079 ht->destroy = NULL; 00080 00081 return ht; 00082 }
void handle_table_destroy | ( | struct handle_table * | ht | ) |
Definition at line 281 of file u_handle_table.c.
References assert, handle_table::destroy, FREE, handle_table_clear(), handle_table::objects, and handle_table::size.
00282 { 00283 unsigned index; 00284 assert(ht); 00285 00286 if(ht->destroy) 00287 for(index = 0; index < ht->size; ++index) 00288 handle_table_clear(ht, index); 00289 00290 FREE(ht->objects); 00291 FREE(ht); 00292 }
void* handle_table_get | ( | struct handle_table * | ht, | |
unsigned | handle | |||
) |
Fetch an existing object.
Returns NULL for an invalid handle.
Definition at line 218 of file u_handle_table.c.
References assert, handle_table::objects, and handle_table::size.
00220 { 00221 void *object; 00222 00223 assert(ht); 00224 assert(handle); 00225 if(!handle || handle > ht->size) 00226 return NULL; 00227 00228 object = ht->objects[handle - 1]; 00229 00230 return object; 00231 }
unsigned handle_table_get_first_handle | ( | struct handle_table * | ht | ) |
Definition at line 274 of file u_handle_table.c.
References handle_table_get_next_handle().
00275 { 00276 return handle_table_get_next_handle(ht, 0); 00277 }
unsigned handle_table_get_next_handle | ( | struct handle_table * | ht, | |
unsigned | handle | |||
) |
Definition at line 259 of file u_handle_table.c.
References handle_table::objects, and handle_table::size.
00261 { 00262 unsigned index; 00263 00264 for(index = handle; index < ht->size; ++index) { 00265 if(ht->objects[index]) 00266 return index + 1; 00267 } 00268 00269 return 0; 00270 }
void handle_table_remove | ( | struct handle_table * | ht, | |
unsigned | handle | |||
) |
Definition at line 235 of file u_handle_table.c.
References assert, handle_table::filled, handle_table_clear(), handle_table::objects, and handle_table::size.
00237 { 00238 void *object; 00239 unsigned index; 00240 00241 assert(ht); 00242 assert(handle); 00243 if(!handle || handle > ht->size) 00244 return; 00245 00246 index = handle - 1; 00247 object = ht->objects[index]; 00248 if(!object) 00249 return; 00250 00251 handle_table_clear(ht, index); 00252 00253 if(index < ht->filled) 00254 ht->filled = index; 00255 }
static int handle_table_resize | ( | struct handle_table * | ht, | |
unsigned | minimum_size | |||
) | [static] |
Resize the table if necessary.
Definition at line 98 of file u_handle_table.c.
References assert, handle_table::objects, REALLOC, and handle_table::size.
00100 { 00101 unsigned new_size; 00102 void **new_objects; 00103 00104 if(ht->size > minimum_size) 00105 return ht->size; 00106 00107 new_size = ht->size; 00108 while(!(new_size > minimum_size)) 00109 new_size *= 2; 00110 assert(new_size); 00111 00112 new_objects = (void **)REALLOC((void *)ht->objects, 00113 ht->size*sizeof(void *), 00114 new_size*sizeof(void *)); 00115 if(!new_objects) 00116 return 0; 00117 00118 memset(new_objects + ht->size, 0, (new_size - ht->size)*sizeof(void *)); 00119 00120 ht->size = new_size; 00121 ht->objects = new_objects; 00122 00123 return ht->size; 00124 }
unsigned handle_table_set | ( | struct handle_table * | ht, | |
unsigned | handle, | |||
void * | object | |||
) |
Returns zero on failure (out of memory).
Definition at line 188 of file u_handle_table.c.
References assert, handle_table_clear(), handle_table_resize(), and handle_table::objects.
00191 { 00192 unsigned index; 00193 00194 assert(ht); 00195 assert(handle); 00196 if(!handle) 00197 return 0; 00198 00199 assert(object); 00200 if(!object) 00201 return 0; 00202 00203 index = handle - 1; 00204 00205 /* grow the table if necessary */ 00206 if(!handle_table_resize(ht, index)) 00207 return 0; 00208 00209 handle_table_clear(ht, index); 00210 00211 ht->objects[index] = object; 00212 00213 return handle; 00214 }
void handle_table_set_destroy | ( | struct handle_table * | ht, | |
void(*)(void *object) | destroy | |||
) |
Set an optional destructor callback.
If set, it will be called during handle_table_remove and handle_table_destroy calls.
Definition at line 86 of file u_handle_table.c.
References assert, and handle_table::destroy.