summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c620
1 files changed, 0 insertions, 620 deletions
diff --git a/hash.c b/hash.c
deleted file mode 100644
index 7881fc64..00000000
--- a/hash.c
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
- * hash.c: chained hash tables
- *
- * Reference: Your favorite introductory book on algorithms
- *
- * Copyright (C) 2000 Bjorn Reese and Daniel Veillard.
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
- * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
- *
- * Author: bjorn.reese@systematic.dk
- */
-
-#ifdef WIN32
-#include "win32config.h"
-#else
-#include "config.h"
-#endif
-
-#include <string.h>
-#include <libxml/hash.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/parser.h>
-
-/*
- * A single entry in the hash table
- */
-typedef struct _xmlHashEntry xmlHashEntry;
-typedef xmlHashEntry *xmlHashEntryPtr;
-struct _xmlHashEntry {
- struct _xmlHashEntry *next;
- xmlChar *name;
- xmlChar *name2;
- xmlChar *name3;
- void *payload;
-};
-
-/*
- * The entire hash table
- */
-struct _xmlHashTable {
- struct _xmlHashEntry **table;
- int size;
- int nbElems;
-};
-
-/*
- * xmlHashComputeKey:
- * Calculate the hash key
- */
-static unsigned long
-xmlHashComputeKey(xmlHashTablePtr table, const xmlChar *string) {
- unsigned long value = 0L;
- char ch;
-
- while ((ch = *string++) != 0) {
- /* value *= 31; */
- value += (unsigned long)ch;
- }
- return (value % table->size);
-}
-
-/**
- * xmlHashCreate:
- * @size: the size of the hash table
- *
- * Create a new xmlHashTablePtr.
- *
- * Returns the newly created object, or NULL if an error occured.
- */
-xmlHashTablePtr
-xmlHashCreate(int size) {
- xmlHashTablePtr table;
-
- if (size <= 0)
- size = 256;
-
- table = xmlMalloc(sizeof(xmlHashTable));
- if (table) {
- table->size = size;
- table->nbElems = 0;
- table->table = xmlMalloc(size * sizeof(xmlHashEntry));
- if (table->table) {
- memset(table->table, 0, size * sizeof(xmlHashEntry));
- return(table);
- }
- xmlFree(table);
- }
- return(NULL);
-}
-
-/**
- * xmlHashFree:
- * @table: the hash table
- * @f: the deallocator function for items in the hash
- *
- * Free the hash table and its contents. The userdata is
- * deallocated with f if provided.
- */
-void
-xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
-
- if (table == NULL)
- return;
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- iter = table->table[i];
- while (iter) {
- next = iter->next;
- if (iter->name)
- xmlFree(iter->name);
- if (iter->name2)
- xmlFree(iter->name2);
- if (iter->name3)
- xmlFree(iter->name3);
- if (f)
- f(iter->payload, iter->name);
- iter->payload = NULL;
- xmlFree(iter);
- iter = next;
- }
- table->table[i] = NULL;
- }
- xmlFree(table->table);
- }
- xmlFree(table);
-}
-
-/**
- * xmlHashAddEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the name. Duplicate names generate errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata) {
- return(xmlHashAddEntry3(table, name, NULL, NULL, userdata));
-}
-
-/**
- * xmlHashAddEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the (name, name2) tuple. Duplicate tuples generate errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, void *userdata) {
- return(xmlHashAddEntry3(table, name, name2, NULL, userdata));
-}
-
-/**
- * xmlHashUpdateEntry:
- * @table: the hash table
- * @name: the name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the name. Existing entry for this name will be removed
- * and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry(xmlHashTablePtr table, const xmlChar *name,
- void *userdata, xmlHashDeallocator f) {
- return(xmlHashUpdateEntry3(table, name, NULL, NULL, userdata, f));
-}
-
-/**
- * xmlHashUpdateEntry2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the (name, name2) tuple. Existing entry for this tuple will
- * be removed and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, void *userdata,
- xmlHashDeallocator f) {
- return(xmlHashUpdateEntry3(table, name, name2, NULL, userdata, f));
-}
-
-/**
- * xmlHashLookup:
- * @table: the hash table
- * @name: the name of the userdata
- *
- * Find the userdata specified by the name.
- *
- * Returns the a pointer to the userdata
- */
-void *
-xmlHashLookup(xmlHashTablePtr table, const xmlChar *name) {
- return(xmlHashLookup3(table, name, NULL, NULL));
-}
-
-/**
- * xmlHashLookup2:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- *
- * Find the userdata specified by the (name, name2) tuple.
- *
- * Returns the a pointer to the userdata
- */
-void *
-xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2) {
- return(xmlHashLookup3(table, name, name2, NULL));
-}
-
-/**
- * xmlHashAddEntry3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @userdata: a pointer to the userdata
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the tuple (name, name2, name3). Duplicate entries generate
- * errors.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- void *userdata) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr insert;
-
- if ((table == NULL) || name == NULL)
- return(-1);
-
- /*
- * Check for duplicate and insertion location.
- */
- key = xmlHashComputeKey(table, name);
- if (table->table[key] == NULL) {
- insert = NULL;
- } else {
- for (insert = table->table[key]; insert->next != NULL;
- insert = insert->next) {
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3)))
- return(-1);
- }
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3)))
- return(-1);
- }
-
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
- entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
- entry->payload = userdata;
- entry->next = NULL;
-
-
- if (insert == NULL) {
- table->table[key] = entry;
- } else {
- insert->next = entry;
- }
- table->nbElems++;
- return(0);
-}
-
-/**
- * xmlHashUpdateEntry3:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @userdata: a pointer to the userdata
- * @f: the deallocator function for replaced item (if any)
- *
- * Add the userdata to the hash table. This can later be retrieved
- * by using the tuple (name, name2, name3). Existing entry for this tuple
- * will be removed and freed with @f if found.
- *
- * Returns 0 the addition succeeded and -1 in case of error.
- */
-int
-xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- void *userdata, xmlHashDeallocator f) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr insert;
-
- if ((table == NULL) || name == NULL)
- return(-1);
-
- /*
- * Check for duplicate and insertion location.
- */
- key = xmlHashComputeKey(table, name);
- if (table->table[key] == NULL) {
- insert = NULL;
- } else {
- for (insert = table->table[key]; insert->next != NULL;
- insert = insert->next) {
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3))) {
- if (f)
- f(insert->payload, insert->name);
- insert->payload = userdata;
- return(0);
- }
- }
- if ((xmlStrEqual(insert->name, name)) &&
- (xmlStrEqual(insert->name2, name2)) &&
- (xmlStrEqual(insert->name3, name3))) {
- if (f)
- f(insert->payload, insert->name);
- insert->payload = userdata;
- return(0);
- }
- }
-
- entry = xmlMalloc(sizeof(xmlHashEntry));
- if (entry == NULL)
- return(-1);
- entry->name = xmlStrdup(name);
- entry->name2 = xmlStrdup(name2);
- entry->name3 = xmlStrdup(name3);
- entry->payload = userdata;
- entry->next = NULL;
- table->nbElems++;
-
-
- if (insert == NULL) {
- table->table[key] = entry;
- } else {
- insert->next = entry;
- }
- return(0);
-}
-
-/**
- * xmlHashLookup:
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- *
- * Find the userdata specified by the (name, name2, name3) tuple.
- *
- * Returns the a pointer to the userdata
- */
-void *
-xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3) {
- unsigned long key;
- xmlHashEntryPtr entry;
-
- if (table == NULL)
- return(NULL);
- if (name == NULL)
- return(NULL);
- key = xmlHashComputeKey(table, name);
- for (entry = table->table[key]; entry != NULL; entry = entry->next) {
- if ((xmlStrEqual(entry->name, name)) &&
- (xmlStrEqual(entry->name2, name2)) &&
- (xmlStrEqual(entry->name3, name3)))
- return(entry->payload);
- }
- return(NULL);
-}
-
-/**
- * xmlHashScan:
- * @table: the hash table
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash table and applied f to each value.
- */
-void
-xmlHashScan(xmlHashTablePtr table, xmlHashScanner f, void *data) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
-
- if (table == NULL)
- return;
- if (f == NULL)
- return;
-
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- iter = table->table[i];
- while (iter) {
- next = iter->next;
- if (f)
- f(iter->payload, data, iter->name);
- iter = next;
- }
- }
- }
-}
-
-/**
- * xmlHashScan3:
- * @table: the hash table
- * @name: the name of the userdata or NULL
- * @name2: a second name of the userdata or NULL
- * @name3: a third name of the userdata or NULL
- * @f: the scanner function for items in the hash
- * @data: extra data passed to f
- *
- * Scan the hash table and applied f to each value matching
- * (name, name2, name3) tuple. If one of the names is null,
- * the comparison is considered to match.
- */
-void
-xmlHashScan3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- xmlHashScanner f, void *data) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
-
- if (table == NULL)
- return;
- if (f == NULL)
- return;
-
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- iter = table->table[i];
- while (iter) {
- next = iter->next;
- if (((name == NULL) || (xmlStrEqual(name, iter->name))) &&
- ((name2 == NULL) || (xmlStrEqual(name2, iter->name2))) &&
- ((name3 == NULL) || (xmlStrEqual(name3, iter->name3)))) {
- f(iter->payload, data, iter->name);
- }
- iter = next;
- }
- }
- }
-}
-
-/**
- * xmlHashCopy:
- * @table: the hash table
- * @f: the copier function for items in the hash
- *
- * Scan the hash table and applied f to each value.
- *
- * Returns the new table or NULL in case of error.
- */
-xmlHashTablePtr
-xmlHashCopy(xmlHashTablePtr table, xmlHashCopier f) {
- int i;
- xmlHashEntryPtr iter;
- xmlHashEntryPtr next;
- xmlHashTablePtr ret;
-
- if (table == NULL)
- return(NULL);
- if (f == NULL)
- return(NULL);
-
- ret = xmlHashCreate(table->size);
- if (table->table) {
- for(i = 0; i < table->size; i++) {
- iter = table->table[i];
- while (iter) {
- next = iter->next;
- xmlHashAddEntry3(ret, iter->name, iter->name2,
- iter->name3, f(iter->payload, iter->name));
- iter = next;
- }
- }
- }
- ret->nbElems = table->nbElems;
- return(ret);
-}
-
-/**
- * xmlHashSize:
- * @table: the hash table
- *
- * Returns the number of elements in the hash table or
- * -1 in case of error
- */
-int
-xmlHashSize(xmlHashTablePtr table) {
- if (table == NULL)
- return(-1);
- return(table->nbElems);
-}
-
-/**
- * @table: the hash table
- * @name: the name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the (name, name2, name3) tuple and remove
- * it from the hash table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int xmlHashRemoveEntry(xmlHashTablePtr table, const xmlChar *name,
- xmlHashDeallocator f) {
- return(xmlHashRemoveEntry3(table, name, NULL, NULL, f));
-}
-
-/**
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the (name, name2, name3) tuple and remove
- * it from the hash table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int xmlHashRemoveEntry2(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, xmlHashDeallocator f) {
- return(xmlHashRemoveEntry3(table, name, name2, NULL, f));
-}
-
-/**
- * @table: the hash table
- * @name: the name of the userdata
- * @name2: a second name of the userdata
- * @name3: a third name of the userdata
- * @f: the deallocator function for removed item (if any)
- *
- * Find the userdata specified by the (name, name2, name3) tuple and remove
- * it from the hash table. Existing userdata for this tuple will be removed
- * and freed with @f.
- *
- * Returns 0 if the removal succeeded and -1 in case of error or not found.
- */
-int xmlHashRemoveEntry3(xmlHashTablePtr table, const xmlChar *name,
- const xmlChar *name2, const xmlChar *name3,
- xmlHashDeallocator f) {
- unsigned long key;
- xmlHashEntryPtr entry;
- xmlHashEntryPtr prev = NULL;
-
- if (table == NULL || name == NULL)
- return(-1);
-
- key = xmlHashComputeKey(table, name);
- if (table->table[key] == NULL) {
- return(-1);
- } else {
- for (entry = table->table[key]; entry != NULL; entry = entry->next) {
- if (xmlStrEqual(entry->name, name) &&
- xmlStrEqual(entry->name2, name2) &&
- xmlStrEqual(entry->name3, name3)) {
- if(f)
- f(entry->payload, entry->name);
- entry->payload = NULL;
- if(entry->name)
- xmlFree(entry->name);
- if(entry->name2)
- xmlFree(entry->name2);
- if(entry->name3)
- xmlFree(entry->name3);
- if(prev)
- prev->next = entry->next;
- else
- table->table[key] = entry->next;
- xmlFree(entry);
- table->nbElems--;
- return(0);
- }
- prev = entry;
- }
- return(-1);
- }
-} \ No newline at end of file