Initial import of the CDE 2.1.30 sources from the Open Group.
This commit is contained in:
280
cde/lib/DtSvc/DtUtil1/strtab.c
Normal file
280
cde/lib/DtSvc/DtUtil1/strtab.c
Normal file
@@ -0,0 +1,280 @@
|
||||
/* $XConsortium: strtab.c /main/4 1996/05/09 04:23:54 drk $ */
|
||||
/*
|
||||
routines to implement a string -> unique ptr table & access functions
|
||||
suitable for use with shared memory
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "DtHash.h"
|
||||
#include "DtShmDb.h"
|
||||
|
||||
typedef struct strtab {
|
||||
unsigned int st_size; /* size in bytes */
|
||||
unsigned int st_stroffset; /* offset (bytes) from this structure to contained strings */
|
||||
unsigned int st_taboffset; /* offset (bytes) from this structure to table offset */
|
||||
unsigned int st_count; /* number of elements in this string table */
|
||||
} strtab_t;
|
||||
|
||||
typedef struct strtab_entry {
|
||||
unsigned int key; /* offset into contained strings */
|
||||
unsigned short first; /* offset in table to first string to hash to this spot */
|
||||
unsigned short next; /* offset in table to next item to hash to this spot */
|
||||
} strtab_entry_t;
|
||||
|
||||
typedef struct strlist {
|
||||
DtHashTbl sl_hash; /* hash table to hold strings during definition */
|
||||
DtHashTbl sl_bosons; /* reverse hash table for Nolan's lookup function */
|
||||
unsigned int sl_charcount; /* count of current bytes of strings */
|
||||
} strlist_t;
|
||||
|
||||
struct strtab_build {
|
||||
unsigned int index; /* iteration */
|
||||
unsigned char * strstart; /* start of strings */
|
||||
strtab_entry_t * tabstart; /* start of table */
|
||||
strtab_t * strtab; /* pointer to head */
|
||||
};
|
||||
|
||||
#define NOT_AN_INDEX ((unsigned short) 0xffff)
|
||||
|
||||
static void inc_it (int * a, int * b, unsigned char * key);
|
||||
static void build_it(int a, struct strtab_build * ptr, unsigned char * key);
|
||||
extern char * strdup(const char *);
|
||||
typedef int (*des_func)(void *);
|
||||
|
||||
/*
|
||||
client routine
|
||||
|
||||
returns offset in string table where string is found,
|
||||
else -1 if string is not found.
|
||||
*/
|
||||
|
||||
const char * _DtShmBosonToString(DtShmStrtab strtab, int boson)
|
||||
{
|
||||
const char * s = (const char *) strtab + ((strtab_t *) strtab)->st_stroffset;
|
||||
return(s+boson);
|
||||
}
|
||||
|
||||
|
||||
DtShmBoson _DtShmStringToBoson(DtShmStrtab strtab, const char * string)
|
||||
{
|
||||
register unsigned int i,j;
|
||||
register unsigned const char * s;
|
||||
register strtab_entry_t * ptr = (strtab_entry_t *) ((unsigned char *) strtab +
|
||||
((strtab_t *) strtab) -> st_taboffset);
|
||||
|
||||
/*
|
||||
hash the input string
|
||||
*/
|
||||
i = 1;
|
||||
j = 0;
|
||||
s = (unsigned const char *) string;
|
||||
|
||||
while(*s!=0)
|
||||
j += (*s++ << i++);
|
||||
|
||||
i = j % ((strtab_t *) strtab)->st_count;
|
||||
|
||||
/*
|
||||
check bucket first pointer....
|
||||
*/
|
||||
|
||||
if((i=(ptr+i)->first) == NOT_AN_INDEX)
|
||||
return(-1);
|
||||
|
||||
/*
|
||||
loop through other buckets on hash table, looking for
|
||||
our string. Note that we reused s.
|
||||
*/
|
||||
|
||||
s = (unsigned const char *) strtab + ((strtab_t *) strtab)->st_stroffset;
|
||||
|
||||
while(strcmp( (char *) (s + ptr[i].key), string))
|
||||
if((i= ptr[i].next) == NOT_AN_INDEX)
|
||||
return(-1);
|
||||
|
||||
return(ptr[i].key);
|
||||
}
|
||||
|
||||
|
||||
|
||||
DtShmProtoStrtab
|
||||
_DtShmProtoInitStrtab(int sizeguess)
|
||||
{
|
||||
strlist_t * ptr = (strlist_t *) malloc(sizeof(*ptr));
|
||||
if(!ptr)
|
||||
return(NULL);
|
||||
|
||||
if(!(ptr->sl_hash = _DtUtilMakeHash(sizeguess))) {
|
||||
free(ptr);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
if(!(ptr->sl_bosons = _DtUtilMakeIHash(sizeguess))) {
|
||||
(void)_DtUtilDestroyHash(ptr->sl_hash, NULL, NULL);
|
||||
free(ptr);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ptr->sl_charcount = 1;
|
||||
return((DtShmProtoStrtab) ptr);
|
||||
}
|
||||
|
||||
int
|
||||
_DtShmProtoDestroyStrtab(DtShmProtoStrtab strlist)
|
||||
{
|
||||
strlist_t * ptr = (strlist_t *) strlist;
|
||||
|
||||
_DtUtilDestroyHash(ptr->sl_hash, NULL, NULL);
|
||||
_DtUtilDestroyHash(ptr->sl_bosons, (des_func)free, NULL);
|
||||
free(ptr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
DtShmBoson
|
||||
_DtShmProtoAddStrtab(DtShmProtoStrtab strlist, const char * string, int * isnew)
|
||||
{
|
||||
strlist_t * ptr = (strlist_t *) strlist;
|
||||
|
||||
int * bucket = (int *) _DtUtilGetHash(ptr->sl_hash, (const unsigned char *)string);
|
||||
|
||||
int ret = *bucket;
|
||||
|
||||
if(*bucket == NULL) /* new */ {
|
||||
unsigned char ** sptr;
|
||||
*isnew = 1;
|
||||
*bucket = ret = ptr->sl_charcount;
|
||||
sptr = (unsigned char**)_DtUtilGetHash(ptr->sl_bosons, (const unsigned char *)ret);
|
||||
*sptr = (unsigned char*)strdup(string);
|
||||
ptr->sl_charcount += strlen(string) + 1;
|
||||
}
|
||||
|
||||
else {
|
||||
*isnew = 0;
|
||||
}
|
||||
|
||||
|
||||
return((DtShmBoson)ret);
|
||||
}
|
||||
|
||||
const char *
|
||||
_DtShmProtoLookUpStrtab (DtShmProtoStrtab prototab, DtShmBoson boson)
|
||||
{
|
||||
strlist_t * ptr = (strlist_t *) prototab;
|
||||
unsigned char ** sptr;
|
||||
|
||||
sptr = (unsigned char **) _DtUtilFindHash(ptr->sl_bosons, (const unsigned char *) boson);
|
||||
|
||||
return(sptr?((const char *)*sptr):NULL);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_DtShmProtoSizeStrtab(DtShmProtoStrtab strlist)
|
||||
{
|
||||
int foo[2];
|
||||
int size;
|
||||
strlist_t * ptr = (strlist_t * ) strlist;
|
||||
|
||||
foo[1] = foo[0] = 0;
|
||||
|
||||
_DtUtilOperateHash(ptr->sl_hash, inc_it, &foo);
|
||||
|
||||
size = sizeof(strtab_t) + (foo[0]) * sizeof(strtab_entry_t) + foo[0] + foo[1] + 3 ;
|
||||
/* header */ /* table */ /* for string + terminator */ /* padding */
|
||||
|
||||
/*
|
||||
fix size so that it is always a multiple of 4 for ease of programming
|
||||
*/
|
||||
size = (~3) & (size+3);
|
||||
|
||||
return(size);
|
||||
|
||||
}
|
||||
|
||||
DtShmStrtab
|
||||
_DtShmProtoCopyStrtab(DtShmProtoStrtab in, void * destination)
|
||||
{
|
||||
strlist_t * strlist = (strlist_t *) in;
|
||||
strtab_t * ptr = (strtab_t *) destination;
|
||||
|
||||
int foo[2];
|
||||
int size;
|
||||
struct strtab_build building;
|
||||
|
||||
|
||||
foo[0] = foo[1] = 0;
|
||||
|
||||
_DtUtilOperateHash(strlist->sl_hash, inc_it, &foo);
|
||||
|
||||
size = sizeof(strtab_t) + (foo[0]) * sizeof(strtab_entry_t) + (foo[0] + foo[1] + 3) & ~3 ;
|
||||
/* header */ /* table */ /* for string + terminator */
|
||||
|
||||
memset((char *) ptr, 255, size);
|
||||
|
||||
|
||||
ptr-> st_size= size;
|
||||
ptr-> st_stroffset = sizeof(*ptr);
|
||||
ptr-> st_taboffset = sizeof(*ptr) + (foo[0] + foo[1] + 3) & ~3;
|
||||
ptr-> st_count = foo[0]; /* patch alignment */
|
||||
|
||||
building.index = 0;
|
||||
building.strstart = (unsigned char *) ptr + ptr->st_stroffset;
|
||||
building.tabstart = (strtab_entry_t *) ((unsigned char *) ptr + ptr->st_taboffset);
|
||||
building.strtab = ptr;
|
||||
|
||||
_DtUtilOperateHash(strlist->sl_hash, build_it, & building);
|
||||
return((DtShmStrtab) destination);
|
||||
}
|
||||
|
||||
static void build_it(int a, struct strtab_build * ptr, unsigned char * key)
|
||||
{
|
||||
register unsigned int i,j;
|
||||
register unsigned char * s;
|
||||
register strtab_entry_t * e;
|
||||
register unsigned short * add_ptr;
|
||||
|
||||
strcpy((char *) ptr->strstart + a, (const char *)key);
|
||||
|
||||
i = 1;
|
||||
j = 0;
|
||||
s = key;
|
||||
|
||||
while(*s!=0)
|
||||
j += (*s++ << i++);
|
||||
|
||||
i = j % ((strtab_t *) ptr->strtab)->st_count;
|
||||
|
||||
e = ptr->tabstart + ptr->index;
|
||||
|
||||
e -> key = a; /* save key value in our block */
|
||||
e -> next = NOT_AN_INDEX;
|
||||
|
||||
e = ptr->tabstart + i;
|
||||
|
||||
if(e->first == NOT_AN_INDEX)
|
||||
add_ptr = & e->first;
|
||||
else {
|
||||
e = ptr->tabstart + e->first;
|
||||
while( e->next != NOT_AN_INDEX)
|
||||
e = ptr->tabstart + e->next;
|
||||
add_ptr = & e->next;
|
||||
}
|
||||
|
||||
*add_ptr = ptr->index++;
|
||||
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void inc_it(int * a, int * b, unsigned char * key)
|
||||
{
|
||||
b[0]++;
|
||||
b[1] += strlen((const char *)key) + 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user