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
00032
00033
00034
00035 #include "ocilib_internal.h"
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 unsigned int OCI_HashCompute(OCI_HashTable *table, const mtext *str)
00046 {
00047 unsigned int h;
00048 mtext *p;
00049 mtext c;
00050
00051 OCI_CHECK(table == NULL, 0);
00052 OCI_CHECK(str == NULL, 0);
00053
00054 for(h = 0, p = (mtext *) str; (*p) != 0; p++)
00055 {
00056 c = *p;
00057
00058 h = 31 * h + mttoupper(c);
00059 }
00060
00061 return (h % table->size);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 OCI_HashTable * OCI_API OCI_HashCreate(unsigned int size, unsigned int type)
00073 {
00074 OCI_HashTable *table = NULL;
00075 boolean res = TRUE;
00076
00077
00078
00079 table = (OCI_HashTable *) OCI_MemAlloc(OCI_IPC_HASHTABLE, sizeof(*table), 1, TRUE);
00080
00081
00082
00083 if (table != NULL)
00084 {
00085 table->size = size;
00086 table->type = type;
00087 table->count = 0;
00088
00089 table->items = (OCI_HashEntry **) OCI_MemAlloc(OCI_IPC_HASHENTRY_ARRAY,
00090 sizeof(*table->items),
00091 size, TRUE);
00092 res = (table->items != NULL);
00093 }
00094 else
00095 res = FALSE;
00096
00097 if (res == FALSE)
00098 OCI_HashFree(table);
00099
00100 OCI_RESULT(res);
00101
00102 return table;
00103 }
00104
00105
00106
00107
00108
00109 boolean OCI_API OCI_HashFree(OCI_HashTable *table)
00110 {
00111 unsigned int i;
00112
00113 OCI_HashEntry *e1, *e2;
00114 OCI_HashValue *v1, *v2;
00115
00116 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00117
00118 for (i = 0; i < table->size; i++)
00119 {
00120 e1 = table->items[i];
00121
00122 while (e1 != NULL)
00123 {
00124 e2 = e1;
00125 e1 = e1->next;
00126
00127 v1 = e2->values;
00128
00129 while (v1 != NULL)
00130 {
00131 v2 = v1;
00132 v1 = v1->next;
00133
00134 if (table->type == OCI_HASH_STRING)
00135 OCI_FREE(v2->value.p_mtext);
00136
00137 OCI_FREE(v2);
00138 }
00139
00140 if (e2->key)
00141 OCI_FREE(e2->key);
00142
00143 if (e2)
00144 OCI_FREE(e2);
00145 }
00146 }
00147
00148 if (table->items != NULL)
00149 {
00150 OCI_FREE(table->items);
00151 }
00152
00153 OCI_FREE(table);
00154
00155 OCI_RESULT(TRUE);
00156
00157 return TRUE;
00158 }
00159
00160
00161
00162
00163
00164 unsigned int OCI_API OCI_HashGetSize(OCI_HashTable *table)
00165 {
00166 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0);
00167
00168 OCI_RESULT(TRUE);
00169
00170 return table->size;
00171 }
00172
00173
00174
00175
00176
00177 unsigned int OCI_API OCI_HashGetType(OCI_HashTable *table)
00178 {
00179 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, OCI_UNKNOWN);
00180
00181 OCI_RESULT(TRUE);
00182
00183 return table->type;
00184 }
00185
00186
00187
00188
00189
00190 OCI_HashValue * OCI_API OCI_HashGetValue(OCI_HashTable *table, const mtext *key)
00191 {
00192 OCI_HashEntry *e = NULL;
00193 OCI_HashValue *v = NULL;
00194
00195 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00196
00197 e = OCI_HashLookup(table, key, FALSE);
00198
00199 if (e != NULL)
00200 v = e->values;
00201
00202 OCI_RESULT(v != NULL);
00203
00204 return v;
00205 }
00206
00207
00208
00209
00210
00211 OCI_HashEntry * OCI_API OCI_HashGetEntry(OCI_HashTable *table, unsigned int index)
00212 {
00213 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00214 OCI_CHECK_BOUND(NULL, index, 1, table->size, NULL);
00215
00216 OCI_RESULT(TRUE);
00217
00218 return table->items[index];
00219 }
00220
00221
00222
00223
00224
00225 const mtext * OCI_API OCI_HashGetString(OCI_HashTable *table, const mtext *key)
00226 {
00227 OCI_HashValue *v = NULL;
00228 const mtext *value = NULL;
00229
00230 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00231 OCI_CHECK(table->type != OCI_HASH_STRING, NULL);
00232
00233 v = OCI_HashGetValue(table, key);
00234
00235 if (v != NULL)
00236 {
00237 value = v->value.p_mtext;
00238 }
00239
00240 OCI_RESULT(v != NULL);
00241
00242 return value;
00243 }
00244
00245
00246
00247
00248
00249 int OCI_API OCI_HashGetInt(OCI_HashTable *table, const mtext *key)
00250 {
00251 OCI_HashValue *v = NULL;
00252 int value = 0;
00253
00254 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0);
00255 OCI_CHECK(table->type != OCI_HASH_INTEGER, 0);
00256
00257 v = OCI_HashGetValue(table, key);
00258
00259 if (v != NULL)
00260 {
00261 value = v->value.num;
00262 }
00263
00264 OCI_RESULT(v != NULL);
00265
00266 return value;
00267 }
00268
00269
00270
00271
00272
00273 void * OCI_API OCI_HashGetPointer(OCI_HashTable *table, const mtext *key)
00274 {
00275 OCI_HashValue *v = NULL;
00276 void *value = NULL;
00277
00278 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00279 OCI_CHECK(table->type != OCI_HASH_POINTER, NULL);
00280
00281 v = OCI_HashGetValue(table, key);
00282
00283 if (v != NULL)
00284 {
00285 value = v->value.p_void;
00286 }
00287
00288 OCI_RESULT(v != NULL);
00289
00290 return value;
00291 }
00292
00293
00294
00295
00296
00297 boolean OCI_HashAdd(OCI_HashTable *table, const mtext *key, OCI_Variant value,
00298 unsigned int type)
00299 {
00300 OCI_HashEntry * e = NULL;
00301 OCI_HashValue * v = NULL, *v1 = NULL, *v2 = NULL;
00302
00303 OCI_CHECK(table == NULL, FALSE);
00304 OCI_CHECK(key == NULL, FALSE);
00305 OCI_CHECK(table->type != type, FALSE);
00306
00307 e = OCI_HashLookup(table, key, TRUE);
00308
00309 if (e != NULL)
00310 {
00311 v = (OCI_HashValue *) OCI_MemAlloc(OCI_IPC_HASHVALUE, sizeof(*v), 1, TRUE);
00312
00313 if (v != NULL)
00314 {
00315 if (table->type == OCI_HASH_STRING && value.p_mtext != NULL)
00316 {
00317 v->value.p_mtext = mtsdup(value.p_mtext);
00318 }
00319 else if (table->type == OCI_HASH_INTEGER)
00320 {
00321 v->value.num = value.num;
00322 }
00323 else
00324 v->value.p_void = value.p_void;
00325
00326 v1 = v2 = e->values;
00327
00328 while (v1 != NULL)
00329 {
00330 v2 = v1;
00331 v1 = v1->next;
00332 }
00333
00334 if (v2 != NULL)
00335 v2->next = v;
00336 else
00337 e->values = v;
00338 }
00339 }
00340
00341 return (v != NULL);
00342 }
00343
00344
00345
00346
00347
00348 boolean OCI_API OCI_HashAddString(OCI_HashTable *table, const mtext *key,
00349 const mtext *value)
00350 {
00351 boolean res = TRUE;
00352 OCI_Variant v;
00353
00354 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00355
00356 v.p_mtext = (mtext *) value;
00357
00358 res = OCI_HashAdd(table, key, v, OCI_HASH_STRING);
00359
00360 OCI_RESULT(res);
00361
00362 return res;
00363 }
00364
00365
00366
00367
00368
00369 boolean OCI_API OCI_HashAddInt(OCI_HashTable *table, const mtext *key,
00370 int value)
00371 {
00372 boolean res = TRUE;
00373 OCI_Variant v;
00374
00375 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00376
00377 v.num = value;
00378
00379 res = OCI_HashAdd(table, key, v, OCI_HASH_INTEGER);
00380
00381 OCI_RESULT(res);
00382
00383 return res;
00384 }
00385
00386
00387
00388
00389
00390 boolean OCI_API OCI_HashAddPointer(OCI_HashTable *table, const mtext *key,
00391 void *value)
00392 {
00393 boolean res = TRUE;
00394 OCI_Variant v;
00395
00396 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE);
00397
00398 v.p_void = value;
00399
00400 res = OCI_HashAdd(table, key, v, OCI_HASH_POINTER);
00401
00402 OCI_RESULT(res);
00403
00404 return res;
00405 }
00406
00407
00408
00409
00410
00411 OCI_HashEntry * OCI_API OCI_HashLookup(OCI_HashTable *table, const mtext *key,
00412 boolean create)
00413 {
00414 OCI_HashEntry *e = NULL, *e1 = NULL, *e2 = NULL;
00415 unsigned int i;
00416
00417 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL);
00418 OCI_CHECK_PTR(OCI_IPC_STRING, key, NULL);
00419
00420 i = OCI_HashCompute(table, key);
00421
00422 if (i < table->size)
00423 {
00424 for(e = table->items[i]; e != NULL; e = e->next)
00425 {
00426 if (mtscasecmp(e->key, key) == 0)
00427 break;
00428 }
00429
00430 if ((e == NULL) && (create == TRUE))
00431 {
00432 e = (OCI_HashEntry *) OCI_MemAlloc(OCI_IPC_HASHENTRY, sizeof(*e), 1, TRUE);
00433
00434 if (e != NULL)
00435 {
00436 e->key = mtsdup(key);
00437
00438 e1 = e2 = table->items[i];
00439
00440 while (e1 != NULL)
00441 {
00442 e2 = e1;
00443 e1 = e1->next;
00444 }
00445
00446 if (e2 != NULL)
00447 e2->next = e;
00448 else
00449 table->items[i] = e;
00450 }
00451 }
00452 }
00453
00454 OCI_RESULT(e != NULL);
00455
00456 return e;
00457 }