1 //========================================================================
5 // Copyright 2001-2003 Glyph & Cog, LLC
7 //========================================================================
11 #ifdef USE_GCC_PRAGMAS
12 #pragma implementation
16 #include "GooString.h"
19 //------------------------------------------------------------------------
21 struct GooHashBucket
{
35 //------------------------------------------------------------------------
37 GooHash::GooHash(GBool deleteKeysA
) {
40 deleteKeys
= deleteKeysA
;
42 tab
= (GooHashBucket
**)gmallocn(size
, sizeof(GooHashBucket
*));
43 for (h
= 0; h
< size
; ++h
) {
53 for (h
= 0; h
< size
; ++h
) {
66 void GooHash::add(GooString
*key
, void *val
) {
70 // expand the table if necessary
76 p
= new GooHashBucket
;
85 void GooHash::add(GooString
*key
, int val
) {
89 // expand the table if necessary
95 p
= new GooHashBucket
;
104 void GooHash::replace(GooString
*key
, void *val
) {
108 if ((p
= find(key
, &h
))) {
118 void GooHash::replace(GooString
*key
, int val
) {
122 if ((p
= find(key
, &h
))) {
132 void *GooHash::lookup(GooString
*key
) {
136 if (!(p
= find(key
, &h
))) {
142 int GooHash::lookupInt(GooString
*key
) {
146 if (!(p
= find(key
, &h
))) {
152 void *GooHash::lookup(const char *key
) {
156 if (!(p
= find(key
, &h
))) {
162 int GooHash::lookupInt(const char *key
) {
166 if (!(p
= find(key
, &h
))) {
172 void *GooHash::remove(GooString
*key
) {
178 if (!(p
= find(key
, &h
))) {
195 int GooHash::removeInt(GooString
*key
) {
201 if (!(p
= find(key
, &h
))) {
218 void *GooHash::remove(const char *key
) {
224 if (!(p
= find(key
, &h
))) {
241 int GooHash::removeInt(const char *key
) {
247 if (!(p
= find(key
, &h
))) {
264 void GooHash::startIter(GooHashIter
**iter
) {
265 *iter
= new GooHashIter
;
270 GBool
GooHash::getNext(GooHashIter
**iter
, GooString
**key
, void **val
) {
275 (*iter
)->p
= (*iter
)->p
->next
;
277 while (!(*iter
)->p
) {
278 if (++(*iter
)->h
== size
) {
283 (*iter
)->p
= tab
[(*iter
)->h
];
285 *key
= (*iter
)->p
->key
;
286 *val
= (*iter
)->p
->val
.p
;
290 GBool
GooHash::getNext(GooHashIter
**iter
, GooString
**key
, int *val
) {
295 (*iter
)->p
= (*iter
)->p
->next
;
297 while (!(*iter
)->p
) {
298 if (++(*iter
)->h
== size
) {
303 (*iter
)->p
= tab
[(*iter
)->h
];
305 *key
= (*iter
)->p
->key
;
306 *val
= (*iter
)->p
->val
.i
;
310 void GooHash::killIter(GooHashIter
**iter
) {
315 void GooHash::expand() {
316 GooHashBucket
**oldTab
;
323 tab
= (GooHashBucket
**)gmallocn(size
, sizeof(GooHashBucket
*));
324 for (h
= 0; h
< size
; ++h
) {
327 for (i
= 0; i
< oldSize
; ++i
) {
330 oldTab
[i
] = oldTab
[i
]->next
;
339 GooHashBucket
*GooHash::find(GooString
*key
, int *h
) {
343 for (p
= tab
[*h
]; p
; p
= p
->next
) {
344 if (!p
->key
->cmp(key
)) {
351 GooHashBucket
*GooHash::find(const char *key
, int *h
) {
355 for (p
= tab
[*h
]; p
; p
= p
->next
) {
356 if (!p
->key
->cmp(key
)) {
363 int GooHash::hash(GooString
*key
) {
369 for (p
= key
->getCString(), i
= 0; i
< key
->getLength(); ++p
, ++i
) {
370 h
= 17 * h
+ (int)(*p
& 0xff);
372 return (int)(h
% size
);
375 int GooHash::hash(const char *key
) {
380 for (p
= key
; *p
; ++p
) {
381 h
= 17 * h
+ (int)(*p
& 0xff);
383 return (int)(h
% size
);