dd_dynamic_array.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include "dd_dynamic_array.h"
  4. #include <string.h>
  5. /* Init empty array */
  6. int dd_da_init(struct dd_dynamic_array *da, int el_size) {
  7. /* Init everything to 0, except element size to given value */
  8. da->element_size = el_size;
  9. da->elements = 0;
  10. da->array_size = 0;
  11. da->array = 0;
  12. /* Everything OK */
  13. return 0;
  14. }
  15. /* Init array with specific array size */
  16. int dd_da_inita(struct dd_dynamic_array *da, int el_size, int ar_size) {
  17. /* Init element and array size, and allocate memory
  18. * there are no elements in initialization
  19. */
  20. da->element_size = el_size;
  21. da->elements = 0;
  22. /* create array based on (array_size * element_size) */
  23. da->array_size = ar_size;
  24. da->array = malloc( da->element_size *da->array_size );
  25. /* Check allocation */
  26. if (!da->array) {
  27. fprintf(stderr, "da_inita: cannot allocate memory\n");
  28. return -1;
  29. }
  30. /* Everything OK */
  31. return 0;
  32. }
  33. /* Adds one element (of size element_size) to the array */
  34. int dd_da_add(struct dd_dynamic_array *da, void *data) {
  35. /* first check if array can hold new data, if not
  36. * increase array size, then just add the new element
  37. */
  38. /* No array exists */
  39. if (!da->array) {
  40. /* Init array at 3 elements */
  41. da->array_size = 3;
  42. da->array = malloc(da->element_size *da->array_size);
  43. /* check allocation */
  44. if (!da->array) {
  45. printf("da_add: cannot allocate memory\n");
  46. return -1;
  47. }
  48. } else
  49. /* New element will go over array size */
  50. if (da->elements +1 > da->array_size) {
  51. /* Double array size */
  52. da->array_size *= 2;
  53. void *temp = realloc(da->array, da->element_size *da->array_size);
  54. /* Allocation worked */
  55. if (temp) {
  56. da->array = temp;
  57. }
  58. /* Allocation failed */
  59. else {
  60. printf("error: cannot re-allocate memory, abort\n");
  61. return -1;
  62. }
  63. }
  64. /* Copy element byte-by-byte (according to element_size) to array */
  65. memcpy( ((char*)da->array) +(da->element_size *da->elements),
  66. data, da->element_size);
  67. /* Increment elements */
  68. da->elements++;
  69. /* Return OK */
  70. return 0;
  71. }
  72. /* Adds an array of data to the dynamic array */
  73. int dd_da_adda(struct dd_dynamic_array *da, void *data, unsigned int ar_size) {
  74. /* For each element, try to add it, return on error
  75. * (char*) is used to count 1 byte at a time, this might need fixing later on
  76. */
  77. for (unsigned int i = 0; i < ar_size; i++) {
  78. if (dd_da_add(da, ((char*) data) +(da->element_size *i)) != 0) {
  79. fprintf(stderr, "da_adda: unable to add array of data to dynamic array\n");
  80. return -1;
  81. }
  82. }
  83. return 0;
  84. }
  85. int dd_da_pop(struct dd_dynamic_array *da) {
  86. if (da->elements > 0) {
  87. da->elements--;
  88. if (da->elements < da->array_size/3) {
  89. da->array_size /= 3;
  90. void *ptr;
  91. ptr = realloc(da->array, da->array_size * da->element_size);
  92. if (ptr) {
  93. da->array = ptr;
  94. return 0;
  95. }
  96. return -1;
  97. }
  98. return 0;
  99. }
  100. return -1;
  101. }
  102. int dd_da_remove(struct dd_dynamic_array *da, unsigned int element) {
  103. /* selected element does not exist */
  104. if (element >= da->elements) {
  105. return -1;;
  106. }
  107. /* move elements one step backwards */
  108. unsigned int i = element;
  109. for (i = element+1; i < da->elements; i++) {
  110. memcpy( dd_da_get(da, i-1), dd_da_get(da, i), da->element_size );
  111. }
  112. /* finaly, remove element */
  113. da->elements--;
  114. /* element removed succesfully */
  115. return 0;
  116. }
  117. /* Clean allocated array */
  118. void dd_da_free(struct dd_dynamic_array *da) {
  119. /* if array exists, free it, leaves struct in undefined state */
  120. if (da->array) {
  121. free(da->array);
  122. }
  123. }
  124. /* Get element */
  125. void *dd_da_get(struct dd_dynamic_array *da, unsigned int element) {
  126. return ((char*)da->array) +(element *da->element_size);
  127. }