home *** CD-ROM | disk | FTP | other *** search
/ Turbo Toolbox / Turbo_Toolbox.iso / extra18 / ctricks / dynarray / array.c next >
Encoding:
C/C++ Source or Header  |  1992-01-29  |  6.4 KB  |  196 lines

  1. /* ------------------------------------------------- */
  2. /*                      ARRAY.C                      */
  3. /*             Verwaltung dynamischer Arrays         */
  4. /*          (c) 1992 Thomas Lach & DMV-Verlag        */
  5. /* ------------------------------------------------- */
  6.  
  7. /* ------------------------------------------------- */
  8. /* void * ArrayGetwoErr(_Array *arr, size_t position)*/
  9. /* MACRO                                             */
  10. /* -- Adressierung eines bestimmten Elements         */
  11. /*    ohne Fehlercode                                */
  12. /*                                                   */
  13. /*    _Array * ArrayStart(size_t elem_size);         */
  14. /* -- initilialisierung des _Array Pointers          */
  15. /*                                                   */
  16. /*    ArrayChgAlloc(_Array *arr, int siz)  MACRO     */
  17. /* -- Verändern des AllocSizes für die Erweiterung   */
  18. /*    des Arrays                                     */
  19. /*                                                   */
  20. /*   _Array * ArrayAdd(_Array *arr, char *data);     */
  21. /* -- Einhängen eines Elements in das _Array         */
  22. /*    (mit evtl. Erweiterung des Arrays)             */
  23. /*                                                   */
  24. /* ------------------------------------------------- */
  25. /*                                                   */
  26. /*  void *ArrayChg(_Array *arr,                      */
  27. /*                 void *data, size_t pos)           */
  28. /*  Austausch eines bestimmten Elements mit Rückgabe */
  29. /*  des alten Elements                               */
  30. /*                                                   */
  31. /* ------------------------------------------------- */
  32. /*                                                   */
  33. /*  void *ArrayDel(_Array *arr, size_t pos)          */
  34. /*  Löschen eines bestimmten Elementes mit Rückgabe. */
  35. /*  Das letzte Element wird in das Gelöschte kopiert */
  36. /*  und ArrCount um 1 dekrementiert.                 */
  37. /*                                                   */
  38. /* ------------------------------------------------- */
  39. /*                                                   */
  40. /*   void     ArrayKill(_Array *arr);                */
  41. /*   Zerstören des _Array Pointers                   */
  42. /*                                                   */
  43. /* ------------------------------------------------- */
  44. /*                                                   */
  45. /*   ArrayElemNum(_Array *arr)     MACRO             */
  46. /*   Anzahl der Elemente eines Arrays                */
  47. /*                                                   */
  48. /*                                                   */
  49. /*   ArrayErr(_Array *arr)         MACRO             */
  50. /*   Abfrage des Fehlercodes                         */
  51. /*                                                   */
  52. /*   ArrayData(_Array *arr)        MACRO             */
  53. /*   Zeiger auf die Daten eines Arrays               */
  54. /*                                                   */
  55. /* ------------------------------------------------- */
  56.  
  57. #include <alloc.h>                /* malloc, calloc,
  58.                                      realloc, free   */
  59. #include <string.h>               /* memcpy          */
  60. #include <limits.h>               /* UINT_MAX        */
  61.  
  62. #include "array.h"
  63.  
  64. #define SETERR(arr,code)              \
  65.         { arr->ErrCode = code;        \
  66.           ArrayErrorFunction(arr); }
  67.  
  68. static const MinArr = 10;
  69.  
  70. static int _ArrayErrorFunction(_Array *arr);
  71.  
  72. int (*ArrayErrorFunction)(_Array *arr) =
  73.      _ArrayErrorFunction;
  74.  
  75. /* ------------------------------------------------- */
  76.  
  77. _Array * ArrayStart(size_t size)
  78. {
  79.   char   *ar, *tmp;
  80.   static _Array * a;
  81.  
  82.   if ((a = (_Array *) malloc(sizeof(_Array))) ==
  83.        NULLARRAY)
  84.     return (NULLARRAY);
  85.   if ((ar = (char *) calloc(MinArr, size)) == NULL)
  86.     return (NULLARRAY);
  87.   if ((tmp = (char *) malloc(size)) == (char *) 0)
  88.     return (NULLARRAY);
  89.  
  90.   a->Arr = ar, a->ArrSize = MinArr,
  91.   a->Tmp = tmp, a->ErrCode = ARR_NOERR,
  92.   a->ArrCount = 0, a->AllocSize = MinArr,
  93.   a->ItemSize = size;
  94.  
  95.   return a;
  96. }
  97.  
  98. /* ------------------------------------------------- */
  99.  
  100. _Array * ArrayAdd(_Array *arr, char *data)
  101. {
  102.   char *tmp;
  103.   long pos = ((long)arr->ItemSize *
  104.               (long) arr->ArrCount);
  105.  
  106.   SETERR(arr, ARR_NOERR);         // clear error code
  107.  
  108.   if ((pos+arr->ItemSize) > UINT_MAX) {
  109.     SETERR(arr, ARR_LIMERR);
  110.     return NULLARRAY;
  111.   }   // size > 64k
  112.  
  113.   if (arr->ArrCount < arr->ArrSize) {
  114.     // empty places ?
  115.     memcpy(arr->Arr+(arr->ItemSize*arr->ArrCount++),
  116.            data, arr->ItemSize);
  117.     return arr;
  118.   }
  119.  
  120.   tmp = realloc(arr->Arr,
  121.       (arr->ArrSize + arr->AllocSize) * arr->ItemSize);
  122.  
  123.   if (tmp != (char *)0) {                // copy data
  124.     memcpy(tmp+(arr->ArrCount *
  125.            arr->ItemSize), data, arr->ItemSize);
  126.     arr->ArrCount++;
  127.     arr->ArrSize += arr->AllocSize;
  128.     arr->Arr = tmp;
  129.     return arr;
  130.   }
  131.  
  132.   SETERR(arr, ARR_MEMERR);
  133.  
  134.   return NULLARRAY;
  135. }
  136.  
  137. /* ------------------------------------------------- */
  138.  
  139. void *ArrayChg(_Array *arr, void *data, size_t pos)
  140. {
  141.   memcpy(arr->Tmp, ArrayGet(arr, pos), arr->ItemSize);
  142.   memcpy(ArrayGet(arr, pos), data, arr->ItemSize);
  143.  
  144.   return arr->Tmp;
  145. }
  146.  
  147. /* ------------------------------------------------- */
  148.  
  149. void *ArrayGet(_Array *arr, size_t pos)
  150. {
  151.   SETERR(arr, ARR_NOERR);          // clear error code
  152.   if (pos < ArrayElemNum(arr))
  153.     return (void*)&(arr->Arr[pos*arr->ItemSize]);
  154.   SETERR(arr, ARR_MAXERR);
  155.   return (void *)0;
  156. }
  157.  
  158. /* ------------------------------------------------- */
  159.  
  160. void *ArrayDel(_Array *arr, size_t pos)
  161. {
  162.   memcpy(arr->Tmp, ArrayGet(arr, pos), arr->ItemSize);
  163.  
  164.   if (pos < ArrayElemNum(arr)-1) {
  165.     memcpy(ArrayGet(arr,pos),ArrayGet(arr,(pos+1)),
  166.           (ArrayElemNum(arr)-pos)*arr->ItemSize);
  167.   }
  168.  
  169.   ArrayElemNum(arr)-- ;
  170.  
  171.   return arr->Tmp;
  172. }
  173.  
  174. /* ------------------------------------------------- */
  175.  
  176. void ArrayKill(_Array *arr)
  177. {
  178.   free(arr->Arr);
  179.   free(arr->Tmp);
  180.   memset(arr, 0, sizeof(_Array));
  181.   free(arr);
  182.   arr = NULLARRAY;
  183. }
  184.  
  185. /* ------------------------------------------------- */
  186.  
  187. static int _ArrayErrorFunction(_Array *arr)
  188. {
  189.   if (arr->ErrCode != ARR_NOERR)
  190.     return arr->ErrCode;
  191.   return arr->ErrCode;
  192. }
  193. /* ------------------------------------------------- */
  194. /*               Ende von ARRAY.C                    */
  195.  
  196.