OCILIB (C Driver for Oracle) 3.9.2
|
00001 /* 00002 +-----------------------------------------------------------------------------------------+ 00003 | | 00004 | OCILIB - C Driver for Oracle | 00005 | | 00006 | (C Wrapper for Oracle OCI) | 00007 | | 00008 | Website : http://www.ocilib.net | 00009 | | 00010 | Copyright (c) 2007-2011 Vincent ROGIER <vince.rogier@ocilib.net> | 00011 | | 00012 +-----------------------------------------------------------------------------------------+ 00013 | | 00014 | This library is free software; you can redistribute it and/or | 00015 | modify it under the terms of the GNU Lesser General Public | 00016 | License as published by the Free Software Foundation; either | 00017 | version 2 of the License, or (at your option) any later version. | 00018 | | 00019 | This library is distributed in the hope that it will be useful, | 00020 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 00021 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 00022 | Lesser General Public License for more details. | 00023 | | 00024 | You should have received a copy of the GNU Lesser General Public | 00025 | License along with this library; if not, write to the Free | 00026 | Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 00027 | | 00028 +-----------------------------------------------------------------------------------------+ 00029 */ 00030 00031 /* --------------------------------------------------------------------------------------------- * 00032 * $Id: hash.c, v 3.9.2 2011-07-13 00:00 Vincent Rogier $ 00033 * --------------------------------------------------------------------------------------------- */ 00034 00035 #include "ocilib_internal.h" 00036 00037 /* ********************************************************************************************* * 00038 * PRIVATE FUNCTIONS 00039 * ********************************************************************************************* */ 00040 00041 /* --------------------------------------------------------------------------------------------- * 00042 * OCI_HashCompute 00043 * --------------------------------------------------------------------------------------------- */ 00044 00045 unsigned int OCI_HashCompute 00046 ( 00047 OCI_HashTable *table, 00048 const mtext *str 00049 ) 00050 { 00051 unsigned int h; 00052 mtext *p; 00053 mtext c; 00054 00055 OCI_CHECK(table == NULL, 0); 00056 OCI_CHECK(str == NULL, 0); 00057 00058 for(h = 0, p = (mtext *) str; (*p) != 0; p++) 00059 { 00060 c = *p; 00061 00062 h = 31 * h + mttoupper(c); 00063 } 00064 00065 return (h % table->size); 00066 } 00067 00068 /* ********************************************************************************************* * 00069 * PUBLIC FUNCTIONS 00070 * ********************************************************************************************* */ 00071 00072 /* --------------------------------------------------------------------------------------------- * 00073 * OCI_HashCreate 00074 * --------------------------------------------------------------------------------------------- */ 00075 00076 OCI_HashTable * OCI_API OCI_HashCreate 00077 ( 00078 unsigned int size, 00079 unsigned int type 00080 ) 00081 { 00082 OCI_HashTable *table = NULL; 00083 boolean res = TRUE; 00084 00085 /* allocate table structure */ 00086 00087 table = (OCI_HashTable *) OCI_MemAlloc(OCI_IPC_HASHTABLE, sizeof(*table), (size_t) 1, TRUE); 00088 00089 /* set up attributes and allocate internal array of hash entry pointers */ 00090 00091 if (table != NULL) 00092 { 00093 table->size = size; 00094 table->type = type; 00095 table->count = 0; 00096 00097 table->items = (OCI_HashEntry **) OCI_MemAlloc(OCI_IPC_HASHENTRY_ARRAY, 00098 sizeof(*table->items), 00099 (size_t) size, TRUE); 00100 res = (table->items != NULL); 00101 } 00102 else 00103 { 00104 res = FALSE; 00105 } 00106 00107 if (res == FALSE) 00108 { 00109 OCI_HashFree(table); 00110 } 00111 00112 OCI_RESULT(res); 00113 00114 return table; 00115 } 00116 00117 /* --------------------------------------------------------------------------------------------- * 00118 * OCI_HashFree 00119 * --------------------------------------------------------------------------------------------- */ 00120 00121 boolean OCI_API OCI_HashFree 00122 ( 00123 OCI_HashTable *table 00124 ) 00125 { 00126 unsigned int i; 00127 00128 OCI_HashEntry *e1, *e2; 00129 OCI_HashValue *v1, *v2; 00130 00131 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE); 00132 00133 for (i = 0; i < table->size; i++) 00134 { 00135 e1 = table->items[i]; 00136 00137 while (e1 != NULL) 00138 { 00139 e2 = e1; 00140 e1 = e1->next; 00141 00142 v1 = e2->values; 00143 00144 while (v1 != NULL) 00145 { 00146 v2 = v1; 00147 v1 = v1->next; 00148 00149 if (table->type == OCI_HASH_STRING) 00150 { 00151 OCI_FREE(v2->value.p_mtext); 00152 } 00153 00154 OCI_FREE(v2); 00155 } 00156 00157 if (e2->key) 00158 { 00159 OCI_FREE(e2->key); 00160 } 00161 00162 if (e2) 00163 { 00164 OCI_FREE(e2); 00165 } 00166 } 00167 } 00168 00169 if (table->items != NULL) 00170 { 00171 OCI_FREE(table->items); 00172 } 00173 00174 OCI_FREE(table); 00175 00176 OCI_RESULT(TRUE); 00177 00178 return TRUE; 00179 } 00180 00181 /* --------------------------------------------------------------------------------------------- * 00182 * OCI_HashGetSize 00183 * --------------------------------------------------------------------------------------------- */ 00184 00185 unsigned int OCI_API OCI_HashGetSize 00186 ( 00187 OCI_HashTable *table 00188 ) 00189 { 00190 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0); 00191 00192 OCI_RESULT(TRUE); 00193 00194 return table->size; 00195 } 00196 00197 /* --------------------------------------------------------------------------------------------- * 00198 * OCI_HashGetType 00199 * --------------------------------------------------------------------------------------------- */ 00200 00201 unsigned int OCI_API OCI_HashGetType 00202 ( 00203 OCI_HashTable *table 00204 ) 00205 { 00206 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, OCI_UNKNOWN); 00207 00208 OCI_RESULT(TRUE); 00209 00210 return table->type; 00211 } 00212 00213 /* --------------------------------------------------------------------------------------------- * 00214 * OCI_HashGetValue 00215 * --------------------------------------------------------------------------------------------- */ 00216 00217 OCI_HashValue * OCI_API OCI_HashGetValue 00218 ( 00219 OCI_HashTable *table, 00220 const mtext *key 00221 ) 00222 { 00223 OCI_HashEntry *e = NULL; 00224 OCI_HashValue *v = NULL; 00225 00226 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL); 00227 00228 e = OCI_HashLookup(table, key, FALSE); 00229 00230 if (e != NULL) 00231 { 00232 v = e->values; 00233 } 00234 00235 OCI_RESULT(v != NULL); 00236 00237 return v; 00238 } 00239 00240 /* --------------------------------------------------------------------------------------------- * 00241 * OCI_HashGetEntry 00242 * --------------------------------------------------------------------------------------------- */ 00243 00244 OCI_HashEntry * OCI_API OCI_HashGetEntry 00245 ( 00246 OCI_HashTable *table, 00247 unsigned int index 00248 ) 00249 { 00250 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL); 00251 OCI_CHECK_BOUND(NULL, index, 1, table->size, NULL); 00252 00253 OCI_RESULT(TRUE); 00254 00255 return table->items[index]; 00256 } 00257 00258 /* --------------------------------------------------------------------------------------------- * 00259 * OCI_HashGetString 00260 * --------------------------------------------------------------------------------------------- */ 00261 00262 const mtext * OCI_API OCI_HashGetString 00263 ( 00264 OCI_HashTable *table, 00265 const mtext *key 00266 ) 00267 { 00268 OCI_HashValue *v = NULL; 00269 const mtext *value = NULL; 00270 00271 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL); 00272 OCI_CHECK(table->type != OCI_HASH_STRING, NULL); 00273 00274 v = OCI_HashGetValue(table, key); 00275 00276 if (v != NULL) 00277 { 00278 value = v->value.p_mtext; 00279 } 00280 00281 OCI_RESULT(v != NULL); 00282 00283 return value; 00284 } 00285 00286 /* --------------------------------------------------------------------------------------------- * 00287 * OCI_HashGetInt 00288 * --------------------------------------------------------------------------------------------- */ 00289 00290 int OCI_API OCI_HashGetInt 00291 ( 00292 OCI_HashTable *table, 00293 const mtext *key 00294 ) 00295 { 00296 OCI_HashValue *v = NULL; 00297 int value = 0; 00298 00299 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, 0); 00300 OCI_CHECK(table->type != OCI_HASH_INTEGER, 0); 00301 00302 v = OCI_HashGetValue(table, key); 00303 00304 if (v != NULL) 00305 { 00306 value = v->value.num; 00307 } 00308 00309 OCI_RESULT(v != NULL); 00310 00311 return value; 00312 } 00313 00314 /* --------------------------------------------------------------------------------------------- * 00315 * OCI_HashGetPointer 00316 * --------------------------------------------------------------------------------------------- */ 00317 00318 void * OCI_API OCI_HashGetPointer 00319 ( 00320 OCI_HashTable *table, 00321 const mtext *key 00322 ) 00323 { 00324 OCI_HashValue *v = NULL; 00325 void *value = NULL; 00326 00327 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL); 00328 OCI_CHECK(table->type != OCI_HASH_POINTER, NULL); 00329 00330 v = OCI_HashGetValue(table, key); 00331 00332 if (v != NULL) 00333 { 00334 value = v->value.p_void; 00335 } 00336 00337 OCI_RESULT(v != NULL); 00338 00339 return value; 00340 } 00341 00342 /* --------------------------------------------------------------------------------------------- * 00343 * OCI_HashAdd 00344 * --------------------------------------------------------------------------------------------- */ 00345 00346 boolean OCI_HashAdd 00347 ( 00348 OCI_HashTable *table, 00349 const mtext *key, 00350 OCI_Variant value, 00351 unsigned int type 00352 ) 00353 { 00354 OCI_HashEntry * e = NULL; 00355 OCI_HashValue * v = NULL, *v1 = NULL, *v2 = NULL; 00356 00357 OCI_CHECK(table == NULL, FALSE); 00358 OCI_CHECK(key == NULL, FALSE); 00359 OCI_CHECK(table->type != type, FALSE); 00360 00361 e = OCI_HashLookup(table, key, TRUE); 00362 00363 if (e != NULL) 00364 { 00365 v = (OCI_HashValue *) OCI_MemAlloc(OCI_IPC_HASHVALUE, sizeof(*v), (size_t) 1, TRUE); 00366 00367 if (v != NULL) 00368 { 00369 if (table->type == OCI_HASH_STRING && value.p_mtext != NULL) 00370 { 00371 v->value.p_mtext = mtsdup(value.p_mtext); 00372 } 00373 else if (table->type == OCI_HASH_INTEGER) 00374 { 00375 v->value.num = value.num; 00376 } 00377 else 00378 { 00379 v->value.p_void = value.p_void; 00380 } 00381 00382 v1 = v2 = e->values; 00383 00384 while (v1 != NULL) 00385 { 00386 v2 = v1; 00387 v1 = v1->next; 00388 } 00389 00390 if (v2 != NULL) 00391 { 00392 v2->next = v; 00393 } 00394 else 00395 { 00396 e->values = v; 00397 } 00398 } 00399 } 00400 00401 return (v != NULL); 00402 } 00403 00404 /* --------------------------------------------------------------------------------------------- * 00405 * OCI_HashAddString 00406 * --------------------------------------------------------------------------------------------- */ 00407 00408 boolean OCI_API OCI_HashAddString 00409 ( 00410 OCI_HashTable *table, 00411 const mtext *key, 00412 const mtext *value 00413 ) 00414 { 00415 boolean res = TRUE; 00416 OCI_Variant v; 00417 00418 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE); 00419 00420 v.p_mtext = (mtext *) value; 00421 00422 res = OCI_HashAdd(table, key, v, OCI_HASH_STRING); 00423 00424 OCI_RESULT(res); 00425 00426 return res; 00427 } 00428 00429 /* --------------------------------------------------------------------------------------------- * 00430 * OCI_HashAddInt 00431 * --------------------------------------------------------------------------------------------- */ 00432 00433 boolean OCI_API OCI_HashAddInt 00434 ( 00435 OCI_HashTable *table, 00436 const mtext *key, 00437 int value 00438 ) 00439 { 00440 boolean res = TRUE; 00441 OCI_Variant v; 00442 00443 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE); 00444 00445 v.num = value; 00446 00447 res = OCI_HashAdd(table, key, v, OCI_HASH_INTEGER); 00448 00449 OCI_RESULT(res); 00450 00451 return res; 00452 } 00453 00454 /* --------------------------------------------------------------------------------------------- * 00455 * OCI_HashAddPointer 00456 * --------------------------------------------------------------------------------------------- */ 00457 00458 boolean OCI_API OCI_HashAddPointer 00459 ( 00460 OCI_HashTable *table, 00461 const mtext *key, 00462 void *value 00463 ) 00464 { 00465 boolean res = TRUE; 00466 OCI_Variant v; 00467 00468 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, FALSE); 00469 00470 v.p_void = value; 00471 00472 res = OCI_HashAdd(table, key, v, OCI_HASH_POINTER); 00473 00474 OCI_RESULT(res); 00475 00476 return res; 00477 } 00478 00479 /* --------------------------------------------------------------------------------------------- * 00480 * OCI_HashLookup 00481 * --------------------------------------------------------------------------------------------- */ 00482 00483 OCI_HashEntry * OCI_API OCI_HashLookup 00484 ( 00485 OCI_HashTable *table, 00486 const mtext *key, 00487 boolean create 00488 ) 00489 { 00490 OCI_HashEntry *e = NULL, *e1 = NULL, *e2 = NULL; 00491 unsigned int i; 00492 00493 OCI_CHECK_PTR(OCI_IPC_HASHTABLE, table, NULL); 00494 OCI_CHECK_PTR(OCI_IPC_STRING, key, NULL); 00495 00496 i = OCI_HashCompute(table, key); 00497 00498 if (i < table->size) 00499 { 00500 for(e = table->items[i]; e != NULL; e = e->next) 00501 { 00502 if (mtscasecmp(e->key, key) == 0) 00503 { 00504 break; 00505 } 00506 } 00507 00508 if ((e == NULL) && (create == TRUE)) 00509 { 00510 e = (OCI_HashEntry *) OCI_MemAlloc(OCI_IPC_HASHENTRY, sizeof(*e), (size_t) 1, TRUE); 00511 00512 if (e != NULL) 00513 { 00514 e->key = mtsdup(key); 00515 00516 e1 = e2 = table->items[i]; 00517 00518 while (e1 != NULL) 00519 { 00520 e2 = e1; 00521 e1 = e1->next; 00522 } 00523 00524 if (e2 != NULL) 00525 { 00526 e2->next = e; 00527 } 00528 else 00529 { 00530 table->items[i] = e; 00531 } 00532 } 00533 } 00534 } 00535 00536 OCI_RESULT(e != NULL); 00537 00538 return e; 00539 }