zc_arraylist.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. * This file is part of the zlog Library.
  3. *
  4. * Copyright (C) 2011 by Hardy Simpson <HardySimpson1984@gmail.com>
  5. *
  6. * Licensed under the LGPL v2.1, see the file COPYING in base directory.
  7. */
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <strings.h>
  11. #include <errno.h>
  12. #include "zc_defs.h"
  13. zc_arraylist_t *zc_arraylist_new(zc_arraylist_del_fn del)
  14. {
  15. zc_arraylist_t *a_list;
  16. a_list = (zc_arraylist_t *) calloc(1, sizeof(zc_arraylist_t));
  17. if (!a_list) {
  18. zc_error("calloc fail, errno[%d]", errno);
  19. return NULL;
  20. }
  21. a_list->size = ARRAY_LIST_DEFAULT_SIZE;
  22. a_list->len = 0;
  23. /* this could be NULL */
  24. a_list->del = del;
  25. a_list->array = (void **)calloc(a_list->size, sizeof(void *));
  26. if (!a_list->array) {
  27. zc_error("calloc fail, errno[%d]", errno);
  28. free(a_list);
  29. return NULL;
  30. }
  31. return a_list;
  32. }
  33. void zc_arraylist_del(zc_arraylist_t * a_list)
  34. {
  35. int i;
  36. if (!a_list)
  37. return;
  38. if (a_list->del) {
  39. for (i = 0; i < a_list->len; i++) {
  40. if (a_list->array[i])
  41. a_list->del(a_list->array[i]);
  42. }
  43. }
  44. if (a_list->array)
  45. free(a_list->array);
  46. free(a_list);
  47. return;
  48. }
  49. static int zc_arraylist_expand_inner(zc_arraylist_t * a_list, int max)
  50. {
  51. void *tmp;
  52. int new_size;
  53. int diff_size;
  54. new_size = zc_max(a_list->size * 2, max);
  55. tmp = realloc(a_list->array, new_size * sizeof(void *));
  56. if (!tmp) {
  57. zc_error("realloc fail, errno[%d]", errno);
  58. return -1;
  59. }
  60. a_list->array = (void **)tmp;
  61. diff_size = new_size - a_list->size;
  62. if (diff_size) memset(a_list->array + a_list->size, 0x00, diff_size * sizeof(void *));
  63. a_list->size = new_size;
  64. return 0;
  65. }
  66. int zc_arraylist_set(zc_arraylist_t * a_list, int idx, void *data)
  67. {
  68. if (idx > a_list->size - 1) {
  69. if (zc_arraylist_expand_inner(a_list, idx)) {
  70. zc_error("expand_internal fail");
  71. return -1;
  72. }
  73. }
  74. if (a_list->array[idx] && a_list->del) a_list->del(a_list->array[idx]);
  75. a_list->array[idx] = data;
  76. if (a_list->len <= idx)
  77. a_list->len = idx + 1;
  78. return 0;
  79. }
  80. int zc_arraylist_add(zc_arraylist_t * a_list, void *data)
  81. {
  82. return zc_arraylist_set(a_list, a_list->len, data);
  83. }
  84. /* assum idx < len */
  85. static int zc_arraylist_insert_inner(zc_arraylist_t * a_list, int idx,
  86. void *data)
  87. {
  88. if (a_list->array[idx] == NULL) {
  89. a_list->array[idx] = data;
  90. return 0;
  91. }
  92. if (a_list->len > a_list->size - 1) {
  93. if (zc_arraylist_expand_inner(a_list, 0)) {
  94. zc_error("expand_internal fail");
  95. return -1;
  96. }
  97. }
  98. memmove(a_list->array + idx + 1, a_list->array + idx,
  99. (a_list->len - idx) * sizeof(void *));
  100. a_list->array[idx] = data;
  101. a_list->len++;
  102. return 0;
  103. }
  104. int zc_arraylist_sortadd(zc_arraylist_t * a_list, zc_arraylist_cmp_fn cmp,
  105. void *data)
  106. {
  107. int i;
  108. for (i = 0; i < a_list->len; i++) {
  109. if ((*cmp) (a_list->array[i], data) > 0)
  110. break;
  111. }
  112. if (i == a_list->len)
  113. return zc_arraylist_add(a_list, data);
  114. else
  115. return zc_arraylist_insert_inner(a_list, i, data);
  116. }