This is an example much like the one shown in Advanced use of Eet Data Descriptors.
The difference is that here we're attaining ourselves to two new data types to store in an Eet file -- unions and variants. We don't try to come with data mapping to real world use cases, here. Instead, we're defining 3 different simple structures to be used throughout the example:
typedef struct _Example_Struct1 Example_Struct1; typedef struct _Example_Struct2 Example_Struct2; typedef struct _Example_Struct3 Example_Struct3; struct _Example_Struct1 { double val1; int stuff; const char *s1; }; struct _Example_Struct2 { Eina_Bool b1; unsigned long long v1; }; struct _Example_Struct3 { int body; };
To identify, for both union and variant data cases, the type of each chunk of data, we're defining types to point to each of those structs:
typedef enum _Example_Data_Type Example_Data_Type; enum _Example_Data_Type { EET_UNKNOWN = 0, EET_STRUCT1, EET_STRUCT2, EET_STRUCT3 };
We have also a mapping from those types to name strings, to be used in the Eet unions and variants type_get()
and type_set()
type identifying callbacks:
struct { Example_Data_Type u; const char *name; } eet_mapping[] = { { EET_STRUCT1, "ST1" }, { EET_STRUCT2, "ST2" }, { EET_STRUCT3, "ST3" }, { EET_UNKNOWN, NULL } };
In this example, we have no fancy hash to store our data into profiles/accounts, but just two lists for union and variant data nodes:
typedef struct _Example_Lists Example_Lists; struct _Example_Lists { Eina_List *union_list; Eina_List *variant_list; };
Let's begin with our unions, then, which look like:
typedef struct _Example_Union Example_Union; struct _Example_Union { Example_Data_Type type; union { Example_Struct1 st1; Example_Struct2 st2; Example_Struct3 st3; } u; };
The first interesting part of the code is where we define our data descriptors for the main lists, the unions and all of structures upon which those two depend.
/* declaring types */ _data_descriptors_init(void) { Eet_Data_Descriptor_Class eddc; EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists); _lists_descriptor = eet_data_descriptor_file_new(&eddc); _struct_1_descriptor = _st1_dd(); _struct_2_descriptor = _st2_dd(); _struct_3_descriptor = _st3_dd(); /* for union */ EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union); _union_descriptor = eet_data_descriptor_file_new(&eddc); eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; eddc.func.type_get = _union_type_get; eddc.func.type_set = _union_type_set; _union_unified_descriptor = eet_data_descriptor_file_new(&eddc); EET_DATA_DESCRIPTOR_ADD_MAPPING( _union_unified_descriptor, "ST1", _struct_1_descriptor); EET_DATA_DESCRIPTOR_ADD_MAPPING( _union_unified_descriptor, "ST2", _struct_2_descriptor); EET_DATA_DESCRIPTOR_ADD_MAPPING( _union_unified_descriptor, "ST3", _struct_3_descriptor); EET_DATA_DESCRIPTOR_ADD_UNION( _union_descriptor, Example_Union, "u", u, type, _union_unified_descriptor); EET_DATA_DESCRIPTOR_ADD_LIST( _lists_descriptor, Example_Lists, "union_list", union_list, _union_descriptor);
Example_Struct1
, Example_Struct2
and Example_Struct3
is straightforward, a matter already covered on Advanced use of Eet Data Descriptors. What is new, here, are the two type matching functions for our unions. There, we must set the data
pointer to its matching type, on _union_type_set
and return the correct matching type, on _union_type_get:
With the EET_DATA_DESCRIPTOR_ADD_MAPPING calls, which follow, we make the the link between our type names and their respective structs. The code handling actual data is pretty much the same as in Advanced use of Eet Data Descriptors -- one uses command line arguments to enter new data chunks (or just to visualize the contents of an Eet file), signalling if they are unions or variants. One must also pass the type of the data chuck to enter, with integers 1, 2 or 3. Then, come the fields for each type:
"Usage:\n\t%s <input> <output> [action action-params]\n\n" "where actions and their parameters are:\n" "\tunion <type> [fields]\n" "\tvariant <type> [fields]\n" "\n", argv[0]);
Variants are very similar to unions, except that data chunks need not contain previously allocated space for each of the possible types of data going in them:
typedef struct _Example_Variant_Type Example_Variant_Type; struct _Example_Variant_Type { const char *type; Eina_Bool unknow : 1; }; struct _Example_Variant { Example_Variant_Type t; void *data; /* differently than the union type, we * don't need to pre-allocate the memory * for the field*/ };
The code declaring the data descriptors and handling the data is very similar to the unions part, and is left for the reader to check for him/herself. The complete code of the example follows.
00001 /* 00002 * build: gcc -o eet_data_file_descriptor_02 eet-data-file_descriptor_02.c `pkg-config --cflags --libs eet eina` 00003 */ 00004 00005 #include <Eina.h> 00006 #include <Eet.h> 00007 #include <stdio.h> 00008 #include <limits.h> 00009 #include <sys/types.h> 00010 #include <sys/stat.h> 00011 #include <unistd.h> 00012 00013 typedef enum _Example_Data_Type Example_Data_Type; 00014 typedef struct _Example_Variant_Type Example_Variant_Type; 00015 typedef struct _Example_Variant Example_Variant; 00016 typedef struct _Example_Union Example_Union; 00017 typedef struct _Example_Struct1 Example_Struct1; 00018 typedef struct _Example_Struct2 Example_Struct2; 00019 typedef struct _Example_Struct3 Example_Struct3; 00020 typedef struct _Example_Lists Example_Lists; 00021 00022 enum _Example_Data_Type 00023 { 00024 EET_UNKNOWN = 0, 00025 EET_STRUCT1, 00026 EET_STRUCT2, 00027 EET_STRUCT3 00028 }; 00029 00030 struct 00031 { 00032 Example_Data_Type u; 00033 const char *name; 00034 } eet_mapping[] = { 00035 { EET_STRUCT1, "ST1" }, 00036 { EET_STRUCT2, "ST2" }, 00037 { EET_STRUCT3, "ST3" }, 00038 { EET_UNKNOWN, NULL } 00039 }; 00040 00041 struct _Example_Struct1 00042 { 00043 double val1; 00044 int stuff; 00045 const char *s1; 00046 }; 00047 00048 struct _Example_Struct2 00049 { 00050 Eina_Bool b1; 00051 unsigned long long v1; 00052 }; 00053 00054 struct _Example_Struct3 00055 { 00056 int body; 00057 }; 00058 00059 struct _Example_Union 00060 { 00061 Example_Data_Type type; 00062 00063 union { 00064 Example_Struct1 st1; 00065 Example_Struct2 st2; 00066 Example_Struct3 st3; 00067 } u; 00068 }; 00069 00070 struct _Example_Variant_Type 00071 { 00072 const char *type; 00073 Eina_Bool unknow : 1; 00074 }; 00075 00076 struct _Example_Variant 00077 { 00078 Example_Variant_Type t; 00079 00080 void *data; /* differently than the union type, we 00081 * don't need to pre-allocate the memory 00082 * for the field*/ 00083 }; 00084 00085 struct _Example_Lists 00086 { 00087 Eina_List *union_list; 00088 Eina_List *variant_list; 00089 }; 00090 00091 static void 00092 _st1_set(Example_Struct1 *st1, 00093 double v1, 00094 int v2, 00095 const char *v3) 00096 { 00097 st1->val1 = v1; 00098 st1->stuff = v2; 00099 st1->s1 = v3; 00100 } /* _st1_set */ 00101 00102 static void 00103 _st2_set(Example_Struct2 *st2, 00104 Eina_Bool v1, 00105 unsigned long long v2) 00106 { 00107 st2->b1 = v1; 00108 st2->v1 = v2; 00109 } /* _st2_set */ 00110 00111 static void 00112 _st3_set(Example_Struct3 *st3, 00113 int v1) 00114 { 00115 st3->body = v1; 00116 } /* _st3_set */ 00117 00118 static const char * 00119 /* union 00120 type_get() */ 00121 _union_type_get(const void *data, 00122 Eina_Bool *unknow) 00123 { 00124 const Example_Data_Type *u = data; 00125 int i; 00126 00127 if (unknow) 00128 *unknow = EINA_FALSE; 00129 00130 for (i = 0; eet_mapping[i].name != NULL; ++i) 00131 if (*u == eet_mapping[i].u) 00132 return eet_mapping[i].name; 00133 00134 if (unknow) 00135 *unknow = EINA_TRUE; 00136 00137 return NULL; 00138 } /* _union_type_get */ 00139 00140 static Eina_Bool 00141 _union_type_set(const char *type, 00142 void *data, 00143 Eina_Bool unknow) 00144 { 00145 Example_Data_Type *u = data; 00146 int i; 00147 00148 if (unknow) 00149 return EINA_FALSE; 00150 00151 for (i = 0; eet_mapping[i].name != NULL; ++i) 00152 if (strcmp(eet_mapping[i].name, type) == 0) 00153 { 00154 *u = eet_mapping[i].u; 00155 return EINA_TRUE; 00156 } 00157 00158 return EINA_FALSE; 00159 } /* _union_type_set */ 00160 00161 static const char * 00162 _variant_type_get(const void *data, 00163 Eina_Bool *unknow) 00164 { 00165 const Example_Variant_Type *type = data; 00166 int i; 00167 00168 if (unknow) 00169 *unknow = type->unknow; 00170 00171 for (i = 0; eet_mapping[i].name != NULL; ++i) 00172 if (strcmp(type->type, eet_mapping[i].name) == 0) 00173 return eet_mapping[i].name; 00174 00175 if (unknow) 00176 *unknow = EINA_FALSE; 00177 00178 return type->type; 00179 } /* _variant_type_get */ 00180 00181 static Eina_Bool 00182 _variant_type_set(const char *type, 00183 void *data, 00184 Eina_Bool unknow) 00185 { 00186 Example_Variant_Type *vt = data; 00187 00188 vt->type = type; 00189 vt->unknow = unknow; 00190 return EINA_TRUE; 00191 } /* _variant_type_set */ 00192 00193 static Eet_Data_Descriptor * 00194 _st1_dd(void) 00195 { 00196 Eet_Data_Descriptor_Class eddc; 00197 Eet_Data_Descriptor *res; 00198 00199 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1); 00200 res = eet_data_descriptor_file_new(&eddc); 00201 EET_DATA_DESCRIPTOR_ADD_BASIC( 00202 res, Example_Struct1, "val1", val1, EET_T_DOUBLE); 00203 EET_DATA_DESCRIPTOR_ADD_BASIC( 00204 res, Example_Struct1, "stuff", stuff, EET_T_INT); 00205 EET_DATA_DESCRIPTOR_ADD_BASIC( 00206 res, Example_Struct1, "s1", s1, EET_T_STRING); 00207 00208 return res; 00209 } /* _st1_dd */ 00210 00211 static Eet_Data_Descriptor * 00212 _st2_dd(void) 00213 { 00214 Eet_Data_Descriptor_Class eddc; 00215 Eet_Data_Descriptor *res; 00216 00217 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2); 00218 res = eet_data_descriptor_file_new(&eddc); 00219 EET_DATA_DESCRIPTOR_ADD_BASIC( 00220 res, Example_Struct2, "b1", b1, EET_T_UCHAR); 00221 EET_DATA_DESCRIPTOR_ADD_BASIC( 00222 res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG); 00223 00224 return res; 00225 } /* _st2_dd */ 00226 00227 static Eet_Data_Descriptor * 00228 _st3_dd(void) 00229 { 00230 Eet_Data_Descriptor_Class eddc; 00231 Eet_Data_Descriptor *res; 00232 00233 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3); 00234 res = eet_data_descriptor_file_new(&eddc); 00235 EET_DATA_DESCRIPTOR_ADD_BASIC( 00236 res, Example_Struct3, "body", body, EET_T_INT); 00237 00238 return res; 00239 } /* _st3_dd */ 00240 00241 /* string that represents the entry in the eet file. you might like to 00242 * have different profiles or so in the same file, this is possible 00243 * with different strings 00244 */ 00245 static const char CACHE_FILE_ENTRY[] = "cache"; 00246 00247 /* keep the descriptor static global, so it can be shared by different 00248 * functions (load/save) of this and only this file. 00249 */ 00250 static Eet_Data_Descriptor *_lists_descriptor; 00251 static Eet_Data_Descriptor *_struct_1_descriptor; 00252 static Eet_Data_Descriptor *_struct_2_descriptor; 00253 static Eet_Data_Descriptor *_struct_3_descriptor; 00254 static Eet_Data_Descriptor *_union_descriptor; 00255 static Eet_Data_Descriptor *_variant_descriptor; 00256 static Eet_Data_Descriptor *_union_unified_descriptor; 00257 static Eet_Data_Descriptor *_variant_unified_descriptor; 00258 00259 /* keep file handle alive, so mmap()ed strings are all alive as 00260 * well */ 00261 static Eet_File *_cache_file = NULL; 00262 static Eet_Dictionary *_cache_dict = NULL; 00263 00264 static void 00265 /* declaring types */ 00266 _data_descriptors_init(void) 00267 { 00268 Eet_Data_Descriptor_Class eddc; 00269 00270 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists); 00271 _lists_descriptor = eet_data_descriptor_file_new(&eddc); 00272 00273 _struct_1_descriptor = _st1_dd(); 00274 _struct_2_descriptor = _st2_dd(); 00275 _struct_3_descriptor = _st3_dd(); 00276 00277 /* for union */ 00278 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union); 00279 _union_descriptor = eet_data_descriptor_file_new(&eddc); 00280 00281 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; 00282 eddc.func.type_get = _union_type_get; 00283 eddc.func.type_set = _union_type_set; 00284 _union_unified_descriptor = eet_data_descriptor_file_new(&eddc); 00285 00286 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00287 _union_unified_descriptor, "ST1", _struct_1_descriptor); 00288 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00289 _union_unified_descriptor, "ST2", _struct_2_descriptor); 00290 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00291 _union_unified_descriptor, "ST3", _struct_3_descriptor); 00292 00293 EET_DATA_DESCRIPTOR_ADD_UNION( 00294 _union_descriptor, Example_Union, "u", u, type, 00295 _union_unified_descriptor); 00296 00297 EET_DATA_DESCRIPTOR_ADD_LIST( 00298 _lists_descriptor, Example_Lists, "union_list", union_list, 00299 _union_descriptor); 00300 00301 /* for variant */ 00302 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant); 00303 _variant_descriptor = eet_data_descriptor_file_new(&eddc); 00304 00305 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; 00306 eddc.func.type_get = _variant_type_get; 00307 eddc.func.type_set = _variant_type_set; 00308 _variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc); 00309 00310 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00311 _variant_unified_descriptor, "ST1", _struct_1_descriptor); 00312 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00313 _variant_unified_descriptor, "ST2", _struct_2_descriptor); 00314 EET_DATA_DESCRIPTOR_ADD_MAPPING( 00315 _variant_unified_descriptor, "ST3", _struct_3_descriptor); 00316 00317 EET_DATA_DESCRIPTOR_ADD_VARIANT( 00318 _variant_descriptor, Example_Variant, "data", data, t, 00319 _variant_unified_descriptor); 00320 00321 EET_DATA_DESCRIPTOR_ADD_LIST( 00322 _lists_descriptor, Example_Lists, "variant_list", variant_list, 00323 _variant_descriptor); 00324 } /* _data_descriptors_init */ 00325 00326 static void 00327 _data_descriptors_shutdown(void) 00328 { 00329 eet_data_descriptor_free(_lists_descriptor); 00330 eet_data_descriptor_free(_struct_1_descriptor); 00331 eet_data_descriptor_free(_struct_2_descriptor); 00332 eet_data_descriptor_free(_struct_3_descriptor); 00333 eet_data_descriptor_free(_union_descriptor); 00334 eet_data_descriptor_free(_variant_descriptor); 00335 eet_data_descriptor_free(_union_unified_descriptor); 00336 eet_data_descriptor_free(_variant_unified_descriptor); 00337 } /* _data_descriptors_shutdown */ 00338 00339 /* need to check if the pointer came from mmap()ed area in 00340 * eet_dictionary or it was allocated with eina_stringshare_add() 00341 */ 00342 static void 00343 _string_free(const char *str) 00344 { 00345 if (!str) 00346 return; 00347 00348 if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str))) 00349 return; 00350 00351 eina_stringshare_del(str); 00352 } /* _string_free */ 00353 00354 static Example_Union * 00355 _union_1_new(const char *v1, 00356 const char *v2, 00357 const char *v3) 00358 { 00359 Example_Union *un = calloc(1, sizeof(Example_Union)); 00360 if (!un) 00361 { 00362 fprintf( 00363 stderr, "ERROR: could not allocate an Example_Union struct.\n"); 00364 return NULL; 00365 } 00366 00367 un->type = EET_STRUCT1; 00368 _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3)); 00369 00370 return un; 00371 } 00372 00373 static Example_Union * 00374 _union_2_new(const char *v1, 00375 const char *v2) 00376 { 00377 Example_Union *un = calloc(1, sizeof(Example_Union)); 00378 if (!un) 00379 { 00380 fprintf( 00381 stderr, "ERROR: could not allocate an Example_Union struct.\n"); 00382 return NULL; 00383 } 00384 00385 un->type = EET_STRUCT2; 00386 _st2_set(&(un->u.st2), atoi(v1), atoi(v2)); 00387 00388 return un; 00389 } 00390 00391 static Example_Union * 00392 _union_3_new(const char *v1) 00393 { 00394 Example_Union *un = calloc(1, sizeof(Example_Union)); 00395 if (!un) 00396 { 00397 fprintf( 00398 stderr, "ERROR: could not allocate an Example_Union struct.\n"); 00399 return NULL; 00400 } 00401 00402 un->type = EET_STRUCT3; 00403 _st3_set(&(un->u.st3), atoi(v1)); 00404 00405 return un; 00406 } 00407 00408 static Example_Variant * 00409 _variant_1_new(const char *v1, 00410 const char *v2, 00411 const char *v3) 00412 { 00413 Example_Struct1 *st1; 00414 Example_Variant *va = calloc(1, sizeof(Example_Variant)); 00415 if (!va) 00416 { 00417 fprintf( 00418 stderr, "ERROR: could not allocate an Example_Variant struct.\n"); 00419 return NULL; 00420 } 00421 00422 va = calloc(1, sizeof (Example_Variant)); 00423 va->t.type = eet_mapping[0].name; 00424 st1 = calloc(1, sizeof (Example_Struct1)); 00425 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3)); 00426 va->data = st1; 00427 00428 return va; 00429 } 00430 00431 static Example_Variant * 00432 _variant_2_new(const char *v1, 00433 const char *v2) 00434 { 00435 printf("varinant 2 new\n"); 00436 00437 Example_Struct2 *st2; 00438 Example_Variant *va = calloc(1, sizeof(Example_Variant)); 00439 if (!va) 00440 { 00441 fprintf( 00442 stderr, "ERROR: could not allocate an Example_Variant struct.\n"); 00443 return NULL; 00444 } 00445 00446 va = calloc(1, sizeof (Example_Variant)); 00447 00448 va->t.type = eet_mapping[1].name; 00449 00450 printf("type gets %s\n", va->t.type); 00451 00452 st2 = calloc(1, sizeof (Example_Struct2)); 00453 _st2_set(st2, atoi(v1), atoi(v2)); 00454 va->data = st2; 00455 00456 return va; 00457 } 00458 00459 static Example_Variant * 00460 _variant_3_new(const char *v1) 00461 { 00462 Example_Struct3 *st3; 00463 Example_Variant *va = calloc(1, sizeof(Example_Variant)); 00464 if (!va) 00465 { 00466 fprintf( 00467 stderr, "ERROR: could not allocate an Example_Variant struct.\n"); 00468 return NULL; 00469 } 00470 00471 va = calloc(1, sizeof (Example_Variant)); 00472 va->t.type = eet_mapping[2].name; 00473 st3 = calloc(1, sizeof (Example_Struct3)); 00474 _st3_set(st3, atoi(v1)); 00475 va->data = st3; 00476 00477 return va; 00478 } 00479 00480 static Example_Lists * 00481 _data_new(void) 00482 { 00483 Example_Lists *example_lists = calloc(1, sizeof(Example_Lists)); 00484 if (!example_lists) 00485 { 00486 fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n"); 00487 return NULL; 00488 } 00489 00490 return example_lists; 00491 } /* _data_new */ 00492 00493 static void 00494 _union_free(Example_Union *un) 00495 { 00496 if (un->type == EET_STRUCT1) 00497 { 00498 Example_Struct1 *st1 = &(un->u.st1); 00499 _string_free(st1->s1); 00500 } 00501 00502 free(un); 00503 } 00504 00505 static void 00506 _variant_free(Example_Variant *va) 00507 { 00508 if (!strcmp(va->t.type, eet_mapping[0].name)) 00509 { 00510 Example_Struct1 *st1 = va->data; 00511 _string_free(st1->s1); 00512 } 00513 00514 free(va->data); 00515 free(va); 00516 } 00517 00518 static void 00519 _data_free(Example_Lists *cache) 00520 { 00521 Example_Union *un; 00522 Example_Variant *va; 00523 00524 EINA_LIST_FREE(cache->union_list, un) 00525 _union_free(un); 00526 00527 EINA_LIST_FREE(cache->variant_list, va) 00528 _variant_free(va); 00529 00530 free(cache); 00531 } /* _data_free */ 00532 00533 static Example_Lists * 00534 _data_load(const char *filename) 00535 { 00536 Example_Lists *data; 00537 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ); 00538 if (!ef) 00539 { 00540 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename); 00541 return NULL; 00542 } 00543 00544 data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY); 00545 if (!data) 00546 { 00547 eet_close(ef); 00548 return NULL; 00549 } 00550 00551 if (_cache_file) 00552 eet_close(_cache_file); 00553 00554 _cache_file = ef; 00555 _cache_dict = eet_dictionary_get(ef); 00556 00557 return data; 00558 } /* _data_load */ 00559 00560 static Eina_Bool 00561 _data_save(const Example_Lists *cache, 00562 const char *filename) 00563 { 00564 char tmp[PATH_MAX]; 00565 Eet_File *ef; 00566 Eina_Bool ret; 00567 unsigned int i, len; 00568 struct stat st; 00569 00570 len = eina_strlcpy(tmp, filename, sizeof(tmp)); 00571 if (len + 12 >= (int)sizeof(tmp)) 00572 { 00573 fprintf(stderr, "ERROR: file name is too big: %s\n", filename); 00574 return EINA_FALSE; 00575 } 00576 00577 i = 0; 00578 do 00579 { 00580 snprintf(tmp + len, 12, ".%u", i); 00581 i++; 00582 } 00583 while (stat(tmp, &st) == 0); 00584 00585 ef = eet_open(tmp, EET_FILE_MODE_WRITE); 00586 if (!ef) 00587 { 00588 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp); 00589 return EINA_FALSE; 00590 } 00591 00592 ret = eet_data_write 00593 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE); 00594 00595 eet_close(ef); 00596 00597 if (ret) 00598 { 00599 unlink(filename); 00600 rename(tmp, filename); 00601 } 00602 00603 return ret; 00604 } /* _data_save */ 00605 00606 static void 00607 _print_union(const Example_Union *un) 00608 { 00609 printf("\t | type: %s'\n", eet_mapping[un->type - 1].name); 00610 00611 switch (un->type) 00612 { 00613 case EET_STRUCT1: 00614 printf("\t\t val1: %f\n", un->u.st1.val1); 00615 printf("\t\t stuff: %d\n", un->u.st1.stuff); 00616 printf("\t\t s1: %s\n", un->u.st1.s1); 00617 break; 00618 00619 case EET_STRUCT2: 00620 printf("\t\t val1: %i\n", un->u.st2.b1); 00621 printf("\t\t stuff: %lli\n", un->u.st2.v1); 00622 break; 00623 00624 case EET_STRUCT3: 00625 printf("\t\t val1: %i\n", un->u.st3.body); 00626 break; 00627 00628 default: 00629 return; 00630 } 00631 } 00632 00633 static void 00634 _print_variant(const Example_Variant *va) 00635 { 00636 printf("\t | type: %s'\n", va->t.type); 00637 00638 switch (va->t.type[2]) 00639 { 00640 case '1': 00641 { 00642 Example_Struct1 *st1 = va->data; 00643 00644 printf("\t\t val1: %f\n", st1->val1); 00645 printf("\t\t stuff: %d\n", st1->stuff); 00646 printf("\t\t s1: %s\n", st1->s1); 00647 } 00648 break; 00649 00650 case '2': 00651 { 00652 Example_Struct2 *st2 = va->data; 00653 00654 printf("\t\t val1: %i\n", st2->b1); 00655 printf("\t\t stuff: %lli\n", st2->v1); 00656 } 00657 break; 00658 00659 case '3': 00660 { 00661 Example_Struct3 *st3 = va->data; 00662 00663 printf("\t\t val1: %i\n", st3->body); 00664 } 00665 break; 00666 00667 default: 00668 return; 00669 } 00670 } 00671 00672 int 00673 main(int argc, 00674 char *argv[]) 00675 { 00676 Example_Lists *data_lists; 00677 int ret = 0; 00678 00679 if (argc < 3) 00680 { 00681 fprintf(stderr, 00682 "Usage:\n\t%s <input> <output> [action action-params]\n\n" 00683 "where actions and their parameters are:\n" 00684 "\tunion <type> [fields]\n" 00685 "\tvariant <type> [fields]\n" 00686 "\n", 00687 argv[0]); 00688 return -1; 00689 } 00690 00691 eina_init(); 00692 eet_init(); 00693 _data_descriptors_init(); 00694 00695 data_lists = _data_load(argv[1]); 00696 if (!data_lists) 00697 { 00698 printf("Creating new data lists.\n"); 00699 data_lists = _data_new(); 00700 if (!data_lists) 00701 { 00702 ret = -2; 00703 goto end; 00704 } 00705 } 00706 00707 if (argc > 3) 00708 { 00709 if (strcmp(argv[3], "union") == 0) 00710 { 00711 if (argc > 4) 00712 { 00713 int type = atoi(argv[4]); 00714 Example_Union *un; 00715 00716 if (type < EET_STRUCT1 || type > EET_STRUCT3) 00717 { 00718 fprintf(stderr, 00719 "ERROR: invalid type parameter (%s).\n", 00720 argv[4]); 00721 goto cont; 00722 } 00723 00724 switch (type) 00725 { 00726 case 1: 00727 if (argc != 8) 00728 { 00729 fprintf( 00730 stderr, "ERROR: wrong number of parameters" 00731 " (%d).\n", argc); 00732 goto cont; 00733 } 00734 00735 un = _union_1_new( 00736 argv[5], argv[6], argv[7]); 00737 if (!un) 00738 { 00739 fprintf( 00740 stderr, "ERROR: could not create the " 00741 "requested union.\n"); 00742 goto cont; 00743 } 00744 data_lists->union_list = 00745 eina_list_append(data_lists->union_list, un); 00746 break; 00747 00748 case 2: 00749 if (argc != 7) 00750 { 00751 fprintf( 00752 stderr, "ERROR: wrong number of parameters" 00753 " (%d).\n", argc); 00754 goto cont; 00755 } 00756 00757 un = _union_2_new(argv[5], argv[6]); 00758 if (!un) 00759 { 00760 fprintf( 00761 stderr, "ERROR: could not create the " 00762 "requested union.\n"); 00763 goto cont; 00764 } 00765 data_lists->union_list = 00766 eina_list_append(data_lists->union_list, un); 00767 break; 00768 00769 case 3: 00770 if (argc != 6) 00771 { 00772 fprintf( 00773 stderr, "ERROR: wrong number of parameters" 00774 " (%d).\n", argc); 00775 goto cont; 00776 } 00777 00778 un = _union_3_new(argv[5]); 00779 if (!un) 00780 { 00781 fprintf( 00782 stderr, "ERROR: could not create the " 00783 "requested union.\n"); 00784 goto cont; 00785 } 00786 data_lists->union_list = 00787 eina_list_append(data_lists->union_list, un); 00788 break; 00789 00790 default: 00791 fprintf( 00792 stderr, "ERROR: bad type of of struct passed\n"); 00793 goto cont; 00794 } 00795 } 00796 else 00797 fprintf(stderr, 00798 "ERROR: wrong number of parameters (%d).\n", 00799 argc); 00800 } 00801 else if (strcmp(argv[3], "variant") == 0) 00802 { 00803 if (argc > 4) 00804 { 00805 int type = atoi(argv[4]); 00806 Example_Variant *va; 00807 00808 if (type < EET_STRUCT1 || type > EET_STRUCT3) 00809 { 00810 fprintf(stderr, 00811 "ERROR: invalid type parameter (%s).\n", 00812 argv[4]); 00813 goto cont; 00814 } 00815 00816 switch (type) 00817 { 00818 case 1: 00819 if (argc != 8) 00820 { 00821 fprintf( 00822 stderr, "ERROR: wrong number of parameters" 00823 " (%d).\n", argc); 00824 goto cont; 00825 } 00826 00827 va = _variant_1_new( 00828 argv[5], argv[6], argv[7]); 00829 if (!va) 00830 { 00831 fprintf( 00832 stderr, "ERROR: could not create the " 00833 "requested variant.\n"); 00834 goto cont; 00835 } 00836 data_lists->variant_list = 00837 eina_list_append(data_lists->variant_list, va); 00838 break; 00839 00840 case 2: 00841 if (argc != 7) 00842 { 00843 fprintf( 00844 stderr, "ERROR: wrong number of parameters" 00845 " (%d).\n", argc); 00846 goto cont; 00847 } 00848 00849 va = _variant_2_new(argv[5], argv[6]); 00850 if (!va) 00851 { 00852 fprintf( 00853 stderr, "ERROR: could not create the " 00854 "requested variant.\n"); 00855 goto cont; 00856 } 00857 data_lists->variant_list = 00858 eina_list_append(data_lists->variant_list, va); 00859 break; 00860 00861 case 3: 00862 if (argc != 6) 00863 { 00864 fprintf( 00865 stderr, "ERROR: wrong number of parameters" 00866 " (%d).\n", argc); 00867 goto cont; 00868 } 00869 00870 va = _variant_3_new(argv[5]); 00871 if (!va) 00872 { 00873 fprintf( 00874 stderr, "ERROR: could not create the " 00875 "requested variant.\n"); 00876 goto cont; 00877 } 00878 data_lists->variant_list = 00879 eina_list_append(data_lists->variant_list, va); 00880 break; 00881 00882 default: 00883 fprintf( 00884 stderr, "ERROR: bad type of of struct passed\n"); 00885 goto cont; 00886 } 00887 } 00888 else 00889 fprintf(stderr, 00890 "ERROR: wrong number of parameters (%d).\n", 00891 argc); 00892 } 00893 else 00894 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]); 00895 } 00896 00897 cont: 00898 printf("Cached data:\n"); 00899 00900 printf("\tstats: unions=%u, variants=%u\n", 00901 eina_list_count(data_lists->union_list), 00902 eina_list_count(data_lists->variant_list)); 00903 00904 if (eina_list_count(data_lists->union_list)) 00905 { 00906 const Eina_List *l; 00907 const Example_Union *un; 00908 printf("\t * union list:\n"); 00909 00910 EINA_LIST_FOREACH(data_lists->union_list, l, un) 00911 { 00912 _print_union(un); 00913 } 00914 } 00915 00916 if (eina_list_count(data_lists->variant_list)) 00917 { 00918 const Eina_List *l; 00919 const Example_Variant *un; 00920 printf("\t * variant list:\n"); 00921 00922 EINA_LIST_FOREACH(data_lists->variant_list, l, un) 00923 { 00924 _print_variant(un); 00925 } 00926 } 00927 00928 printf("\n"); 00929 00930 if (!_data_save(data_lists, argv[2])) 00931 ret = -3; 00932 00933 _data_free(data_lists); 00934 00935 end: 00936 if (_cache_file) 00937 eet_close(_cache_file); 00938 _data_descriptors_shutdown(); 00939 eet_shutdown(); 00940 eina_shutdown(); 00941 00942 return ret; 00943 } /* main */ 00944