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