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 = 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 
EAPI void eina_stringshare_del(Eina_Stringshare *str)
Note that the given string has lost an instance.
Definition: eina_stringshare.c:537
EAPI Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieve an instance of a string for use in a program.
Definition: eina_stringshare.c:610
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:1502
#define rename(src, dst)
Wrapper around evil_rename().
Definition: evil_stdio.h:226
int version
ABI version.
Definition: Eet.h:2475
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
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition: eina_types.h:311
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition: Eet.h:485
#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
File is read-only.
Definition: Eet.h:466
EAPI int eet_shutdown(void)
Shut down the EET library.
Definition: eet_lib.c:622
int eina_init(void)
Initialize the Eina library.
Definition: eina_main.c:247
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
static unsigned int eina_list_count(const Eina_List *list)
Get 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:2104
#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
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2379
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition: Eet.h:491
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2375
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
#define EET_T_INT
Data type: int.
Definition: Eet.h:2371
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition: eina_types.h:317
int eina_shutdown(void)
Shut down the Eina library.
Definition: eina_main.c:317
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
The file that provides the eet functions.
File is write-only.
Definition: Eet.h:467
#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
EAPI size_t eina_strlcpy(char *dst, const char *src, size_t siz) EINA_ARG_NONNULL(1
Copy 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:2430
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
#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
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 Utility library.
Instructs Eet about memory management for different needs under serialization and parse process...
Definition: Eet.h:2473
#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
unsigned char Eina_Bool
Type to mimic a boolean.
Definition: eina_types.h:305
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2374
#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
EAPI Eet_Error eet_close(Eet_File *ef)
Close an eet file handle and flush pending writes.
Definition: eet_lib.c:1752
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2378
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2421
#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
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
Type for a generic double linked list.
Definition: eina_list.h:320
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
#define EINA_LIST_FOREACH(list, l, data)
Macro to iterate over a list.
Definition: eina_list.h:1387
#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
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:2649
#define EET_T_FLOAT
Data type: float.
Definition: Eet.h:2373
EAPI int eet_init(void)
Initialize the EET library.
Definition: eet_lib.c:539