File descriptor data example, with Eet unions and variants

This is an example much like the one shown in Advanced use of Eet Data Descriptors.

The difference is that here we're attaining ourselves to two new data types to store in an Eet file – unions and variants. We don't try to come with data mapping to real world use cases, here. Instead, we're defining 3 different simple structures to be used throughout the example:

typedef struct _Example_Struct1 Example_Struct1;
typedef struct _Example_Struct2 Example_Struct2;
typedef struct _Example_Struct3 Example_Struct3;
struct _Example_Struct1
{
double val1;
int stuff;
const char *s1;
};
struct _Example_Struct2
{
Eina_Bool b1;
unsigned long long v1;
};
struct _Example_Struct3
{
int body;
Eina_Bool
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:527
};

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;
};
Eina_List
struct _Eina_List Eina_List
Type for a generic double linked list.
Definition eina_list.h:304

Let's begin with our unions, then, which look like:

typedef struct _Example_Union Example_Union;
struct _Example_Union
{
Example_Data_Type type;
union {
Example_Struct1 st1;
Example_Struct2 st2;
Example_Struct3 st3;
float f;
const char* string;
} u;
};

The first interesting part of the code is where we define our data descriptors for the main lists, the unions and all of structures upon which those two depend.

/* declaring types */
_data_descriptors_init(void)
{
Eet_Data_Descriptor_Class eddc;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
_lists_descriptor = eet_data_descriptor_file_new(&eddc);
_struct_1_descriptor = _st1_dd();
_struct_2_descriptor = _st2_dd();
_struct_3_descriptor = _st3_dd();
/* for union */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
_union_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _union_type_get;
eddc.func.type_set = _union_type_set;
_union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST1", _struct_1_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST2", _struct_2_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST3", _struct_3_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "float", EET_T_FLOAT);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "string", EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_UNION(
_union_descriptor, Example_Union, "u", u, type,
_union_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_LIST(
_lists_descriptor, Example_Lists, "union_list", union_list,
_union_descriptor);
EET_DATA_DESCRIPTOR_ADD_UNION
#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:3834
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET
#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:3092
EET_T_STRING
#define EET_T_STRING
Data type: char *.
Definition Eet.h:2606
EET_T_FLOAT
#define EET_T_FLOAT
Data type: float.
Definition Eet.h:2600
EET_DATA_DESCRIPTOR_CLASS_VERSION
#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:2657
eet_data_descriptor_file_new
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
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC
#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:3907
EET_DATA_DESCRIPTOR_ADD_LIST
#define EET_DATA_DESCRIPTOR_ADD_LIST(edd, struct_type, name, member, subtype)
Adds a linked list type to a data descriptor.
Definition Eet.h:3528
EET_DATA_DESCRIPTOR_ADD_MAPPING
#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:3887
Eet_Data_Descriptor_Class
struct _Eet_Data_Descriptor_Class Eet_Data_Descriptor_Class
Instructs Eet about memory management for different needs under serialization and parse process.
Definition Eet.h:2665
_Eet_Data_Descriptor_Class::type_set
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:2865
_Eet_Data_Descriptor_Class::version
int version
ABI version.
Definition Eet.h:2846
_Eet_Data_Descriptor_Class::type_get
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:2864

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.

//Compile with:
// gcc -o eet-data-file_descriptor_02 eet-data-file_descriptor_02.c `pkg-config --cflags --libs eet eina`
#include <Eina.h>
#include <Eet.h>
#include <stdio.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
typedef enum _Example_Data_Type Example_Data_Type;
typedef struct _Example_Variant_Type Example_Variant_Type;
typedef struct _Example_Variant Example_Variant;
typedef struct _Example_Union Example_Union;
typedef struct _Example_Struct1 Example_Struct1;
typedef struct _Example_Struct2 Example_Struct2;
typedef struct _Example_Struct3 Example_Struct3;
typedef struct _Example_Lists Example_Lists;
enum _Example_Data_Type
{
EET_UNKNOWN = 0,
EET_STRUCT1,
EET_STRUCT2,
EET_STRUCT3,
EET_BASIC_FLOAT,
EET_BASIC_STRING
};
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 }
};
struct _Example_Struct1
{
double val1;
int stuff;
const char *s1;
};
struct _Example_Struct2
{
Eina_Bool b1;
unsigned long long v1;
};
struct _Example_Struct3
{
int body;
};
struct _Example_Union
{
Example_Data_Type type;
union {
Example_Struct1 st1;
Example_Struct2 st2;
Example_Struct3 st3;
float f;
const char* string;
} u;
};
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*/
};
struct _Example_Lists
{
Eina_List *union_list;
Eina_List *variant_list;
};
static void
_st1_set(Example_Struct1 *st1,
double v1,
int v2,
const char *v3)
{
st1->val1 = v1;
st1->stuff = v2;
st1->s1 = v3;
} /* _st1_set */
static void
_st2_set(Example_Struct2 *st2,
Eina_Bool v1,
unsigned long long v2)
{
st2->b1 = v1;
st2->v1 = v2;
} /* _st2_set */
static void
_st3_set(Example_Struct3 *st3,
int v1)
{
st3->body = v1;
} /* _st3_set */
static const char *
/* union
type_get() */
_union_type_get(const void *data,
Eina_Bool *unknow)
{
const Example_Data_Type *u = data;
int i;
if (unknow)
*unknow = EINA_FALSE;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (*u == eet_mapping[i].u)
return eet_mapping[i].name;
if (unknow)
*unknow = EINA_TRUE;
return NULL;
} /* _union_type_get */
static Eina_Bool
_union_type_set(const char *type,
void *data,
Eina_Bool unknow)
{
Example_Data_Type *u = data;
int i;
if (unknow)
return EINA_FALSE;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(eet_mapping[i].name, type) == 0)
{
*u = eet_mapping[i].u;
return EINA_TRUE;
}
return EINA_FALSE;
} /* _union_type_set */
static const char *
_variant_type_get(const void *data,
Eina_Bool *unknow)
{
const Example_Variant_Type *type = data;
int i;
if (unknow)
*unknow = type->unknow;
for (i = 0; eet_mapping[i].name != NULL; ++i)
if (strcmp(type->type, eet_mapping[i].name) == 0)
return eet_mapping[i].name;
if (unknow)
*unknow = EINA_FALSE;
return type->type;
} /* _variant_type_get */
static Eina_Bool
_variant_type_set(const char *type,
void *data,
Eina_Bool unknow)
{
Example_Variant_Type *vt = data;
vt->type = type;
vt->unknow = unknow;
return EINA_TRUE;
} /* _variant_type_set */
static Eet_Data_Descriptor *
_st1_dd(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *res;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct1);
res = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct1, "val1", val1, EET_T_DOUBLE);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct1, "stuff", stuff, EET_T_INT);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct1, "s1", s1, EET_T_STRING);
return res;
} /* _st1_dd */
static Eet_Data_Descriptor *
_st2_dd(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *res;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct2);
res = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct2, "b1", b1, EET_T_UCHAR);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct2, "v1", v1, EET_T_ULONG_LONG);
return res;
} /* _st2_dd */
static Eet_Data_Descriptor *
_st3_dd(void)
{
Eet_Data_Descriptor_Class eddc;
Eet_Data_Descriptor *res;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Struct3);
res = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_BASIC(
res, Example_Struct3, "body", body, EET_T_INT);
return res;
} /* _st3_dd */
/* string that represents the entry in the eet file. you might like to
* have different profiles or so in the same file, this is possible
* with different strings
*/
static const char CACHE_FILE_ENTRY[] = "cache";
/* keep the descriptor static global, so it can be shared by different
* functions (load/save) of this and only this file.
*/
static Eet_Data_Descriptor *_lists_descriptor;
static Eet_Data_Descriptor *_struct_1_descriptor;
static Eet_Data_Descriptor *_struct_2_descriptor;
static Eet_Data_Descriptor *_struct_3_descriptor;
static Eet_Data_Descriptor *_union_descriptor;
static Eet_Data_Descriptor *_variant_descriptor;
static Eet_Data_Descriptor *_union_unified_descriptor;
static Eet_Data_Descriptor *_variant_unified_descriptor;
/* keep file handle alive, so mmap()ed strings are all alive as
* well */
static Eet_File *_cache_file = NULL;
static Eet_Dictionary *_cache_dict = NULL;
static void
/* declaring types */
_data_descriptors_init(void)
{
Eet_Data_Descriptor_Class eddc;
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Lists);
_lists_descriptor = eet_data_descriptor_file_new(&eddc);
_struct_1_descriptor = _st1_dd();
_struct_2_descriptor = _st2_dd();
_struct_3_descriptor = _st3_dd();
/* for union */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Union);
_union_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _union_type_get;
eddc.func.type_set = _union_type_set;
_union_unified_descriptor = eet_data_descriptor_file_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST1", _struct_1_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST2", _struct_2_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_union_unified_descriptor, "ST3", _struct_3_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "float", EET_T_FLOAT);
EET_DATA_DESCRIPTOR_ADD_MAPPING_BASIC(
_union_unified_descriptor, "string", EET_T_STRING);
EET_DATA_DESCRIPTOR_ADD_UNION(
_union_descriptor, Example_Union, "u", u, type,
_union_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_LIST(
_lists_descriptor, Example_Lists, "union_list", union_list,
_union_descriptor);
/* for variant */
EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Example_Variant);
_variant_descriptor = eet_data_descriptor_file_new(&eddc);
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc.func.type_get = _variant_type_get;
eddc.func.type_set = _variant_type_set;
_variant_unified_descriptor = eet_data_descriptor_stream_new(&eddc);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_variant_unified_descriptor, "ST1", _struct_1_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_variant_unified_descriptor, "ST2", _struct_2_descriptor);
EET_DATA_DESCRIPTOR_ADD_MAPPING(
_variant_unified_descriptor, "ST3", _struct_3_descriptor);
EET_DATA_DESCRIPTOR_ADD_VARIANT(
_variant_descriptor, Example_Variant, "data", data, t,
_variant_unified_descriptor);
EET_DATA_DESCRIPTOR_ADD_LIST(
_lists_descriptor, Example_Lists, "variant_list", variant_list,
_variant_descriptor);
} /* _data_descriptors_init */
static void
_data_descriptors_shutdown(void)
{
eet_data_descriptor_free(_lists_descriptor);
eet_data_descriptor_free(_struct_1_descriptor);
eet_data_descriptor_free(_struct_2_descriptor);
eet_data_descriptor_free(_struct_3_descriptor);
eet_data_descriptor_free(_union_descriptor);
eet_data_descriptor_free(_variant_descriptor);
eet_data_descriptor_free(_union_unified_descriptor);
eet_data_descriptor_free(_variant_unified_descriptor);
} /* _data_descriptors_shutdown */
/* need to check if the pointer came from mmap()ed area in
* eet_dictionary or it was allocated with eina_stringshare_add()
*/
static void
_string_free(const char *str)
{
if (!str)
return;
if ((_cache_dict) && (eet_dictionary_string_check(_cache_dict, str)))
return;
eina_stringshare_del(str);
} /* _string_free */
static Example_Union *
_union_1_new(const char *v1,
const char *v2,
const char *v3)
{
Example_Union *un = calloc(1, sizeof(Example_Union));
if (!un)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Union struct.\n");
return NULL;
}
un->type = EET_STRUCT1;
_st1_set(&(un->u.st1), eina_convert_strtod_c(v1, NULL), atoi(v2), eina_stringshare_add(v3));
return un;
}
static Example_Union *
_union_2_new(const char *v1,
const char *v2)
{
Example_Union *un = calloc(1, sizeof(Example_Union));
if (!un)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Union struct.\n");
return NULL;
}
un->type = EET_STRUCT2;
_st2_set(&(un->u.st2), atoi(v1), atoi(v2));
return un;
}
static Example_Union *
_union_3_new(const char *v1)
{
Example_Union *un = calloc(1, sizeof(Example_Union));
if (!un)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Union struct.\n");
return NULL;
}
un->type = EET_STRUCT3;
_st3_set(&(un->u.st3), atoi(v1));
return un;
}
static Example_Union *
_union_float_new(const char *v1)
{
Example_Union *un = calloc(1, sizeof(Example_Union));
if (!un)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Union struct.\n");
return NULL;
}
un->type = EET_BASIC_FLOAT;
un->u.f = eina_convert_strtod_c(v1, NULL);
return un;
}
static Example_Union *
_union_string_new(const char *v1)
{
Example_Union *un = calloc(1, sizeof(Example_Union));
if (!un)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Union struct.\n");
return NULL;
}
un->type = EET_BASIC_STRING;
un->u.string = v1;
return un;
}
static Example_Variant *
_variant_1_new(const char *v1,
const char *v2,
const char *v3)
{
Example_Struct1 *st1;
Example_Variant *va = calloc(1, sizeof(Example_Variant));
if (!va)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Variant struct.\n");
return NULL;
}
va->t.type = eet_mapping[0].name;
st1 = calloc(1, sizeof (Example_Struct1));
_st1_set(st1, eina_convert_strtod_c(v1, NULL), atoi(v2), eina_stringshare_add(v3));
va->data = st1;
return va;
}
static Example_Variant *
_variant_2_new(const char *v1,
const char *v2)
{
printf("varinant 2 new\n");
Example_Struct2 *st2;
Example_Variant *va = calloc(1, sizeof(Example_Variant));
if (!va)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Variant struct.\n");
return NULL;
}
va->t.type = eet_mapping[1].name;
printf("type gets %s\n", va->t.type);
st2 = calloc(1, sizeof (Example_Struct2));
_st2_set(st2, atoi(v1), atoi(v2));
va->data = st2;
return va;
}
static Example_Variant *
_variant_3_new(const char *v1)
{
Example_Struct3 *st3;
Example_Variant *va = calloc(1, sizeof(Example_Variant));
if (!va)
{
fprintf(
stderr, "ERROR: could not allocate an Example_Variant struct.\n");
return NULL;
}
va->t.type = eet_mapping[2].name;
st3 = calloc(1, sizeof (Example_Struct3));
_st3_set(st3, atoi(v1));
va->data = st3;
return va;
}
static Example_Lists *
_data_new(void)
{
Example_Lists *example_lists = calloc(1, sizeof(Example_Lists));
if (!example_lists)
{
fprintf(stderr, "ERROR: could not allocate a Example_Lists struct.\n");
return NULL;
}
return example_lists;
} /* _data_new */
static void
_union_free(Example_Union *un)
{
if (un->type == EET_STRUCT1)
{
Example_Struct1 *st1 = &(un->u.st1);
_string_free(st1->s1);
}
free(un);
}
static void
_variant_free(Example_Variant *va)
{
if (!strcmp(va->t.type, eet_mapping[0].name))
{
Example_Struct1 *st1 = va->data;
_string_free(st1->s1);
}
free(va->data);
free(va);
}
static void
_data_free(Example_Lists *cache)
{
Example_Union *un;
Example_Variant *va;
EINA_LIST_FREE(cache->union_list, un)
_union_free(un);
EINA_LIST_FREE(cache->variant_list, va)
_variant_free(va);
free(cache);
} /* _data_free */
static Example_Lists *
_data_load(const char *filename)
{
Example_Lists *data;
Eet_File *ef = eet_open(filename, EET_FILE_MODE_READ);
if (!ef)
{
fprintf(stderr, "ERROR: could not open '%s' for read\n", filename);
return NULL;
}
data = eet_data_read(ef, _lists_descriptor, CACHE_FILE_ENTRY);
if (!data)
{
eet_close(ef);
return NULL;
}
if (_cache_file)
eet_close(_cache_file);
_cache_file = ef;
_cache_dict = eet_dictionary_get(ef);
return data;
} /* _data_load */
static Eina_Bool
_data_save(const Example_Lists *cache,
const char *filename)
{
char tmp[PATH_MAX];
Eet_File *ef;
Eina_Bool ret;
unsigned int i, len;
struct stat st;
len = eina_strlcpy(tmp, filename, sizeof(tmp));
if (len + 12 >= (int)sizeof(tmp))
{
fprintf(stderr, "ERROR: file name is too big: %s\n", filename);
return EINA_FALSE;
}
i = 0;
do
{
snprintf(tmp + len, 12, ".%u", i);
i++;
}
while (stat(tmp, &st) == 0);
ef = eet_open(tmp, EET_FILE_MODE_WRITE);
if (!ef)
{
fprintf(stderr, "ERROR: could not open '%s' for write\n", tmp);
return EINA_FALSE;
}
ret = eet_data_write
(ef, _lists_descriptor, CACHE_FILE_ENTRY, cache, EINA_TRUE);
eet_close(ef);
if (ret)
{
unlink(filename);
rename(tmp, filename);
}
return ret;
} /* _data_save */
static void
_print_union(const Example_Union *un)
{
printf("\t | type: %s'\n", eet_mapping[un->type - 1].name);
switch (un->type)
{
case EET_STRUCT1:
printf("\t\t val1: %f\n", un->u.st1.val1);
printf("\t\t stuff: %d\n", un->u.st1.stuff);
printf("\t\t s1: %s\n", un->u.st1.s1);
break;
case EET_STRUCT2:
printf("\t\t val1: %i\n", un->u.st2.b1);
printf("\t\t stuff: %lli\n", un->u.st2.v1);
break;
case EET_STRUCT3:
printf("\t\t val1: %i\n", un->u.st3.body);
break;
case EET_BASIC_FLOAT:
printf("\t\t float: %f\n", un->u.f);
break;
case EET_BASIC_STRING:
printf("\t\t string: %s\n", un->u.string);
break;
default:
return;
}
}
static void
_print_variant(const Example_Variant *va)
{
printf("\t | type: %s'\n", va->t.type);
switch (va->t.type[2])
{
case '1':
{
Example_Struct1 *st1 = va->data;
printf("\t\t val1: %f\n", st1->val1);
printf("\t\t stuff: %d\n", st1->stuff);
printf("\t\t s1: %s\n", st1->s1);
}
break;
case '2':
{
Example_Struct2 *st2 = va->data;
printf("\t\t val1: %i\n", st2->b1);
printf("\t\t stuff: %lli\n", st2->v1);
}
break;
case '3':
{
Example_Struct3 *st3 = va->data;
printf("\t\t val1: %i\n", st3->body);
}
break;
default:
return;
}
}
int
main(int argc,
char *argv[])
{
Example_Lists *data_lists;
int ret = 0;
if (argc < 3)
{
fprintf(stderr,
"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]);
return -1;
}
eina_init();
eet_init();
_data_descriptors_init();
data_lists = _data_load(argv[1]);
if (!data_lists)
{
printf("Creating new data lists.\n");
data_lists = _data_new();
if (!data_lists)
{
ret = -2;
goto end;
}
}
if (argc > 3)
{
if (strcmp(argv[3], "union") == 0)
{
if (argc > 4)
{
int type = atoi(argv[4]);
Example_Union *un;
if (type < EET_STRUCT1 || type > EET_BASIC_STRING)
{
fprintf(stderr,
"ERROR: invalid type parameter (%s).\n",
argv[4]);
goto cont;
}
switch (type)
{
case 1:
if (argc != 8)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
un = _union_1_new(
argv[5], argv[6], argv[7]);
if (!un)
{
fprintf(
stderr, "ERROR: could not create the "
"requested union.\n");
goto cont;
}
data_lists->union_list =
eina_list_append(data_lists->union_list, un);
break;
case 2:
if (argc != 7)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
un = _union_2_new(argv[5], argv[6]);
if (!un)
{
fprintf(
stderr, "ERROR: could not create the "
"requested union.\n");
goto cont;
}
data_lists->union_list =
eina_list_append(data_lists->union_list, un);
break;
case 3:
if (argc != 6)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
un = _union_3_new(argv[5]);
if (!un)
{
fprintf(
stderr, "ERROR: could not create the "
"requested union.\n");
goto cont;
}
data_lists->union_list =
eina_list_append(data_lists->union_list, un);
break;
case EET_BASIC_FLOAT:
if (argc != 6)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
un = _union_float_new(argv[5]);
if (!un)
{
fprintf(
stderr, "ERROR: could not create the "
"requested union.\n");
goto cont;
}
data_lists->union_list =
eina_list_append(data_lists->union_list, un);
break;
case EET_BASIC_STRING:
if (argc != 6)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
un = _union_string_new(argv[5]);
if (!un)
{
fprintf(
stderr, "ERROR: could not create the "
"requested union.\n");
goto cont;
}
data_lists->union_list =
eina_list_append(data_lists->union_list, un);
break;
default:
fprintf(
stderr, "ERROR: bad type of of struct passed\n");
goto cont;
}
}
else
fprintf(stderr,
"ERROR: wrong number of parameters (%d).\n",
argc);
}
else if (strcmp(argv[3], "variant") == 0)
{
if (argc > 4)
{
int type = atoi(argv[4]);
Example_Variant *va;
if (type < EET_STRUCT1 || type > EET_STRUCT3)
{
fprintf(stderr,
"ERROR: invalid type parameter (%s).\n",
argv[4]);
goto cont;
}
switch (type)
{
case 1:
if (argc != 8)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
va = _variant_1_new(
argv[5], argv[6], argv[7]);
if (!va)
{
fprintf(
stderr, "ERROR: could not create the "
"requested variant.\n");
goto cont;
}
data_lists->variant_list =
eina_list_append(data_lists->variant_list, va);
break;
case 2:
if (argc != 7)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
va = _variant_2_new(argv[5], argv[6]);
if (!va)
{
fprintf(
stderr, "ERROR: could not create the "
"requested variant.\n");
goto cont;
}
data_lists->variant_list =
eina_list_append(data_lists->variant_list, va);
break;
case 3:
if (argc != 6)
{
fprintf(
stderr, "ERROR: wrong number of parameters"
" (%d).\n", argc);
goto cont;
}
va = _variant_3_new(argv[5]);
if (!va)
{
fprintf(
stderr, "ERROR: could not create the "
"requested variant.\n");
goto cont;
}
data_lists->variant_list =
eina_list_append(data_lists->variant_list, va);
break;
default:
fprintf(
stderr, "ERROR: bad type of of struct passed\n");
goto cont;
}
}
else
fprintf(stderr,
"ERROR: wrong number of parameters (%d).\n",
argc);
}
else
fprintf(stderr, "ERROR: unknown action '%s'\n", argv[3]);
}
cont:
printf("Cached data:\n");
printf("\tstats: unions=%u, variants=%u\n",
eina_list_count(data_lists->union_list),
eina_list_count(data_lists->variant_list));
if (eina_list_count(data_lists->union_list))
{
const Eina_List *l;
const Example_Union *un;
printf("\t * union list:\n");
EINA_LIST_FOREACH(data_lists->union_list, l, un)
{
_print_union(un);
}
}
if (eina_list_count(data_lists->variant_list))
{
const Eina_List *l;
const Example_Variant *un;
printf("\t * variant list:\n");
EINA_LIST_FOREACH(data_lists->variant_list, l, un)
{
_print_variant(un);
}
}
printf("\n");
if (!_data_save(data_lists, argv[2]))
ret = -3;
_data_free(data_lists);
end:
if (_cache_file)
eet_close(_cache_file);
_data_descriptors_shutdown();
eet_shutdown();
eina_shutdown();
return ret;
} /* main */
Eet.h
The file that provides the eet functions.
Eina.h
Eina Utility library.
EET_T_UCHAR
#define EET_T_UCHAR
Data type: unsigned char.
Definition Eet.h:2602
eet_data_descriptor_free
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
eet_data_read
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:2379
EET_T_INT
#define EET_T_INT
Data type: int.
Definition Eet.h:2598
eet_data_descriptor_stream_new
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
EET_DATA_DESCRIPTOR_ADD_VARIANT
#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:3866
EET_T_DOUBLE
#define EET_T_DOUBLE
Data type: double.
Definition Eet.h:2601
EET_DATA_DESCRIPTOR_ADD_BASIC
#define EET_DATA_DESCRIPTOR_ADD_BASIC(edd, struct_type, name, member, type)
Adds a basic data element to a data descriptor.
Definition Eet.h:3449
eet_data_write
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:2416
Eet_Data_Descriptor
struct _Eet_Data_Descriptor Eet_Data_Descriptor
Opaque handle that have information on a type members.
Definition Eet.h:2648
EET_T_ULONG_LONG
#define EET_T_ULONG_LONG
Data type: unsigned long long.
Definition Eet.h:2605
Eet_Dictionary
struct _Eet_Dictionary Eet_Dictionary
Opaque handle that defines a file-backed (mmaped) dictionary of strings.
Definition Eet.h:533
eet_close
EAPI Eet_Error eet_close(Eet_File *ef)
Closes an eet file handle and flush pending writes.
Definition eet_lib.c:1934
eet_dictionary_string_check
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:601
Eet_File
struct _Eet_File Eet_File
Opaque handle that defines an Eet file (or memory).
Definition Eet.h:527
eet_open
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:1525
eet_dictionary_get
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:2599
EET_FILE_MODE_READ
@ EET_FILE_MODE_READ
File is read-only.
Definition Eet.h:479
EET_FILE_MODE_WRITE
@ EET_FILE_MODE_WRITE
File is write-only.
Definition Eet.h:480
eet_init
EAPI int eet_init(void)
Initializes the EET library.
Definition eet_lib.c:543
eet_shutdown
EAPI int eet_shutdown(void)
Shuts down the EET library.
Definition eet_lib.c:597
eina_convert_strtod_c
EINA_API double eina_convert_strtod_c(const char *nptr, char **endptr)
Converts a string to a floating point number.
Definition eina_convert.c:472
eina_list_append
EINA_API 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
EINA_LIST_FOREACH
#define EINA_LIST_FOREACH(list, l, _data)
Definition for the macro to iterate over a list.
Definition eina_list.h:1415
EINA_LIST_FREE
#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
eina_shutdown
EINA_API int eina_shutdown(void)
Shuts down the Eina library.
Definition eina_main.c:379
eina_init
EINA_API int eina_init(void)
Initializes the Eina library.
Definition eina_main.c:291
eina_strlcpy
EINA_API size_t eina_strlcpy(char *dst, const char *src, size_t siz)
Copies a c-string to another.
Definition eina_str.c:317
eina_stringshare_add
EINA_API Eina_Stringshare * eina_stringshare_add(const char *str)
Retrieves an instance of a string for use in a program.
Definition eina_stringshare.c:606
eina_stringshare_del
EINA_API void eina_stringshare_del(Eina_Stringshare *str)
Notes that the given string has lost an instance.
Definition eina_stringshare.c:533
EINA_TRUE
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
EINA_FALSE
#define EINA_FALSE
boolean value FALSE (numerical value 0)
Definition eina_types.h:533