dyn_arr.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "misc/dynarr.h"
  2. #define ARRAY_PTR_CHECK if(array_ptr == NULL || array_ptr->data_ptr == NULL){\
  3. /**/DYNARR_DBG("array not initialized");\
  4. return false; \
  5. }
  6. bool dynarr_init(dynarr_t* array_ptr, size_t array_size, size_t data_size){
  7. if(array_ptr == NULL || data_size == 0 || array_size == 0){
  8. /**/DYNARR_DBG("Invalid parameter: array_ptr(%p) data_size(%u) array_size(%u)", array_ptr, data_size, array_size);
  9. return false;
  10. }
  11. if(array_ptr->data_ptr != NULL ){
  12. /**/DYNARR_DBG("Array already initialized: array_ptr->data_ptr=%p", array_ptr->data_ptr);
  13. return false;
  14. }
  15. /**/DYNARR_DBG("Array parameters:\n\t\t\tarray_size(%u)\n\t\t\tdata_size(%u)\n\t\t\ttotal size(bytes):%u", array_size, data_size, (array_size * data_size));
  16. void* temp_array = c_zalloc(array_size * data_size);
  17. if(temp_array == NULL){
  18. /**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (array_size * data_size), system_get_free_heap_size());
  19. return false;
  20. }
  21. array_ptr->data_ptr = temp_array;
  22. array_ptr->array_size = array_size;
  23. array_ptr->data_size = data_size;
  24. array_ptr->used = 0;
  25. return true;
  26. }
  27. bool dynarr_resize(dynarr_t* array_ptr, size_t elements_to_add){
  28. ARRAY_PTR_CHECK;
  29. if(elements_to_add <= 0){
  30. /**/DYNARR_DBG("Invalid qty: elements_to_add=%u", elements_to_add);
  31. return false;
  32. }
  33. size_t new_array_size = array_ptr->array_size + elements_to_add;
  34. /**/DYNARR_DBG("old size=%u\tnew size=%u\tmem used=%u",
  35. array_ptr->array_size, new_array_size, (new_array_size * array_ptr->data_size));
  36. void* temp_array_p = c_realloc(array_ptr->data_ptr, new_array_size * array_ptr->data_size);
  37. if(temp_array_p == NULL){
  38. /**/DYNARR_ERR("malloc FAIL! req:%u free:%u", (new_array_size * array_ptr->data_size), system_get_free_heap_size());
  39. return false;
  40. }
  41. array_ptr->data_ptr = temp_array_p;
  42. size_t prev_size = array_ptr->array_size;
  43. array_ptr->array_size = new_array_size;
  44. //set memory to 0 for newly added array elements
  45. memset((uint8*) array_ptr->data_ptr + (prev_size * array_ptr->data_size), 0, (elements_to_add * array_ptr->data_size));
  46. /**/DYNARR_DBG("Array successfully resized");
  47. return true;
  48. }
  49. bool dynarr_remove(dynarr_t* array_ptr, void* element_to_remove){
  50. ARRAY_PTR_CHECK;
  51. uint8* element_ptr = element_to_remove;
  52. uint8* data_ptr = array_ptr->data_ptr;
  53. if(dynarr_boundaryCheck(array_ptr, element_to_remove) == FALSE){
  54. return false;
  55. }
  56. //overwrite element to be removed by shifting all elements to the left
  57. memmove(element_ptr, element_ptr + array_ptr->data_size, (array_ptr->array_size - 1) * array_ptr->data_size - (element_ptr - data_ptr));
  58. //clear newly freed element
  59. memset(data_ptr + ((array_ptr->array_size-1) * array_ptr->data_size), 0, array_ptr->data_size);
  60. //decrement array used since we removed an element
  61. array_ptr->used--;
  62. /**/DYNARR_DBG("element(%p) removed from array", element_ptr);
  63. return true;
  64. }
  65. bool dynarr_add(dynarr_t* array_ptr, void* data_ptr, size_t data_size){
  66. ARRAY_PTR_CHECK;
  67. if(data_size != array_ptr->data_size){
  68. /**/DYNARR_DBG("Invalid data size: data_size(%u) != arr->data_size(%u)", data_size, array_ptr->data_size);
  69. return false;
  70. }
  71. if(array_ptr->array_size == array_ptr->used){
  72. if(!dynarr_resize(array_ptr, (array_ptr->array_size/2))){
  73. return false;
  74. }
  75. }
  76. memcpy(((uint8*)array_ptr->data_ptr + (array_ptr->used * array_ptr->data_size)), data_ptr, array_ptr->data_size);
  77. array_ptr->used++;
  78. return true;
  79. }
  80. bool dynarr_boundaryCheck(dynarr_t* array_ptr, void* element_to_check){
  81. ARRAY_PTR_CHECK;
  82. uint8* data_ptr = array_ptr->data_ptr;
  83. uint8* element_ptr = element_to_check;
  84. if(element_ptr < data_ptr || ((element_ptr - data_ptr) / array_ptr->data_size) > array_ptr->array_size - 1){
  85. /**/DYNARR_DBG("element_ptr(%p) out of bounds: first element ptr:%p last element ptr:%p",
  86. element_ptr, data_ptr, data_ptr + ((array_ptr->array_size - 1) * array_ptr->data_size));
  87. return false;
  88. }
  89. return true;
  90. }
  91. bool dynarr_free(dynarr_t* array_ptr){
  92. ARRAY_PTR_CHECK;
  93. c_free(array_ptr->data_ptr);
  94. array_ptr->data_ptr=NULL;
  95. array_ptr->array_size = array_ptr->used = 0;
  96. /**/DYNARR_DBG("array freed");
  97. return true;
  98. }