New files.
authortomo <tomo>
Wed, 20 Aug 2003 17:53:30 +0000 (17:53 +0000)
committertomo <tomo>
Wed, 20 Aug 2003 17:53:30 +0000 (17:53 +0000)
chise-name.h [new file with mode: 0644]
name.c [new file with mode: 0644]

diff --git a/chise-name.h b/chise-name.h
new file mode 100644 (file)
index 0000000..6c469ed
--- /dev/null
@@ -0,0 +1,17 @@
+#ifndef _CHISE_NAME_H
+#define _CHISE_NAME_H
+
+typedef struct CHISE_HASH_TABLE_ENTRY CHISE_HASH_TABLE_ENTRY;
+typedef struct CHISE_HASH_TABLE CHISE_HASH_TABLE;
+
+typedef CHISE_HASH_TABLE CHISE_NAME_TABLE;
+typedef CHISE_HASH_TABLE_ENTRY CHISE_NAME_TABLE_ENTRY;
+
+CHISE_NAME_TABLE* chise_make_name_table ();
+void chise_destroy_name_table (CHISE_NAME_TABLE* table);
+int chise_name_table_put (CHISE_NAME_TABLE* table,
+                         unsigned char *key, void *value);
+void* chise_name_table_get (CHISE_NAME_TABLE* table, unsigned char *key);
+int chise_name_table_grow (CHISE_NAME_TABLE* table);
+
+#endif /* !_CHISE_NAME_H */
diff --git a/name.c b/name.c
new file mode 100644 (file)
index 0000000..501df93
--- /dev/null
+++ b/name.c
@@ -0,0 +1,167 @@
+#include <string.h>
+
+typedef struct CHISE_HASH_TABLE_ENTRY
+{
+  void *key;
+  void *value;
+} CHISE_HASH_TABLE_ENTRY;
+
+typedef struct CHISE_HASH_TABLE
+{
+  size_t size;
+  CHISE_HASH_TABLE_ENTRY *data;
+} CHISE_HASH_TABLE;
+
+CHISE_HASH_TABLE*
+chise_make_hash_table (size_t size)
+{
+  CHISE_HASH_TABLE* hash
+    = (CHISE_HASH_TABLE*)malloc (sizeof (CHISE_HASH_TABLE));
+
+  if (hash == NULL)
+    return NULL;
+
+  hash->data
+    = (CHISE_HASH_TABLE_ENTRY*) malloc (sizeof (CHISE_HASH_TABLE_ENTRY)
+                                       * size);
+  if (hash->data == NULL)
+    {
+      free (hash);
+      return NULL;
+    }
+
+  hash->size = size;
+  memset (hash->data, 0, sizeof (CHISE_HASH_TABLE_ENTRY) * size);
+  return hash;
+}
+
+void
+chise_destroy_hash_table (CHISE_HASH_TABLE* hash)
+{
+  if (hash == NULL)
+    return;
+  free (hash->data);
+  free (hash);
+}
+
+
+/* derived from hashpjw, Dragon Book P436. */
+int
+chise_hash_c_string (const unsigned char *ptr)
+{
+  int hash = 0;
+
+  while (*ptr != '\0')
+    {
+      int g;
+      hash = (hash << 4) + *ptr++;
+      g = hash & 0xf0000000;
+      if (g)
+       hash = (hash ^ (g >> 24)) ^ g;
+    }
+  return hash & 07777777777;
+}
+
+
+typedef CHISE_HASH_TABLE CHISE_NAME_TABLE;
+typedef CHISE_HASH_TABLE_ENTRY CHISE_NAME_TABLE_ENTRY;
+
+CHISE_NAME_TABLE*
+chise_make_name_table ()
+{
+  return chise_make_hash_table (32);
+}
+
+void
+chise_destroy_name_table (CHISE_NAME_TABLE* table)
+{
+  chise_destroy_hash_table (table);
+}
+
+int
+chise_name_table_put (CHISE_NAME_TABLE* table,
+                     unsigned char *key, void *value)
+{
+  int i, index;
+  CHISE_NAME_TABLE_ENTRY* entry;
+
+  if (table == NULL)
+    return -1;
+
+  index = chise_hash_c_string (key) % table->size;
+  for (i = index; i < table->size; i++)
+    {
+      entry = &table->data[i];
+      if (entry->key == NULL)
+       {
+         size_t len = strlen (key);
+
+         entry->key = (unsigned char*)malloc (len + 1);
+         if (entry->key == NULL)
+           return -1;
+         strcpy (entry->key, key);
+         entry->value = value;
+         return 0;
+       }
+      else if (strcmp (entry->key, key) == 0)
+       {
+         entry->value = value;
+         return 0;
+       }
+    }
+  if (chise_name_table_grow (table) == 0)
+    return chise_name_table_put (table, key, value);
+  return -1;
+}
+
+void *
+chise_name_table_get (CHISE_NAME_TABLE* table,
+                     unsigned char *key)
+{
+  int i, index;
+  CHISE_NAME_TABLE_ENTRY entry;
+
+  if (table == NULL)
+    return NULL;
+
+  index = chise_hash_c_string (key) % table->size;
+  for (i = index; i < table->size; i++)
+    {
+      entry = table->data[i];
+      if (entry.key == NULL)
+       return NULL;
+      else if (strcmp (entry.key, key) == 0)
+       return entry.value;
+    }
+  return NULL;
+}
+
+int
+chise_name_table_grow (CHISE_NAME_TABLE* table)
+{
+  CHISE_NAME_TABLE *new_table
+    = chise_make_hash_table (table->size * 2);
+  int i;
+
+  if (new_table == NULL)
+    return -1;
+
+  for (i = 0; i < table->size; i++)
+    {
+      CHISE_NAME_TABLE_ENTRY entry = table->data[i];
+      if ( (entry.key != NULL) && (entry.value != NULL) )
+       {
+         int status
+           = chise_name_table_put (new_table, entry.key, entry.value);
+         if (status != 0)
+           {
+             chise_destroy_hash_table (new_table);
+             return -1;
+           }
+       }
+    }
+  table->size = new_table->size;
+  table->data = new_table->data;
+  free (new_table);
+  return 0;
+}