1 /* 2 * Copyright (C) 2011 Christos Tsantilas 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 17 * MA 02110-1301 USA. 18 */ 19 20 #ifndef __ARRAY_H 21 #define __ARRAY_H 22 23 #include "c-icap.h" 24 #include "mem.h" 25 26 #ifdef __cplusplus 27 extern "C" 28 { 29 #endif 30 31 /** 32 \defgroup ARRAYS Arrays, stacks, queues and vectors related API 33 \ingroup API 34 * Arrays, stacks, queues and vectors related API. 35 */ 36 37 typedef struct ci_array_item { 38 char *name; 39 void *value; 40 } ci_array_item_t; 41 42 /** 43 \defgroup SIMPLE_ARRAYS Simple arrays related API 44 \ingroup ARRAYS 45 * Arrays which store name/value pair items 46 */ 47 48 /** 49 \typedef ci_array_t 50 \ingroup SIMPLE_ARRAYS 51 * The ci_array_t objects can store a list of name/value pairs. Currently 52 * can grow up to a fixed size. 53 */ 54 typedef struct ci_array { 55 ci_array_item_t *items; 56 char *mem; 57 size_t max_size; 58 unsigned int count; 59 ci_mem_allocator_t *alloc; 60 } ci_array_t; 61 62 /** 63 \def ci_array_value(array, pos) 64 \ingroup SIMPLE_ARRAYS 65 * Return the value of item on position 'pos' 66 */ 67 #define ci_array_value(array, pos) (pos < (array)->count ? (array)->items[pos].value : NULL) 68 69 /** 70 \def ci_array_name(array, pos) 71 \ingroup SIMPLE_ARRAYS 72 * Return the name of item on position 'pos' 73 */ 74 #define ci_array_name(array, pos) (pos < (array)->count ? (array)->items[pos].name : NULL) 75 76 /** 77 \def ci_array_size(array) 78 \ingroup SIMPLE_ARRAYS 79 * Return the size of array 'array' 80 */ 81 #define ci_array_size(array) ((array)->count) 82 83 /** 84 * Allocate the required memory and initialize an ci_array_t object 85 \ingroup SIMPLE_ARRAYS 86 \param max_mem_size the maximum memory to use 87 \return the allocated object on success, or NULL on failure 88 * 89 */ 90 CI_DECLARE_FUNC(ci_array_t *) ci_array_new(size_t max_mem_size); 91 92 /** 93 * Create and initialize an ci_array_t object for the given number of items 94 \ingroup SIMPLE_ARRAYS 95 \param items the maximum aray items 96 \param item_size the items size 97 \return the allocated object on success, or NULL on failure 98 */ 99 CI_DECLARE_FUNC(ci_array_t *) ci_array_new2(size_t items, size_t item_size); 100 101 /** 102 * Destroy an ci_array_t object 103 \ingroup SIMPLE_ARRAYS 104 \param array a pointer to ci_array_t object to be destroyed 105 * 106 */ 107 CI_DECLARE_FUNC(void) ci_array_destroy(ci_array_t *array); 108 109 /** 110 * Add an name/value pair item to the array. 111 \ingroup SIMPLE_ARRAYS 112 \param array a pointer to the ci_array_t object 113 \param name the name part of the name/value pair item to add 114 \param value the value part of the name/value pair item to add 115 \param size the size of the value part of the new item. 116 \return a pointer to the new array item on success, NULL otherwise 117 */ 118 CI_DECLARE_FUNC(const ci_array_item_t *) ci_array_add(ci_array_t *array, const char *name, const void *value, size_t size); 119 120 /** 121 * Delete the last element of the array. 122 \ingroup SIMPLE_ARRAYS 123 \param array a pointer to the ci_array_t object 124 \return a pointer to the popped array item on success, NULL otherwise 125 */ 126 CI_DECLARE_FUNC(const ci_array_item_t *)ci_array_pop(ci_array_t *array); 127 128 /** 129 * Search in an array for an item with the given name 130 \ingroup SIMPLE_ARRAYS 131 \param array a pointer to the ci_array_t object 132 \param name the item to be search for. 133 \return pointer to the value pair of the array item if found, NULL otherwise 134 */ 135 CI_DECLARE_FUNC(const void *) ci_array_search(ci_array_t *array, const char *name); 136 137 /** 138 * Run the given function for each array item 139 \ingroup SIMPLE_ARRAYS 140 \param array a pointer to the ci_array_t object 141 \param data a pointer to data which will be passed on fn function 142 \param fn a pointer to the function which will be run for each array item. The iteration will stop if the fn function return non zero value 143 */ 144 CI_DECLARE_FUNC(void) ci_array_iterate(const ci_array_t *array, void *data, int (*fn)(void *data, const char *name, const void *)); 145 146 /** 147 * Get an item of the array. 148 \ingroup SIMPLE_ARRAYS 149 \param array a pointer to the ci_array_t object 150 \param pos The position of the item in array 151 \return a pointer to the array item on success, NULL otherwise 152 */ 153 CI_DECLARE_FUNC(const ci_array_item_t *) ci_array_get_item(ci_array_t *array, int pos); 154 155 /** 156 \defgroup STR_ARRAYS Arrays of strings related API 157 \ingroup SIMPLE_ARRAYS 158 * Arrays which store name/value pair items 159 */ 160 161 /** 162 \typedef ci_str_array_t 163 \ingroup STR_ARRAYS 164 * An alias to the ci_array_t object. It is used to store items with string 165 * values to an array. 166 * The ci_str_array_new, ci_str_array_destroy, ci_str_array_add, 167 * ci_str_array_search and ci_str_array_iterate defines are similar to 168 * the equivalent ci_array_* functions with the required typecasting to 169 * work with strings. 170 */ 171 typedef ci_array_t ci_str_array_t; 172 #define ci_str_array_new ci_array_new 173 #define ci_str_array_destroy ci_array_destroy 174 #define ci_str_array_add(array, name, value) ci_array_add((ci_array_t *)(array), name, value, (strlen(value)+1)) 175 #define ci_str_array_pop(array) ci_array_pop((ci_array_t *)(array)) 176 #define ci_str_array_get_item(array, pos) ci_array_get_item((ci_array_t *)(array), pos) 177 #define ci_str_array_search(array, name) (const char *)ci_array_search((ci_array_t *)(array), name) 178 #define ci_str_array_iterate ci_array_iterate 179 #define ci_str_array_value(array, pos) ci_array_value((ci_array_t *)(array), pos) 180 #define ci_str_array_name(array, pos) ci_array_name((ci_array_t *)(array), pos) 181 #define ci_str_array_size(array) ci_array_size((ci_array_t *)(array)) 182 183 184 /** 185 \defgroup PTR_ARRAYS Arrays of pointers 186 \ingroup SIMPLE_ARRAYS 187 * Arrays of name/pointers to objects pairs 188 */ 189 190 /** 191 \typedef ci_ptr_array_t 192 \ingroup PTR_ARRAYS 193 * The ci_ptr_array_t objects can store a list of name and pointer to object 194 * pairs. It is similar to the ci_array_t object but does not store the value 195 * but a pointer to the value. 196 */ 197 typedef ci_array_t ci_ptr_array_t; 198 199 /** 200 \def ci_ptr_array_value(ptr_array, pos) 201 \ingroup PTR_ARRAYS 202 * Return the value of item at position 'pos' 203 */ 204 #define ci_ptr_array_value(array, pos) ci_array_value((ci_array_t *)(array), pos) 205 206 /** 207 \def ci_ptr_array_value(ptr_array, pos) 208 \ingroup PTR_ARRAYS 209 * Return the name of item at position 'pos' 210 */ 211 #define ci_ptr_array_name(array, pos) ci_array_name((ci_array_t *)(array), pos) 212 213 /** 214 \def ci_ptr_array_value(ptr_array) 215 \ingroup PTR_ARRAYS 216 * Return the size of ptr_array 217 */ 218 #define ci_ptr_array_size(array) ci_array_size((ci_array_t *)(array)) 219 220 /** 221 \def ci_ptr_array_new() 222 \ingroup PTR_ARRAYS 223 * Create a new ci_ptr_array_t object. Similar to the ci_array_new() function. 224 */ 225 #define ci_ptr_array_new ci_array_new 226 227 /** 228 * Create and initialize an ci_ptr_array_t object for the given number of items 229 \ingroup PTR_ARRAYS 230 \param items the maximum aray items 231 \return the allocated object on success, or NULL on failure 232 */ 233 CI_DECLARE_FUNC(ci_ptr_array_t *) ci_ptr_array_new2(size_t items); 234 235 /** 236 \def ci_ptr_array_destroy(ptr_array) 237 \ingroup PTR_ARRAYS 238 * Destroy a ci_ptr_array_t object. Similar to the ci_array_destroy function 239 */ 240 #define ci_ptr_array_destroy(ptr_array) ci_array_destroy((ci_array_t *)(ptr_array)) 241 242 /** 243 * Search in an array for an item with the given name 244 \ingroup PTR_ARRAYS 245 \param array a pointer to the ci_ptr_array_t object 246 \param name the item to be search for. 247 \return pointer to the value pair of the array item if found, NULL otherwise 248 */ 249 CI_DECLARE_FUNC(void *) ci_ptr_array_search(ci_ptr_array_t *array, const char *name); 250 251 252 /** 253 \def ci_ptr_array_iterate(ptr_array, data, fn) 254 \ingroup PTR_ARRAYS 255 * Run the function fn for each item of the ci_ptr_array_t object. Similar to 256 * the ci_array_iterate function 257 */ 258 #define ci_ptr_array_iterate(ptr_array, data, fn) ci_array_iterate((ci_array_t *)(ptr_array), data, fn) 259 260 /** 261 * Add an name/value pair item to the ci_ptr_array_t object. 262 \ingroup PTR_ARRAYS 263 \param ptr_array a pointer to the ci_ptr_array_t object 264 \param name the name part of the name/value pair item to be added 265 \param value a pointer to the value part of the name/value pair item to be 266 * added 267 \return a pointer to the new array item on success, NULL otherwise 268 * 269 */ 270 CI_DECLARE_FUNC(const ci_array_item_t *) ci_ptr_array_add(ci_ptr_array_t *ptr_array, const char *name, void *value); 271 272 /** 273 * Pop and delete the last item of a ci_ptr_array_t object. 274 \ingroup PTR_ARRAYS 275 \param ptr_array a pointer to the ci_ptr_array_t object 276 \return a pointer to the popped array item 277 */ 278 CI_DECLARE_FUNC(const ci_array_item_t *) ci_ptr_array_pop(ci_ptr_array_t *ptr_array); 279 280 /** 281 * Pop and delete the last item of a ci_ptr_array_t object. 282 \ingroup PTR_ARRAYS 283 \param ptr_array a pointer to the ci_ptr_array_t object 284 \param name a pointer to a buffer where the name of the poped item will be 285 * store, or NULL 286 \param name_size the size of name buffer 287 \return a pointer to the value of the popped item 288 */ 289 CI_DECLARE_FUNC(void *) ci_ptr_array_pop_value(ci_ptr_array_t *ptr_array, char *name, size_t name_size); 290 291 /** 292 \def ci_ptr_array_get_item() 293 \ingroup PTR_ARRAYS 294 * Get an array item. Wrapper to the ci_array_get_item() function. 295 */ 296 #define ci_ptr_array_get_item(array, pos) ci_array_get_item((ci_array_t *)(array), pos) 297 298 /** 299 \defgroup DYNAMIC_ARRAYS Dynamic arrays related API 300 \ingroup ARRAYS 301 * Arrays which store name/value pair items, and can grow unlimited. 302 * 303 */ 304 305 /** 306 \typedef ci_dyn_array_t 307 \ingroup DYNAMIC_ARRAYS 308 * The ci_dyn_array_t objects can store a list of name/value pairs. 309 * The memory RAM space of dynamic array items can not be released 310 * before the ci_dyn_array destroyed. 311 */ 312 typedef struct ci_dyn_array { 313 ci_array_item_t **items; 314 int count; 315 int max_items; 316 ci_mem_allocator_t *alloc; 317 } ci_dyn_array_t; 318 319 /** 320 \def ci_dyn_array_get_item(array, pos) 321 \ingroup DYNAMIC_ARRAYS 322 * Return the ci_array_item_t item on position 'pos' 323 */ 324 #define ci_dyn_array_get_item(array, pos) (pos < (array)->count ? (array)->items[pos] : NULL) 325 326 /** 327 \def ci_dyn_array_value(array, pos) 328 \ingroup DYNAMIC_ARRAYS 329 * Return the value of item on position 'pos' 330 */ 331 #define ci_dyn_array_value(array, pos) ((pos < (array)->count && (array)->items[pos] != NULL) ? (array)->items[pos]->value : NULL) 332 333 /** 334 \def ci_dyn_array_name(array, pos) 335 \ingroup DYNAMIC_ARRAYS 336 * Return the name of item on position 'pos' 337 */ 338 #define ci_dyn_array_name(array, pos) ((pos < (array)->count && (array)->items[pos] != NULL) ? (array)->items[pos]->name : NULL) 339 340 /** 341 \def ci_dyn_array_size(array) 342 \ingroup DYNAMIC_ARRAYS 343 * Return the size of array 'array' 344 */ 345 #define ci_dyn_array_size(array) ((array)->count) 346 347 /** 348 * Allocate the required memory and initialize an ci_dyn_array_t object 349 \ingroup DYNAMIC_ARRAYS 350 \param mem_size the initial size to use for dyn_array 351 \return the allocated object on success, or NULL on failure 352 * 353 */ 354 CI_DECLARE_FUNC(ci_dyn_array_t *) ci_dyn_array_new(size_t mem_size); 355 356 /** 357 * Create and initialize an ci_dyn_array_t object for the given number of items 358 \ingroup DYNAMIC_ARRAYS 359 \param items the maximum aray items 360 \param item_size the items size 361 \return the allocated object on success, or NULL on failure 362 */ 363 CI_DECLARE_FUNC(ci_dyn_array_t *) ci_dyn_array_new2(size_t items, size_t item_size); 364 365 /** 366 * Destroy an ci_dyn_array_t object 367 \ingroup DYNAMIC_ARRAYS 368 \param array a pointer to ci_dyn_array_t object to be destroyed 369 */ 370 CI_DECLARE_FUNC(void) ci_dyn_array_destroy(ci_dyn_array_t *array); 371 372 /** 373 * Add an name/value pair item to a dynamic array. 374 \ingroup DYNAMIC_ARRAYS 375 \param array a pointer to the ci_dyn_array_t object 376 \param name the name part of the name/value pair item to be added 377 \param value the value part of the name/value pair item to be added 378 \param size the size of the value part of the new item. 379 \return a pointer to the new array item on success, NULL otherwise 380 */ 381 CI_DECLARE_FUNC(const ci_array_item_t *) ci_dyn_array_add(ci_dyn_array_t *array, const char *name, const void *value, size_t size); 382 383 /** 384 * Search in an dynamic array for an item with the given name 385 \ingroup DYNAMIC_ARRAYS 386 \param array a pointer to the ci_dyn_array_t object 387 \param name the item to be search for. 388 \return pointer to the value pair of the array item if found, NULL otherwise 389 */ 390 CI_DECLARE_FUNC(const void *) ci_dyn_array_search(ci_dyn_array_t *array, const char *name); 391 392 /** 393 * Run the given function for each dynamic array item 394 \ingroup DYNAMIC_ARRAYS 395 \param array a pointer to the ci_dyn_array_t object 396 \param data a pointer to data which will be passed on fn function 397 \param fn a pointer to the function which will be run for each array item. 398 * The iteration will stop if the fn function return non zero value. 399 */ 400 CI_DECLARE_FUNC(void) ci_dyn_array_iterate(const ci_dyn_array_t *array, void *data, int (*fn)(void *data, const char *name, const void *)); 401 402 /** 403 \defgroup PTR_DYNAMIC_ARRAYS Dynamic arrays of pointers related API 404 \ingroup DYNAMIC_ARRAYS 405 * Arrays which store name/value pair items 406 */ 407 408 /** 409 \typedef ci_ptr_dyn_array_t 410 \ingroup PTR_DYNAMIC_ARRAYS 411 * An alias to the ci_dyn_array_t object. It is used to store pointers 412 * to an array. 413 * The ci_ptr_dyn_array_new, ci_ptr_dyn_array_destroy, ci_ptr_dyn_array_search 414 * and ci_ptr_dyn_array_iterate defines are equivalent to the ci_dyn_array_* 415 * functions with the required typecasting. 416 */ 417 typedef ci_dyn_array_t ci_ptr_dyn_array_t; 418 #define ci_ptr_dyn_array_new(size) ci_dyn_array_new(size) 419 #define ci_ptr_dyn_array_new2(items, item_size) ci_dyn_array_new2(items, item_size) 420 #define ci_ptr_dyn_array_destroy(ptr_array) ci_dyn_array_destroy((ci_dyn_array_t *)(ptr_array)) 421 #define ci_ptr_dyn_array_search(ptr_array, name) ci_dyn_array_search((ci_dyn_array_t *)(ptr_array), name) 422 #define ci_ptr_dyn_array_iterate(ptr_array, data, fn) ci_dyn_array_iterate((ci_dyn_array_t *)(ptr_array), data, fn) 423 424 #define ci_ptr_dyn_array_get_item(ptr_array, pos) ci_dyn_array_get_item((ci_dyn_array_t *)(ptr_array), pos) 425 #define ci_ptr_dyn_array_value(ptr_array, pos) ci_dyn_array_value((ci_dyn_array_t *)(ptr_array), pos) 426 #define ci_ptr_dyn_array_name(ptr_array, pos) ci_dyn_array_name((ci_dyn_array_t *)(ptr_array), pos) 427 #define ci_ptr_dyn_array_size(ptr_array) ci_dyn_array_size((ci_dyn_array_t *)(ptr_array)) 428 429 /** 430 * Add an name/value pair item to the array. 431 \ingroup PTR_DYNAMIC_ARRAYS 432 \param ptr_array a pointer to the ci_ptr_dyn_array_t object 433 \param name the name part of the name/pointer pair item to be added 434 \param pointer the pointer part of the name/value pair item to be added 435 \return a pointer to the new array item on success, NULL otherwise 436 */ 437 CI_DECLARE_FUNC(const ci_array_item_t *) ci_ptr_dyn_array_add(ci_ptr_dyn_array_t *ptr_array, const char *name, void *pointer); 438 439 440 /** 441 \defgroup VECTORS Simple vectors related API 442 \ingroup ARRAYS 443 * Structure which can store lists of objects 444 */ 445 446 /** 447 \typedef ci_vector_t 448 \ingroup VECTORS 449 * The ci_vector_t objects can store a list of objects. Currently can grow up 450 * to a fixed size. 451 */ 452 typedef struct ci_vector { 453 void **items; 454 void **last; 455 char *mem; 456 size_t max_size; 457 int count; 458 ci_mem_allocator_t *alloc; 459 } ci_vector_t; 460 461 /** 462 * Allocate the required memory and initialize a ci_vector_t object 463 \ingroup VECTORS 464 \param max_size the maximum memory to use 465 \return the allocated object on success, or NULL on failure 466 */ 467 CI_DECLARE_FUNC(ci_vector_t *) ci_vector_create(size_t max_size); 468 469 /** 470 * Destroy an ci_vector_t object 471 \ingroup VECTORS 472 \param vector a pointer to ci_vector_t object to be destroyed 473 */ 474 CI_DECLARE_FUNC(void) ci_vector_destroy(ci_vector_t *vector); 475 476 /** 477 * Add an item to the vector. 478 \ingroup VECTORS 479 \param vector a pointer to the ci_vector_t object 480 \param obj pointer to the object to add in vector 481 \param size the size of the new item. 482 \return a pointer to the new item on success, NULL otherwise 483 */ 484 CI_DECLARE_FUNC(void *) ci_vector_add(ci_vector_t *vector, const void *obj, size_t size); 485 486 /** 487 * Run the given function for each vector item 488 \ingroup VECTORS 489 \param vector a pointer to the ci_vector_t object 490 \param data a pointer to data which will be passed to the fn function 491 \param fn a pointer to the function which will be run for each vector item. 492 * The iteration will stop if the fn function return non zero value. 493 */ 494 CI_DECLARE_FUNC(void) ci_vector_iterate(const ci_vector_t *vector, void *data, int (*fn)(void *data, const void *)); 495 496 /** 497 * Delete the last element of a vector. 498 \ingroup VECTORS 499 \param vector a pointer to the ci_vector_t object 500 \return a pointer to the popped vector item on success, NULL otherwise 501 */ 502 CI_DECLARE_FUNC(void *) ci_vector_pop(ci_vector_t *vector); 503 504 /** 505 \def ci_vector_get(vector, i) 506 \ingroup VECTORS 507 * Return a pointer to the i item of the vector 508 */ 509 #define ci_vector_get(vector, i) (i < vector->count ? (const void *)vector->items[i]: (const void *)NULL) 510 511 512 CI_DECLARE_FUNC(const void **) ci_vector_cast_to_voidvoid(ci_vector_t *vector); 513 CI_DECLARE_FUNC(ci_vector_t *)ci_vector_cast_from_voidvoid(const void **p); 514 515 /** 516 \defgroup STR_VECTORS Vectors of strings 517 \ingroup VECTORS 518 * 519 */ 520 521 /** 522 \typedef ci_str_vector_t 523 \ingroup STR_VECTORS 524 * The ci_str_vector is used to implement string vectors. 525 * The ci_str_vector_create, ci_str_vector_destroy, ci_str_vector_add, 526 * and ci_str_vector_pop defines are similar and equivalent to the ci_vector_* 527 * functions. 528 */ 529 typedef ci_vector_t ci_str_vector_t; 530 #define ci_str_vector_create ci_vector_create 531 #define ci_str_vector_destroy ci_vector_destroy 532 #define ci_str_vector_add(vect, string) ((const char *)ci_vector_add((ci_vector_t *)(vect), string, (strlen(string)+1))) 533 #define ci_str_vector_get(vector, i) (i < vector->count ? (const char *)vector->items[i]: (const char *)NULL) 534 #define ci_str_vector_pop(vect) ((const char *)ci_vector_pop((ci_vector_t *)(vect))) 535 #define ci_str_vector_cast_to_charchar(vector) ((const char **)ci_vector_cast_to_voidvoid((ci_vector_t *)(vector))) 536 #define ci_str_vector_cast_from_charchar(p) ((ci_str_vector_t *)ci_vector_cast_from_voidvoid((const void **)p)) 537 538 /** 539 * Run the given function for each string vector item 540 \ingroup STR_VECTORS 541 \param vector a pointer to the ci_vector_t object 542 \param data a pointer to data which will be passed to the fn function 543 \param fn a pointer to the function which will be run for each string vector 544 * item. The iteration will stop if the fn function return non zero value. 545 */ 546 CI_DECLARE_FUNC(void) ci_str_vector_iterate(const ci_str_vector_t *vector, void *data, int (*fn)(void *data, const char *)); 547 548 /** 549 * Search for a string in a string vector. 550 \ingroup STR_VECTORS 551 \param vector a pointer to the ci_vector_t object 552 \param str the string to search for 553 \return a pointer to the new item on success, NULL otherwise 554 */ 555 CI_DECLARE_FUNC(const char *) ci_str_vector_search(ci_str_vector_t *vector, const char *str); 556 557 /** 558 \defgroup PTR_VECTORS Vectors of pointers 559 \ingroup VECTORS 560 */ 561 562 /** 563 \typedef ci_ptr_vector_t 564 \ingroup PTR_VECTORS 565 * The ci_ptr_vector is used to implement vectors storing pointers. 566 * The ci_ptr_vector_create, ci_ptr_vector_destroy, ci_ptr_vector_iterate, 567 * and ci_ptr_vector_get defines are similar and equivalent to the ci_vector_* functions. 568 */ 569 typedef ci_vector_t ci_ptr_vector_t; 570 #define ci_ptr_vector_create ci_vector_create 571 #define ci_ptr_vector_destroy ci_vector_destroy 572 #define ci_ptr_vector_iterate ci_vector_iterate 573 #define ci_ptr_vector_get ci_vector_get 574 575 /** 576 * Add an item to the vector. 577 \ingroup PTR_VECTORS 578 \param vector a pointer to the ci_vector_t object 579 \param pointer the pointer to store in vector 580 \return a pointer to the new item on success, NULL otherwise 581 */ 582 CI_DECLARE_FUNC(void *) ci_ptr_vector_add(ci_vector_t *vector, void *pointer); 583 584 /** 585 \defgroup LISTS Lists API 586 \ingroup ARRAYS 587 * Lists for storing items, and can grow unlimited. 588 * 589 */ 590 591 typedef struct ci_list_item { 592 void *item; 593 struct ci_list_item *next; 594 } ci_list_item_t; 595 596 /** 597 \typedef ci_list_t 598 \ingroup LISTS 599 * The ci_list_t objects can store a list of objects, with a predefined size. 600 * The list items can be removed. 601 * The memory RAM space of list can not be decreased before the 602 * ci_list destroyed. However the memory of removed items reused. 603 */ 604 typedef struct ci_list { 605 ci_list_item_t *items; 606 ci_list_item_t *last; 607 ci_list_item_t *trash; 608 ci_list_item_t *cursor; 609 ci_list_item_t *tmp; 610 size_t obj_size; 611 ci_mem_allocator_t *alloc; 612 613 int (*cmp_func)(const void *obj, const void *user_data, size_t user_data_size); 614 int (*copy_func)(void *newObj, const void *oldObj); 615 void (*free_func)(void *obj); 616 } ci_list_t; 617 618 /** 619 * Allocate the required memory and initialize a ci_list_t object 620 \ingroup LISTS 621 \param init_size the initial memory size to use 622 \param obj_size the size of stored objects. If it is 0 then stores pointers 623 * to objects. 624 \return the allocated object on success, or NULL on failure 625 */ 626 CI_DECLARE_FUNC(ci_list_t *) ci_list_create(size_t init_size, size_t obj_size); 627 628 /** 629 \def ci_list_first(ci_list_t *list) 630 * Gets the first item of the list and updates the list cursor to the next item. 631 * WARNING: do not mix this macro with ci_list_iterate. Use the ci_list_head 632 * and ci_list_tail macros instead 633 \ingroup LISTS 634 \param list a pointer to the ci_list_t object 635 \return The first item if exist, NULL otherwise 636 */ 637 #define ci_list_first(list) (list && (list)->items && (((list)->cursor = (list)->items->next) != NULL || 1) ? (list)->items->item : NULL) 638 639 640 /** 641 \def ci_list_next() 642 * Return the next item of the list and updates the list cursor to the next 643 * item. 644 * WARNING: It does not check for valid list object. 645 * WARNING: do not mix this macro with ci_list_iterate! 646 \ingroup LISTS 647 \param list a pointer to the ci_list_t object 648 \return The next item if exist, NULL otherwise 649 */ 650 #define ci_list_next(list) (((list)->tmp = (list)->cursor) != NULL && (((list)->cursor = (list)->cursor->next) != NULL || 1) ? (list)->tmp->item : NULL) 651 652 653 /** 654 \def ci_list_head(list) 655 \ingroup LISTS 656 * Return the head of the list 657 */ 658 #define ci_list_head(list) (list && list->items != NULL ? list->items->item : NULL) 659 660 /** 661 \def ci_list_tail(list) 662 \ingroup LISTS 663 * Return last item of the list. 664 */ 665 #define ci_list_tail(list) (list && list->last != NULL ? list->last->item : NULL) 666 667 /** 668 * Destroy an ci_list_t object 669 \ingroup LISTS 670 \param list a pointer to ci_list_t object to be destroyed 671 */ 672 CI_DECLARE_FUNC(void) ci_list_destroy(ci_list_t *list); 673 674 /** 675 * Run the given function for each list item 676 \ingroup LISTS 677 \param list a pointer to the ci_list_t object 678 \param data a pointer to data which will be passed to the fn function 679 \param fn a pointer to the function which will be run for each vector item. 680 * The iteration will stop if the fn function return non zero value. 681 */ 682 CI_DECLARE_FUNC(void) ci_list_iterate(ci_list_t *list, void *data, int (*fn)(void *data, const void *obj)); 683 684 /** 685 * Add an item to the head of list. 686 \ingroup LISTS 687 \param list a pointer to the ci_list_t object 688 \param obj pointer to the object to add in vector 689 \return a pointer to the new item on success, NULL otherwise 690 */ 691 CI_DECLARE_FUNC(const void *) ci_list_push(ci_list_t *list, const void *obj); 692 693 /** 694 * Add an item to the tail of list. 695 \ingroup LISTS 696 \param list a pointer to the ci_list_t object 697 \param obj pointer to the object to add in vector 698 \return a pointer to the new item on success, NULL otherwise 699 */ 700 CI_DECLARE_FUNC(const void *) ci_list_push_back(ci_list_t *list, const void *data); 701 702 /** 703 * Remove the first item of the list. 704 \ingroup LISTS 705 \param list a pointer to the ci_list_t object 706 \param obj pointer to an object to store removed item 707 \return a pointer to the obj on success, NULL otherwise 708 */ 709 CI_DECLARE_FUNC(void *) ci_list_pop(ci_list_t *list, void *obj); 710 711 /** 712 * Remove the last item of the list. 713 \ingroup LISTS 714 \param list a pointer to the ci_list_t object 715 \param obj pointer to an object to store removed item 716 \return a pointer to the obj on success, NULL otherwise 717 */ 718 CI_DECLARE_FUNC(void *) ci_list_pop_back(ci_list_t *list, void *obj); 719 720 /** 721 * Remove the first found item equal to the obj. 722 \ingroup LISTS 723 \param list a pointer to the ci_list_t object 724 \param obj pointer to an object to remove 725 \return not 0 on success, 0 otherwise 726 */ 727 CI_DECLARE_FUNC(int) ci_list_remove(ci_list_t *list, const void *obj); 728 729 /** 730 * Return the first found item equal to the obj. 731 \ingroup LISTS 732 \param list a pointer to the ci_list_t object 733 \param obj pointer to an object to remove 734 \return the found item on success, NULL otherwise 735 */ 736 CI_DECLARE_FUNC(const void *) ci_list_search(ci_list_t *list, const void *data); 737 738 /** 739 * Return the first found item equal to the obj, using the cmp_func as 740 * comparison function. 741 \ingroup LISTS 742 \param list a pointer to the ci_list_t object 743 \param obj pointer to an object to remove 744 \param cmp_func the comparison function to use 745 \return the found item on success, NULL otherwise 746 */ 747 CI_DECLARE_FUNC(const void *) ci_list_search2(ci_list_t *list, const void *data, int (*cmp_func)(const void *obj, const void *user_data, size_t user_data_size)); 748 749 /** 750 * Sorts the list using as compare function the default. 751 \ingroup LISTS 752 \param list a pointer to the ci_list_t object 753 */ 754 CI_DECLARE_FUNC(void) ci_list_sort(ci_list_t *list); 755 756 /** 757 * Sorts the list using as compare function the cmp_func. 758 \ingroup LISTS 759 \param list a pointer to the ci_list_t object 760 \param cmp_func the compare function to use 761 */ 762 CI_DECLARE_FUNC(void) ci_list_sort2(ci_list_t *list, int (*cmp_func)(const void *obj1, const void *obj2, size_t obj_size)); 763 764 /* 765 The following three functions are undocumented. Probably will be removed or replaced 766 by others. 767 */ 768 CI_DECLARE_FUNC(void) ci_list_cmp_handler(ci_list_t *list, int (*cmp_func)(const void *obj, const void *user_data, size_t user_data_size)); 769 CI_DECLARE_FUNC(void) ci_list_copy_handler(ci_list_t *list, int (*copy_func)(void *newObj, const void *oldObj)); 770 CI_DECLARE_FUNC(void) ci_list_free_handler(ci_list_t *list, void (*free_func)(void *obj)); 771 772 #ifdef __cplusplus 773 } 774 #endif 775 776 #endif /*__ARRAY_H*/ 777