Example_Eet_Data_File_Descriptor_02(3)

NAME
Example_Eet_Data_File_Descriptor_02 - 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

3.  Then, come the fields for each type:

                "Usage:t%s <input> <output> [action action-params]n"
                "where actions and their parameters are:
                "	union <type> [fields]
                "	variant <type> [fields]
                ",
                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.);
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.);
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.);
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.);
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.);
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.);
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);
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.);
485         return NULL;
486      }
487
488    va->t.type = eet_mapping[1].name;
489
490    printf("type gets %s, 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.);
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.);
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, 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, 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, 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("	  |   type: %s', eet_mapping[un->type - 1].name);
649
650    switch (un->type)
651      {
652       case EET_STRUCT1:
653         printf("		  val1: %f, un->u.st1.val1);
654         printf("		  stuff: %d, un->u.st1.stuff);
655         printf("		  s1: %s, un->u.st1.s1);
656         break;
657
658       case EET_STRUCT2:
659         printf("		  val1: %i, un->u.st2.b1);
660         printf("		  stuff: %lli, un->u.st2.v1);
661         break;
662
663       case EET_STRUCT3:
664         printf("		  val1: %i, un->u.st3.body);
665         break;
666
667       case EET_BASIC_FLOAT:
668         printf("		  float: %f, un->u.f);
669         break;
670
671       case EET_BASIC_STRING:
672         printf("		  string: %s, 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("	  |   type: %s', va->t.type);
684
685    switch (va->t.type[2])
686      {
687       case '1':
688       {
689          Example_Struct1 *st1 = va->data;
690
691          printf("		  val1: %f, st1->val1);
692          printf("		  stuff: %d, st1->stuff);
693          printf("		  s1: %s, st1->s1);
694       }
695       break;
696
697       case '2':
698       {
699          Example_Struct2 *st2 = va->data;
700
701          printf("		  val1: %i, st2->b1);
702          printf("		  stuff: %lli, st2->v1);
703       }
704       break;
705
706       case '3':
707       {
708          Example_Struct3 *st3 = va->data;
709
710          printf("		  val1: %i, 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:t%s <input> <output> [action action-params]n"
730                 "where actions and their parameters are:
731                 "	union <type> [fields]
732                 "	variant <type> [fields]
733                 ",
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.);
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).,
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)., 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.);
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)., 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.);
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)., 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.);
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)., 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.);
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)., 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.);
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);
882                        goto cont;
883                     }
884                }
885              else
886                fprintf(stderr,
887                        "ERROR: wrong number of parameters (%d).,
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).,
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)., 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.);
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)., 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.);
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)., 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.);
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);
974                        goto cont;
975                     }
976                }
977              else
978                fprintf(stderr,
979                        "ERROR: wrong number of parameters (%d).,
980                        argc);
981           }
982         else
983           fprintf(stderr, "ERROR: unknown action '%s', argv[3]);
984      }
985
986 cont:
987    printf("Cached data:);
988
989    printf("	stats: unions=%u, variants=%u,
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("	  * union list:);
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("	  * variant list:);
1010
1011         EINA_LIST_FOREACH(data_lists->variant_list, l, un)
1012           {
1013              _print_variant(un);
1014           }
1015      }
1016
1017    printf(");
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