File descriptor data example, with Eet unions and variants

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);
The code for descriptors on `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

1. 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.

1 //Compile with:
2 // gcc -o eet-data-file_descriptor_02 eet-data-file_descriptor_02.c `pkg-config --cflags --libs eet eina`
3
4 #include <Eina.h>
5 #include <Eet.h>
6 #include <stdio.h>
7 #include <limits.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11
12 typedef enum _Example_Data_Type Example_Data_Type;
13 typedef struct _Example_Variant_Type Example_Variant_Type;
14 typedef struct _Example_Variant Example_Variant;
15 typedef struct _Example_Union Example_Union;
16 typedef struct _Example_Struct1 Example_Struct1;
17 typedef struct _Example_Struct2 Example_Struct2;
18 typedef struct _Example_Struct3 Example_Struct3;
19 typedef struct _Example_Lists Example_Lists;
20
21 enum _Example_Data_Type
22 {
23 EET_UNKNOWN = 0,
24 EET_STRUCT1,
25 EET_STRUCT2,
26 EET_STRUCT3,
27 EET_BASIC_FLOAT,
28 EET_BASIC_STRING
29 };
30
31 struct
32 {
33 Example_Data_Type u;
34 const char *name;
35 } eet_mapping[] = {
36 { EET_STRUCT1, "ST1" },
37 { EET_STRUCT2, "ST2" },
38 { EET_STRUCT3, "ST3" },
39 { EET_BASIC_FLOAT, "float" },
40 { EET_BASIC_STRING, "string" },
41 { EET_UNKNOWN, NULL }
42 };
43
44 struct _Example_Struct1
45 {
46 double val1;
47 int stuff;
48 const char *s1;
49 };
50
51 struct _Example_Struct2
52 {
53 Eina_Bool b1;
54 unsigned long long v1;
55 };
56
57 struct _Example_Struct3
58 {
59 int body;
60 };
61
62 struct _Example_Union
63 {
64 Example_Data_Type type;
65
66 union {
67 Example_Struct1 st1;
68 Example_Struct2 st2;
69 Example_Struct3 st3;
70 float f;
71 const char* string;
72 } u;
73 };
74
75 struct _Example_Variant_Type
76 {
77 const char *type;
78 Eina_Bool unknow : 1;
79 };
80
81 struct _Example_Variant
82 {
83 Example_Variant_Type t;
84
85 void *data; /* differently than the union type, we
86 * don't need to pre-allocate the memory
87 * for the field*/
88 };
89
90 struct _Example_Lists
91 {
92 Eina_List *union_list;
93 Eina_List *variant_list;
94 };
95
96 static void
97 _st1_set(Example_Struct1 *st1,
98 double v1,
99 int v2,
100 const char *v3)
101 {
102 st1->val1 = v1;
103 st1->stuff = v2;
104 st1->s1 = v3;
105 } /* _st1_set */
106
107 static void
108 _st2_set(Example_Struct2 *st2,
109 Eina_Bool v1,
110 unsigned long long v2)
111 {
112 st2->b1 = v1;
113 st2->v1 = v2;
114 } /* _st2_set */
115
116 static void
117 _st3_set(Example_Struct3 *st3,
118 int v1)
119 {
120 st3->body = v1;
121 } /* _st3_set */
122
123 static const char *
124 /* union
125 type_get() */
126 _union_type_get(const void *data,
127 Eina_Bool *unknow)
128 {
129 const Example_Data_Type *u = data;
130 int i;
131
132 if (unknow)
133 *unknow = EINA_FALSE;
134
135 for (i = 0; eet_mapping[i].name != NULL; ++i)
136 if (*u == eet_mapping[i].u)
137 return eet_mapping[i].name;
138
139 if (unknow)
140 *unknow = EINA_TRUE;
141
142 return NULL;
143 } /* _union_type_get */
144
145 static Eina_Bool
146 _union_type_set(const char *type,
147 void *data,
148 Eina_Bool unknow)
149 {
150 Example_Data_Type *u = data;
151 int i;
152
153 if (unknow)
154 return EINA_FALSE;
155
156 for (i = 0; eet_mapping[i].name != NULL; ++i)
157 if (strcmp(eet_mapping[i].name, type) == 0)
158 {
159 *u = eet_mapping[i].u;
160 return EINA_TRUE;
161 }
162
163 return EINA_FALSE;
164 } /* _union_type_set */
165
166 static const char *
167 _variant_type_get(const void *data,
168 Eina_Bool *unknow)
169 {
170 const Example_Variant_Type *type = data;
171 int i;
172
173 if (unknow)
174 *unknow = type->unknow;
175
176 for (i = 0; eet_mapping[i].name != NULL; ++i)
177 if (strcmp(type->type, eet_mapping[i].name) == 0)
178 return eet_mapping[i].name;
179
180 if (unknow)
181 *unknow = EINA_FALSE;
182
183 return type->type;
184 } /* _variant_type_get */
185
186 static Eina_Bool
187 _variant_type_set(const char *type,
188 void *data,
189 Eina_Bool unknow)
190 {
191 Example_Variant_Type *vt = data;
192
193 vt->type = type;
194 vt->unknow = unknow;
195 return EINA_TRUE;
196 } /* _variant_type_set */
197
198 static Eet_Data_Descriptor *
199 _st1_dd(void)
200 {
201 Eet_Data_Descriptor_Class eddc;
202 Eet_Data_Descriptor *res;
203
204 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1);
205 res = eet_data_descriptor_file_new(&eddc);
206 EET_DATA_DESCRIPTOR_ADD_BASIC(
207 res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
208 EET_DATA_DESCRIPTOR_ADD_BASIC(
209 res, Example_Struct1, "stuff", stuff, EET_T_INT);
210 EET_DATA_DESCRIPTOR_ADD_BASIC(
211 res, Example_Struct1, "s1", s1, EET_T_STRING);
212
213 return res;
214 } /* _st1_dd */
215
216 static Eet_Data_Descriptor *
217 _st2_dd(void)
218 {
219 Eet_Data_Descriptor_Class eddc;
220 Eet_Data_Descriptor *res;
221
222 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2);
223 res = eet_data_descriptor_file_new(&eddc);
224 EET_DATA_DESCRIPTOR_ADD_BASIC(
225 res, Example_Struct2, "b1", b1, EET_T_UCHAR);
226 EET_DATA_DESCRIPTOR_ADD_BASIC(
227 res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG);
228
229 return res;
230 } /* _st2_dd */
231
232 static Eet_Data_Descriptor *
233 _st3_dd(void)
234 {
235 Eet_Data_Descriptor_Class eddc;
236 Eet_Data_Descriptor *res;
237
238 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3);
239 res = eet_data_descriptor_file_new(&eddc);
240 EET_DATA_DESCRIPTOR_ADD_BASIC(
241 res, Example_Struct3, "body", body, EET_T_INT);
242
243 return res;
244 } /* _st3_dd */
245
246 /* string that represents the entry in the eet file. you might like to
247 * have different profiles or so in the same file, this is possible
248 * with different strings
249 */
250 static const char CACHE_FILE_ENTRY[] = "cache";
251
252 /* keep the descriptor static global, so it can be shared by different
253 * functions (load/save) of this and only this file.
254 */
255 static Eet_Data_Descriptor *_lists_descriptor;
256 static Eet_Data_Descriptor *_struct_1_descriptor;
257 static Eet_Data_Descriptor *_struct_2_descriptor;
258 static Eet_Data_Descriptor *_struct_3_descriptor;
259 static Eet_Data_Descriptor *_union_descriptor;
260 static Eet_Data_Descriptor *_variant_descriptor;
261 static Eet_Data_Descriptor *_union_unified_descriptor;
262 static Eet_Data_Descriptor *_variant_unified_descriptor;
263
264 /* keep file handle alive, so mmap()ed strings are all alive as
265 * well */
266 static Eet_File *_cache_file = NULL;
267 static Eet_Dictionary *_cache_dict = NULL;
268
269 static void
270 /* declaring types */
271 _data_descriptors_init(void)
272 {
273 Eet_Data_Descriptor_Class eddc;
274
275 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
276 _lists_descriptor = eet_data_descriptor_file_new(&eddc);
277
278 _struct_1_descriptor = _st1_dd();
279 _struct_2_descriptor = _st2_dd();
280 _struct_3_descriptor = _st3_dd();
281
282 /* for union */
283 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
284 _union_descriptor = eet_data_descriptor_file_new(&eddc);
285
286 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
287 eddc.func.type_get = _union_type_get;
288 eddc.func.type_set = _union_type_set;
289 _union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
290
291 EET_DATA_DESCRIPTOR_ADD_MAPPING(
292 _union_unified_descriptor, "ST1", _struct_1_descriptor);
293 EET_DATA_DESCRIPTOR_ADD_MAPPING(
294 _union_unified_descriptor, "ST2", _struct_2_descriptor);
295 EET_DATA_DESCRIPTOR_ADD_MAPPING(
296 _union_unified_descriptor, "ST3", _struct_3_descriptor);
297 EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
298 _union_unified_descriptor, "float", EET_T_FLOAT);
299 EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
300 _union_unified_descriptor, "string", EET_T_STRING);
301
302 EET_DATA_DESCRIPTOR_ADD_UNION(
303 _union_descriptor, Example_Union, "u", u, type,
304 _union_unified_descriptor);
305
306 EET_DATA_DESCRIPTOR_ADD_LIST(
307 _lists_descriptor, Example_Lists, "union_list", union_list,
308 _union_descriptor);
309
310 /* for variant */
311 EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant);
312 _variant_descriptor = eet_data_descriptor_file_new(&eddc);
313
314 eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
315 eddc.func.type_get = _variant_type_get;
316 eddc.func.type_set = _variant_type_set;
317 _variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
318
319 EET_DATA_DESCRIPTOR_ADD_MAPPING(
320 _variant_unified_descriptor, "ST1", _struct_1_descriptor);
321 EET_DATA_DESCRIPTOR_ADD_MAPPING(
322 _variant_unified_descriptor, "ST2", _struct_2_descriptor);
323 EET_DATA_DESCRIPTOR_ADD_MAPPING(
324 _variant_unified_descriptor, "ST3", _struct_3_descriptor);
325
326 EET_DATA_DESCRIPTOR_ADD_VARIANT(
327 _variant_descriptor, Example_Variant, "data", data, t,
328 _variant_unified_descriptor);
329
330 EET_DATA_DESCRIPTOR_ADD_LIST(
331 _lists_descriptor, Example_Lists, "variant_list", variant_list,
332 _variant_descriptor);
333 } /* _data_descriptors_init */
334
335 static void
336 _data_descriptors_shutdown(void)
337 {
338 eet_data_descriptor_free(_lists_descriptor);
339 eet_data_descriptor_free(_struct_1_descriptor);
340 eet_data_descriptor_free(_struct_2_descriptor);
341 eet_data_descriptor_free(_struct_3_descriptor);
342 eet_data_descriptor_free(_union_descriptor);
343 eet_data_descriptor_free(_variant_descriptor);
344 eet_data_descriptor_free(_union_unified_descriptor);
345 eet_data_descriptor_free(_variant_unified_descriptor);
346 } /* _data_descriptors_shutdown */
347
348 /* need to check if the pointer came from mmap()ed area in
349 * eet_dictionary or it was allocated with eina_stringshare_add()
350 */
351 static void
352 _string_free(const char *str)
353 {
354 if (!str)
355 return;
356
357 if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str)))
358 return;
359
360 eina_stringshare_del(str);
361 } /* _string_free */
362
363 static Example_Union *
364 _union_1_new(const char *v1,
365 const char *v2,
366 const char *v3)
367 {
368 Example_Union *un = calloc(1, sizeof(Example_Union));
369 if (!un)
370 {
371 fprintf(
372 stderr, "ERROR: could not allocate an Example_Union struct.\n");
373 return NULL;
374 }
375
376 un->type = EET_STRUCT1;
377 _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3));
378
379 return un;
380 }
381
382 static Example_Union *
383 _union_2_new(const char *v1,
384 const char *v2)
385 {
386 Example_Union *un = calloc(1, sizeof(Example_Union));
387 if (!un)
388 {
389 fprintf(
390 stderr, "ERROR: could not allocate an Example_Union struct.\n");
391 return NULL;
392 }
393
394 un->type = EET_STRUCT2;
395 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
396
397 return un;
398 }
399
400 static Example_Union *
401 _union_3_new(const char *v1)
402 {
403 Example_Union *un = calloc(1, sizeof(Example_Union));
404 if (!un)
405 {
406 fprintf(
407 stderr, "ERROR: could not allocate an Example_Union struct.\n");
408 return NULL;
409 }
410
411 un->type = EET_STRUCT3;
412 _st3_set(&(un->u.st3), atoi(v1));
413
414 return un;
415 }
416
417 static Example_Union *
418 _union_float_new(const char *v1)
419 {
420 Example_Union *un = calloc(1, sizeof(Example_Union));
421 if (!un)
422 {
423 fprintf(
424 stderr, "ERROR: could not allocate an Example_Union struct.\n");
425 return NULL;
426 }
427
428 un->type = EET_BASIC_FLOAT;
429 un->u.f = atof(v1);
430
431 return un;
432 }
433
434 static Example_Union *
435 _union_string_new(const char *v1)
436 {
437 Example_Union *un = calloc(1, sizeof(Example_Union));
438 if (!un)
439 {
440 fprintf(
441 stderr, "ERROR: could not allocate an Example_Union struct.\n");
442 return NULL;
443 }
444
445 un->type = EET_BASIC_STRING;
446 un->u.string = v1;
447
448 return un;
449 }
450
451 static Example_Variant *
452 _variant_1_new(const char *v1,
453 const char *v2,
454 const char *v3)
455 {
456 Example_Struct1 *st1;
457 Example_Variant *va = calloc(1, sizeof(Example_Variant));
458 if (!va)
459 {
460 fprintf(
461 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
462 return NULL;
463 }
464
465 va->t.type = eet_mapping[0].name;
466 st1 = calloc(1, sizeof (Example_Struct1));
467 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
468 va->data = st1;
469
470 return va;
471 }
472
473 static Example_Variant *
474 _variant_2_new(const char *v1,
475 const char *v2)
476 {
477 printf("varinant 2 new\n");
478
479 Example_Struct2 *st2;
480 Example_Variant *va = calloc(1, sizeof(Example_Variant));
481 if (!va)
482 {
483 fprintf(
484 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
485 return NULL;
486 }
487
488 va->t.type = eet_mapping[1].name;
489
490 printf("type gets %s\n", va->t.type);
491
492 st2 = calloc(1, sizeof (Example_Struct2));
493 _st2_set(st2, atoi(v1), atoi(v2));
494 va->data = st2;
495
496 return va;
497 }
498
499 static Example_Variant *
500 _variant_3_new(const char *v1)
501 {
502 Example_Struct3 *st3;
503 Example_Variant *va = calloc(1, sizeof(Example_Variant));
504 if (!va)
505 {
506 fprintf(
507 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
508 return NULL;
509 }
510
511 va->t.type = eet_mapping[2].name;
512 st3 = calloc(1, sizeof (Example_Struct3));
513 _st3_set(st3, atoi(v1));
514 va->data = st3;
515
516 return va;
517 }
518
519 static Example_Lists *
520 _data_new(void)
521 {
522 Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
523 if (!example_lists)
524 {
525 fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
526 return NULL;
527 }
528
529 return example_lists;
530 } /* _data_new */
531
532 static void
533 _union_free(Example_Union *un)
534 {
535 if (un->type == EET_STRUCT1)
536 {
537 Example_Struct1 *st1 = &(un->u.st1);
538 _string_free(st1->s1);
539 }
540
541 free(un);
542 }
543
544 static void
545 _variant_free(Example_Variant *va)
546 {
547 if (!strcmp(va->t.type, eet_mapping[0].name))
548 {
549 Example_Struct1 *st1 = va->data;
550 _string_free(st1->s1);
551 }
552
553 free(va->data);
554 free(va);
555 }
556
557 static void
558 _data_free(Example_Lists *cache)
559 {
560 Example_Union *un;
561 Example_Variant *va;
562
563 EINA_LIST_FREE(cache->union_list, un)
564 _union_free(un);
565
566 EINA_LIST_FREE(cache->variant_list, va)
567 _variant_free(va);
568
569 free(cache);
570 } /* _data_free */
571
572 static Example_Lists *
573 _data_load(const char *filename)
574 {
575 Example_Lists *data;
576 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
577 if (!ef)
578 {
579 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
580 return NULL;
581 }
582
583 data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
584 if (!data)
585 {
586 eet_close(ef);
587 return NULL;
588 }
589
590 if (_cache_file)
591 eet_close(_cache_file);
592
593 _cache_file = ef;
594 _cache_dict = eet_dictionary_get(ef);
595
596 return data;
597 } /* _data_load */
598
599 static Eina_Bool
600 _data_save(const Example_Lists *cache,
601 const char *filename)
602 {
603 char tmp[PATH_MAX];
604 Eet_File *ef;
605 Eina_Bool ret;
606 unsigned int i, len;
607 struct stat st;
608
609 len = eina_strlcpy(tmp, filename, sizeof(tmp));
610 if (len + 12 >= (int)sizeof(tmp))
611 {
612 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
613 return EINA_FALSE;
614 }
615
616 i = 0;
617 do
618 {
619 snprintf(tmp + len, 12, ".%u", i);
620 i++;
621 }
622 while (stat(tmp, &st) == 0);
623
624 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
625 if (!ef)
626 {
627 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
628 return EINA_FALSE;
629 }
630
631 ret = eet_data_write
632 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
633
634 eet_close(ef);
635
636 if (ret)
637 {
638 unlink(filename);
639 rename(tmp, filename);
640 }
641
642 return ret;
643 } /* _data_save */
644
645 static void
646 _print_union(const Example_Union *un)
647 {
648 printf("\t | type: %s'\n", eet_mapping[un->type - 1].name);
649
650 switch (un->type)
651 {
652 case EET_STRUCT1:
653 printf("\t\t val1: %f\n", un->u.st1.val1);
654 printf("\t\t stuff: %d\n", un->u.st1.stuff);
655 printf("\t\t s1: %s\n", un->u.st1.s1);
656 break;
657
658 case EET_STRUCT2:
659 printf("\t\t val1: %i\n", un->u.st2.b1);
660 printf("\t\t stuff: %lli\n", un->u.st2.v1);
661 break;
662
663 case EET_STRUCT3:
664 printf("\t\t val1: %i\n", un->u.st3.body);
665 break;
666
667 case EET_BASIC_FLOAT:
668 printf("\t\t float: %f\n", un->u.f);
669 break;
670
671 case EET_BASIC_STRING:
672 printf("\t\t string: %s\n", un->u.string);
673 break;
674
675 default:
676 return;
677 }
678 }
679
680 static void
681 _print_variant(const Example_Variant *va)
682 {
683 printf("\t | type: %s'\n", va->t.type);
684
685 switch (va->t.type[2])
686 {
687 case '1':
688 {
689 Example_Struct1 *st1 = va->data;
690
691 printf("\t\t val1: %f\n", st1->val1);
692 printf("\t\t stuff: %d\n", st1->stuff);
693 printf("\t\t s1: %s\n", st1->s1);
694 }
695 break;
696
697 case '2':
698 {
699 Example_Struct2 *st2 = va->data;
700
701 printf("\t\t val1: %i\n", st2->b1);
702 printf("\t\t stuff: %lli\n", st2->v1);
703 }
704 break;
705
706 case '3':
707 {
708 Example_Struct3 *st3 = va->data;
709
710 printf("\t\t val1: %i\n", st3->body);
711 }
712 break;
713
714 default:
715 return;
716 }
717 }
718
719 int
720 main(int argc,
721 char *argv[])
722 {
723 Example_Lists *data_lists;
724 int ret = 0;
725
726 if (argc < 3)
727 {
728 fprintf(stderr,
729 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
730 "where actions and their parameters are:\n"
731 "\tunion <type> [fields]\n"
732 "\tvariant <type> [fields]\n"
733 "\n",
734 argv[0]);
735 return -1;
736 }
737
738 eina_init();
739 eet_init();
740 _data_descriptors_init();
741
742 data_lists = _data_load(argv[1]);
743 if (!data_lists)
744 {
745 printf("Creating new data lists.\n");
746 data_lists = _data_new();
747 if (!data_lists)
748 {
749 ret = -2;
750 goto end;
751 }
752 }
753
754 if (argc > 3)
755 {
756 if (strcmp(argv[3], "union") == 0)
757 {
758 if (argc > 4)
759 {
760 int type = atoi(argv[4]);
761 Example_Union *un;
762
763 if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
764 {
765 fprintf(stderr,
766 "ERROR: invalid type parameter (%s).\n",
767 argv[4]);
768 goto cont;
769 }
770
771 switch (type)
772 {
773 case 1:
774 if (argc != 8)
775 {
776 fprintf(
777 stderr, "ERROR: wrong number of parameters"
778 " (%d).\n", argc);
779 goto cont;
780 }
781
782 un = _union_1_new(
783 argv[5], argv[6], argv[7]);
784 if (!un)
785 {
786 fprintf(
787 stderr, "ERROR: could not create the "
788 "requested union.\n");
789 goto cont;
790 }
791 data_lists->union_list =
792 eina_list_append(data_lists->union_list, un);
793 break;
794
795 case 2:
796 if (argc != 7)
797 {
798 fprintf(
799 stderr, "ERROR: wrong number of parameters"
800 " (%d).\n", argc);
801 goto cont;
802 }
803
804 un = _union_2_new(argv[5], argv[6]);
805 if (!un)
806 {
807 fprintf(
808 stderr, "ERROR: could not create the "
809 "requested union.\n");
810 goto cont;
811 }
812 data_lists->union_list =
813 eina_list_append(data_lists->union_list, un);
814 break;
815
816 case 3:
817 if (argc != 6)
818 {
819 fprintf(
820 stderr, "ERROR: wrong number of parameters"
821 " (%d).\n", argc);
822 goto cont;
823 }
824
825 un = _union_3_new(argv[5]);
826 if (!un)
827 {
828 fprintf(
829 stderr, "ERROR: could not create the "
830 "requested union.\n");
831 goto cont;
832 }
833 data_lists->union_list =
834 eina_list_append(data_lists->union_list, un);
835 break;
836
837 case EET_BASIC_FLOAT:
838 if (argc != 6)
839 {
840 fprintf(
841 stderr, "ERROR: wrong number of parameters"
842 " (%d).\n", argc);
843 goto cont;
844 }
845
846 un = _union_float_new(argv[5]);
847 if (!un)
848 {
849 fprintf(
850 stderr, "ERROR: could not create the "
851 "requested union.\n");
852 goto cont;
853 }
854 data_lists->union_list =
855 eina_list_append(data_lists->union_list, un);
856 break;
857
858 case EET_BASIC_STRING:
859 if (argc != 6)
860 {
861 fprintf(
862 stderr, "ERROR: wrong number of parameters"
863 " (%d).\n", argc);
864 goto cont;
865 }
866
867 un = _union_string_new(argv[5]);
868 if (!un)
869 {
870 fprintf(
871 stderr, "ERROR: could not create the "
872 "requested union.\n");
873 goto cont;
874 }
875 data_lists->union_list =
876 eina_list_append(data_lists->union_list, un);
877 break;
878
879 default:
880 fprintf(
881 stderr, "ERROR: bad type of of struct passed\n");
882 goto cont;
883 }
884 }
885 else
886 fprintf(stderr,
887 "ERROR: wrong number of parameters (%d).\n",
888 argc);
889 }
890 else if (strcmp(argv[3], "variant") == 0)
891 {
892 if (argc > 4)
893 {
894 int type = atoi(argv[4]);
895 Example_Variant *va;
896
897 if (type < EET_STRUCT1 || type > EET_STRUCT3)
898 {
899 fprintf(stderr,
900 "ERROR: invalid type parameter (%s).\n",
901 argv[4]);
902 goto cont;
903 }
904
905 switch (type)
906 {
907 case 1:
908 if (argc != 8)
909 {
910 fprintf(
911 stderr, "ERROR: wrong number of parameters"
912 " (%d).\n", argc);
913 goto cont;
914 }
915
916 va = _variant_1_new(
917 argv[5], argv[6], argv[7]);
918 if (!va)
919 {
920 fprintf(
921 stderr, "ERROR: could not create the "
922 "requested variant.\n");
923 goto cont;
924 }
925 data_lists->variant_list =
926 eina_list_append(data_lists->variant_list, va);
927 break;
928
929 case 2:
930 if (argc != 7)
931 {
932 fprintf(
933 stderr, "ERROR: wrong number of parameters"
934 " (%d).\n", argc);
935 goto cont;
936 }
937
938 va = _variant_2_new(argv[5], argv[6]);
939 if (!va)
940 {
941 fprintf(
942 stderr, "ERROR: could not create the "
943 "requested variant.\n");
944 goto cont;
945 }
946 data_lists->variant_list =
947 eina_list_append(data_lists->variant_list, va);
948 break;
949
950 case 3:
951 if (argc != 6)
952 {
953 fprintf(
954 stderr, "ERROR: wrong number of parameters"
955 " (%d).\n", argc);
956 goto cont;
957 }
958
959 va = _variant_3_new(argv[5]);
960 if (!va)
961 {
962 fprintf(
963 stderr, "ERROR: could not create the "
964 "requested variant.\n");
965 goto cont;
966 }
967 data_lists->variant_list =
968 eina_list_append(data_lists->variant_list, va);
969 break;
970
971 default:
972 fprintf(
973 stderr, "ERROR: bad type of of struct passed\n");
974 goto cont;
975 }
976 }
977 else
978 fprintf(stderr,
979 "ERROR: wrong number of parameters (%d).\n",
980 argc);
981 }
982 else
983 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
984 }
985
986 cont:
987 printf("Cached data:\n");
988
989 printf("\tstats: unions=%u, variants=%u\n",
990 eina_list_count(data_lists->union_list),
991 eina_list_count(data_lists->variant_list));
992
993 if (eina_list_count(data_lists->union_list))
994 {
995 const Eina_List *l;
996 const Example_Union *un;
997 printf("\t * union list:\n");
998
999 EINA_LIST_FOREACH(data_lists->union_list, l, un)
1000 {
1001 _print_union(un);
1002 }
1003 }
1004
1005 if (eina_list_count(data_lists->variant_list))
1006 {
1007 const Eina_List *l;
1008 const Example_Variant *un;
1009 printf("\t * variant list:\n");
1010
1011 EINA_LIST_FOREACH(data_lists->variant_list, l, un)
1012 {
1013 _print_variant(un);
1014 }
1015 }
1016
1017 printf("\n");
1018
1019 if (!_data_save(data_lists, argv[2]))
1020 ret = -3;
1021
1022 _data_free(data_lists);
1023
1024 end:
1025 if (_cache_file)
1026 eet_close(_cache_file);
1027 _data_descriptors_shutdown();
1028 eet_shutdown();
1029 eina_shutdown();
1030
1031 return ret;
1032 } /* main */
1033
eina_stringshare_del
EAPI void eina_stringshare_del(Eina_Stringshare *str)
Note that the given string has lost an instance.
Definition: eina_stringshare.c:537
eina_stringshare_add
EAPI Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieve an instance of a string for use in a program.
Definition: eina_stringshare.c:610
eet_open
EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode)
Open an eet file on disk, and returns a handle to it.
Definition: eet_lib.c:1491
_Eet_Data_Descriptor_Class::version
int version
ABI version.
Definition: Eet.h:2820
eet_data_write
EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
Write a data structure from memory and store in an eet file.
Definition: eet_data.c:2408
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:338
Eet_File
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition: Eet.h:518
EET_DATA_DESCRIPTOR_ADD_UNION
#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type)
Add an union type to a data descriptor.
Definition: Eet.h:3757
EET_FILE_MODE_READ
File is read-only.
Definition: Eet.h:475
eet_shutdown
EAPI int eet_shutdown(void)
Shut down the EET library.
Definition: eet_lib.c:607
eina_init
int eina_init(void)
Initialize the Eina library.
Definition: eina_main.c:244
_Eet_Data_Descriptor_Class::type_get
Eet_Descriptor_Type_Get_Callback type_get
get the type, as used in the union or variant mapping, that should be used to store the given data in...
Definition: Eet.h:2838
eina_list_count
static unsigned int eina_list_count(const Eina_List *list)
Get the count of the number of items in a list.
eet_data_descriptor_free
EAPI void eet_data_descriptor_free(Eet_Data_Descriptor *edd)
This function frees a data descriptor when it is not needed anymore.
Definition: eet_data.c:2107
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC
#define EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(unified_type, name, basic_type)
Add a mapping of a basic type to a data descriptor that will be used by a union type.
Definition: Eet.h:3830
EET_T_STRING
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2580
Eet_Dictionary
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition: Eet.h:524
EET_T_UCHAR
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2576
eet_dictionary_string_check
EAPI int eet_dictionary_string_check(Eet_Dictionary *ed, const char *string)
Check if a given string comes from a given dictionary.
Definition: eet_dictionary.c:489
EET_T_INT
#define EET_T_INT
Data type: int.
Definition: Eet.h:2572
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:344
eina_shutdown
int eina_shutdown(void)
Shut down the Eina library.
Definition: eina_main.c:310
eina_list_append
Eina_List * eina_list_append(Eina_List *list, const void *data)
Append the given data to the given linked list.
Definition: eina_list.c:550
Eet.h
The file that provides the eet functions.
EET_FILE_MODE_WRITE
File is write-only.
Definition: Eet.h:476
EET_DATA_DESCRIPTOR_ADD_MAPPING
#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype)
Add a mapping to a data descriptor that will be used by union, variant or inherited type...
Definition: Eet.h:3810
eina_strlcpy
EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) EINA_ARG_NONNULL(1
Copy a c-string to another.
EET_DATA_DESCRIPTOR_CLASS_VERSION
#define EET_DATA_DESCRIPTOR_CLASS_VERSION
The version of Eet_Data_Descriptor_Class at the time of the distribution of the sources.
Definition: Eet.h:2631
eet_data_descriptor_stream_new
EAPI Eet_Data_Descriptor * eet_data_descriptor_stream_new(const Eet_Data_Descriptor_Class *eddc)
This function creates a new data descriptor and returns a handle to the new data descriptor.
Definition: eet_data.c:2087
EET_DATA_DESCRIPTOR_ADD_VARIANT
#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type)
Add a automatically selectable type to a data descriptor.
Definition: Eet.h:3789
eet_data_read
EAPI void * eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
Read a data structure from an eet file and decodes it.
Definition: eet_data.c:2374
Eina.h
Eina Utility library.
_Eet_Data_Descriptor_Class
Instructs Eet about memory management for different needs under serialization and parse process...
Definition: Eet.h:2818
EET_DATA_DESCRIPTOR_ADD_BASIC
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Add a basic data element to a data descriptor.
Definition: Eet.h:3420
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:332
EET_T_DOUBLE
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2575
EET_DATA_DESCRIPTOR_ADD_LIST
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Add a linked list type to a data descriptor.
Definition: Eet.h:3499
eet_close
EAPI Eet_Error eet_close(Eet_File *ef)
Close an eet file handle and flush pending writes.
Definition: eet_lib.c:1889
EET_T_ULONG_LONG
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2579
Eet_Data_Descriptor
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2622
EINA_LIST_FREE
#define EINA_LIST_FREE(list, data)
Macro to remove each list node while having access to each node&#39;s data.
Definition: eina_list.h:1626
eet_data_descriptor_file_new
EAPI Eet_Data_Descriptor * eet_data_descriptor_file_new(const Eet_Data_Descriptor_Class *eddc)
This function creates a new data descriptor and returns a handle to the new data descriptor.
Definition: eet_data.c:2093
_Eina_List
Type for a generic double linked list.
Definition: eina_list.h:320
_Eet_Data_Descriptor_Class::type_set
Eet_Descriptor_Type_Set_Callback type_set
called when loading a mapped type with the given type used to describe the type in the descriptor ...
Definition: Eet.h:2839
EINA_LIST_FOREACH
#define EINA_LIST_FOREACH(list, l, data)
Macro to iterate over a list.
Definition: eina_list.h:1414
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET
#define EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(clas, type)
This macro is an helper that set all the parameter of an Eet_Data_Descriptor_Class correctly when you...
Definition: Eet.h:3065
eet_dictionary_get
EAPI Eet_Dictionary * eet_dictionary_get(Eet_File *ef)
Return a handle to the shared string dictionary of the Eet file.
Definition: eet_lib.c:2546
EET_T_FLOAT
#define EET_T_FLOAT
Data type: float.
Definition: Eet.h:2574
eet_init
EAPI int eet_init(void)
Initialize the EET library.
Definition: eet_lib.c:553