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
{
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)
{
_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 */
_union_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.func.type_get = _union_type_get;
eddc.func.type_set = _union_type_set;
_union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
_union_unified_descriptor, "ST1", _struct_1_descriptor);
_union_unified_descriptor, "ST2", _struct_2_descriptor);
_union_unified_descriptor, "ST3", _struct_3_descriptor);
_union_unified_descriptor, "float", EET_T_FLOAT);
_union_unified_descriptor, "string", EET_T_STRING);
_union_descriptor, Example_Union, "u", u, type,
_union_unified_descriptor);
_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 {
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);
207  res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
209  res, Example_Struct1, "stuff", stuff, EET_T_INT);
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 {
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);
225  res, Example_Struct2, "b1", b1, EET_T_UCHAR);
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 {
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);
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 {
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 
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 
292  _union_unified_descriptor, "ST1", _struct_1_descriptor);
294  _union_unified_descriptor, "ST2", _struct_2_descriptor);
296  _union_unified_descriptor, "ST3", _struct_3_descriptor);
298  _union_unified_descriptor, "float", EET_T_FLOAT);
300  _union_unified_descriptor, "string", EET_T_STRING);
301 
303  _union_descriptor, Example_Union, "u", u, type,
304  _union_unified_descriptor);
305 
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 
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 
320  _variant_unified_descriptor, "ST1", _struct_1_descriptor);
322  _variant_unified_descriptor, "ST2", _struct_2_descriptor);
324  _variant_unified_descriptor, "ST3", _struct_3_descriptor);
325 
327  _variant_descriptor, Example_Variant, "data", data, t,
328  _variant_unified_descriptor);
329 
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 
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 
EAPI Eet_File * eet_open(const char *file, Eet_File_Mode mode)
Opens an eet file on disk, and returns a handle to it.
Definition: eet_lib.c:1499
int version
ABI version.
Definition: Eet.h:2829
EAPI int eet_data_write(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name, const void *data, int compress)
Writes a data structure from memory and store in an eet file.
Definition: eet_data.c:2414
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:533
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition: Eet.h:527
#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type)
Adds an union type to a data descriptor.
Definition: Eet.h:3817
int eina_init(void)
Initializes the Eina library.
Definition: eina_main.c:279
int eina_shutdown(void)
Shuts down the Eina library.
Definition: eina_main.c:350
File is read-only.
Definition: Eet.h:479
EAPI int eet_shutdown(void)
Shuts down the EET library.
Definition: eet_lib.c:594
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:2847
static unsigned int eina_list_count(const Eina_List *list)
Gets the count of the number of items in a list.
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:2102
#define EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(unified_type, name, basic_type)
Adds a mapping of a basic type to a data descriptor that will be used by a union type.
Definition: Eet.h:3890
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2589
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition: Eet.h:533
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2585
EAPI int eet_dictionary_string_check(Eet_Dictionary *ed, const char *string)
Checks if a given string comes from a given dictionary.
Definition: eet_dictionary.c:493
#define EET_T_INT
Data type: int.
Definition: Eet.h:2581
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:539
EAPI Eina_List * eina_list_append(Eina_List *list, const void *data)
Appends the given data to the given linked list.
Definition: eina_list.c:584
The file that provides the eet functions.
File is write-only.
Definition: Eet.h:480
#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype)
Adds a mapping to a data descriptor that will be used by union, variant or inherited type.
Definition: Eet.h:3870
EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) EINA_ARG_NONNULL(1
Copies a c-string to another.
#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:2640
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:2082
#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type)
Adds a automatically selectable type to a data descriptor.
Definition: Eet.h:3849
EAPI void * eet_data_read(Eet_File *ef, Eet_Data_Descriptor *edd, const char *name)
Reads a data structure from an eet file and decodes it.
Definition: eet_data.c:2377
Eina Utility library.
void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance.
Definition: eina_stringshare.c:533
Instructs Eet about memory management for different needs under serialization and parse process.
Definition: Eet.h:2827
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Adds a basic data element to a data descriptor.
Definition: Eet.h:3432
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:527
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2584
#define EINA_LIST_FOREACH(list, l, _data)
Definition for the macro to iterate over a list.
Definition: eina_list.h:1415
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Adds a linked list type to a data descriptor.
Definition: Eet.h:3511
EAPI Eet_Error eet_close(Eet_File *ef)
Closes an eet file handle and flush pending writes.
Definition: eet_lib.c:1899
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2588
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2631
#define EINA_LIST_FREE(list, data)
Definition for the macro to remove each list node while having access to each node's data.
Definition: eina_list.h:1629
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:2088
Type for a generic double linked list.
Definition: eina_list.h:317
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:2848
Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieves an instance of a string for use in a program.
Definition: eina_stringshare.c:606
#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:3075
EAPI Eet_Dictionary * eet_dictionary_get(Eet_File *ef)
Returns a handle to the shared string dictionary of the Eet file.
Definition: eet_lib.c:2564
#define EET_T_FLOAT
Data type: float.
Definition: Eet.h:2583
EAPI int eet_init(void)
Initializes the EET library.
Definition: eet_lib.c:540