home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / ns2tab / part01 / vtable.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-04  |  3.6 KB  |  190 lines

  1. /*
  2.  * VARIABLE LENGTH TABLES
  3.  *
  4.  * Features: Grows according to how many records you put into it.
  5.  *           It it not possible to have empty slots in the table.
  6.  */
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <assert.h>
  10. #include "vtable.h"
  11. #include <string.h>
  12. #ifndef SYSV
  13. #include <memory.h>
  14. #endif
  15.  
  16. vtable *
  17. VTableCreate(int recsize)
  18. {
  19.    vtable *vt;
  20.  
  21.    assert(recsize);
  22.    vt = (vtable *)malloc(sizeof(vtable));
  23.    assert(vt);
  24.    memset(vt,0,sizeof(vtable));
  25.    vt->rec_size = recsize;
  26.    vt->cmp = (vtablecmp)memcmp;
  27.    vt->magic = 0xdb;
  28.    return vt;
  29. }
  30.  
  31. VTableSet(vtable *vt,int recsize)
  32. {
  33.    memset(vt,0,sizeof(vtable));
  34.    vt->rec_size = recsize;
  35.    vt->cmp = (vtablecmp)memcmp;
  36.    vt->magic = 0xdb;
  37. }
  38.  
  39. int
  40. VTableAlloc(vtable *vt,int nelem)
  41. {
  42.  /* Allocate more space */
  43.     if(nelem <= 0 || nelem == vt->num_slots)
  44.          return 0;
  45.     if(nelem < vt->num_slots)
  46.     {
  47.     if(vt->end > nelem)
  48.        return 1;
  49.     }
  50.     vt->num_slots = nelem;
  51.     if(vt->end == 0)
  52.     vt->data = malloc(vt->num_slots * vt->rec_size);
  53.     else
  54.     vt->data = realloc(vt->data,vt->num_slots * vt->rec_size);
  55.     return 0;
  56. }
  57.  
  58. void VTableSetCmp(vtable *vt,vtablecmp cmp)
  59. {
  60.    vt->cmp = cmp;
  61. }
  62.  
  63. void
  64. VTableAppend(vtable *vt,char *data)
  65. {
  66.     assert(vt && (vt->magic == 0xdb));
  67.     if(vt->num_slots == vt->end)
  68.     { /* Allocate more space */
  69.         vt->num_slots += (vt->num_slots / 2) + 2;
  70.         if(vt->end == 0)
  71.         vt->data = malloc(vt->num_slots * vt->rec_size);
  72.     else
  73.         vt->data = realloc(vt->data,vt->num_slots * vt->rec_size);
  74.     }
  75.     memcpy(vt->data + (vt->rec_size * vt->end),data,vt->rec_size);
  76.     vt->end++;
  77. }
  78.  
  79. /*
  80.  * Only to be used if your table was created with VTableCreate
  81.  */
  82. void
  83. VTableDestroy(vtable *vt)
  84. {
  85.     assert(vt && (vt->magic == 0xdb));
  86.     if(vt->data) free(vt->data);
  87.     vt->data = NULL;
  88.     vt->num_slots = 0;
  89.     vt->magic = 0;
  90.     free(vt);
  91. }
  92.  
  93. void
  94. VTableClean(vtable *vt)
  95. {
  96.     if(vt->data) free(vt->data);
  97. /*  vt->rec_size = 0; */
  98.     vt->data = NULL;
  99.     vt->num_slots = 0;
  100.     vt->end = 0;
  101. }
  102.  
  103. char *
  104. VTableIndex(vtable *vt,int inx)
  105. {
  106.     if(!vt->data) return NULL;
  107.     if((inx >= vt->end)|| inx <0) return NULL;
  108.     return vt->data + (inx * vt->rec_size);
  109. }
  110.  
  111. /*
  112.  * This function is designed for a while loop.
  113.  */
  114. char *
  115. VTableNext(vtable *vt,int *inx,int step)
  116. {
  117.    char *rec;
  118.  
  119.     assert(vt && (vt->magic == 0xdb));
  120.     rec = VTableIndex(vt,*inx);
  121.     if(rec)
  122.         (*inx)+= step;
  123.     return rec;
  124. }
  125.  
  126. char *
  127. VTableLookup(vtable *vt,char *key)
  128. {
  129.     register int position;
  130.  
  131.     if(!vt->data) return (char*)0;
  132.     for(position = 0; position < vt->end; position++)
  133.     {
  134.     if(!(*vt->cmp)(key,vt->data + (position * vt->rec_size),vt->rec_size))
  135.         break;
  136.     }
  137.     if(position == vt->end) return (char*)0;
  138.  
  139.     return vt->data + (position * vt->rec_size);
  140. }
  141.  
  142. void
  143. VTableRemove(vtable *vt,char *rec)
  144. {
  145.     register int position;
  146.  
  147.     if(!vt->data) return;
  148.     for(position = 0; position < vt->end; position++)
  149.     {
  150.     if(!(*vt->cmp)(rec,vt->data + (position * vt->rec_size),vt->rec_size))
  151.         break;
  152.     }
  153.     if(position == vt->end) return;
  154.  
  155.     VTableIRemove(vt,position);
  156.     return ;
  157. }
  158.  
  159. void
  160. VTableIRemove(vtable *vt,int position)
  161. {
  162.     if(position >= vt->end || position < 0) return;
  163.  
  164.     if(!vt->data) return;
  165.     /* Ripple children down one space from "position" */
  166.     vt->end--;
  167.     if((vt->end - position) > 0)
  168.     {
  169.     bcopy(vt->data + ((position+1) * vt->rec_size),
  170.         vt->data + (position * vt->rec_size),
  171.         (vt->end - position) * vt->rec_size);
  172.     }
  173.     return ;
  174. }
  175.  
  176. int
  177. VTableSize(vtable *vt)
  178. {
  179.     return vt->end;
  180. }
  181.  
  182. /*
  183.  * Keep the allocated space.
  184.  */
  185. void
  186. VTableZero(vtable *vt)
  187. {
  188.     vt->end = 0;
  189. }
  190.