home *** CD-ROM | disk | FTP | other *** search
- /*
- * VARIABLE LENGTH TABLES
- *
- * Features: Grows according to how many records you put into it.
- * It it not possible to have empty slots in the table.
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <assert.h>
- #include "vtable.h"
- #include <string.h>
- #ifndef SYSV
- #include <memory.h>
- #endif
-
- vtable *
- VTableCreate(int recsize)
- {
- vtable *vt;
-
- assert(recsize);
- vt = (vtable *)malloc(sizeof(vtable));
- assert(vt);
- memset(vt,0,sizeof(vtable));
- vt->rec_size = recsize;
- vt->cmp = (vtablecmp)memcmp;
- vt->magic = 0xdb;
- return vt;
- }
-
- VTableSet(vtable *vt,int recsize)
- {
- memset(vt,0,sizeof(vtable));
- vt->rec_size = recsize;
- vt->cmp = (vtablecmp)memcmp;
- vt->magic = 0xdb;
- }
-
- int
- VTableAlloc(vtable *vt,int nelem)
- {
- /* Allocate more space */
- if(nelem <= 0 || nelem == vt->num_slots)
- return 0;
- if(nelem < vt->num_slots)
- {
- if(vt->end > nelem)
- return 1;
- }
- vt->num_slots = nelem;
- if(vt->end == 0)
- vt->data = malloc(vt->num_slots * vt->rec_size);
- else
- vt->data = realloc(vt->data,vt->num_slots * vt->rec_size);
- return 0;
- }
-
- void VTableSetCmp(vtable *vt,vtablecmp cmp)
- {
- vt->cmp = cmp;
- }
-
- void
- VTableAppend(vtable *vt,char *data)
- {
- assert(vt && (vt->magic == 0xdb));
- if(vt->num_slots == vt->end)
- { /* Allocate more space */
- vt->num_slots += (vt->num_slots / 2) + 2;
- if(vt->end == 0)
- vt->data = malloc(vt->num_slots * vt->rec_size);
- else
- vt->data = realloc(vt->data,vt->num_slots * vt->rec_size);
- }
- memcpy(vt->data + (vt->rec_size * vt->end),data,vt->rec_size);
- vt->end++;
- }
-
- /*
- * Only to be used if your table was created with VTableCreate
- */
- void
- VTableDestroy(vtable *vt)
- {
- assert(vt && (vt->magic == 0xdb));
- if(vt->data) free(vt->data);
- vt->data = NULL;
- vt->num_slots = 0;
- vt->magic = 0;
- free(vt);
- }
-
- void
- VTableClean(vtable *vt)
- {
- if(vt->data) free(vt->data);
- /* vt->rec_size = 0; */
- vt->data = NULL;
- vt->num_slots = 0;
- vt->end = 0;
- }
-
- char *
- VTableIndex(vtable *vt,int inx)
- {
- if(!vt->data) return NULL;
- if((inx >= vt->end)|| inx <0) return NULL;
- return vt->data + (inx * vt->rec_size);
- }
-
- /*
- * This function is designed for a while loop.
- */
- char *
- VTableNext(vtable *vt,int *inx,int step)
- {
- char *rec;
-
- assert(vt && (vt->magic == 0xdb));
- rec = VTableIndex(vt,*inx);
- if(rec)
- (*inx)+= step;
- return rec;
- }
-
- char *
- VTableLookup(vtable *vt,char *key)
- {
- register int position;
-
- if(!vt->data) return (char*)0;
- for(position = 0; position < vt->end; position++)
- {
- if(!(*vt->cmp)(key,vt->data + (position * vt->rec_size),vt->rec_size))
- break;
- }
- if(position == vt->end) return (char*)0;
-
- return vt->data + (position * vt->rec_size);
- }
-
- void
- VTableRemove(vtable *vt,char *rec)
- {
- register int position;
-
- if(!vt->data) return;
- for(position = 0; position < vt->end; position++)
- {
- if(!(*vt->cmp)(rec,vt->data + (position * vt->rec_size),vt->rec_size))
- break;
- }
- if(position == vt->end) return;
-
- VTableIRemove(vt,position);
- return ;
- }
-
- void
- VTableIRemove(vtable *vt,int position)
- {
- if(position >= vt->end || position < 0) return;
-
- if(!vt->data) return;
- /* Ripple children down one space from "position" */
- vt->end--;
- if((vt->end - position) > 0)
- {
- bcopy(vt->data + ((position+1) * vt->rec_size),
- vt->data + (position * vt->rec_size),
- (vt->end - position) * vt->rec_size);
- }
- return ;
- }
-
- int
- VTableSize(vtable *vt)
- {
- return vt->end;
- }
-
- /*
- * Keep the allocated space.
- */
- void
- VTableZero(vtable *vt)
- {
- vt->end = 0;
- }
-