-+-+-+-+-+-+-+-+ START OF PART 206 -+-+-+-+-+-+-+-+ X */ X strncpy(strbuffer, strentry->strdata, *buffersize); X `7D X `7D X `7D X`7D /* ptk_inttostring */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern Pint ptk_stringtoint(C(Pchar *) tablestr, C(Pchar *) str) XPreANSI(Pchar *tablestr) XPreANSI(Pchar *str) X/* X** \parambegin X** \param`7BPchar *`7D`7Btablestr`7D`7Bname of hashtable`7D`7BIN`7D X** \param`7BPchar *`7D`7Bstr`7D`7Bstring to be searched for in string table` V7D`7BIN`7D X** \paramend X** \blurb`7BThis function returns the integer allocated for the string \pard Vesc`7Bstr`7D X** in hashtable \pardesc`7Btablestr`7D. X** If the string has not already been allocated an integer, X** then it is allocated one and this value is`20 X** returned.`7D X*/ X`7B X Pint hashvalue, stid, strlength; X Pchar *newstr; X ptkboolean found; X Pint foundentry; X ptkshashtable *table; X X if ((table = ptk_stringtotable(tablestr)) != NULL) X `7B X strlength = stringlength(str); X newstr = (Pchar *)malloc(strlength + 1); /* `60+1' for \0 character */ X parsestring(str, newstr, strlength); X hashvalue = hashstring(newstr, strlength); /* calc hashvalue */ X if (table->hashtable`5Bhashvalue - 1`5D == NIL) X `7B `20 X /* no collision, so add string */ X if (addstringtotable(table, newstr, &stid)) X table->hashtable`5Bhashvalue - 1`5D = stid - table->minuniqint; X free(newstr); X return stid; X `7D`20 X else`20 X `7B X /* collision, so traverse clash pointers to first free position */ X searchforstring(newstr, table->hashtable`5Bhashvalue - 1`5D, X table, &foundentry, &found); X if (found) X `7B X free(newstr);`20 X return table->stridtable`5Bfoundentry`5D.uniqint; `20 X /* string already present */ X `7D X else`20 X `7B `20 X /* add into table */ X if (addstringtotable(table, newstr, &stid)) X`09`7B X table->hashtable`5Bhashvalue - 1`5D = stid - table->minuniqint; X table->stridtable`5Bstid - table->minuniqint`5D.prevptr = foundent Vry; X table->stridtable`5Bfoundentry`5D.clashptr = stid - table->minuniq Vint; X `7D X free(newstr); X return stid; X `7D /* else */ X `7D /* else */ X `7D X`7D /* ptk_stringtoint */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern ptkboolean ptk_delstring(C(Pchar *) tablestr, C(Pchar *) delstr) XPreANSI(Pchar *tablestr) XPreANSI(Pchar *delstr) X/* X** \parambegin X** \param`7BPchar *`7D`7Btablestr`7D`7Bname of hashtable`7D`7BIN`7D X** \param`7BPchar *`7D`7Bdelstr`7D`7Bstring to be deleted from string table` V7D`7BIN`7D X** \paramend X** \blurb`7BThis function deletes the string \pardesc`7Bdelstr`7D from hasht Vable X** \pardesc`7Btablestr`7D. The result of the function is X** TRUE if the string was, otherwise FALSE.`7D X*/`20 X`7B X Pint hashvalue, strlength; X Pchar *newstr; X ptkboolean found; X ptksstridentry *strentry; X Pint foundentry; X ptkshashtable *table; X X if ((table = ptk_stringtotable(tablestr)) != NULL) X `7B X strlength = stringlength(delstr); X newstr = (Pchar *)malloc(strlength + 1); X parsestring(delstr, newstr, strlength); X hashvalue = hashstring(newstr, strlength); X searchforstring(newstr, table->hashtable`5Bhashvalue - 1`5D, table, X `09`09 &foundentry, &found); X if (!found) X `7B`20 X free(newstr); `20 X /* string not present */ X return FALSE; X `7D X else`20 X `7B X free(newstr); X strentry = &table->stridtable`5Bfoundentry`5D; X if (strentry->prevptr == NIL)`20 X `7B `20 X /* entry at head of list */ X if (strentry->clashptr == NIL) /* only one entry */ X table->hashtable`5Bhashvalue - 1`5D = NIL; X else`20 X `7B `20 X /* more than one entry in list */ X table->stridtable`5B(strentry->clashptr)`5D.prevptr = NIL; X `20 X /* by-pass deleted entry`20 X table->hashtable`5Bhashvalue - 1`5D = strentry->clashptr; */ X `7D X `7D /* if */ X else`20 X if (strentry->clashptr == NIL) /* at end of list */ X `7B X table->hashtable`5Bhashvalue - 1`5D = strentry->prevptr; X table->stridtable`5B(strentry->prevptr)`5D.clashptr = NIL; X `7D X else`20 X `7B`20 X /* in middle of list, so by-pass entry */ X table->stridtable`5B(strentry->prevptr)`5D.clashptr =`20 X strentry->clashptr; X table->stridtable`5B(strentry->clashptr)`5D.prevptr =`20 X strentry->prevptr; X `7D X free(table->stridtable`5Bfoundentry`5D.strdata); /* retrieve id */ X table->stridtable`5Bfoundentry`5D.strdata = NULL; X table->stridtable`5Bfoundentry`5D.clashptr = NIL; X table->stridtable`5Bfoundentry`5D.prevptr = NIL; X freestrid(&table->freeintlist, table->stridtable`5Bfoundentry`5D.uniqi Vnt); X return TRUE; X `7D`20 X `7D X`7D /* ptk_delstring */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern ptkboolean ptk_delhashtable(C(Pchar *) tablestr) XPreANSI(Pchar *tablestr) X/* X** \parambegin X** \param`7BPchar *`7D`7Btablestr`7D`7Bname of table to be deleted`7D`7BIN`7 VD X** \paramend X** \blurb`7BThis function deletes hastable \pardesc`7Btablestr`7D from the X** table of hashtables, X** returning TRUE if the table was deleted, otherwise FALSE.`7D X*/`20 X`7B X Pint hashvalue, strlength; X Pchar *newstr; X ptkboolean found; X Pint foundentry; X ptkshashtable *delptr; X ptkstableentry *tabentry; X ptksfreeint *freeptr, *nextptr; X Pint i; X X strlength = stringlength(tablestr); X newstr = (Pchar *)malloc(strlength + 1); /* `60+1' for \0 character */ X parsestring(tablestr, newstr, strlength); X hashvalue = hashstring(newstr, strlength); /* calc hashvalue */ X if (toptable.hashtable`5Bhashvalue - 1`5D == NIL) X `7B `20 X /* no collision, so no table */ X free(newstr); X return FALSE; X `7D`20 X else`20 X `7B X /* collision, so traverse clash pointers to first free position */ X searchfortable(newstr, toptable.hashtable`5Bhashvalue - 1`5D, X &foundentry, &found); X X /* get pointer to hashtable */ X X delptr = toptable.tablelist`5Bfoundentry`5D.tableptr; X X /* delete each string in hashtable */ X X /* free string table */ X X for (i = 0; i < delptr->numstrings; i++) X `7B X free(delptr->stridtable`5Bi`5D.strdata); X free(delptr->stridtable`5Bi`5D); X `7D X X /* free freeintlist */ X freeptr = delptr->freeintlist; X if (freeptr != NULL) X `7B`20 X nextptr = freeptr->next; X free(freeptr); X freeptr = nextptr; X `7D X X /* free ptkshashtable */ X `20 X free(delptr); X `20 X toptable.tablelist`5Bfoundentry`5D.tableptr = NULL; X X /* delete tableentry from ptkshashtablelst */ X X tabentry = &toptable.tablelist`5Bfoundentry`5D; X if (tabentry->prevptr == NIL)`20 X `7B `20 X /* entry at head of list */ X if (tabentry->clashptr == NIL) /* only one entry */ X toptable.hashtable`5Bhashvalue - 1`5D = NIL; X else`20 X `7B `20 X /* more than one entry in list */ X`09toptable.tablelist`5B(tabentry->clashptr)`5D.prevptr = NIL; X X`09/* by-pass deleted entry`20 X toptable.hashtable`5Bhashvalue - 1`5D = tabentry->clashptr; */ X `7D X `7D /* if */ X else X if (tabentry->clashptr == NIL) /* at end of list */ X `7B X toptable.tablelist`5B(tabentry->prevptr)`5D.clashptr = NIL; X toptable.hashtable`5Bhashvalue - 1`5D = tabentry->prevptr; X `7D X else`20 X `7B`20 X /* in middle of list, so by-pass entry */ X toptable.tablelist`5B(tabentry->prevptr)`5D.clashptr =`20 X tabentry->clashptr; X toptable.tablelist`5B(tabentry->clashptr)`5D.prevptr =`20 X tabentry->prevptr; X `7D X free(toptable.tablelist`5Bfoundentry`5D.strdata); /* retrieve id */ X toptable.tablelist`5Bfoundentry`5D.strdata = NULL; X toptable.tablelist`5Bfoundentry`5D.clashptr = NIL; X toptable.tablelist`5Bfoundentry`5D.prevptr = NIL; X free(newstr);`20 X return TRUE; X `7D /* else */ X`7D /* ptk_delhashtable */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern ptkboolean ptk_stringused(C(Pchar *) tablestr, C(Pchar *) str) XPreANSI(Pchar *tablestr) XPreANSI(Pchar *str) X/* X** \parambegin X** \param`7BPchar *`7D`7Btablestr`7D`7Bname of hashtable`7D`7BIN`7D X** \param`7BPchar *`7D`7Bstr`7D`7Bstring to search for in string table`7D`7B VIN`7D X** \paramend X** \blurb`7BThis function checks if the string \pardesc`7Bstr`7D X** has already been used in hashtable \pardesc`7Btablestr`7D, X** Returning TRUE if string was used in the hashtable, otherwise FALSE.`7D X*/ X`7B X Pint hashvalue, strlength; X Pchar *newstr; X ptkboolean found; X Pint foundentry; X ptkshashtable *table; X X if ((table = ptk_stringtotable(tablestr)) != NULL) X `7B X strlength = stringlength(str); X newstr = (Pchar *)malloc(strlength + 1); X parsestring(str, newstr, strlength); X hashvalue = hashstring(newstr, strlength); /* calc hashvalue */ X if (table->hashtable`5Bhashvalue - 1`5D == NIL) X `7B `20 X /* not present */ X return FALSE; X `7D X else`20 X `7B X /* collision, so traverse clash pointers to search for occurence */ X searchforstring(newstr, table->hashtable`5Bhashvalue - 1`5D, table, X &foundentry, &found); X return found; X `7D X `7D X`7D /* ptk_stringused */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_inqstrings(C(Pchar *) tablestr, C(Pint) size,`20 X C(Pint *) totalsize, C(Pchar *) strbuffer, X C(ptksstringtable *) strtable) X XPreANSI(Pchar *tablestr) XPreANSI(Pint size) XPreANSI(Pint *totalsize) XPreANSI(Pchar *strbuffer) XPreANSI(ptksstringtable *strtable) X/* X** \parambegin X** \param`7BPchar *`7D`7Btablestr`7D`7Bname of hashtable`7D`7BIN`7D X** \param`7BPint`7D`7Bsize`7D`7Bnumber of bytes allocated by the user for st Vring table data.`7D`7BIN`7D X** \param`7BPint *`7D`7Btotalsize`7D`7Bactual size of buffer required for st Vring table data.`7D`7BOUT`7D X** \param`7BPchar *`7D`7Bstrbuffer`7D`7Bapplication supplied buffer for stri Vng table data`7D`7BOUT`7D X** \param`7Bptksstringtable *`7D`7Bstrtable`7D`7Bstruct containing length of V arrays and pointer to data in strbuffer.`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function is used to interogate hashtable \pardesc`7Btablest Vr`7D. X** A list of the \pardesc`7Bsize`7D strings contained in the hashtable are r Veturned X** in the user specified buffer \pardesc`7Bstrbuffer`7D, together with their X** corresponding X** string lengths and integer hash values.`7D X*/ X`7B X Pint ind; X ptksstridentry *strentry; X Pint *stidptr; X Pint *strlenptr; X Pchar **strptr; X Pchar *stringptr; X Pint counter = 0; X ptkshashtable *table; X X if ((table = ptk_stringtotable(tablestr)) != NULL) X `7B X *totalsize = 0; X for (ind = 0; ind < table->numstrings; ind++)`20 X `7B X strentry = (table->stridtable + ind); X if (strentry->strdata != NULL) X `7B`20 X *totalsize += (2 * sizeof(Pint)) + sizeof(Pchar *) +`20 X (strentry->stringlen + 1); X counter++; X `7D `20 X `7D X `20 X strtable->listlen = counter; X /* if application buffer is big enough, copy in data */ X if (counter > 0) X `7B X if ((size >= *totalsize) && (strbuffer != NULL)) X `7B X /* pointers into application supplied buffer */ X stidptr = strtable->intlist = (Pint *)strbuffer; X strlenptr = strtable->strlenlist = (Pint *)(strbuffer +`20 X (counter * sizeof(Pint))); X strptr = strtable->strlist = (Pchar **)(strbuffer +`20 X (2 * (counter * sizeof(Pint)))); X stringptr = (Pchar *)(strptr + (counter * sizeof(Pchar *))); X for (ind = 0; ind < table->numstrings; ind++) X `7B `20 X if ((table->stridtable + ind)->strdata != NULL)`20 X `7B `20 X strentry = (table->stridtable + ind); X strncpy(stringptr, strentry->strdata,`20 X (strentry->stringlen + 1)); X *strptr = (Pchar *)stringptr; X strptr++; X stringptr += (strentry->stringlen + 2);`20 X *strlenptr = (Pint)strentry->stringlen; X strlenptr++; X *stidptr = (Pint)strentry->uniqint; X stidptr++;`20 X `7D X `7D X `7D X `7D X `7D X`7D /* ptk_inqstrings */ X X/*-------------------------------------------------------------------------- V*/ X X/*function:external*/ Xextern void ptk_inqhashtables(C(Pint) size, C(Pint *) totalsize,`20 X C(Pchar *) strbuffer, C(ptkstablelist *) tablerec V) XPreANSI(Pint size) XPreANSI(Pint *totalsize) XPreANSI(Pchar *strbuffer) XPreANSI(ptkstablelist *tablerec) X/* X** \parambegin X** \param`7BPint`7D`7Bsize`7D`7Bnumber of bytes allocated for the hashtable V data.`7D`7BIN`7D X** \param`7BPint *`7D`7Btotalsize`7D`7Bactual number of bytes required for h Vashtable data.`7D`7BOUT`7D X** \param`7BPchar *`7D`7Bstrbuffer`7D`7Bpointer to buffer for hashtable data V`7D`7BOUT`7D X** \param`7Bptkstablelist *`7D`7Btablerec`7D`7Bhash table data.`7D`7BOUT`7D X** \paramend X** \blurb`7BThis function returns in the X** user specified buffer \pardesc`7Bstrbuffer`7D`20 X** the names of each hashtable contained in the table of hashtables.`7D X*/ X`7B X Pint ind; X ptkstableentry *tabentry; X Pint *strlenptr; X Pchar **strptr; X Pchar *stringptr; X Pint counter = 0; X X *totalsize = 0; +-+-+-+-+-+-+-+- END OF PART 206 +-+-+-+-+-+-+-+-