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.
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.
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;
21 enum _Example_Data_Type
36 { EET_STRUCT1,
"ST1" },
37 { EET_STRUCT2,
"ST2" },
38 { EET_STRUCT3,
"ST3" },
39 { EET_BASIC_FLOAT,
"float" },
40 { EET_BASIC_STRING,
"string" },
44 struct _Example_Struct1
51 struct _Example_Struct2
54 unsigned long long v1;
57 struct _Example_Struct3
64 Example_Data_Type type;
75 struct _Example_Variant_Type
81 struct _Example_Variant
83 Example_Variant_Type t;
97 _st1_set(Example_Struct1 *st1,
108 _st2_set(Example_Struct2 *st2,
110 unsigned long long v2)
117 _st3_set(Example_Struct3 *st3,
126 _union_type_get(
const void *data,
129 const Example_Data_Type *u = data;
135 for (i = 0; eet_mapping[i].name != NULL; ++i)
136 if (*u == eet_mapping[i].u)
137 return eet_mapping[i].name;
146 _union_type_set(
const char *type,
150 Example_Data_Type *u = data;
156 for (i = 0; eet_mapping[i].name != NULL; ++i)
157 if (strcmp(eet_mapping[i].name, type) == 0)
159 *u = eet_mapping[i].u;
167 _variant_type_get(
const void *data,
170 const Example_Variant_Type *type = data;
174 *unknow = type->unknow;
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;
187 _variant_type_set(
const char *type,
191 Example_Variant_Type *vt = data;
209 res, Example_Struct1,
"stuff", stuff,
EET_T_INT);
241 res, Example_Struct3,
"body", body,
EET_T_INT);
250 static const char CACHE_FILE_ENTRY[] =
"cache";
266 static Eet_File *_cache_file = NULL;
271 _data_descriptors_init(
void)
278 _struct_1_descriptor = _st1_dd();
279 _struct_2_descriptor = _st2_dd();
280 _struct_3_descriptor = _st3_dd();
287 eddc.func.
type_get = _union_type_get;
288 eddc.func.
type_set = _union_type_set;
292 _union_unified_descriptor,
"ST1", _struct_1_descriptor);
294 _union_unified_descriptor,
"ST2", _struct_2_descriptor);
296 _union_unified_descriptor,
"ST3", _struct_3_descriptor);
303 _union_descriptor, Example_Union,
"u", u, type,
304 _union_unified_descriptor);
307 _lists_descriptor, Example_Lists,
"union_list", union_list,
315 eddc.func.
type_get = _variant_type_get;
316 eddc.func.
type_set = _variant_type_set;
320 _variant_unified_descriptor,
"ST1", _struct_1_descriptor);
322 _variant_unified_descriptor,
"ST2", _struct_2_descriptor);
324 _variant_unified_descriptor,
"ST3", _struct_3_descriptor);
327 _variant_descriptor, Example_Variant,
"data", data, t,
328 _variant_unified_descriptor);
331 _lists_descriptor, Example_Lists,
"variant_list", variant_list,
332 _variant_descriptor);
336 _data_descriptors_shutdown(
void)
352 _string_free(
const char *str)
363 static Example_Union *
364 _union_1_new(
const char *v1,
368 Example_Union *un = calloc(1,
sizeof(Example_Union));
372 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
376 un->type = EET_STRUCT1;
382 static Example_Union *
383 _union_2_new(
const char *v1,
386 Example_Union *un = calloc(1,
sizeof(Example_Union));
390 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
394 un->type = EET_STRUCT2;
395 _st2_set(&(un->u.st2), atoi(v1), atoi(v2));
400 static Example_Union *
401 _union_3_new(
const char *v1)
403 Example_Union *un = calloc(1,
sizeof(Example_Union));
407 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
411 un->type = EET_STRUCT3;
412 _st3_set(&(un->u.st3), atoi(v1));
417 static Example_Union *
418 _union_float_new(
const char *v1)
420 Example_Union *un = calloc(1,
sizeof(Example_Union));
424 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
428 un->type = EET_BASIC_FLOAT;
434 static Example_Union *
435 _union_string_new(
const char *v1)
437 Example_Union *un = calloc(1,
sizeof(Example_Union));
441 stderr,
"ERROR: could not allocate an Example_Union struct.\n");
445 un->type = EET_BASIC_STRING;
451 static Example_Variant *
452 _variant_1_new(
const char *v1,
456 Example_Struct1 *st1;
457 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
461 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
465 va->t.type = eet_mapping[0].name;
466 st1 = calloc(1,
sizeof (Example_Struct1));
473 static Example_Variant *
474 _variant_2_new(
const char *v1,
477 printf(
"varinant 2 new\n");
479 Example_Struct2 *st2;
480 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
484 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
488 va->t.type = eet_mapping[1].name;
490 printf(
"type gets %s\n", va->t.type);
492 st2 = calloc(1,
sizeof (Example_Struct2));
493 _st2_set(st2, atoi(v1), atoi(v2));
499 static Example_Variant *
500 _variant_3_new(
const char *v1)
502 Example_Struct3 *st3;
503 Example_Variant *va = calloc(1,
sizeof(Example_Variant));
507 stderr,
"ERROR: could not allocate an Example_Variant struct.\n");
511 va->t.type = eet_mapping[2].name;
512 st3 = calloc(1,
sizeof (Example_Struct3));
513 _st3_set(st3, atoi(v1));
519 static Example_Lists *
522 Example_Lists *example_lists = calloc(1,
sizeof(Example_Lists));
525 fprintf(stderr,
"ERROR: could not allocate a Example_Lists struct.\n");
529 return example_lists;
533 _union_free(Example_Union *un)
535 if (un->type == EET_STRUCT1)
537 Example_Struct1 *st1 = &(un->u.st1);
538 _string_free(st1->s1);
545 _variant_free(Example_Variant *va)
547 if (!strcmp(va->t.type, eet_mapping[0].name))
549 Example_Struct1 *st1 = va->data;
550 _string_free(st1->s1);
558 _data_free(Example_Lists *cache)
572 static Example_Lists *
573 _data_load(
const char *filename)
579 fprintf(stderr,
"ERROR: could not open '%s' for read\n", filename);
583 data =
eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
600 _data_save(
const Example_Lists *cache,
601 const char *filename)
610 if (len + 12 >= (
int)
sizeof(tmp))
612 fprintf(stderr,
"ERROR: file name is too big: %s\n", filename);
619 snprintf(tmp + len, 12,
".%u", i);
622 while (stat(tmp, &st) == 0);
627 fprintf(stderr,
"ERROR: could not open '%s' for write\n", tmp);
632 (ef, _lists_descriptor, CACHE_FILE_ENTRY, cache,
EINA_TRUE);
639 rename(tmp, filename);
646 _print_union(
const Example_Union *un)
648 printf(
"\t | type: %s'\n", eet_mapping[un->type - 1].name);
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);
659 printf(
"\t\t val1: %i\n", un->u.st2.b1);
660 printf(
"\t\t stuff: %lli\n", un->u.st2.v1);
664 printf(
"\t\t val1: %i\n", un->u.st3.body);
667 case EET_BASIC_FLOAT:
668 printf(
"\t\t float: %f\n", un->u.f);
671 case EET_BASIC_STRING:
672 printf(
"\t\t string: %s\n", un->u.string);
681 _print_variant(
const Example_Variant *va)
683 printf(
"\t | type: %s'\n", va->t.type);
685 switch (va->t.type[2])
689 Example_Struct1 *st1 = va->data;
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);
699 Example_Struct2 *st2 = va->data;
701 printf(
"\t\t val1: %i\n", st2->b1);
702 printf(
"\t\t stuff: %lli\n", st2->v1);
708 Example_Struct3 *st3 = va->data;
710 printf(
"\t\t val1: %i\n", st3->body);
723 Example_Lists *data_lists;
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" 740 _data_descriptors_init();
742 data_lists = _data_load(argv[1]);
745 printf(
"Creating new data lists.\n");
746 data_lists = _data_new();
756 if (strcmp(argv[3],
"union") == 0)
760 int type = atoi(argv[4]);
763 if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
766 "ERROR: invalid type parameter (%s).\n",
777 stderr,
"ERROR: wrong number of parameters" 783 argv[5], argv[6], argv[7]);
787 stderr,
"ERROR: could not create the " 788 "requested union.\n");
791 data_lists->union_list =
799 stderr,
"ERROR: wrong number of parameters" 804 un = _union_2_new(argv[5], argv[6]);
808 stderr,
"ERROR: could not create the " 809 "requested union.\n");
812 data_lists->union_list =
820 stderr,
"ERROR: wrong number of parameters" 825 un = _union_3_new(argv[5]);
829 stderr,
"ERROR: could not create the " 830 "requested union.\n");
833 data_lists->union_list =
837 case EET_BASIC_FLOAT:
841 stderr,
"ERROR: wrong number of parameters" 846 un = _union_float_new(argv[5]);
850 stderr,
"ERROR: could not create the " 851 "requested union.\n");
854 data_lists->union_list =
858 case EET_BASIC_STRING:
862 stderr,
"ERROR: wrong number of parameters" 867 un = _union_string_new(argv[5]);
871 stderr,
"ERROR: could not create the " 872 "requested union.\n");
875 data_lists->union_list =
881 stderr,
"ERROR: bad type of of struct passed\n");
887 "ERROR: wrong number of parameters (%d).\n",
890 else if (strcmp(argv[3],
"variant") == 0)
894 int type = atoi(argv[4]);
897 if (type < EET_STRUCT1 || type > EET_STRUCT3)
900 "ERROR: invalid type parameter (%s).\n",
911 stderr,
"ERROR: wrong number of parameters" 917 argv[5], argv[6], argv[7]);
921 stderr,
"ERROR: could not create the " 922 "requested variant.\n");
925 data_lists->variant_list =
933 stderr,
"ERROR: wrong number of parameters" 938 va = _variant_2_new(argv[5], argv[6]);
942 stderr,
"ERROR: could not create the " 943 "requested variant.\n");
946 data_lists->variant_list =
954 stderr,
"ERROR: wrong number of parameters" 959 va = _variant_3_new(argv[5]);
963 stderr,
"ERROR: could not create the " 964 "requested variant.\n");
967 data_lists->variant_list =
973 stderr,
"ERROR: bad type of of struct passed\n");
979 "ERROR: wrong number of parameters (%d).\n",
983 fprintf(stderr,
"ERROR: unknown action '%s'\n", argv[3]);
987 printf(
"Cached data:\n");
989 printf(
"\tstats: unions=%u, variants=%u\n",
996 const Example_Union *un;
997 printf(
"\t * union list:\n");
1008 const Example_Variant *un;
1009 printf(
"\t * variant list:\n");
1019 if (!_data_save(data_lists, argv[2]))
1022 _data_free(data_lists);
1027 _data_descriptors_shutdown();
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
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