00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "xmldef.h"
00032
00033 #ifdef XML_UNICODE_WCHAR_T
00034 #ifndef XML_UNICODE
00035 #define XML_UNICODE
00036 #endif
00037 #endif
00038
00039 #include "hashtable.h"
00040
00041 #define INIT_SIZE 64
00042
00043 static
00044 int keyeq(KEY s1, KEY s2)
00045 {
00046 for (; *s1 == *s2; s1++, s2++)
00047 if (*s1 == 0)
00048 return 1;
00049 return 0;
00050 }
00051
00052 static
00053 unsigned long hash(KEY s)
00054 {
00055 unsigned long h = 0;
00056 while (*s)
00057 h = (h << 5) + h + (unsigned char)*s++;
00058 return h;
00059 }
00060
00061 NAMED *lookup(HASH_TABLE *table, KEY name, size_t createSize)
00062 {
00063 size_t i;
00064 if (table->size == 0) {
00065 if (!createSize)
00066 return 0;
00067 table->v = calloc(INIT_SIZE, sizeof(NAMED *));
00068 if (!table->v)
00069 return 0;
00070 table->size = INIT_SIZE;
00071 table->usedLim = INIT_SIZE / 2;
00072 i = hash(name) & (table->size - 1);
00073 }
00074 else {
00075 unsigned long h = hash(name);
00076 for (i = h & (table->size - 1);
00077 table->v[i];
00078 i == 0 ? i = table->size - 1 : --i) {
00079 if (keyeq(name, table->v[i]->name))
00080 return table->v[i];
00081 }
00082 if (!createSize)
00083 return 0;
00084 if (table->used == table->usedLim) {
00085
00086 size_t newSize = table->size * 2;
00087 NAMED **newV = calloc(newSize, sizeof(NAMED *));
00088 if (!newV)
00089 return 0;
00090 for (i = 0; i < table->size; i++)
00091 if (table->v[i]) {
00092 size_t j;
00093 for (j = hash(table->v[i]->name) & (newSize - 1);
00094 newV[j];
00095 j == 0 ? j = newSize - 1 : --j)
00096 ;
00097 newV[j] = table->v[i];
00098 }
00099 free(table->v);
00100 table->v = newV;
00101 table->size = newSize;
00102 table->usedLim = newSize/2;
00103 for (i = h & (table->size - 1);
00104 table->v[i];
00105 i == 0 ? i = table->size - 1 : --i)
00106 ;
00107 }
00108 }
00109 table->v[i] = calloc(1, createSize);
00110 if (!table->v[i])
00111 return 0;
00112 table->v[i]->name = name;
00113 (table->used)++;
00114 return table->v[i];
00115 }
00116
00117 void hashTableDestroy(HASH_TABLE *table)
00118 {
00119 size_t i;
00120 for (i = 0; i < table->size; i++) {
00121 NAMED *p = table->v[i];
00122 if (p)
00123 free(p);
00124 }
00125 free(table->v);
00126 }
00127
00128 void hashTableInit(HASH_TABLE *p)
00129 {
00130 p->size = 0;
00131 p->usedLim = 0;
00132 p->used = 0;
00133 p->v = 0;
00134 }
00135
00136 void hashTableIterInit(HASH_TABLE_ITER *iter, const HASH_TABLE *table)
00137 {
00138 iter->p = table->v;
00139 iter->end = iter->p + table->size;
00140 }
00141
00142 NAMED *hashTableIterNext(HASH_TABLE_ITER *iter)
00143 {
00144 while (iter->p != iter->end) {
00145 NAMED *tem = *(iter->p)++;
00146 if (tem)
00147 return tem;
00148 }
00149 return 0;
00150 }
00151