summaryrefslogtreecommitdiffstats
path: root/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc
diff options
context:
space:
mode:
authorSlávek Banko <slavek.banko@axis.cz>2021-11-05 13:28:23 +0100
committerSlávek Banko <slavek.banko@axis.cz>2021-11-05 13:28:23 +0100
commit8c787c3591c1c885b91a54128835b400858c5cca (patch)
treeeca1b776912a305c4d45b3964038278a2fae1ead /debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc
parentfe188b907cdf30dfdfe0eba9412e7f8749fec158 (diff)
downloadextra-dependencies-8c787c3591c1c885b91a54128835b400858c5cca.tar.gz
extra-dependencies-8c787c3591c1c885b91a54128835b400858c5cca.zip
DEB htdig: Added to repository.
Signed-off-by: Slávek Banko <slavek.banko@axis.cz>
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc')
-rw-r--r--debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc416
1 files changed, 416 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc b/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc
new file mode 100644
index 00000000..8c0da019
--- /dev/null
+++ b/debian/htdig/htdig-3.2.0b6/htlib/Dictionary.cc
@@ -0,0 +1,416 @@
+//
+// Dictionary.cc
+//
+// Dictionary: This class provides an object lookup table.
+// Each object in the dictionary is indexed with a string.
+// The objects can be returned by mentioning their
+// string index.
+//
+// Part of the ht://Dig package <http://www.htdig.org/>
+// Copyright (c) 1995-2004 The ht://Dig Group
+// For copyright details, see the file COPYING in your distribution
+// or the GNU Library General Public License (LGPL) version 2 or later
+// <http://www.gnu.org/copyleft/lgpl.html>
+//
+// $Id: Dictionary.cc,v 1.16 2004/05/28 13:15:20 lha Exp $
+//
+
+#ifdef HAVE_CONFIG_H
+#include "htconfig.h"
+#endif /* HAVE_CONFIG_H */
+
+#include "Dictionary.h"
+
+#include <stdlib.h>
+
+class DictionaryEntry
+{
+public:
+ unsigned int hash;
+ char *key;
+ Object *value;
+ DictionaryEntry *next;
+
+ ~DictionaryEntry();
+ void release();
+};
+
+DictionaryEntry::~DictionaryEntry()
+{
+ free(key);
+ delete value;
+}
+
+void
+DictionaryEntry::release()
+{
+ value = NULL; // Prevent the value from being deleted
+}
+
+
+//*********************************************************************
+//
+Dictionary::Dictionary()
+{
+ init(101, 10.0f);
+}
+
+Dictionary::Dictionary(int initialCapacity, float loadFactor)
+{
+ init(initialCapacity, loadFactor);
+}
+
+Dictionary::Dictionary(int initialCapacity)
+{
+ init(initialCapacity, 0.75f);
+}
+
+Dictionary::Dictionary(const Dictionary& other)
+{
+ init(other.initialCapacity, other.loadFactor);
+
+ DictionaryCursor cursor;
+ const char* key;
+ for(other.Start_Get(cursor); (key = other.Get_Next(cursor));) {
+ Add(key, other[key]);
+ }
+}
+
+//*********************************************************************
+//
+Dictionary::~Dictionary()
+{
+ Destroy();
+
+ delete [] table;
+}
+
+
+//*********************************************************************
+//
+void
+Dictionary::Destroy()
+{
+ DictionaryEntry *t, *n;
+
+ for (int i = 0; i < tableLength; i++)
+ {
+ if (table[i] != NULL)
+ {
+ t = table[i];
+ do { // clear out hash chain
+ n = t->next;
+ delete t;
+ t = n;
+ } while (n);
+ table[i] = NULL;
+ }
+ }
+ count = 0;
+}
+
+//*********************************************************************
+//
+void
+Dictionary::Release()
+{
+ DictionaryEntry *t, *n;
+
+ for (int i = 0; i < tableLength; i++)
+ {
+ if (table[i] != NULL)
+ {
+ t = table[i];
+ do { // clear out hash chain
+ n = t->next;
+ t->release();
+ delete t;
+ t = n;
+ } while (n);
+ table[i] = NULL;
+ }
+ }
+ count = 0;
+}
+
+
+//*********************************************************************
+//
+void
+Dictionary::init(int initialCapacity, float loadFactor)
+{
+ if (initialCapacity <= 0)
+ initialCapacity = 101;
+ if (loadFactor <= 0.0)
+ loadFactor = 0.75f;
+ Dictionary::loadFactor = loadFactor;
+ table = new DictionaryEntry*[initialCapacity];
+ for (int i = 0; i < initialCapacity; i++)
+ {
+ table[i] = NULL;
+ }
+ threshold = (int)(initialCapacity * loadFactor);
+ tableLength = initialCapacity;
+ count = 0;
+}
+
+//*********************************************************************
+//
+unsigned int
+Dictionary::hashCode(const char *key) const
+{
+ char *test;
+ long conv_key = strtol(key, &test, 10);
+ if (key && *key && !*test) // Conversion succeeded
+ return conv_key;
+
+ char *base = (char*)malloc(strlen(key) + 2);
+ char *tmp_key = base;
+ strcpy(tmp_key, key);
+
+ unsigned int h = 0;
+ int length = strlen(tmp_key);
+
+ if (length >= 16)
+ {
+ tmp_key += strlen(tmp_key) - 15;
+ length = strlen(tmp_key);
+ }
+ for (int i = length; i > 0; i--)
+ {
+ h = (h*37) + *tmp_key++;
+ }
+
+ free(base);
+ return h;
+}
+
+//*********************************************************************
+// Add an entry to the hash table. This will replace the
+// data associated with an already existing key.
+//
+void
+Dictionary::Add(const String& name, Object *obj)
+{
+ unsigned int hash = hashCode(name);
+ int index = hash % tableLength;
+ DictionaryEntry *e;
+
+ for (e = table[index]; e != NULL; e = e->next)
+ {
+ if (e->hash == hash && strcmp(e->key, name) == 0)
+ {
+ delete e->value;
+ e->value = obj;
+ return;
+ }
+ }
+
+ if (count >= threshold)
+ {
+ rehash();
+ Add(name, obj);
+ return;
+ }
+
+ e = new DictionaryEntry();
+ e->hash = hash;
+ e->key = strdup(name);
+ e->value = obj;
+ e->next = table[index];
+ table[index] = e;
+ count++;
+}
+
+
+//*********************************************************************
+// Remove an entry from the hash table.
+//
+int
+Dictionary::Remove(const String& name)
+{
+ if (!count)
+ return 0;
+
+ unsigned int hash = hashCode(name);
+ int index = hash % tableLength;
+ DictionaryEntry *e, *prev;
+
+ for (e = table[index], prev = NULL; e != NULL; prev = e, e = e->next)
+ {
+ if (hash == e->hash && strcmp(e->key, name) == 0)
+ {
+ if (prev != NULL)
+ {
+ prev->next = e->next;
+ }
+ else
+ {
+ table[index] = e->next;
+ }
+ count--;
+ delete e;
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+//*********************************************************************
+//
+Object *Dictionary::Find(const String& name) const
+{
+ if (!count)
+ return NULL;
+
+ unsigned int hash = hashCode(name);
+ int index = hash % tableLength;
+ DictionaryEntry *e;
+
+ for (e = table[index]; e != NULL; e = e->next)
+ {
+ if (e->hash == hash && strcmp(e->key, name) == 0)
+ {
+ return e->value;
+ }
+ }
+ return NULL;
+}
+
+
+//*********************************************************************
+//
+Object *Dictionary::operator[](const String& name) const
+{
+ return Find(name);
+}
+
+
+//*********************************************************************
+//
+int Dictionary::Exists(const String& name) const
+{
+ if (!count)
+ return 0;
+
+ unsigned int hash = hashCode(name);
+ int index = hash % tableLength;
+ DictionaryEntry *e;
+
+ for (e = table[index]; e != NULL; e = e->next)
+ {
+ if (e->hash == hash && strcmp(e->key, name) == 0)
+ {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+//*********************************************************************
+//
+void
+Dictionary::rehash()
+{
+ DictionaryEntry **oldTable = table;
+ int oldCapacity = tableLength;
+
+ int newCapacity;
+ DictionaryEntry *e;
+ int i, index;
+
+ newCapacity = count > oldCapacity ? count * 2 + 1 : oldCapacity * 2 + 1;
+
+ DictionaryEntry **newTable = new DictionaryEntry*[newCapacity];
+
+ for (i = 0; i < newCapacity; i++)
+ {
+ newTable[i] = NULL;
+ }
+
+ threshold = (int) (newCapacity * loadFactor);
+ table = newTable;
+ tableLength = newCapacity;
+
+ for (i = oldCapacity; i-- > 0;)
+ {
+ for (DictionaryEntry *old = oldTable[i]; old != NULL;)
+ {
+ e = old;
+ old = old->next;
+ index = e->hash % newCapacity;
+ e->next = newTable[index];
+ newTable[index] = e;
+ }
+ }
+ delete [] oldTable;
+}
+
+
+//*********************************************************************
+//
+void
+Dictionary::Start_Get(DictionaryCursor& cursor) const
+{
+ cursor.currentTableIndex = -1;
+ cursor.currentDictionaryEntry = NULL;
+}
+
+
+//*********************************************************************
+//
+char *
+Dictionary::Get_Next(DictionaryCursor& cursor) const
+{
+ while (cursor.currentDictionaryEntry == NULL ||
+ cursor.currentDictionaryEntry->next == NULL)
+ {
+ cursor.currentTableIndex++;
+
+ if (cursor.currentTableIndex >= tableLength)
+ {
+ cursor.currentTableIndex--;
+ return NULL;
+ }
+
+ cursor.currentDictionaryEntry = table[cursor.currentTableIndex];
+
+ if (cursor.currentDictionaryEntry != NULL)
+ {
+ return cursor.currentDictionaryEntry->key;
+ }
+ }
+
+ cursor.currentDictionaryEntry = cursor.currentDictionaryEntry->next;
+ return cursor.currentDictionaryEntry->key;
+}
+
+//*********************************************************************
+//
+Object *
+Dictionary::Get_NextElement(DictionaryCursor& cursor) const
+{
+ while (cursor.currentDictionaryEntry == NULL ||
+ cursor.currentDictionaryEntry->next == NULL)
+ {
+ cursor.currentTableIndex++;
+
+ if (cursor.currentTableIndex >= tableLength)
+ {
+ cursor.currentTableIndex--;
+ return NULL;
+ }
+
+ cursor.currentDictionaryEntry = table[cursor.currentTableIndex];
+
+ if (cursor.currentDictionaryEntry != NULL)
+ {
+ return cursor.currentDictionaryEntry->value;
+ }
+ }
+
+ cursor.currentDictionaryEntry = cursor.currentDictionaryEntry->next;
+ return cursor.currentDictionaryEntry->value;
+}