vec.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /** @file vec.c
  2. * Implementation of variable length vector of arbitrary structures.
  3. */
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include "private.h"
  10. faux_vec_t *faux_vec_new(size_t item_size, faux_vec_kcmp_fn matchFn)
  11. {
  12. faux_vec_t *faux_vec = NULL;
  13. faux_vec = faux_zmalloc(sizeof(*faux_vec));
  14. assert(faux_vec);
  15. if (!faux_vec)
  16. return NULL;
  17. // Init
  18. faux_vec->data = NULL;
  19. faux_vec->item_size = item_size;
  20. faux_vec->len = 0;
  21. faux_vec->kcmpFn = matchFn;
  22. return faux_vec;
  23. }
  24. void faux_vec_free(faux_vec_t *faux_vec)
  25. {
  26. if (!faux_vec)
  27. return;
  28. faux_free(faux_vec->data);
  29. faux_free(faux_vec);
  30. }
  31. size_t faux_vec_len(const faux_vec_t *faux_vec)
  32. {
  33. assert(faux_vec);
  34. if (!faux_vec)
  35. return 0;
  36. return faux_vec->len;
  37. }
  38. size_t faux_vec_item_size(const faux_vec_t *faux_vec)
  39. {
  40. assert(faux_vec);
  41. if (!faux_vec)
  42. return 0;
  43. return faux_vec->item_size;
  44. }
  45. void *faux_vec_item(const faux_vec_t *faux_vec, unsigned int index)
  46. {
  47. assert(faux_vec);
  48. if (!faux_vec)
  49. return NULL;
  50. if ((index + 1) > faux_vec_len(faux_vec))
  51. return NULL;
  52. return (char *)faux_vec->data + index * faux_vec_item_size(faux_vec);
  53. }
  54. void *faux_vec_data(const faux_vec_t *faux_vec)
  55. {
  56. assert(faux_vec);
  57. if (!faux_vec)
  58. return NULL;
  59. return faux_vec->data;
  60. }
  61. void *faux_vec_add(faux_vec_t *faux_vec)
  62. {
  63. void *new_vector = NULL;
  64. size_t new_data_len = 0;
  65. assert(faux_vec);
  66. if (!faux_vec)
  67. return NULL;
  68. // Allocate space to hold new vector
  69. new_data_len = (faux_vec_len(faux_vec) + 1) * faux_vec_item_size(faux_vec);
  70. new_vector = realloc(faux_vec->data, new_data_len);
  71. assert(new_vector);
  72. if (!new_vector)
  73. return NULL;
  74. faux_vec->len++;
  75. faux_vec->data = new_vector;
  76. // Return newly created item (it's last one)
  77. return faux_vec_item(faux_vec, faux_vec_len(faux_vec) - 1);
  78. }
  79. ssize_t faux_vec_del(faux_vec_t *faux_vec, unsigned int index)
  80. {
  81. void *new_vector = NULL;
  82. size_t new_data_len = 0;
  83. assert(faux_vec);
  84. if (!faux_vec)
  85. return -1;
  86. if ((index + 1) > faux_vec_len(faux_vec))
  87. return -1;
  88. // Move following items to fill the space of deleted item
  89. if (index != (faux_vec_len(faux_vec) - 1)) { // Is it last item?
  90. void *item_to_del = faux_vec_item(faux_vec, index);
  91. void *next_item = faux_vec_item(faux_vec, index + 1);
  92. unsigned int items_to_move =
  93. faux_vec_len(faux_vec) - (index + 1);
  94. memmove(item_to_del, next_item,
  95. items_to_move * faux_vec_item_size(faux_vec));
  96. }
  97. // Re-allocate space to hold new vector
  98. faux_vec->len--;
  99. new_data_len = faux_vec_len(faux_vec) * faux_vec_item_size(faux_vec);
  100. new_vector = realloc(faux_vec->data, new_data_len);
  101. assert(new_vector);
  102. if (!new_vector)
  103. return -1;
  104. faux_vec->data = new_vector;
  105. return faux_vec_len(faux_vec);
  106. }
  107. int faux_vec_find_fn(const faux_vec_t *faux_vec, faux_vec_kcmp_fn matchFn,
  108. const void *userkey, unsigned int start_index)
  109. {
  110. unsigned int i = 0;
  111. assert(faux_vec);
  112. if (!faux_vec)
  113. return -1;
  114. assert(userkey);
  115. if (!userkey)
  116. return -1;
  117. assert(matchFn);
  118. if (!matchFn)
  119. return -1;
  120. for (i = start_index; i < faux_vec_len(faux_vec); i++) {
  121. if (matchFn(userkey, faux_vec_item(faux_vec, i)) == 0)
  122. return i;
  123. }
  124. return -1;
  125. }
  126. int faux_vec_find(const faux_vec_t *faux_vec, const void *userkey,
  127. unsigned int start_index)
  128. {
  129. assert(faux_vec);
  130. if (!faux_vec)
  131. return -1;
  132. assert(faux_vec->kcmpFn);
  133. if (!faux_vec->kcmpFn)
  134. return -1;
  135. return faux_vec_find_fn(faux_vec, faux_vec->kcmpFn,
  136. userkey, start_index);
  137. }