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