00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if defined(sccs)
00022 static const char *rcsid = "$Header: /export/cvs-gridlab/wp-1/Codes/GATEngine/C-reference/src/GATTable.c,v 1.53 2004/04/02 12:31:58 hartmutkaiser Exp $";
00023 #endif
00024
00025
00026
00027 #include <stdlib.h>
00028 #include <stdio.h>
00029 #include <string.h>
00030
00031
00032 #include "GATInternal.h"
00033 #include "GATType.h"
00034 #include "GATTable.h"
00035 #include "GATTableAnyKey.h"
00036 #include "GATErrors.h"
00037 #include "GATXdsWrapper.h"
00038 #include "GATUtil.h"
00039
00040
00041
00042
00043
00044 typedef struct Hash_String_S
00045 {
00046 char *data;
00047 }
00048 *Hash_String;
00049
00050 typedef struct Hash_float_S
00051 {
00052 float data;
00053 }
00054 *Hash_float;
00055
00056 typedef struct Hash_int_S
00057 {
00058 int32_t data;
00059 }
00060 *Hash_int;
00061
00062 typedef struct Hash_short_S
00063 {
00064 int16_t data;
00065 }
00066 *Hash_short;
00067
00068 typedef struct Hash_double_S
00069 {
00070 double data;
00071 }
00072 *Hash_double;
00073
00074 typedef struct Hash_GATObject_S
00075 {
00076 GATObject data;
00077 }
00078 *Hash_GATObject;
00079
00080 typedef struct Hash_Element_S
00081 {
00082 GATType type;
00083 void *value;
00084 char *key;
00085 unsigned long hash;
00086 struct Hash_Element_S *next;
00087 }*Hash_Element;
00088
00089
00090 GATOBJECT_DEFINE_VTABLE(GATTable);
00091 GATSERIALISABLE_DEFINE_VTABLE(GATTable);
00092
00093 struct GATTable_S
00094 {
00095
00096 GATTable_vtable *GATObject__vtable;
00097
00098 GATTable_ISerialisable_vtable *GATSerialisable__vtable;
00099
00100 GATTable_GetKeySizeProc get_key_size;
00101 GATTable_EqualKeysProc equal_keys;
00102 GATTable_CloneKeyProc clone_key;
00103 GATTable_GetHashProc get_hash;
00104 GATTable_DestroyKeyProc destroy_key;
00105
00106
00107 GATuint32 table_length;
00108 Hash_Element *table;
00109 GATuint32 element_count;
00110 GATuint32 load_limit;
00111 GATBool isdirty;
00112 };
00113
00114
00115 GATOBJECT_DEFINE_CONVERTERS(GATTable)
00116
00117
00118 static GATBool
00119 GATTable_Internal_Equal_Keys(GATTable_const table, void const *key1,
00120 const void *key2);
00121 static unsigned long
00122 GATTable_Internal_Hash_sdbm(GATTable_const table, void const *key);
00123 static GATuint32
00124 GATTable_Internal_Get_KeySize(GATTable_const table, void const *key);
00125 static GATResult
00126 GATTable_Internal_CloneKey(GATTable_const table, void const *src, void **dest);
00127 static void
00128 GATTable_Internal_Destroy_Key(GATTable_const table, void **key);
00129
00130 static GATuint32
00131 GATTable_Internal_Index(GATuint32 table_length, unsigned long hash_value);
00132 static GATResult
00133 GATTable_Internal_Expand(GATTable table);
00134 static GATResult
00135 GATTable_Internal_Add(GATTable table, const void *key, void *value,
00136 GATType type);
00137
00138
00139 static GATResult
00140 GATTable_SerialiseItems(GATTable_const list, GATXds xds,
00141 GATXdsScope flag, void **buffer, size_t *buffer_size, GATBool clear_dirty);
00142
00143 static GATResult
00144 GATTable_DeSerialise_Create(GATXds xds, GATuint32 table_length,
00145 GATuint32 element_count, GATTable *table);
00146
00147
00148 static GATBool
00149 GATTable_Internal_Equal_Keys_String(GATTable_const table, void const *key1,
00150 const void *key2);
00151 static GATuint32
00152 GATTable_Internal_Get_KeySize_String(GATTable_const table, void const *key);
00153 static GATResult
00154 GATTable_Internal_CloneKey_String(GATTable_const table, void const *src,
00155 void **dest);
00156
00157
00158 static GATTable_vtable GATTable__vtable = {
00159 GATTable_GetType,
00160 GATTable_Destroy,
00161 GATTable_Equals,
00162 GATTable_Clone,
00163 GATTable_GetInterface,
00164 NULL
00165 };
00166
00167 static GATTable_ISerialisable_vtable GATTable_ISerialisable__vtable = {
00168 GATTable_Serialise,
00169 GATTable_DeSerialise,
00170 GATTable_GetIsDirty
00171 };
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 GATResult GATTable_Register_GATSerialisable()
00183 {
00184 return GATObject_Register_GATSerialisable(GATType_GATTable,
00185 &GATTable_ISerialisable__vtable);
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 GATTable GATTable_Create(void)
00198 {
00199 return GATTable_CreateAnyKey(GATTable_Internal_Get_KeySize_String,
00200 GATTable_Internal_Equal_Keys_String, GATTable_Internal_CloneKey_String,
00201 GATTable_Default_Hash_sdbm, GATTable_Default_Destroy_Key);
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 GATTable GATTable_CreateAnyKey(GATTable_GetKeySizeProc get_keysize,
00227 GATTable_EqualKeysProc equalkeys, GATTable_CloneKeyProc copykey,
00228 GATTable_GetHashProc get_hash, GATTable_DestroyKeyProc destroy_key)
00229 {
00230 GATTable table;
00231 GATuint32 i;
00232 GATuint32 size = 1u;
00233 GATuint32 minsize = 16;
00234 float const maxloadfactor = 0.75f;
00235
00236
00237 while (size < minsize)
00238 size <<= 1;
00239
00240 if ((table = (GATTable) malloc(sizeof (struct GATTable_S))) != NULL)
00241 {
00242 memset(table, 0, sizeof(struct GATTable_S));
00243 table->GATObject__vtable = &GATTable__vtable;
00244 table->GATSerialisable__vtable = &GATTable_ISerialisable__vtable;
00245
00246 table->get_key_size = get_keysize;
00247 table->equal_keys = (NULL != equalkeys) ? equalkeys : GATTable_Default_Equal_Keys;
00248 table->clone_key = (NULL != copykey) ? copykey : GATTable_Default_Clone_Key;
00249 table->get_hash = (NULL != get_hash) ? get_hash : GATTable_Default_Hash_sdbm;
00250 table->destroy_key = (NULL != destroy_key) ? destroy_key : GATTable_Default_Destroy_Key;
00251
00252 if ((table->table
00253 = (Hash_Element *) malloc(sizeof (Hash_Element) * size)) == NULL)
00254 {
00255 free(table);
00256 table = NULL;
00257 }
00258 else
00259 {
00260
00261 for (i = 0; i < size; i++)
00262 {
00263 table->table[i] = NULL;
00264 }
00265
00266 table->table_length = size;
00267 table->element_count = 0;
00268
00269 table->load_limit = (GATuint32) ((float) size * maxloadfactor);
00270 }
00271 }
00272 return table;
00273 }
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285 GATType GATTable_GetType(GATTable_const table)
00286 {
00287 GAT_UNUSED_PARAMETER(table);
00288 return GATType_GATTable;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302 GATResult GATTable_Clone(GATTable_const table, GATTable *new_table)
00303 {
00304 GATTable clone;
00305 GATuint32 i;
00306 Hash_Element element;
00307 GATResult result;
00308
00309 result = GAT_SUCCESS;
00310 *new_table = NULL;
00311
00312 if ((clone = (GATTable) malloc(sizeof (struct GATTable_S))) != NULL)
00313 {
00314 memset(clone, 0, sizeof(struct GATTable_S));
00315 clone->GATObject__vtable = &GATTable__vtable;
00316 clone->GATSerialisable__vtable = &GATTable_ISerialisable__vtable;
00317 clone->equal_keys = table->equal_keys;
00318 clone->get_hash = table->get_hash;
00319 clone->clone_key = table->clone_key;
00320 clone->get_key_size = table->get_key_size;
00321 clone->destroy_key = table->destroy_key;
00322
00323 if ((clone->table
00324 = (Hash_Element *) malloc(sizeof (Hash_Element) * table->table_length)) != NULL)
00325 {
00326 memset(clone->table, 0, sizeof (Hash_Element) * table->table_length);
00327 clone->table_length = table->table_length;
00328 clone->element_count = 0;
00329 clone->load_limit = table->load_limit;
00330
00331 for(i=0; i<table->table_length;i++)
00332 {
00333 for(element = table->table[i];;)
00334 {
00335 if(element == NULL)
00336 {
00337 break;
00338 }
00339 else
00340 switch(element->type)
00341 {
00342 case GATType_GATint32:
00343 result = GATTable_Add_int(clone, element->key, ((Hash_int)element->value)->data);
00344 break;
00345 case GATType_GATint16:
00346 result = GATTable_Add_short(clone, element->key, ((Hash_short)element->value)->data);
00347 break;
00348 case GATType_GATdouble64:
00349 result = GATTable_Add_double(clone, element->key, ((Hash_double)element->value)->data);
00350 break;
00351 case GATType_String:
00352 result = GATTable_Add_String(clone, element->key, ((Hash_String)element->value)->data);
00353 break;
00354 case GATType_GATfloat32:
00355 result = GATTable_Add_float(clone, element->key, ((Hash_float)element->value)->data);
00356 break;
00357 default:
00358 if (GATType_GATObject & element->type)
00359 {
00360 result = GATTable_Add_GATObject(clone, element->key,
00361 ((Hash_GATObject) element->value)->data);
00362 }
00363 else
00364 {
00365 result = GAT_KEY_TYPE_ERROR;
00366 }
00367 break;
00368 }
00369
00370 if(result != GAT_SUCCESS)
00371 {
00372 GATTable_Destroy(&clone);
00373 clone = NULL;
00374 break;
00375 }
00376 else
00377 {
00378 element = element->next;
00379 }
00380 }
00381
00382 if(result != GAT_SUCCESS)
00383 {
00384 break;
00385 }
00386 }
00387 }
00388 }
00389
00390 if (GAT_SUCCESS == result)
00391 {
00392 *new_table = clone;
00393 }
00394
00395 return result;
00396 }
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410 GATResult
00411 GATTable_Equals(GATTable_const lhs, GATTable_const rhs, GATBool *isequal)
00412 {
00413 GATResult result = GAT_SUCCESS;
00414
00415 *isequal = GATFalse;
00416 if (NULL == lhs || NULL == rhs || NULL == isequal)
00417 {
00418
00419 result = GAT_INVALID_HANDLE;
00420 }
00421 else
00422 {
00423 if (lhs->element_count != rhs->element_count ||
00424 lhs->table_length != rhs->table_length)
00425 {
00426
00427 result = GAT_SUCCESS;
00428 }
00429 else
00430 {
00431 GATuint32 i = 0;
00432 for(; i < lhs->table_length; ++i)
00433 {
00434 Hash_Element lhs_e = lhs->table[i];
00435 Hash_Element rhs_e = rhs->table[i];
00436
00437 *isequal = GATTrue;
00438 for(; NULL != lhs_e; lhs_e = lhs_e->next, rhs_e = rhs_e->next)
00439 {
00440 if (NULL == rhs_e || lhs_e->type != rhs_e->type)
00441 {
00442 break;
00443 }
00444
00445 switch(lhs_e->type)
00446 {
00447 case GATType_GATint16:
00448 *isequal = (((Hash_short) lhs_e->value)->data ==
00449 ((Hash_short) rhs_e->value)->data) ? GATTrue : GATFalse;
00450 break;
00451
00452 case GATType_GATint32:
00453 *isequal = (((Hash_int) lhs_e->value)->data ==
00454 ((Hash_int) rhs_e->value)->data) ? GATTrue : GATFalse;
00455 break;
00456
00457 case GATType_GATfloat32:
00458 *isequal = (((Hash_float) lhs_e->value)->data ==
00459 ((Hash_float) rhs_e->value)->data) ? GATTrue : GATFalse;
00460 break;
00461
00462 case GATType_GATdouble64:
00463 *isequal = (((Hash_double) lhs_e->value)->data ==
00464 ((Hash_double) rhs_e->value)->data) ? GATTrue : GATFalse;
00465 break;
00466
00467 case GATType_String:
00468 *isequal = GATTable_Internal_Equal_Keys(lhs,
00469 ((Hash_String) lhs_e->value)->data,
00470 ((Hash_String) rhs_e->value)->data);
00471 break;
00472
00473 default:
00474 if (GATType_GATObject & lhs_e->type)
00475 {
00476
00477 result = GATObject_Equals(((Hash_GATObject) lhs_e->value)->data,
00478 ((Hash_GATObject) rhs_e->value)->data, isequal);
00479 }
00480 else
00481 {
00482 result = GAT_KEY_TYPE_ERROR;
00483 }
00484 break;
00485 }
00486
00487 if(result != GAT_SUCCESS || GATFalse == *isequal)
00488 {
00489 break;
00490 }
00491 }
00492
00493 if(result != GAT_SUCCESS || GATFalse == *isequal)
00494 {
00495 break;
00496 }
00497 }
00498 }
00499 }
00500 return result;
00501 }
00502
00503
00504
00505
00506
00507
00508
00509
00510 void GATTable_Destroy(GATTable * table)
00511 {
00512 if (NULL != table && NULL != *table)
00513 {
00514 GATuint32 i;
00515 Hash_Element e;
00516 Hash_Element f;
00517 Hash_Element *t = (*table)->table;
00518
00519 for (i = 0; i < (*table)->table_length; i++)
00520 {
00521 e = t[i];
00522 while (NULL != e)
00523 {
00524 f = e;
00525 e = e->next;
00526 if (f->type == GATType_String)
00527 {
00528 free(((Hash_String) f->value)->data);
00529 }
00530 else if (f->type & GATType_GATObject)
00531 {
00532 GATObject_Destroy(&((Hash_GATObject) f->value)->data);
00533 }
00534 GATTable_Internal_Destroy_Key(*table, (void **) &f->key);
00535 free(f->value);
00536 free(f);
00537 }
00538 }
00539 free((*table)->table);
00540 free(*table);
00541 *table = NULL;
00542 }
00543 }
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557 GATResult
00558 GATTable_GetInterface(GATTable_const table, GATInterface iftype, void const **ifp)
00559 {
00560 GATResult retval = GAT_INVALID_PARAMETER;
00561
00562 if (NULL != ifp && NULL != table)
00563 {
00564 *ifp = NULL;
00565 if (GATInterface_ISerialisable == iftype)
00566 {
00567 *ifp = (void const *) &table->GATSerialisable__vtable;
00568 retval = GAT_SUCCESS;
00569 }
00570 else
00571 {
00572 retval = GAT_NO_INTERFACE;
00573 }
00574 }
00575 return retval;
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590 GATResult GATTable_Remove(GATTable table, const void *key)
00591 {
00592 Hash_Element e;
00593 Hash_Element *pE;
00594 GATResult result;
00595
00596 GATuint32 table_index = GATTable_Internal_Index(table->table_length,
00597 GATTable_Internal_Hash_sdbm(table, key));
00598
00599 pE = &(table->table[table_index]);
00600 e = *pE;
00601
00602 result = GAT_KEY_NOT_FOUND;
00603
00604 while (NULL != e)
00605 {
00606 if (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key))
00607 {
00608 table->element_count--;
00609 table->isdirty = GATTrue;
00610 *pE = e->next;
00611
00612 if (e->type == GATType_String)
00613 {
00614 free(((Hash_String) e->value)->data);
00615 }
00616 else if (e->type & GATType_GATObject)
00617 {
00618 GATObject_Destroy(&((Hash_GATObject) e->value)->data);
00619 }
00620
00621 GATTable_Internal_Destroy_Key(table, (void **) &e->key);
00622 free(e->value);
00623 free(e);
00624 result = GAT_SUCCESS;
00625 break;
00626 }
00627 pE = &(e->next);
00628 e = e->next;
00629 }
00630 return result;
00631 }
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642 GATResult GATTable_Add_int(GATTable table, const void *key, GATint32 data)
00643 {
00644 Hash_int p_int;
00645 GATResult result;
00646
00647 if ((p_int = (Hash_int) malloc(sizeof (struct Hash_int_S))) != NULL)
00648 {
00649 p_int->data = data;
00650 result = GATTable_Internal_Add(table, key, p_int, GATType_GATint32);
00651 if (GAT_SUCCESS != result)
00652 {
00653 free(p_int);
00654 }
00655 }
00656 else
00657 {
00658 result = GAT_MEMORYFAILURE;
00659 }
00660
00661 return result;
00662 }
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674 GATResult GATTable_Add_short(GATTable table, const void *key, GATint16 data)
00675 {
00676 Hash_short p_short;
00677 GATResult result;
00678
00679 if ((p_short
00680 = (Hash_short) malloc(sizeof (struct Hash_short_S))) != NULL)
00681 {
00682 p_short->data = data;
00683
00684 result = GATTable_Internal_Add(table, key, p_short, GATType_GATint16);
00685 if (GAT_SUCCESS != result)
00686 {
00687 free(p_short);
00688 }
00689 }
00690 else
00691 {
00692 result = GAT_MEMORYFAILURE;
00693 }
00694
00695 return result;
00696
00697
00698 }
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710 GATResult GATTable_Add_double(GATTable table, const void *key, GATdouble64 data)
00711 {
00712 Hash_double p_double;
00713 GATResult result;
00714
00715 if ((p_double
00716 = (Hash_double) malloc(sizeof (struct Hash_double_S))) != NULL)
00717 {
00718 p_double->data = data;
00719
00720 result = GATTable_Internal_Add(table, key, p_double, GATType_GATdouble64);
00721 if (GAT_SUCCESS != result)
00722 {
00723 free(p_double);
00724 }
00725 }
00726 else
00727 {
00728 result = GAT_MEMORYFAILURE;
00729 }
00730
00731 return result;
00732 }
00733
00734
00735
00736
00737
00738
00739
00740
00741
00742
00743
00744 GATResult GATTable_Add_float(GATTable table, const void *key, GATfloat32 data)
00745 {
00746 Hash_float p_float;
00747 GATResult result;
00748
00749 if ((p_float
00750 = (Hash_float) malloc(sizeof (struct Hash_float_S))) != NULL)
00751 {
00752 p_float->data = data;
00753
00754 result = GATTable_Internal_Add(table, key, p_float, GATType_GATfloat32);
00755 if (GAT_SUCCESS != result)
00756 {
00757 free(p_float);
00758 }
00759 }
00760 else
00761 {
00762 result = GAT_MEMORYFAILURE;
00763 }
00764
00765 return result;
00766 }
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 GATResult
00779 GATTable_Add_String(GATTable table, const void *key, const char *data)
00780 {
00781 Hash_String p_string;
00782 GATResult result;
00783
00784 if ((p_string
00785 = (Hash_String) malloc(sizeof (struct Hash_String_S))) == NULL)
00786 {
00787 result = GAT_MEMORYFAILURE;
00788 }
00789 else
00790 if ((p_string->data
00791 = (char *) malloc(sizeof (char) * (strlen(data)+1))) == NULL)
00792 {
00793 free(p_string);
00794 result = GAT_MEMORYFAILURE;
00795 }
00796 else
00797 {
00798 strcpy(p_string->data, data);
00799
00800 result = GATTable_Internal_Add(table, key, p_string, GATType_String);
00801 if (GAT_SUCCESS != result)
00802 {
00803 free(p_string->data);
00804 free(p_string);
00805 }
00806 }
00807
00808 return result;
00809 }
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819
00820
00821 GATResult
00822 GATTable_Add_GATObject(GATTable table, const void *key, GATObject_const data)
00823 {
00824 Hash_GATObject p_object;
00825 GATResult result;
00826
00827 if ((p_object
00828 = (Hash_GATObject) malloc(sizeof (struct Hash_GATObject_S))) != NULL)
00829 {
00830 result = GATObject_Clone(data, &p_object->data);
00831 if (GAT_SUCCESS == result)
00832 {
00833 result = GATTable_Internal_Add(table, key, p_object, GATType_GATObject);
00834 if (GAT_SUCCESS != result)
00835 {
00836 GATObject_Destroy(&p_object->data);
00837 free(p_object);
00838 }
00839 }
00840 else
00841 {
00842 free(p_object);
00843 }
00844 }
00845 else
00846 {
00847 result = GAT_MEMORYFAILURE;
00848 }
00849
00850 return result;
00851 }
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861 GATType GATTable_Get_ElementType(GATTable_const table, const void *key)
00862 {
00863 Hash_Element e;
00864 unsigned long hash_value;
00865 GATuint32 table_index;
00866 GATType result;
00867
00868 hash_value = GATTable_Internal_Hash_sdbm(table, key);
00869
00870 table_index = GATTable_Internal_Index(table->table_length, hash_value);
00871
00872 e = table->table[table_index];
00873
00874 result = GATType_NoType;
00875
00876 while (NULL != e)
00877 {
00878 if ((hash_value == e->hash)
00879 && (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
00880 {
00881 result = e->type;
00882 break;
00883 }
00884
00885 e = e->next;
00886 }
00887 return result;
00888 }
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899 void **GATTable_GetKeys(GATTable_const table)
00900 {
00901 void **list = NULL;
00902 GATuint32 i = 0;
00903 GATuint32 key_no = 0;
00904 int retval = GAT_SUCCESS;
00905
00906 list = (void **)malloc(sizeof(void *) * (table->element_count+1));
00907 if (NULL != list)
00908 {
00909 memset(list, 0, sizeof(void *) * (table->element_count+1));
00910 for (; i < table->table_length; ++i)
00911 {
00912 if (NULL != table->table[i])
00913 {
00914 Hash_Element hold = table->table[i];
00915
00916 retval = GAT_SUCCESS;
00917 do
00918 {
00919 retval = GATTable_Internal_CloneKey(table, hold->key, &list[key_no++]);
00920 if (GAT_SUCCESS != retval)
00921 {
00922 break;
00923 }
00924 }
00925 while (NULL != (hold = hold->next));
00926 }
00927 }
00928 list[key_no] = NULL;
00929 }
00930 else
00931 {
00932 retval = GAT_MEMORYFAILURE;
00933 }
00934
00935 if (GAT_SUCCESS != retval)
00936 {
00937
00938 for (i = 0, key_no = 0; i < table->table_length; ++i)
00939 {
00940 free(list[key_no++]);
00941 }
00942 free(list);
00943 list = NULL;
00944 }
00945 return list;
00946 }
00947
00948
00949
00950
00951
00952 void
00953 GATTable_ReleaseKeys(GATTable_const this, void ***keys)
00954 {
00955 GAT_UNUSED_PARAMETER(this);
00956 if (NULL != keys && NULL != *keys)
00957 {
00958 GATuint32 i = 0;
00959 for (; NULL != (*keys)[i]; ++i)
00960 {
00961 free((*keys)[i]);
00962 }
00963 free(*keys);
00964 *keys = NULL;
00965 }
00966 }
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977 GATResult
00978 GATTable_Get_int(GATTable_const table, const void *key, GATint32 *data)
00979 {
00980 GATResult result = GAT_INVALID_HANDLE;
00981 if (NULL != table)
00982 {
00983 Hash_Element e;
00984 unsigned long hash_value;
00985 GATuint32 table_index;
00986
00987 hash_value = GATTable_Internal_Hash_sdbm(table, key);
00988
00989 table_index = GATTable_Internal_Index(table->table_length, hash_value);
00990
00991 e = table->table[table_index];
00992
00993 result = GAT_KEY_NOT_FOUND;
00994
00995 while (NULL != e)
00996 {
00997 if ((hash_value == e->hash)
00998 && (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
00999 {
01000 if (e->type == GATType_GATint32)
01001 {
01002 if (NULL != data)
01003 {
01004 *data = ((Hash_int) e->value)->data;
01005 result = GAT_SUCCESS;
01006 }
01007 else
01008 {
01009 result = GAT_INVALID_PARAMETER;
01010 }
01011 break;
01012 }
01013 else
01014 {
01015 result = GAT_KEY_TYPE_ERROR;
01016 break;
01017 }
01018 }
01019 e = e->next;
01020 }
01021 }
01022 return result;
01023 }
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034 GATResult
01035 GATTable_Get_short(GATTable_const table, const void *key, GATint16 *data)
01036 {
01037 GATResult result = GAT_INVALID_HANDLE;
01038 if (NULL != table)
01039 {
01040 Hash_Element e;
01041 unsigned long hash_value;
01042 GATuint32 table_index;
01043
01044 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01045
01046 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01047
01048 e = table->table[table_index];
01049
01050 result = GAT_KEY_NOT_FOUND;
01051
01052 while (NULL != e)
01053 {
01054 if ((hash_value == e->hash)
01055 && (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01056 {
01057 if (e->type == GATType_GATint16)
01058 {
01059 if (NULL != data)
01060 {
01061 *data = ((Hash_short) e->value)->data;
01062 result = GAT_SUCCESS;
01063 }
01064 else
01065 {
01066 result = GAT_INVALID_PARAMETER;
01067 }
01068 break;
01069 }
01070 else
01071 {
01072 result = GAT_KEY_TYPE_ERROR;
01073 break;
01074 }
01075 }
01076 e = e->next;
01077 }
01078 }
01079 return result;
01080 }
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091 GATResult
01092 GATTable_Get_double(GATTable_const table, const void *key, double *data)
01093 {
01094 GATResult result = GAT_INVALID_HANDLE;
01095 if (NULL != table)
01096 {
01097 Hash_Element e;
01098 unsigned long hash_value;
01099 GATuint32 table_index;
01100
01101 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01102
01103 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01104
01105 e = table->table[table_index];
01106
01107 result = GAT_KEY_NOT_FOUND;
01108
01109 while (NULL != e)
01110 {
01111 if ((hash_value == e->hash)
01112 && (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01113 {
01114 if (e->type == GATType_GATdouble64)
01115 {
01116 if (NULL != data)
01117 {
01118 *data = ((Hash_double) e->value)->data;
01119 result = GAT_SUCCESS;
01120 }
01121 else
01122 {
01123 result = GAT_INVALID_PARAMETER;
01124 }
01125 break;
01126 }
01127 else
01128 {
01129 result = GAT_KEY_TYPE_ERROR;
01130 break;
01131 }
01132 }
01133 e = e->next;
01134 }
01135 }
01136 return result;
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 GATResult
01149 GATTable_Get_float(GATTable_const table, const void *key, float *data)
01150 {
01151 GATResult result = GAT_INVALID_HANDLE;
01152 if (NULL != table)
01153 {
01154 Hash_Element e;
01155 unsigned long hash_value;
01156 GATuint32 table_index;
01157
01158 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01159
01160 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01161
01162 e = table->table[table_index];
01163
01164 result = GAT_KEY_NOT_FOUND;
01165
01166 while (NULL != e)
01167 {
01168 if ((hash_value == e->hash)
01169 && (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01170 {
01171 if (e->type == GATType_GATfloat32)
01172 {
01173 if (NULL != data)
01174 {
01175 *data = ((Hash_float) e->value)->data;
01176 result = GAT_SUCCESS;
01177 }
01178 else
01179 {
01180 result = GAT_INVALID_PARAMETER;
01181 }
01182 break;
01183 }
01184 else
01185 {
01186 result = GAT_KEY_TYPE_ERROR;
01187 break;
01188 }
01189 }
01190 e = e->next;
01191 }
01192 }
01193 return result;
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208 GATResult
01209 GATTable_Get_String(GATTable_const table, const void *key, char *data,
01210 GATuint32 length)
01211 {
01212 GATResult result = GAT_INVALID_HANDLE;
01213 if (NULL != table)
01214 {
01215 Hash_Element e;
01216 unsigned long hash_value;
01217 GATuint32 table_index;
01218 GATuint32 element_length;
01219
01220 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01221
01222 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01223
01224 e = table->table[table_index];
01225
01226 result = GAT_KEY_NOT_FOUND;
01227
01228 while (NULL != e)
01229 {
01230 if ((hash_value == e->hash) &&
01231 (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01232 {
01233 if (e->type == GATType_String)
01234 {
01235 element_length = strlen(((Hash_String) e->value)->data);
01236
01237 if (NULL != data)
01238 {
01239 if (element_length >= length)
01240 {
01241 memcpy(data,
01242 ((Hash_String) e->value)->data,
01243 (sizeof (char) * (length-1)));
01244 data[length-1] = '\0';
01245 }
01246 else
01247 {
01248 memcpy(data, ((Hash_String) e->value)->data,
01249 (sizeof (char) * element_length));
01250 data[element_length] = '\0';
01251 }
01252 }
01253
01254 result = element_length;
01255 break;
01256 }
01257 else
01258 {
01259 result = GAT_KEY_TYPE_ERROR;
01260 break;
01261 }
01262 }
01263 e = e->next;
01264 }
01265 }
01266 return result;
01267 }
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278 GATResult GATTable_Get_GATObject(GATTable_const table, const void *key,
01279 GATObject_const *data)
01280 {
01281 GATResult result = GAT_INVALID_HANDLE;
01282 if (NULL != table)
01283 {
01284 Hash_Element e;
01285 unsigned long hash_value;
01286 GATuint32 table_index;
01287
01288 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01289
01290 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01291
01292 e = table->table[table_index];
01293
01294 result = GAT_KEY_NOT_FOUND;
01295
01296 while (NULL != e)
01297 {
01298 if ((hash_value == e->hash) &&
01299 (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01300 {
01301 if (e->type == GATType_GATObject)
01302 {
01303 if (NULL != data)
01304 {
01305 *data = ((Hash_GATObject) e->value)->data;
01306 result = GAT_SUCCESS;
01307 }
01308 else
01309 {
01310 result = GAT_INVALID_PARAMETER;
01311 }
01312 break;
01313 }
01314 else
01315 {
01316 result = GAT_KEY_TYPE_ERROR;
01317 break;
01318 }
01319 }
01320 e = e->next;
01321 }
01322 }
01323 return result;
01324 }
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339 GATResult
01340 GATTable_internal_Get_GATObjectRef(GATTable_const table, const void *key,
01341 GATObject *object)
01342 {
01343 GATResult result = GAT_INVALID_HANDLE;;
01344 if (NULL != table)
01345 {
01346 Hash_Element e;
01347 unsigned long hash_value;
01348 GATuint32 table_index;
01349
01350 hash_value = GATTable_Internal_Hash_sdbm(table, key);
01351 table_index = GATTable_Internal_Index(table->table_length, hash_value);
01352
01353 e = table->table[table_index];
01354
01355 result = GAT_KEY_NOT_FOUND;
01356
01357 while (NULL != e)
01358 {
01359 if ((hash_value == e->hash) &&
01360 (GATTrue == GATTable_Internal_Equal_Keys(table, key, e->key)))
01361 {
01362 if (e->type == GATType_GATObject)
01363 {
01364 if (NULL != object)
01365 {
01366 *object = ((Hash_GATObject) e->value)->data;
01367 result = GAT_SUCCESS;
01368 }
01369 else
01370 {
01371 result = GAT_INVALID_PARAMETER;
01372 }
01373 break;
01374 }
01375 else
01376 {
01377 result = GAT_KEY_TYPE_ERROR;
01378 break;
01379 }
01380 }
01381 e = e->next;
01382 }
01383 }
01384 return result;
01385 }
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403 GATResult
01404 GATTable_Serialise(GATTable table, GATObject stream, GATBool clear_dirty)
01405 {
01406 GATResult retval = GAT_INVALID_HANDLE;
01407 if (NULL != table)
01408 {
01409 GATXds xds = NULL;
01410 void *xds_buffer = NULL;
01411 GATuint32 xds_buffer_size = 0;
01412 void *xds_item_buffer = NULL;
01413 GATuint32 xds_item_buffer_size = 0;
01414
01415 if (GAT_SUCCESS == (retval = GATXds_Init(&xds, GATXdsType_Encode)) &&
01416 GAT_SUCCESS == (retval = GATXds_Encode(xds, GATXdsScope_Gift,
01417 &xds_buffer, (size_t *) &xds_buffer_size, "uint32 uint32 uint32",
01418 GATTABLE_VERSION1, table->table_length, table->element_count)) &&
01419 GAT_SUCCESS == (retval = GATTable_SerialiseItems(table, xds,
01420 GATXdsScope_Gift, &xds_item_buffer, (size_t *) &xds_item_buffer_size,
01421 clear_dirty)))
01422 {
01423
01424 void *xds_size_buffer = NULL;
01425 GATuint32 xds_size_buffer_size = 0;
01426
01427 if (GAT_SUCCESS == (retval = GATXds_Encode(xds, GATXdsScope_Gift,
01428 &xds_size_buffer, (size_t *) &xds_size_buffer_size, "uint32",
01429 xds_buffer_size + xds_item_buffer_size)))
01430 {
01431 assert(NULL != xds_size_buffer);
01432 retval = GATStreamable_Write(stream, xds_size_buffer,
01433 xds_size_buffer_size, 0);
01434 if (GAT_SUCCESS == retval)
01435 {
01436
01437 assert(NULL != xds_buffer);
01438 retval = GATStreamable_Write(stream, xds_buffer, xds_buffer_size, 0);
01439 }
01440
01441 if (GAT_SUCCESS == retval)
01442 {
01443
01444 retval = GATStreamable_Write(stream, xds_item_buffer,
01445 xds_item_buffer_size, 0);
01446
01447 if (GAT_SUCCESS == retval && clear_dirty)
01448 {
01449 table->isdirty = GATFalse;
01450 }
01451 }
01452 }
01453 free(xds_size_buffer);
01454 }
01455 free(xds_item_buffer);
01456 free(xds_buffer);
01457 GATXds_Destroy(&xds);
01458 }
01459 return retval;
01460 }
01461
01462
01463
01464
01465
01466
01467
01468
01469
01470
01471
01472
01473
01474
01475
01476 GATTable GATTable_DeSerialise(GATContext context, GATObject stream,
01477 GATResult *result)
01478 {
01479 GATTable table = NULL;
01480 char buffer[64];
01481 GATuint32 xds_read_bytes = 0;
01482 int retval = GATStreamable_Read(stream, buffer, sizeof(buffer),
01483 &xds_read_bytes);
01484
01485 if (GAT_SUCCESS == retval)
01486 {
01487 GATXds xds = NULL;
01488
01489 if (GAT_SUCCESS == (retval = GATXds_InitEx(&xds, GATXdsType_Decode, context)))
01490 {
01491 GATuint32 xds_buffer_size = 0;
01492
01493
01494 retval = GATXds_Decode(xds, GATXdsScope_Loan, buffer,
01495 sizeof(buffer), "uint32", &xds_buffer_size);
01496 if (GAT_SUCCESS == retval)
01497 {
01498
01499 retval = GATStreamable_Seek(stream, GATOrigin_Current,
01500 GATXds_GetBufferLen(xds) - xds_read_bytes, 0);
01501
01502 if (GAT_SUCCESS == retval)
01503 {
01504
01505 char *xds_buffer = (char *)malloc(xds_buffer_size);
01506 if (NULL == xds_buffer)
01507 {
01508 retval = GAT_MEMORYFAILURE;
01509 }
01510 else if (GAT_SUCCESS == (retval = GATStreamable_Read(stream,
01511 xds_buffer, xds_buffer_size, 0)))
01512 {
01513
01514 GATuint32 version = 0;
01515
01516 retval = GATXds_Decode(xds, GATXdsScope_Gift, xds_buffer,
01517 xds_buffer_size, "uint32", &version);
01518 if (GAT_SUCCESS != retval ||
01519 (version & ~GATTABLE_MINOR_MASK) > GATTABLE_LASTVERSION)
01520 {
01521 retval = GAT_UNKNOWN_FORMAT;
01522 }
01523 else
01524 {
01525
01526 GATuint32 table_length = 0;
01527 GATuint32 element_count = 0;
01528
01529 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "uint32 uint32",
01530 &table_length, &element_count);
01531 if (GAT_SUCCESS == retval)
01532 {
01533
01534 retval = GATTable_DeSerialise_Create(xds, table_length,
01535 element_count, &table);
01536 }
01537 }
01538 }
01539 }
01540 }
01541 }
01542 GATXds_Destroy(&xds);
01543
01544
01545 }
01546
01547 if (NULL != result)
01548 {
01549 *result = retval;
01550 }
01551 return table;
01552 }
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564 GATResult GATTable_GetIsDirty(GATTable_const table, GATBool *isdirty)
01565 {
01566 GATResult retval = GAT_INVALID_HANDLE;
01567 if (NULL != table)
01568 {
01569 if (NULL != isdirty)
01570 {
01571 *isdirty = table->isdirty;
01572 retval = GAT_SUCCESS;
01573 }
01574 else
01575 {
01576 retval = GAT_INVALID_PARAMETER;
01577 }
01578 }
01579 return retval;
01580 }
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593
01594 unsigned long
01595 GATTable_Default_Hash_sdbm(GATTable_const table, void const *key)
01596 {
01597 GATuint32 key_size = GATTable_Internal_Get_KeySize(table, key);
01598 unsigned long hash = 0;
01599
01600 int8_t* tmp = (int8_t *) key;
01601 int8_t c = *tmp++;
01602 GATuint32 i = 1;
01603
01604 for (; i < key_size; ++i)
01605 {
01606 hash = c + (hash << 6) + (hash << 16) - hash;
01607 if (i < key_size)
01608 {
01609
01610 c = *tmp++;
01611 }
01612 }
01613 return hash;
01614 }
01615
01616
01617
01618
01619
01620
01621
01622
01623
01624
01625
01626
01627
01628
01629 GATResult
01630 GATTable_Default_Clone_Key(GATTable_const table, void const *src, void **dest)
01631 {
01632 GATuint32 key_size = GATTable_Internal_Get_KeySize(table, src);
01633 *dest = GATUtil_memdup(src, key_size);
01634 return (NULL != *dest) ? GAT_SUCCESS : GAT_MEMORYFAILURE;
01635 }
01636
01637
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650 GATBool
01651 GATTable_Default_Equal_Keys(GATTable_const table, void const *key1,
01652 void const *key2)
01653 {
01654 GATuint32 key_size1 = GATTable_Internal_Get_KeySize(table, key1);
01655 GATuint32 key_size2 = GATTable_Internal_Get_KeySize(table, key2);
01656 GATBool retval = GATFalse;
01657
01658 if (key_size1 == key_size2)
01659 {
01660 retval = (0 == memcmp(key1, key2, key_size1)) ? GATTrue : GATFalse;
01661 }
01662 return retval;
01663 }
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674 void
01675 GATTable_Default_Destroy_Key(GATTable_const table, void **key)
01676 {
01677 GAT_UNUSED_PARAMETER(table);
01678 if (NULL != key && NULL != *key)
01679 {
01680 free(*key);
01681 *key = NULL;
01682 }
01683 }
01684
01685
01686
01687
01688
01689
01690
01691
01692
01693
01694
01695
01696 GATuint32 GATTable_Size(GATTable_const table)
01697 {
01698 GATuint32 retval = (GATuint32)(-1);
01699 if (NULL != table)
01700 {
01701 retval = table->element_count;
01702 }
01703 return retval;
01704 }
01705
01706
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717 static GATBool
01718 GATTable_Internal_Equal_Keys(GATTable_const table, void const *key1,
01719 void const *key2)
01720 {
01721 return table->equal_keys(table, key1, key2);
01722 }
01723
01724 static GATBool
01725 GATTable_Internal_Equal_Keys_String(GATTable_const table, void const *key1,
01726 void const *key2)
01727 {
01728 GAT_UNUSED_PARAMETER(table);
01729 return (0 == strcmp((char const *) key1, (char const *) key2)) ?
01730 GATTrue : GATFalse;
01731 }
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741 static unsigned long
01742 GATTable_Internal_Hash_sdbm(GATTable_const table, void const *key)
01743 {
01744 return table->get_hash(table, key);
01745 }
01746
01747
01748
01749
01750
01751
01752
01753
01754
01755 static GATuint32
01756 GATTable_Internal_Get_KeySize(GATTable_const table, void const *key)
01757 {
01758 return table->get_key_size(table, key);
01759 }
01760
01761 static GATuint32
01762 GATTable_Internal_Get_KeySize_String(GATTable_const table, void const *key)
01763 {
01764 GAT_UNUSED_PARAMETER(table);
01765 return strlen((char const *) key) + 1;
01766 }
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779 static GATResult
01780 GATTable_Internal_CloneKey(GATTable_const table, void const *src, void **dest)
01781 {
01782 return table->clone_key(table, src, dest);
01783 }
01784
01785 static GATResult
01786 GATTable_Internal_CloneKey_String(GATTable_const table, void const *src,
01787 void **dest)
01788 {
01789 GAT_UNUSED_PARAMETER(table);
01790 *dest = GATUtil_strdup((char const *)src);
01791 return (NULL != *dest) ? GAT_SUCCESS : GAT_MEMORYFAILURE;
01792 }
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803 static void
01804 GATTable_Internal_Destroy_Key(GATTable_const table, void **key)
01805 {
01806 table->destroy_key(table, key);
01807 }
01808
01809
01810
01811
01812
01813
01814
01815
01816
01817
01818 static GATuint32
01819 GATTable_Internal_Index(GATuint32 table_length, unsigned long hash_value)
01820 {
01821 return (hash_value & (table_length - 1u));
01822
01823 }
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 static GATResult
01834 GATTable_Internal_Expand(GATTable table)
01835 {
01836 GATuint32 new_size = table->table_length << 1;
01837 GATuint32 table_index;
01838 GATResult result;
01839
01840
01841 if (0 == new_size)
01842 {
01843 result = GAT_MEMORYFAILURE;
01844 }
01845 else
01846 {
01847 Hash_Element *new_table = (Hash_Element *) realloc(table->table,
01848 new_size * sizeof (Hash_Element));
01849 if (NULL == new_table)
01850 {
01851 result = GAT_MEMORYFAILURE;
01852 }
01853 else
01854 {
01855 GATuint32 i = table->table_length;
01856 table->table = new_table;
01857
01858
01859 for (; i < new_size; i++)
01860 {
01861 new_table[i] = NULL;
01862 }
01863
01864 for (i = 0; i < table->table_length; i++)
01865 {
01866 Hash_Element *pE;
01867 Hash_Element e;
01868
01869 for (pE = &(new_table[i]), e = *pE; e != NULL; e = *pE)
01870 {
01871 table_index = GATTable_Internal_Index(new_size, e->hash);
01872
01873 if (table_index == i)
01874 {
01875 pE = &(e->next);
01876 }
01877 else
01878 {
01879 *pE = e->next;
01880 e->next = new_table[table_index];
01881 new_table[table_index] = e;
01882 }
01883 }
01884 }
01885
01886 table->table_length = new_size;
01887 table->load_limit <<= 1;
01888 result = GAT_SUCCESS;
01889 }
01890 }
01891
01892 return result;
01893 }
01894
01895
01896
01897
01898
01899
01900
01901
01902
01903
01904
01905
01906
01907
01908 static GATResult
01909 GATTable_Internal_Add(GATTable table, const void *key, void *value,
01910 GATType type)
01911 {
01912 GATuint32 table_index = 0;
01913 Hash_Element e = NULL;
01914 GATResult result = GAT_FAIL;
01915
01916
01917 if ((++(table->element_count) > table->load_limit)
01918 && (GATTable_Internal_Expand(table) == GAT_MEMORYFAILURE))
01919 {
01920 result = GAT_MEMORYFAILURE;
01921 }
01922 else
01923 if ((e = (Hash_Element) malloc(sizeof (struct Hash_Element_S))) == NULL)
01924 {
01925 result = GAT_MEMORYFAILURE;
01926 }
01927 else
01928 {
01929
01930 memset(e, 0, sizeof(struct Hash_Element_S));
01931 e->type = type;
01932 e->hash = GATTable_Internal_Hash_sdbm(table, key);
01933 table_index = GATTable_Internal_Index(table->table_length, e->hash);
01934
01935 table->isdirty = GATTrue;
01936
01937 e->value = value;
01938 e->next = NULL;
01939
01940 result = GATTable_Internal_CloneKey(table, key, (void **) &e->key);
01941 if (GAT_SUCCESS == result)
01942 {
01943
01944 if (NULL != table->table[table_index])
01945 {
01946
01947 Hash_Element hold = NULL;
01948 for (hold = table->table[table_index]; ; hold = hold->next)
01949 {
01950 if (GATTrue == GATTable_Internal_Equal_Keys(table, key, hold->key))
01951 {
01952
01953 result = GAT_KEY_ALREADY_EXISTS;
01954 break;
01955 }
01956
01957 if (NULL == hold->next)
01958 {
01959 break;
01960 }
01961 }
01962
01963 if (GAT_SUCCESS == result)
01964 {
01965 hold->next = e;
01966 }
01967 }
01968 else
01969 {
01970
01971 table->table[table_index] = e;
01972 }
01973 }
01974 }
01975
01976 if (GAT_SUCCESS != result)
01977 {
01978
01979 --table->element_count;
01980 if (NULL != e)
01981 {
01982 GATTable_Internal_Destroy_Key(table, (void **) &e->key);
01983 }
01984 free(e);
01985 }
01986 return result;
01987 }
01988
01989
01990 static GATResult
01991 GATTable_SerialiseItems(GATTable_const table, GATXds xds,
01992 GATXdsScope flag, void **buffer, size_t *buffer_size, GATBool clear_dirty)
01993 {
01994 GATResult retval = GAT_SUCCESS;
01995 GATuint32 i = 0;
01996 GAT_UNUSED_PARAMETER(flag);
01997 GAT_UNUSED_PARAMETER(clear_dirty);
01998 if (table->equal_keys != GATTable_Internal_Equal_Keys_String ||
01999 table->get_hash != GATTable_Default_Hash_sdbm ||
02000 table->get_key_size != GATTable_Internal_Get_KeySize_String ||
02001 table->clone_key != GATTable_Internal_CloneKey_String ||
02002 table->destroy_key != GATTable_Default_Destroy_Key)
02003 {
02004
02005 retval = GAT_NO_INTERFACE;
02006 }
02007 else
02008 {
02009 for(; i < table->table_length; ++i)
02010 {
02011 Hash_Element element = table->table[i];
02012
02013
02014 for(; NULL != element; element = element->next)
02015 {
02016 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "uint32",
02017 (GATuint32)element->type);
02018 if (GAT_SUCCESS != retval)
02019 {
02020 break;
02021 }
02022
02023 switch(element->type)
02024 {
02025 case GATType_GATint32:
02026 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "string int32",
02027 element->key, ((Hash_int) element->value)->data);
02028 break;
02029
02030 case GATType_GATint16:
02031 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "string int32",
02032 element->key, ((Hash_short) element->value)->data);
02033 break;
02034
02035 case GATType_GATdouble64:
02036 retval = GATXds_Encode(xds,(GATXdsScope) 0, 0, 0, "string double",
02037 element->key, ((Hash_double) element->value)->data);
02038 break;
02039
02040 case GATType_GATfloat32:
02041 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "string double",
02042 element->key, (double)((Hash_float) element->value)->data);
02043 break;
02044
02045 case GATType_String:
02046 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "string string",
02047 element->key, ((Hash_String) element->value)->data);
02048 break;
02049
02050 default:
02051 if (GATType_GATObject & element->type)
02052 {
02053 retval = GATXds_Encode(xds, (GATXdsScope)0, 0, 0, "string object",
02054 element->key, ((Hash_GATObject) element->value)->data,
02055 clear_dirty);
02056 }
02057 else
02058 {
02059 retval = GAT_KEY_TYPE_ERROR;
02060 }
02061 break;
02062 }
02063
02064 if(GAT_SUCCESS != retval)
02065 {
02066 break;
02067 }
02068 }
02069
02070 if (GAT_SUCCESS != retval)
02071 {
02072 break;
02073 }
02074 }
02075 }
02076
02077 if (GAT_SUCCESS == retval)
02078 {
02079 retval = GATXds_GetBuffer(xds, GATXdsScope_Gift, buffer, buffer_size);
02080 }
02081 return retval;
02082 }
02083
02084
02085
02086
02087
02088
02089
02090
02091
02092
02093
02094
02095
02096
02097
02098 static GATResult
02099 GATTable_DeSerialise_Create(GATXds xds, GATuint32 table_length,
02100 GATuint32 element_count, GATTable *table)
02101 {
02102 GATResult retval = GAT_MEMORYFAILURE;
02103
02104 GATTable new_table = (GATTable) malloc(sizeof(struct GATTable_S));
02105 if (NULL != new_table)
02106 {
02107 GATuint32 i = 0;
02108
02109 memset(new_table, 0, sizeof(struct GATTable_S));
02110 new_table->GATObject__vtable = &GATTable__vtable;
02111 new_table->GATSerialisable__vtable = &GATTable_ISerialisable__vtable;
02112
02113 new_table->equal_keys = GATTable_Internal_Equal_Keys_String;
02114 new_table->get_hash = GATTable_Default_Hash_sdbm;
02115 new_table->get_key_size = GATTable_Internal_Get_KeySize_String;
02116 new_table->clone_key = GATTable_Internal_CloneKey_String;
02117 new_table->destroy_key = GATTable_Default_Destroy_Key;
02118
02119 new_table->table =
02120 (Hash_Element *) malloc(sizeof(Hash_Element) * table_length);
02121
02122 if (NULL == new_table)
02123 {
02124 free(new_table);
02125 new_table = NULL;
02126 retval = GAT_MEMORYFAILURE;
02127 }
02128 else
02129 {
02130
02131 double const maxloadfactor = 0.75f;
02132
02133 for (i = 0; i < table_length; i++)
02134 {
02135 new_table->table[i] = NULL;
02136 }
02137
02138 new_table->table_length = table_length;
02139 new_table->element_count = 0;
02140
02141 new_table->load_limit = (GATuint32) (table_length * maxloadfactor);
02142 }
02143
02144 for(i = 0; i < element_count; ++i)
02145 {
02146
02147 GATuint32 type = GATType_NoType;
02148 char *key = NULL;
02149
02150 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "uint32", &type);
02151 if (GAT_SUCCESS != retval)
02152 {
02153 break;
02154 }
02155
02156 switch(type)
02157 {
02158 case GATType_GATint32:
02159 {
02160 int data = 0;
02161 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string int32",
02162 &key, &data);
02163 if (GAT_SUCCESS == retval)
02164 {
02165 retval = GATTable_Add_int(new_table, key, data);
02166 }
02167 }
02168 break;
02169
02170 case GATType_GATint16:
02171 {
02172 int data = 0;
02173 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string int32",
02174 &key, &data);
02175 if (GAT_SUCCESS == retval)
02176 {
02177 retval = GATTable_Add_short(new_table, key, data);
02178 }
02179 }
02180 break;
02181
02182 case GATType_GATdouble64:
02183 {
02184 double data = 0;
02185 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string double",
02186 &key, &data);
02187 if (GAT_SUCCESS == retval)
02188 {
02189 retval = GATTable_Add_double(new_table, key, data);
02190 }
02191 }
02192 break;
02193
02194 case GATType_GATfloat32:
02195 {
02196 double data = 0;
02197 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string double",
02198 &key, &data);
02199 if (GAT_SUCCESS == retval)
02200 {
02201 retval = GATTable_Add_float(new_table, key, (float) data);
02202 }
02203 }
02204 break;
02205
02206 case GATType_String:
02207 {
02208 char *data = NULL;
02209 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string string",
02210 &key, &data);
02211 if (GAT_SUCCESS == retval)
02212 {
02213 retval = GATTable_Add_String(new_table, key, data);
02214 free(data);
02215 }
02216 }
02217 break;
02218
02219 default:
02220 if (GATType_GATObject & type)
02221 {
02222 GATObject data = NULL;
02223 retval = GATXds_Decode(xds, (GATXdsScope)0, 0, 0, "string object",
02224 &key, &data);
02225 if (GAT_SUCCESS == retval)
02226 {
02227 retval = GATTable_Add_GATObject(new_table, key, data);
02228 GATObject_Destroy(&data);
02229 }
02230 }
02231 else
02232 {
02233 retval = GAT_KEY_TYPE_ERROR;
02234 }
02235 break;
02236 }
02237 free(key);
02238
02239 if (GAT_SUCCESS != retval)
02240 {
02241 break;
02242 }
02243 }
02244
02245 if (GAT_SUCCESS == retval)
02246 {
02247 if (NULL != table)
02248 {
02249 *table = new_table;
02250 }
02251 else
02252 {
02253 GATTable_Destroy(&new_table);
02254 retval = GAT_INVALID_PARAMETER;
02255 }
02256 }
02257 else
02258 {
02259 GATTable_Destroy(&new_table);
02260 }
02261 }
02262 return retval;
02263 }