- Main Page
- Related Pages
- Modules
- Data Structures
- Files
- Examples

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 = calloc(1, sizeof (Example_Variant));
466 va->t.type = eet_mapping[0].name;
467 st1 = calloc(1, sizeof (Example_Struct1));
468 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
469 va->data = st1;
470
471 return va;
472 }
473
474 static Example_Variant *
475 _variant_2_new(const char *v1,
476 const char *v2)
477 {
478 printf("varinant 2 new\n");
479
480 Example_Struct2 *st2;
481 Example_Variant *va = calloc(1, sizeof(Example_Variant));
482 if (!va)
483 {
484 fprintf(
485 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
486 return NULL;
487 }
488
489 va = calloc(1, sizeof (Example_Variant));
490
491 va->t.type = eet_mapping[1].name;
492
493 printf("type gets %s\n", va->t.type);
494
495 st2 = calloc(1, sizeof (Example_Struct2));
496 _st2_set(st2, atoi(v1), atoi(v2));
497 va->data = st2;
498
499 return va;
500 }
501
502 static Example_Variant *
503 _variant_3_new(const char *v1)
504 {
505 Example_Struct3 *st3;
506 Example_Variant *va = calloc(1, sizeof(Example_Variant));
507 if (!va)
508 {
509 fprintf(
510 stderr, "ERROR: could not allocate an Example_Variant struct.\n");
511 return NULL;
512 }
513
514 va = calloc(1, sizeof (Example_Variant));
515 va->t.type = eet_mapping[2].name;
516 st3 = calloc(1, sizeof (Example_Struct3));
517 _st3_set(st3, atoi(v1));
518 va->data = st3;
519
520 return va;
521 }
522
523 static Example_Lists *
524 _data_new(void)
525 {
526 Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
527 if (!example_lists)
528 {
529 fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
530 return NULL;
531 }
532
533 return example_lists;
534 } /* _data_new */
535
536 static void
537 _union_free(Example_Union *un)
538 {
539 if (un->type == EET_STRUCT1)
540 {
541 Example_Struct1 *st1 = &(un->u.st1);
542 _string_free(st1->s1);
543 }
544
545 free(un);
546 }
547
548 static void
549 _variant_free(Example_Variant *va)
550 {
551 if (!strcmp(va->t.type, eet_mapping[0].name))
552 {
553 Example_Struct1 *st1 = va->data;
554 _string_free(st1->s1);
555 }
556
557 free(va->data);
558 free(va);
559 }
560
561 static void
562 _data_free(Example_Lists *cache)
563 {
564 Example_Union *un;
565 Example_Variant *va;
566
567 EINA_LIST_FREE(cache->union_list, un)
568 _union_free(un);
569
570 EINA_LIST_FREE(cache->variant_list, va)
571 _variant_free(va);
572
573 free(cache);
574 } /* _data_free */
575
576 static Example_Lists *
577 _data_load(const char *filename)
578 {
579 Example_Lists *data;
580 Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
581 if (!ef)
582 {
583 fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
584 return NULL;
585 }
586
587 data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
588 if (!data)
589 {
590 eet_close(ef);
591 return NULL;
592 }
593
594 if (_cache_file)
595 eet_close(_cache_file);
596
597 _cache_file = ef;
598 _cache_dict = eet_dictionary_get(ef);
599
600 return data;
601 } /* _data_load */
602
603 static Eina_Bool
604 _data_save(const Example_Lists *cache,
605 const char *filename)
606 {
607 char tmp[PATH_MAX];
608 Eet_File *ef;
609 Eina_Bool ret;
610 unsigned int i, len;
611 struct stat st;
612
613 len = eina_strlcpy(tmp, filename, sizeof(tmp));
614 if (len + 12 >= (int)sizeof(tmp))
615 {
616 fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
617 return EINA_FALSE;
618 }
619
620 i = 0;
621 do
622 {
623 snprintf(tmp + len, 12, ".%u", i);
624 i++;
625 }
626 while (stat(tmp, &st) == 0);
627
628 ef = eet_open(tmp, EET_FILE_MODE_WRITE);
629 if (!ef)
630 {
631 fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
632 return EINA_FALSE;
633 }
634
635 ret = eet_data_write
636 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
637
638 eet_close(ef);
639
640 if (ret)
641 {
642 unlink(filename);
643 rename(tmp, filename);
644 }
645
646 return ret;
647 } /* _data_save */
648
649 static void
650 _print_union(const Example_Union *un)
651 {
652 printf("\t | type: %s'\n", eet_mapping[un->type - 1].name);
653
654 switch (un->type)
655 {
656 case EET_STRUCT1:
657 printf("\t\t val1: %f\n", un->u.st1.val1);
658 printf("\t\t stuff: %d\n", un->u.st1.stuff);
659 printf("\t\t s1: %s\n", un->u.st1.s1);
660 break;
661
662 case EET_STRUCT2:
663 printf("\t\t val1: %i\n", un->u.st2.b1);
664 printf("\t\t stuff: %lli\n", un->u.st2.v1);
665 break;
666
667 case EET_STRUCT3:
668 printf("\t\t val1: %i\n", un->u.st3.body);
669 break;
670
671 case EET_BASIC_FLOAT:
672 printf("\t\t float: %f\n", un->u.f);
673 break;
674
675 case EET_BASIC_STRING:
676 printf("\t\t string: %s\n", un->u.string);
677 break;
678
679 default:
680 return;
681 }
682 }
683
684 static void
685 _print_variant(const Example_Variant *va)
686 {
687 printf("\t | type: %s'\n", va->t.type);
688
689 switch (va->t.type[2])
690 {
691 case '1':
692 {
693 Example_Struct1 *st1 = va->data;
694
695 printf("\t\t val1: %f\n", st1->val1);
696 printf("\t\t stuff: %d\n", st1->stuff);
697 printf("\t\t s1: %s\n", st1->s1);
698 }
699 break;
700
701 case '2':
702 {
703 Example_Struct2 *st2 = va->data;
704
705 printf("\t\t val1: %i\n", st2->b1);
706 printf("\t\t stuff: %lli\n", st2->v1);
707 }
708 break;
709
710 case '3':
711 {
712 Example_Struct3 *st3 = va->data;
713
714 printf("\t\t val1: %i\n", st3->body);
715 }
716 break;
717
718 default:
719 return;
720 }
721 }
722
723 int
724 main(int argc,
725 char *argv[])
726 {
727 Example_Lists *data_lists;
728 int ret = 0;
729
730 if (argc < 3)
731 {
732 fprintf(stderr,
733 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
734 "where actions and their parameters are:\n"
735 "\tunion <type> [fields]\n"
736 "\tvariant <type> [fields]\n"
737 "\n",
738 argv[0]);
739 return -1;
740 }
741
742 eina_init();
743 eet_init();
744 _data_descriptors_init();
745
746 data_lists = _data_load(argv[1]);
747 if (!data_lists)
748 {
749 printf("Creating new data lists.\n");
750 data_lists = _data_new();
751 if (!data_lists)
752 {
753 ret = -2;
754 goto end;
755 }
756 }
757
758 if (argc > 3)
759 {
760 if (strcmp(argv[3], "union") == 0)
761 {
762 if (argc > 4)
763 {
764 int type = atoi(argv[4]);
765 Example_Union *un;
766
767 if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
768 {
769 fprintf(stderr,
770 "ERROR: invalid type parameter (%s).\n",
771 argv[4]);
772 goto cont;
773 }
774
775 switch (type)
776 {
777 case 1:
778 if (argc != 8)
779 {
780 fprintf(
781 stderr, "ERROR: wrong number of parameters"
782 " (%d).\n", argc);
783 goto cont;
784 }
785
786 un = _union_1_new(
787 argv[5], argv[6], argv[7]);
788 if (!un)
789 {
790 fprintf(
791 stderr, "ERROR: could not create the "
792 "requested union.\n");
793 goto cont;
794 }
795 data_lists->union_list =
796 eina_list_append(data_lists->union_list, un);
797 break;
798
799 case 2:
800 if (argc != 7)
801 {
802 fprintf(
803 stderr, "ERROR: wrong number of parameters"
804 " (%d).\n", argc);
805 goto cont;
806 }
807
808 un = _union_2_new(argv[5], argv[6]);
809 if (!un)
810 {
811 fprintf(
812 stderr, "ERROR: could not create the "
813 "requested union.\n");
814 goto cont;
815 }
816 data_lists->union_list =
817 eina_list_append(data_lists->union_list, un);
818 break;
819
820 case 3:
821 if (argc != 6)
822 {
823 fprintf(
824 stderr, "ERROR: wrong number of parameters"
825 " (%d).\n", argc);
826 goto cont;
827 }
828
829 un = _union_3_new(argv[5]);
830 if (!un)
831 {
832 fprintf(
833 stderr, "ERROR: could not create the "
834 "requested union.\n");
835 goto cont;
836 }
837 data_lists->union_list =
838 eina_list_append(data_lists->union_list, un);
839 break;
840
841 case EET_BASIC_FLOAT:
842 if (argc != 6)
843 {
844 fprintf(
845 stderr, "ERROR: wrong number of parameters"
846 " (%d).\n", argc);
847 goto cont;
848 }
849
850 un = _union_float_new(argv[5]);
851 if (!un)
852 {
853 fprintf(
854 stderr, "ERROR: could not create the "
855 "requested union.\n");
856 goto cont;
857 }
858 data_lists->union_list =
859 eina_list_append(data_lists->union_list, un);
860 break;
861
862 case EET_BASIC_STRING:
863 if (argc != 6)
864 {
865 fprintf(
866 stderr, "ERROR: wrong number of parameters"
867 " (%d).\n", argc);
868 goto cont;
869 }
870
871 un = _union_string_new(argv[5]);
872 if (!un)
873 {
874 fprintf(
875 stderr, "ERROR: could not create the "
876 "requested union.\n");
877 goto cont;
878 }
879 data_lists->union_list =
880 eina_list_append(data_lists->union_list, un);
881 break;
882
883 default:
884 fprintf(
885 stderr, "ERROR: bad type of of struct passed\n");
886 goto cont;
887 }
888 }
889 else
890 fprintf(stderr,
891 "ERROR: wrong number of parameters (%d).\n",
892 argc);
893 }
894 else if (strcmp(argv[3], "variant") == 0)
895 {
896 if (argc > 4)
897 {
898 int type = atoi(argv[4]);
899 Example_Variant *va;
900
901 if (type < EET_STRUCT1 || type > EET_STRUCT3)
902 {
903 fprintf(stderr,
904 "ERROR: invalid type parameter (%s).\n",
905 argv[4]);
906 goto cont;
907 }
908
909 switch (type)
910 {
911 case 1:
912 if (argc != 8)
913 {
914 fprintf(
915 stderr, "ERROR: wrong number of parameters"
916 " (%d).\n", argc);
917 goto cont;
918 }
919
920 va = _variant_1_new(
921 argv[5], argv[6], argv[7]);
922 if (!va)
923 {
924 fprintf(
925 stderr, "ERROR: could not create the "
926 "requested variant.\n");
927 goto cont;
928 }
929 data_lists->variant_list =
930 eina_list_append(data_lists->variant_list, va);
931 break;
932
933 case 2:
934 if (argc != 7)
935 {
936 fprintf(
937 stderr, "ERROR: wrong number of parameters"
938 " (%d).\n", argc);
939 goto cont;
940 }
941
942 va = _variant_2_new(argv[5], argv[6]);
943 if (!va)
944 {
945 fprintf(
946 stderr, "ERROR: could not create the "
947 "requested variant.\n");
948 goto cont;
949 }
950 data_lists->variant_list =
951 eina_list_append(data_lists->variant_list, va);
952 break;
953
954 case 3:
955 if (argc != 6)
956 {
957 fprintf(
958 stderr, "ERROR: wrong number of parameters"
959 " (%d).\n", argc);
960 goto cont;
961 }
962
963 va = _variant_3_new(argv[5]);
964 if (!va)
965 {
966 fprintf(
967 stderr, "ERROR: could not create the "
968 "requested variant.\n");
969 goto cont;
970 }
971 data_lists->variant_list =
972 eina_list_append(data_lists->variant_list, va);
973 break;
974
975 default:
976 fprintf(
977 stderr, "ERROR: bad type of of struct passed\n");
978 goto cont;
979 }
980 }
981 else
982 fprintf(stderr,
983 "ERROR: wrong number of parameters (%d).\n",
984 argc);
985 }
986 else
987 fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
988 }
989
990 cont:
991 printf("Cached data:\n");
992
993 printf("\tstats: unions=%u, variants=%u\n",
994 eina_list_count(data_lists->union_list),
995 eina_list_count(data_lists->variant_list));
996
997 if (eina_list_count(data_lists->union_list))
998 {
999 const Eina_List *l;
1000 const Example_Union *un;
1001 printf("\t * union list:\n");
1002
1003 EINA_LIST_FOREACH(data_lists->union_list, l, un)
1004 {
1005 _print_union(un);
1006 }
1007 }
1008
1009 if (eina_list_count(data_lists->variant_list))
1010 {
1011 const Eina_List *l;
1012 const Example_Variant *un;
1013 printf("\t * variant list:\n");
1014
1015 EINA_LIST_FOREACH(data_lists->variant_list, l, un)
1016 {
1017 _print_variant(un);
1018 }
1019 }
1020
1021 printf("\n");
1022
1023 if (!_data_save(data_lists, argv[2]))
1024 ret = -3;
1025
1026 _data_free(data_lists);
1027
1028 end:
1029 if (_cache_file)
1030 eet_close(_cache_file);
1031 _data_descriptors_shutdown();
1032 eet_shutdown();
1033 eina_shutdown();
1034
1035 return ret;
1036 } /* main */
1037
eina_stringshare_del
void eina_stringshare_del(Eina_Stringshare *str)
Note that the given string has lost an instance.
Definition: eina_stringshare.c:537
eina_stringshare_add
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:1494
rename
#define rename(src, dst)
Wrapper around evil_rename().
Definition: evil_stdio.h:226
_Eet_Data_Descriptor_Class::version
int version
ABI version.
Definition: Eet.h:2475
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:2357
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:311
Eet_File
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition: Eet.h:485
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:3403
EET_FILE_MODE_READ
File is read-only.
Definition: Eet.h:466
eet_shutdown
EAPI int eet_shutdown(void)
Shut down the EET library.
Definition: eet_lib.c:614
eina_init
int eina_init(void)
Initialize the Eina library.
Definition: eina_main.c:247
_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:2493
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:2104
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:3476
EET_T_STRING
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2379
Eet_Dictionary
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition: Eet.h:491
EET_T_UCHAR
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2375
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:499
EET_T_INT
#define EET_T_INT
Data type: int.
Definition: Eet.h:2371
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:317
eina_shutdown
int eina_shutdown(void)
Shut down the Eina library.
Definition: eina_main.c:317
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:530
Eet.h
The file that provides the eet functions.
EET_FILE_MODE_WRITE
File is write-only.
Definition: Eet.h:467
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:3456
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:2430
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:2084
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:3435
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:2323
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:2473
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:3066
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:305
EET_T_DOUBLE
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2374
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:3145
eet_close
EAPI Eet_Error eet_close(Eet_File *ef)
Close an eet file handle and flush pending writes.
Definition: eet_lib.c:1744
EET_T_ULONG_LONG
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2378
Eet_Data_Descriptor
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2421
EINA_LIST_FREE
#define EINA_LIST_FREE(list, data)
Macro to remove each list node while having access to each node's data.
Definition: eina_list.h:1599
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:2090
_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:2494
EINA_LIST_FOREACH
#define EINA_LIST_FOREACH(list, l, data)
Macro to iterate over a list.
Definition: eina_list.h:1387
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:2720
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:2641
EET_T_FLOAT
#define EET_T_FLOAT
Data type: float.
Definition: Eet.h:2373
eet_init
EAPI int eet_init(void)
Initialize the EET library.
Definition: eet_lib.c:531