Advertisement
tm512

DynArray test 1

Nov 21st, 2011
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.97 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <stdint.h>
  5.  
  6. typedef struct
  7. {
  8.     // Element properties
  9.     uint32_t e_size;
  10.     uint32_t e_max;
  11.  
  12.     // >0 if we want to resize array
  13.     uint8_t resize;
  14.  
  15.     void **index;
  16.     void *elements;
  17. } dynarray_t;
  18.  
  19. // Create the array on the heap, initialize.
  20. dynarray_t *dynarray_create (uint32_t size, uint32_t max, uint8_t resize)
  21. {
  22.     dynarray_t *ret = (dynarray_t *) malloc (sizeof (dynarray_t));
  23.  
  24.     if (!ret)
  25.         return NULL;
  26.  
  27.     memset (ret, 0, sizeof (dynarray_t));
  28.  
  29.     ret->e_size = size;
  30.     ret->e_max = max;
  31.     ret->resize = resize;
  32.     ret->index = (void **) malloc (max * sizeof (void *));
  33.     ret->elements = malloc (size * max);
  34.  
  35.     if (!ret->index || !ret->elements)
  36.     {
  37.         free (ret);
  38.         return NULL;
  39.     }
  40.  
  41.     memset (ret->index, 0, max * sizeof (void *));
  42.     memset (ret->elements, 0, size * max);
  43.  
  44.     return ret;
  45. }
  46.  
  47. // Destroy dynarray
  48. void dynarray_delete (dynarray_t *arr)
  49. {
  50.     free (arr->index);
  51.     free (arr->elements);
  52.     free (arr);
  53.  
  54.     return;
  55. }
  56.  
  57. // Resize array, adding arr->resize elements
  58. // returns arr on success, NULL on failure
  59. dynarray_t *dynarray_resize (dynarray_t *arr)
  60. {
  61.     void *tmp;
  62.  
  63.     if (!(tmp = realloc (arr->index, arr->e_max * sizeof (void *) + arr->resize * sizeof (void *))))
  64.         return NULL;
  65.     else
  66.         arr->index = tmp;
  67.  
  68.     if (!(tmp = realloc (arr->elements, arr->e_max * arr->e_size + arr->resize * arr->e_size)))
  69.         return NULL;
  70.  
  71.     // Adjust index if necessary
  72.     void *oldel = arr->elements;
  73.     arr->elements = tmp;
  74.     if (arr->elements != oldel)
  75.     {
  76.         int i;
  77.         for (i = 0; i < arr->e_max; i++)
  78.             if (arr->index [i])
  79.                 arr->index [i] = ((char*)arr->elements) + arr->e_size * i;
  80.     }
  81.  
  82.     // Initialize new memory
  83.     memset (arr->index + arr->e_max, 0, arr->resize * sizeof (void *));
  84.     memset ((char*)arr->elements + arr->e_max * arr->e_size, 0, arr->resize * arr->e_size);
  85.  
  86.     arr->e_max += arr->resize;
  87.  
  88.     return arr;
  89. }
  90.  
  91. // Add element to array, returns pointer to new element or NULL on failure
  92. void *dynarray_push (dynarray_t *arr, void *new)
  93. {
  94.     // Valid?
  95.     if (!arr || !new)
  96.         return NULL;
  97.  
  98.     // Find empty slot
  99.     int i;
  100.     for (i = 0; i < arr->e_max; i++)
  101.         if (arr->index [i] == NULL)
  102.             break;
  103.  
  104.     if (i == arr->e_max) // Out of room, resize!
  105.     {
  106.         if (arr->resize)
  107.         {
  108.             return dynarray_push (dynarray_resize (arr), new);
  109.         }
  110.         else
  111.             return NULL;
  112.     }
  113.  
  114.     return arr->index [i] = memcpy ((char*)arr->elements + arr->e_size * i, new, arr->e_size);
  115. }
  116.  
  117. // Clear element from array
  118. void dynarray_clear (dynarray_t *arr, uint32_t ele)
  119. {
  120.     if (!arr || ele > arr->e_max)
  121.         return;
  122.  
  123.     arr->index [ele] = NULL;
  124.     memset ((char*)arr->elements + ele * arr->e_size, 0, arr->e_size);
  125.  
  126.     return;
  127.  
  128.  
  129. // Pop top element from array, write it to a pointer
  130. void dynarray_pop (dynarray_t *arr, void *dest)
  131. {
  132.     if (!arr || !dest)
  133.         return;
  134.  
  135.     int i;
  136.     for (i = arr->e_max - 1; i >= 0; i--)
  137.         if (arr->index [i])
  138.             break;
  139.  
  140.     memcpy (dest, arr->index [i], arr->e_size);
  141.     dynarray_clear (arr, i);
  142.     return;
  143. }
  144.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement