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:
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:
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:
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:
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.
. What is new, here, are the two type matching functions for our unions. There, we must set the
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.
13 typedef enum _Example_Data_Type Example_Data_Type;
14 typedef struct _Example_Variant_Type Example_Variant_Type;
15 typedef struct _Example_Variant Example_Variant;
16 typedef struct _Example_Union Example_Union;
17 typedef struct _Example_Struct1 Example_Struct1;
18 typedef struct _Example_Struct2 Example_Struct2;
19 typedef struct _Example_Struct3 Example_Struct3;
20 typedef struct _Example_Lists Example_Lists;
22 enum _Example_Data_Type
35 { EET_STRUCT1,
"ST1" },
36 { EET_STRUCT2,
"ST2" },
37 { EET_STRUCT3,
"ST3" },
41 struct _Example_Struct1
48 struct _Example_Struct2
51 unsigned long long v1;
54 struct _Example_Struct3
61 Example_Data_Type type;
70 struct _Example_Variant_Type
76 struct _Example_Variant
78 Example_Variant_Type t;
87 Eina_List *union_list;
88 Eina_List *variant_list;
92 _st1_set(Example_Struct1 *st1,
103 _st2_set(Example_Struct2 *st2,
105 unsigned long long v2)
112 _st3_set(Example_Struct3 *st3,
121 _union_type_get(
const void *data,
124 const Example_Data_Type *u = data;
128 *unknow = EINA_FALSE;
130 for (i = 0; eet_mapping[i].name != NULL; ++i)
131 if (*u == eet_mapping[i].u)
132 return eet_mapping[i].name;
141 _union_type_set(
const char *type,
145 Example_Data_Type *u = data;
151 for (i = 0; eet_mapping[i].name != NULL; ++i)
152 if (strcmp(eet_mapping[i].name, type) == 0)
154 *u = eet_mapping[i].u;
162 _variant_type_get(
const void *data,
165 const Example_Variant_Type *type = data;
169 *unknow = type->unknow;
171 for (i = 0; eet_mapping[i].name != NULL; ++i)
172 if (strcmp(type->type, eet_mapping[i].name) == 0)
173 return eet_mapping[i].name;
176 *unknow = EINA_FALSE;
182 _variant_type_set(
const char *type,
186 Example_Variant_Type *vt = data;
204 res, Example_Struct1,
"stuff", stuff,
EET_T_INT);
236 res, Example_Struct3,
"body", body,
EET_T_INT);
245 static const char CACHE_FILE_ENTRY[] =
"cache";
261 static Eet_File *_cache_file = NULL;
266 _data_descriptors_init(
void)
273 _struct_1_descriptor = _st1_dd();
274 _struct_2_descriptor = _st2_dd();
275 _struct_3_descriptor = _st3_dd();
282 eddc.func.
type_get = _union_type_get;
283 eddc.func.
type_set = _union_type_set;
287 _union_unified_descriptor,
"ST1", _struct_1_descriptor);
289 _union_unified_descriptor,
"ST2", _struct_2_descriptor);
291 _union_unified_descriptor,
"ST3", _struct_3_descriptor);
294 _union_descriptor, Example_Union,
"u", u, type,
295 _union_unified_descriptor);
298 _lists_descriptor, Example_Lists,
"union_list", union_list,
306 eddc.func.
type_get = _variant_type_get;
307 eddc.func.
type_set = _variant_type_set;
311 _variant_unified_descriptor,
"ST1", _struct_1_descriptor);
313 _variant_unified_descriptor,
"ST2", _struct_2_descriptor);
315 _variant_unified_descriptor,
"ST3", _struct_3_descriptor);
318 _variant_descriptor, Example_Variant,
"data", data, t,
319 _variant_unified_descriptor);
322 _lists_descriptor, Example_Lists,
"variant_list", variant_list,
323 _variant_descriptor);
327 _data_descriptors_shutdown(
void)
343 _string_free(
const char *str)
351 eina_stringshare_del(str);
354 static Example_Union *
355 _union_1_new(
const char *v1,
359 Example_Union *un = calloc(1,
sizeof(Example_Union));
363 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
367 un->type = EET_STRUCT1;
368 _st1_set(&(un->u.st1), atof(v1), atoi(v2), eina_stringshare_add(v3));
373 static Example_Union *
374 _union_2_new(
const char *v1,
377 Example_Union *un = calloc(1,
sizeof(Example_Union));
381 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
385 un->type = EET_STRUCT2;
386 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
391 static Example_Union *
392 _union_3_new(
const char *v1)
394 Example_Union *un = calloc(1,
sizeof(Example_Union));
398 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
402 un->type = EET_STRUCT3;
403 _st3_set(&(un->u.st3), atoi(v1));
408 static Example_Variant *
409 _variant_1_new(
const char *v1,
413 Example_Struct1 *st1;
414 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
418 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
422 va = calloc(1,
sizeof (Example_Variant));
423 va->t.type = eet_mapping[0].name;
424 st1 = calloc(1,
sizeof (Example_Struct1));
425 _st1_set(st1, atof(v1), atoi(v2), eina_stringshare_add(v3));
431 static Example_Variant *
432 _variant_2_new(
const char *v1,
435 printf(
"varinant 2 new\n");
437 Example_Struct2 *st2;
438 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
442 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
446 va = calloc(1,
sizeof (Example_Variant));
448 va->t.type = eet_mapping[1].name;
450 printf(
"type gets %s\n", va->t.type);
452 st2 = calloc(1,
sizeof (Example_Struct2));
453 _st2_set(st2, atoi(v1), atoi(v2));
459 static Example_Variant *
460 _variant_3_new(
const char *v1)
462 Example_Struct3 *st3;
463 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
467 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
471 va = calloc(1,
sizeof (Example_Variant));
472 va->t.type = eet_mapping[2].name;
473 st3 = calloc(1,
sizeof (Example_Struct3));
474 _st3_set(st3, atoi(v1));
480 static Example_Lists *
483 Example_Lists *example_lists = calloc(1,
sizeof(Example_Lists));
486 fprintf(stderr,
"ERROR: could not allocate a Example_Lists struct.\n");
490 return example_lists;
494 _union_free(Example_Union *un)
496 if (un->type == EET_STRUCT1)
498 Example_Struct1 *st1 = &(un->u.st1);
499 _string_free(st1->s1);
506 _variant_free(Example_Variant *va)
508 if (!strcmp(va->t.type, eet_mapping[0].name))
510 Example_Struct1 *st1 = va->data;
511 _string_free(st1->s1);
519 _data_free(Example_Lists *cache)
524 EINA_LIST_FREE(cache->union_list, un)
527 EINA_LIST_FREE(cache->variant_list, va)
533 static Example_Lists *
534 _data_load(const
char *filename)
540 fprintf(stderr,
"ERROR: could not open '%s' for read\n", filename);
544 data =
eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
561 _data_save(
const Example_Lists *cache,
562 const char *filename)
570 len = eina_strlcpy(tmp, filename,
sizeof(tmp));
571 if (len + 12 >= (
int)
sizeof(tmp))
573 fprintf(stderr,
"ERROR: file name is too big: %s\n", filename);
580 snprintf(tmp + len, 12,
".%u", i);
583 while (stat(tmp, &st) == 0);
588 fprintf(stderr,
"ERROR: could not open '%s' for write\n", tmp);
593 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
600 rename(tmp, filename);
607 _print_union(
const Example_Union *un)
609 printf(
"\t | type: %s'\n", eet_mapping[un->type - 1].name);
614 printf(
"\t\t val1: %f\n", un->u.st1.val1);
615 printf(
"\t\t stuff: %d\n", un->u.st1.stuff);
616 printf(
"\t\t s1: %s\n", un->u.st1.s1);
620 printf(
"\t\t val1: %i\n", un->u.st2.b1);
621 printf(
"\t\t stuff: %lli\n", un->u.st2.v1);
625 printf(
"\t\t val1: %i\n", un->u.st3.body);
634 _print_variant(
const Example_Variant *va)
636 printf(
"\t | type: %s'\n", va->t.type);
638 switch (va->t.type[2])
642 Example_Struct1 *st1 = va->data;
644 printf(
"\t\t val1: %f\n", st1->val1);
645 printf(
"\t\t stuff: %d\n", st1->stuff);
646 printf(
"\t\t s1: %s\n", st1->s1);
652 Example_Struct2 *st2 = va->data;
654 printf(
"\t\t val1: %i\n", st2->b1);
655 printf(
"\t\t stuff: %lli\n", st2->v1);
661 Example_Struct3 *st3 = va->data;
663 printf(
"\t\t val1: %i\n", st3->body);
676 Example_Lists *data_lists;
682 "Usage:\n\t%s <input> <output> [action action-params]\n\n"
683 "where actions and their parameters are:\n"
684 "\tunion <type> [fields]\n"
685 "\tvariant <type> [fields]\n"
693 _data_descriptors_init();
695 data_lists = _data_load(argv[1]);
698 printf(
"Creating new data lists.\n");
699 data_lists = _data_new();
709 if (strcmp(argv[3],
"union") == 0)
713 int type = atoi(argv[4]);
716 if (type < EET_STRUCT1 || type > EET_STRUCT3)
719 "ERROR: invalid type parameter (%s).\n",
730 stderr,
"ERROR: wrong number of parameters"
736 argv[5], argv[6], argv[7]);
740 stderr,
"ERROR: could not create the "
741 "requested union.\n");
744 data_lists->union_list =
745 eina_list_append(data_lists->union_list, un);
752 stderr,
"ERROR: wrong number of parameters"
757 un = _union_2_new(argv[5], argv[6]);
761 stderr,
"ERROR: could not create the "
762 "requested union.\n");
765 data_lists->union_list =
766 eina_list_append(data_lists->union_list, un);
773 stderr,
"ERROR: wrong number of parameters"
778 un = _union_3_new(argv[5]);
782 stderr,
"ERROR: could not create the "
783 "requested union.\n");
786 data_lists->union_list =
787 eina_list_append(data_lists->union_list, un);
792 stderr,
"ERROR: bad type of of struct passed\n");
798 "ERROR: wrong number of parameters (%d).\n",
801 else if (strcmp(argv[3],
"variant") == 0)
805 int type = atoi(argv[4]);
808 if (type < EET_STRUCT1 || type > EET_STRUCT3)
811 "ERROR: invalid type parameter (%s).\n",
822 stderr,
"ERROR: wrong number of parameters"
828 argv[5], argv[6], argv[7]);
832 stderr,
"ERROR: could not create the "
833 "requested variant.\n");
836 data_lists->variant_list =
837 eina_list_append(data_lists->variant_list, va);
844 stderr,
"ERROR: wrong number of parameters"
849 va = _variant_2_new(argv[5], argv[6]);
853 stderr,
"ERROR: could not create the "
854 "requested variant.\n");
857 data_lists->variant_list =
858 eina_list_append(data_lists->variant_list, va);
865 stderr,
"ERROR: wrong number of parameters"
870 va = _variant_3_new(argv[5]);
874 stderr,
"ERROR: could not create the "
875 "requested variant.\n");
878 data_lists->variant_list =
879 eina_list_append(data_lists->variant_list, va);
884 stderr,
"ERROR: bad type of of struct passed\n");
890 "ERROR: wrong number of parameters (%d).\n",
894 fprintf(stderr,
"ERROR: unknown action '%s'\n", argv[3]);
898 printf(
"Cached data:\n");
900 printf(
"\tstats: unions=%u, variants=%u\n",
901 eina_list_count(data_lists->union_list),
902 eina_list_count(data_lists->variant_list));
904 if (eina_list_count(data_lists->union_list))
907 const Example_Union *un;
908 printf(
"\t * union list:\n");
910 EINA_LIST_FOREACH(data_lists->union_list, l, un)
916 if (eina_list_count(data_lists->variant_list))
919 const Example_Variant *un;
920 printf(
"\t * variant list:\n");
922 EINA_LIST_FOREACH(data_lists->variant_list, l, un)
930 if (!_data_save(data_lists, argv[2]))
933 _data_free(data_lists);
938 _data_descriptors_shutdown();
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:1419
int version
ABI version.
Definition: Eet.h:2457
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:2164
Definition: Eet_private.h:74
#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:3351
File is read-only.
Definition: Eet.h:513
EAPI int eet_shutdown(void)
Shut down the EET library.
Definition: eet_lib.c:634
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:2475
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:1920
#define EET_T_STRING
Data type: char *.
Definition: Eet.h:2363
#define EET_T_UCHAR
Data type: unsigned char.
Definition: Eet.h:2359
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:486
#define EET_T_INT
Data type: int.
Definition: Eet.h:2355
The file that provides the eet functions.
File is write-only.
Definition: Eet.h:514
#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:3404
#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:2412
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:1908
#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:3383
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:2132
Instructs Eet about memory management for different needs under serialization and parse process...
Definition: Eet.h:2455
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Add a basic data element to a data descriptor.
Definition: Eet.h:3040
#define EET_T_DOUBLE
Data type: double.
Definition: Eet.h:2358
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Add a linked list type to a data descriptor.
Definition: Eet.h:3093
EAPI Eet_Error eet_close(Eet_File *ef)
Close an eet file handle and flush pending writes.
Definition: eet_lib.c:1659
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition: Eet.h:2362
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition: Eet.h:2403
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:1914
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:2476
Definition: Eet_private.h:40
#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:2702
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:2553
EAPI int eet_init(void)
Initialize the EET library.
Definition: eet_lib.c:553