summaryrefslogtreecommitdiff
path: root/Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc')
-rw-r--r--Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc384
1 files changed, 384 insertions, 0 deletions
diff --git a/Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc b/Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc
new file mode 100644
index 00000000000..f4a92f17506
--- /dev/null
+++ b/Build/source/libs/poppler/poppler-0.20.2/goo/GooHash.cc
@@ -0,0 +1,384 @@
+//========================================================================
+//
+// GooHash.cc
+//
+// Copyright 2001-2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include "gmem.h"
+#include "GooString.h"
+#include "GooHash.h"
+
+//------------------------------------------------------------------------
+
+struct GooHashBucket {
+ GooString *key;
+ union {
+ void *p;
+ int i;
+ } val;
+ GooHashBucket *next;
+};
+
+struct GooHashIter {
+ int h;
+ GooHashBucket *p;
+};
+
+//------------------------------------------------------------------------
+
+GooHash::GooHash(GBool deleteKeysA) {
+ int h;
+
+ deleteKeys = deleteKeysA;
+ size = 7;
+ tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *));
+ for (h = 0; h < size; ++h) {
+ tab[h] = NULL;
+ }
+ len = 0;
+}
+
+GooHash::~GooHash() {
+ GooHashBucket *p;
+ int h;
+
+ for (h = 0; h < size; ++h) {
+ while (tab[h]) {
+ p = tab[h];
+ tab[h] = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ delete p;
+ }
+ }
+ gfree(tab);
+}
+
+void GooHash::add(GooString *key, void *val) {
+ GooHashBucket *p;
+ int h;
+
+ // expand the table if necessary
+ if (len >= size) {
+ expand();
+ }
+
+ // add the new symbol
+ p = new GooHashBucket;
+ p->key = key;
+ p->val.p = val;
+ h = hash(key);
+ p->next = tab[h];
+ tab[h] = p;
+ ++len;
+}
+
+void GooHash::add(GooString *key, int val) {
+ GooHashBucket *p;
+ int h;
+
+ // expand the table if necessary
+ if (len >= size) {
+ expand();
+ }
+
+ // add the new symbol
+ p = new GooHashBucket;
+ p->key = key;
+ p->val.i = val;
+ h = hash(key);
+ p->next = tab[h];
+ tab[h] = p;
+ ++len;
+}
+
+void GooHash::replace(GooString *key, void *val) {
+ GooHashBucket *p;
+ int h;
+
+ if ((p = find(key, &h))) {
+ p->val.p = val;
+ if (deleteKeys) {
+ delete key;
+ }
+ } else {
+ add(key, val);
+ }
+}
+
+void GooHash::replace(GooString *key, int val) {
+ GooHashBucket *p;
+ int h;
+
+ if ((p = find(key, &h))) {
+ p->val.i = val;
+ if (deleteKeys) {
+ delete key;
+ }
+ } else {
+ add(key, val);
+ }
+}
+
+void *GooHash::lookup(GooString *key) {
+ GooHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ return p->val.p;
+}
+
+int GooHash::lookupInt(GooString *key) {
+ GooHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ return p->val.i;
+}
+
+void *GooHash::lookup(const char *key) {
+ GooHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ return p->val.p;
+}
+
+int GooHash::lookupInt(const char *key) {
+ GooHashBucket *p;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ return p->val.i;
+}
+
+void *GooHash::remove(GooString *key) {
+ GooHashBucket *p;
+ GooHashBucket **q;
+ void *val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.p;
+ delete p;
+ --len;
+ return val;
+}
+
+int GooHash::removeInt(GooString *key) {
+ GooHashBucket *p;
+ GooHashBucket **q;
+ int val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.i;
+ delete p;
+ --len;
+ return val;
+}
+
+void *GooHash::remove(const char *key) {
+ GooHashBucket *p;
+ GooHashBucket **q;
+ void *val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return NULL;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.p;
+ delete p;
+ --len;
+ return val;
+}
+
+int GooHash::removeInt(const char *key) {
+ GooHashBucket *p;
+ GooHashBucket **q;
+ int val;
+ int h;
+
+ if (!(p = find(key, &h))) {
+ return 0;
+ }
+ q = &tab[h];
+ while (*q != p) {
+ q = &((*q)->next);
+ }
+ *q = p->next;
+ if (deleteKeys) {
+ delete p->key;
+ }
+ val = p->val.i;
+ delete p;
+ --len;
+ return val;
+}
+
+void GooHash::startIter(GooHashIter **iter) {
+ *iter = new GooHashIter;
+ (*iter)->h = -1;
+ (*iter)->p = NULL;
+}
+
+GBool GooHash::getNext(GooHashIter **iter, GooString **key, void **val) {
+ if (!*iter) {
+ return gFalse;
+ }
+ if ((*iter)->p) {
+ (*iter)->p = (*iter)->p->next;
+ }
+ while (!(*iter)->p) {
+ if (++(*iter)->h == size) {
+ delete *iter;
+ *iter = NULL;
+ return gFalse;
+ }
+ (*iter)->p = tab[(*iter)->h];
+ }
+ *key = (*iter)->p->key;
+ *val = (*iter)->p->val.p;
+ return gTrue;
+}
+
+GBool GooHash::getNext(GooHashIter **iter, GooString **key, int *val) {
+ if (!*iter) {
+ return gFalse;
+ }
+ if ((*iter)->p) {
+ (*iter)->p = (*iter)->p->next;
+ }
+ while (!(*iter)->p) {
+ if (++(*iter)->h == size) {
+ delete *iter;
+ *iter = NULL;
+ return gFalse;
+ }
+ (*iter)->p = tab[(*iter)->h];
+ }
+ *key = (*iter)->p->key;
+ *val = (*iter)->p->val.i;
+ return gTrue;
+}
+
+void GooHash::killIter(GooHashIter **iter) {
+ delete *iter;
+ *iter = NULL;
+}
+
+void GooHash::expand() {
+ GooHashBucket **oldTab;
+ GooHashBucket *p;
+ int oldSize, h, i;
+
+ oldSize = size;
+ oldTab = tab;
+ size = 2*size + 1;
+ tab = (GooHashBucket **)gmallocn(size, sizeof(GooHashBucket *));
+ for (h = 0; h < size; ++h) {
+ tab[h] = NULL;
+ }
+ for (i = 0; i < oldSize; ++i) {
+ while (oldTab[i]) {
+ p = oldTab[i];
+ oldTab[i] = oldTab[i]->next;
+ h = hash(p->key);
+ p->next = tab[h];
+ tab[h] = p;
+ }
+ }
+ gfree(oldTab);
+}
+
+GooHashBucket *GooHash::find(GooString *key, int *h) {
+ GooHashBucket *p;
+
+ *h = hash(key);
+ for (p = tab[*h]; p; p = p->next) {
+ if (!p->key->cmp(key)) {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+GooHashBucket *GooHash::find(const char *key, int *h) {
+ GooHashBucket *p;
+
+ *h = hash(key);
+ for (p = tab[*h]; p; p = p->next) {
+ if (!p->key->cmp(key)) {
+ return p;
+ }
+ }
+ return NULL;
+}
+
+int GooHash::hash(GooString *key) {
+ const char *p;
+ unsigned int h;
+ int i;
+
+ h = 0;
+ for (p = key->getCString(), i = 0; i < key->getLength(); ++p, ++i) {
+ h = 17 * h + (int)(*p & 0xff);
+ }
+ return (int)(h % size);
+}
+
+int GooHash::hash(const char *key) {
+ const char *p;
+ unsigned int h;
+
+ h = 0;
+ for (p = key; *p; ++p) {
+ h = 17 * h + (int)(*p & 0xff);
+ }
+ return (int)(h % size);
+}