forked from enlightenment/efl
* eet: Add EET_G_VARIANT and EET_G_UNION.
This are the basis for a new edje file format. Next to come EET_G_INHERIT. SVN revision: 48201
This commit is contained in:
parent
7c0098c1a3
commit
a5aaf1723b
|
@ -365,3 +365,7 @@
|
|||
2010-04-16 Cedric BAIL
|
||||
|
||||
* Handle fixed point in data stream.
|
||||
|
||||
2010-04-21 Cedric BAIL
|
||||
|
||||
* Add EET_G_UNION and EET_G_VARIANT.
|
||||
|
|
|
@ -274,7 +274,7 @@ extern "C" {
|
|||
*
|
||||
* If the eet file handle is not valid nothing will be done.
|
||||
*
|
||||
* @since 1.2.3
|
||||
* @since 1.2.4
|
||||
* @ingroup Eet_File_Group
|
||||
*/
|
||||
EAPI Eet_Error eet_sync(Eet_File *ef);
|
||||
|
@ -1491,7 +1491,10 @@ extern "C" {
|
|||
#define EET_G_VAR_ARRAY 102 /**< Variable size array group type */
|
||||
#define EET_G_LIST 103 /**< Linked list group type */
|
||||
#define EET_G_HASH 104 /**< Hash table group type */
|
||||
#define EET_G_LAST 105 /**< Last group type */
|
||||
#define EET_G_UNION 105 /**< Union group type */
|
||||
#define EET_G_INHERIT 106 /**< Inherit object group type */
|
||||
#define EET_G_VARIANT 107 /**< Selectable subtype group */
|
||||
#define EET_G_LAST 108 /**< Last group type */
|
||||
|
||||
#define EET_I_LIMIT 128 /**< Other type exist but are reserved for internal purpose. */
|
||||
|
||||
|
@ -1518,7 +1521,7 @@ extern "C" {
|
|||
* version member so it is compatible with abi changes, or at least
|
||||
* will not crash with them.
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_CLASS_VERSION 2
|
||||
#define EET_DATA_DESCRIPTOR_CLASS_VERSION 3
|
||||
|
||||
/**
|
||||
* @typedef Eet_Data_Descriptor_Class
|
||||
|
@ -1557,6 +1560,9 @@ extern "C" {
|
|||
void (*hash_free) (void *h); /**< free all entries from the hash @p h */
|
||||
char *(*str_direct_alloc) (const char *str); /**< how to allocate a string directly from file backed/mmaped region pointed by @p str */
|
||||
void (*str_direct_free) (const char *str); /**< how to free a string returned by str_direct_alloc */
|
||||
|
||||
const char *(*type_get) (const void *data, Eina_Bool *unknow); /**< convert any kind of data type to a name that define an Eet_Data_Element. */
|
||||
Eina_Bool (*type_set) (const char *type, void *data, Eina_Bool unknow); /**< set the type at a particular adress */
|
||||
} func;
|
||||
};
|
||||
|
||||
|
@ -2163,6 +2169,109 @@ extern "C" {
|
|||
(char *)(&(___ett.member ## _count)) - (char *)(&(___ett)), /* 0, */NULL, subtype); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an union type to a data descriptor
|
||||
* @param edd The data descriptor to add the type to.
|
||||
* @param struct_type The type of the struct.
|
||||
* @param name The string name to use to encode/decode this member
|
||||
* (must be a constant global and never change).
|
||||
* @param member The struct member itself to be encoded.
|
||||
* @param type_member The member that give hints on what is in the union.
|
||||
* @param unified_type Describe all possible type the union could handle.
|
||||
*
|
||||
* This macro lets you easily add an union with a member that specify what is inside.
|
||||
* The @p unified_type is an Eet_Data_Descriptor, but only the entry that match the name
|
||||
* returned by type_get will be used for each serialized data. The type_get and type_set
|
||||
* callback of unified_type should be defined.
|
||||
*
|
||||
* @since 1.2.4
|
||||
* @ingroup Eet_Data_Group
|
||||
* @see Eet_Data_Descriptor_Class
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_ADD_UNION(edd, struct_type, name, member, type_member, unified_type) \
|
||||
{ \
|
||||
struct_type ___ett; \
|
||||
\
|
||||
eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_UNION, \
|
||||
(char *) (&(___ett.member)) - (char *)(&(___ett)), \
|
||||
(char *) (&(___ett.type_member)) - (char *)(&(___ett)), \
|
||||
NULL, unified_type); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a structure variable in size/content depend on it's type
|
||||
* @param edd The data descriptor to add the type to.
|
||||
* @param struct_type The type of the struct.
|
||||
* @param name The string name to use to encode/decode this member
|
||||
* (must be a constant global and never change).
|
||||
* @param member The struct member itself to be encoded.
|
||||
* @param type_member The member that give hints on what is in the union.
|
||||
* @param unified_type Describe all possible type the union could handle.
|
||||
*
|
||||
* This macro lets you easily add a switch for an object oriented representation. The position
|
||||
* of the member that define the type must be fixed for all possible type. Eet will then choose
|
||||
* in the unified_type the structure that need to be allocated to match the detected type.
|
||||
* The type_get and type_set callback of unified_type should be defined. This should be the only
|
||||
* type in edd.
|
||||
*
|
||||
* @since 1.2.4
|
||||
* @ingroup Eet_Data_Group
|
||||
* @see Eet_Data_Descriptor_Class
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_ADD_INHERIT(edd, struct_type, name, member, type_member, unified_type) \
|
||||
{ \
|
||||
struct_type ___ett; \
|
||||
\
|
||||
eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_INHERIT, \
|
||||
(char *) (&(___ett.member)) - (char *)(&(___ett)), \
|
||||
(char *) (&(___ett.type_member)) - (char *)(&(___ett)), \
|
||||
NULL, unified_type); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a automatically selectable type to a data descriptor
|
||||
* @param edd The data descriptor to add the type to.
|
||||
* @param struct_type The type of the struct.
|
||||
* @param name The string name to use to encode/decode this member
|
||||
* (must be a constant global and never change).
|
||||
* @param member The struct member itself to be encoded.
|
||||
* @param type_member The member that give hints on what is in the union.
|
||||
* @param unified_type Describe all possible type the union could handle.
|
||||
*
|
||||
* This macro lets you easily define what the content of @p member points to depending of
|
||||
* the content of @p type_member. The type_get and type_set callback of unified_type should
|
||||
* be defined. If the the type is not know at the time of restoring it, eet will still call
|
||||
* type_set of @p unified_type but the pointer will be set to a serialized binary representation
|
||||
* of what eet know. This make it possible, to save this pointer again by just returning the string
|
||||
* given previously and telling it by setting unknow to EINA_TRUE.
|
||||
*
|
||||
* @since 1.2.4
|
||||
* @ingroup Eet_Data_Group
|
||||
* @see Eet_Data_Descriptor_Class
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, struct_type, name, member, type_member, unified_type) \
|
||||
{ \
|
||||
struct_type ___ett; \
|
||||
\
|
||||
eet_data_descriptor_element_add(edd, name, EET_T_UNKNOW, EET_G_VARIANT, \
|
||||
(char *) (&(___ett.member)) - (char *)(&(___ett)), \
|
||||
(char *) (&(___ett.type_member)) - (char *)(&(___ett)), \
|
||||
NULL, unified_type); \
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a mapping to a data descriptor that will be used by union, variant or inherited type
|
||||
* @param unified_type The data descriptor to add the mapping to.
|
||||
* @param name The string name to get/set type.
|
||||
* @param subtype The matching data descriptor.
|
||||
*
|
||||
* @since 1.2.4
|
||||
* @ingroup Eet_Data_Group
|
||||
* @see Eet_Data_Descriptor_Class
|
||||
*/
|
||||
#define EET_DATA_DESCRIPTOR_ADD_MAPPING(unified_type, name, subtype) \
|
||||
eet_data_descriptor_element_add(unified_type, name, EET_T_UNKNOW, EET_G_UNKNOWN, 0, 0, NULL, subtype);
|
||||
|
||||
/**
|
||||
* @defgroup Eet_Data_Cipher_Group Eet Data Serialization using A Ciphers
|
||||
*
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef struct _Eet_Data_Descriptor_Hash Eet_Data_Descriptor_Hash;
|
|||
typedef struct _Eet_Data_Encode_Hash_Info Eet_Data_Encode_Hash_Info;
|
||||
typedef struct _Eet_Free Eet_Free;
|
||||
typedef struct _Eet_Free_Context Eet_Free_Context;
|
||||
typedef struct _Eet_Variant_Unknow Eet_Variant_Unknow;
|
||||
|
||||
/*---*/
|
||||
|
||||
|
@ -138,6 +139,8 @@ struct _Eet_Data_Descriptor
|
|||
void (*hash_foreach) (void *h, int (*func) (void *h, const char *k, void *dt, void *fdt), void *fdt);
|
||||
void *(*hash_add) (void *h, const char *k, void *d);
|
||||
void (*hash_free) (void *h);
|
||||
const char *(*type_get) (const void *data, Eina_Bool *unknow);
|
||||
Eina_Bool (*type_set) (const char *type, void *data, Eina_Bool unknow);
|
||||
} func;
|
||||
struct {
|
||||
int num;
|
||||
|
@ -147,6 +150,8 @@ struct _Eet_Data_Descriptor
|
|||
Eet_Data_Descriptor_Hash *buckets;
|
||||
} hash;
|
||||
} elements;
|
||||
|
||||
Eina_Bool unified_type : 1;
|
||||
// char *strings;
|
||||
// int strings_len;
|
||||
};
|
||||
|
@ -188,6 +193,14 @@ struct _Eet_Free_Context
|
|||
Eet_Free freelist_direct_str;
|
||||
};
|
||||
|
||||
struct _Eet_Variant_Unknow
|
||||
{
|
||||
EINA_MAGIC;
|
||||
|
||||
int size;
|
||||
char data[1];
|
||||
};
|
||||
|
||||
/*---*/
|
||||
|
||||
static int eet_data_get_char(const Eet_Dictionary *ed, const void *src, const void *src_end, void *dest);
|
||||
|
@ -228,6 +241,12 @@ static int eet_data_get_list(Eet_Free_Context *context, const Eet_Dictionary *e
|
|||
static void eet_data_put_list(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
|
||||
static void eet_data_put_hash(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
|
||||
static int eet_data_get_hash(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, char **p, int *size);
|
||||
static void eet_data_put_union(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
|
||||
static int eet_data_get_union(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, char **p, int *size);
|
||||
static void eet_data_put_inherit(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
|
||||
static int eet_data_get_inherit(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, char **p, int *size);
|
||||
static void eet_data_put_variant(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in);
|
||||
static int eet_data_get_variant(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede, Eet_Data_Chunk *echnk, int type, int group_type, void *data, char **p, int *size);
|
||||
|
||||
static void eet_data_chunk_get(const Eet_Dictionary *ed, Eet_Data_Chunk *chnk, const void *src, int size);
|
||||
static Eet_Data_Chunk *eet_data_chunk_new(void *data, int size, const char *name, int type, int group_type);
|
||||
|
@ -275,7 +294,10 @@ static const Eet_Data_Group_Type_Codec eet_group_codec[] =
|
|||
{ eet_data_get_array, eet_data_put_array },
|
||||
{ eet_data_get_array, eet_data_put_array },
|
||||
{ eet_data_get_list, eet_data_put_list },
|
||||
{ eet_data_get_hash, eet_data_put_hash }
|
||||
{ eet_data_get_hash, eet_data_put_hash },
|
||||
{ eet_data_get_union, eet_data_put_union },
|
||||
{ eet_data_get_inherit, eet_data_put_inherit },
|
||||
{ eet_data_get_variant, eet_data_put_variant }
|
||||
};
|
||||
|
||||
static int _eet_data_words_bigendian = -1;
|
||||
|
@ -325,6 +347,7 @@ static int _eet_data_words_bigendian = -1;
|
|||
#define EET_I_INLINED_STRING 2 << 4
|
||||
#define EET_I_NULL 3 << 4
|
||||
|
||||
#define EET_MAGIC_VARIANT 0xF1234BC
|
||||
/*---*/
|
||||
|
||||
/* CHAR TYPE */
|
||||
|
@ -1305,7 +1328,6 @@ _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
|
|||
Eet_Data_Descriptor *edd;
|
||||
|
||||
if (!eddc) return NULL;
|
||||
if (eddc->version < version) return NULL;
|
||||
|
||||
edd = calloc(1, sizeof (Eet_Data_Descriptor));
|
||||
if (!edd) return NULL;
|
||||
|
@ -1333,11 +1355,16 @@ _eet_data_descriptor_new(const Eet_Data_Descriptor_Class *eddc, int version)
|
|||
edd->func.hash_add = eddc->func.hash_add;
|
||||
edd->func.hash_free = eddc->func.hash_free;
|
||||
|
||||
if (version > 1)
|
||||
if (eddc->version > 1 && version > 1)
|
||||
{
|
||||
edd->func.str_direct_alloc = eddc->func.str_direct_alloc;
|
||||
edd->func.str_direct_free = eddc->func.str_direct_free;
|
||||
}
|
||||
if (eddc->version > 2)
|
||||
{
|
||||
edd->func.type_get = eddc->func.type_get;
|
||||
edd->func.type_set = eddc->func.type_set;
|
||||
}
|
||||
|
||||
return edd;
|
||||
}
|
||||
|
@ -1421,6 +1448,43 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
|
|||
Eet_Data_Element *ede;
|
||||
Eet_Data_Element *tmp;
|
||||
|
||||
/* UNION, INHERITED or VARIANT type would not work with simple type, we need a way to map the type. */
|
||||
if ((group_type == EET_G_INHERIT
|
||||
|| group_type == EET_G_UNION
|
||||
|| group_type == EET_G_VARIANT)
|
||||
&&
|
||||
(type != EET_T_UNKNOW
|
||||
|| subtype == NULL
|
||||
|| subtype->func.type_get == NULL
|
||||
|| subtype->func.type_set == NULL))
|
||||
return ;
|
||||
|
||||
/* Only one element is allowed with INHERITED type */
|
||||
if (group_type == EET_G_INHERIT && edd->elements.num != 0)
|
||||
return ;
|
||||
if (edd->elements.num > 0 && edd->elements.set[0].group_type == EET_G_INHERIT)
|
||||
return ;
|
||||
|
||||
/* VARIANT type will only work if the map only contains EET_G_*, but not INHERIT, UNION, VARIANT and ARRAY. */
|
||||
if (group_type == EET_G_VARIANT)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < subtype->elements.num; ++i)
|
||||
if (subtype->elements.set[i].type != EET_T_UNKNOW
|
||||
&& subtype->elements.set[i].group_type > EET_G_VAR_ARRAY
|
||||
&& subtype->elements.set[i].group_type < EET_G_UNION)
|
||||
return ;
|
||||
|
||||
subtype->unified_type = EINA_TRUE;
|
||||
}
|
||||
if (subtype
|
||||
&& subtype->unified_type
|
||||
&& (type != EET_T_UNKNOW
|
||||
|| group_type < EET_G_UNION))
|
||||
return ;
|
||||
|
||||
/* Sanity check done, let allocate ! */
|
||||
edd->elements.num++;
|
||||
tmp = realloc(edd->elements.set, edd->elements.num * sizeof(Eet_Data_Element));
|
||||
if (!tmp) return ;
|
||||
|
@ -1455,7 +1519,7 @@ eet_data_descriptor_element_add(Eet_Data_Descriptor *edd,
|
|||
ede->group_type = group_type;
|
||||
ede->offset = offset;
|
||||
ede->count = count;
|
||||
/* FIXME: For the time being, EET_G_VAR_ARRAY will put the counter_offset in count. */
|
||||
/* FIXME: For the time being, VAR_ARRAY, INHERIT, UNION and VARIANT will put the counter_offset in count. */
|
||||
ede->counter_offset = count;
|
||||
/* ede->counter_offset = counter_offset; */
|
||||
ede->counter_name = counter_name;
|
||||
|
@ -2440,12 +2504,14 @@ _eet_data_descriptor_decode(Eet_Free_Context *context,
|
|||
break;
|
||||
case EET_G_VAR_ARRAY:
|
||||
return eet_node_var_array_new(chnk.name, NULL);
|
||||
case EET_G_INHERIT:
|
||||
/* This one should work */
|
||||
goto error;
|
||||
case EET_G_LIST:
|
||||
goto error;
|
||||
case EET_G_HASH:
|
||||
goto error;
|
||||
case EET_G_ARRAY:
|
||||
goto error;
|
||||
case EET_G_UNION:
|
||||
case EET_G_VARIANT:
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
@ -2818,6 +2884,379 @@ eet_data_get_array(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
eet_data_put_union(Eet_Dictionary *ed,
|
||||
__UNUSED__ Eet_Data_Descriptor *edd,
|
||||
Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
|
||||
{
|
||||
const char *union_type;
|
||||
int i;
|
||||
|
||||
EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
|
||||
|
||||
union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
|
||||
NULL);
|
||||
|
||||
if (!union_type) return ;
|
||||
|
||||
/* Search the structure of the union to encode. */
|
||||
for (i = 0; i < ede->subtype->elements.num; ++i)
|
||||
if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
|
||||
{
|
||||
Eet_Data_Element *sede;
|
||||
void *data;
|
||||
int size;
|
||||
|
||||
/* Yeah we found it ! */
|
||||
data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
|
||||
if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
|
||||
|
||||
sede = &(ede->subtype->elements.set[i]);
|
||||
data = _eet_data_descriptor_encode(ed,
|
||||
sede->subtype,
|
||||
data_in,
|
||||
&size);
|
||||
if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_union(Eet_Free_Context *context, const Eet_Dictionary *ed,
|
||||
__UNUSED__ Eet_Data_Descriptor *edd,
|
||||
Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
|
||||
int type, int group_type, void *data,
|
||||
char **p, int *size)
|
||||
{
|
||||
const char *union_type;
|
||||
void *data_ret = NULL;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Read type */
|
||||
ret = eet_data_get_type(ed,
|
||||
EET_T_STRING,
|
||||
echnk->data,
|
||||
((char *)echnk->data) + echnk->size,
|
||||
&union_type);
|
||||
if (ret <= 0) goto on_error;
|
||||
|
||||
/* Advance to next chunk */
|
||||
NEXT_CHUNK((*p), (*size), (*echnk), ed);
|
||||
memset(echnk, 0, sizeof(Eet_Data_Chunk));
|
||||
|
||||
/* Read value */
|
||||
eet_data_chunk_get(ed, echnk, *p, *size);
|
||||
if (!echnk->name) goto on_error;
|
||||
|
||||
if (ede)
|
||||
{
|
||||
EET_ASSERT(!(ede->group_type != group_type || ede->type != type), goto on_error);
|
||||
|
||||
/* Search the structure of the union to decode */
|
||||
for (i = 0; i < ede->subtype->elements.num; ++i)
|
||||
if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
|
||||
{
|
||||
Eet_Data_Element *sede;
|
||||
|
||||
/* Yeah we found it ! */
|
||||
sede = &(ede->subtype->elements.set[i]);
|
||||
EET_ASSERT(sede->subtype, goto on_error);
|
||||
|
||||
data_ret = _eet_data_descriptor_decode(context,
|
||||
ed,
|
||||
sede->subtype,
|
||||
echnk->data,
|
||||
echnk->size);
|
||||
if (!data_ret) goto on_error;
|
||||
|
||||
/* Memcopy the structure content to remove pointer indirection. */
|
||||
memcpy(data, data_ret, sede->subtype->size);
|
||||
|
||||
/* data_ret is now useless. */
|
||||
sede->subtype->func.mem_free(data_ret);
|
||||
|
||||
/* Set union type. */
|
||||
if ((!ed) || (!ede->subtype->func.str_direct_alloc))
|
||||
{
|
||||
union_type = ede->subtype->func.str_alloc(union_type);
|
||||
_eet_freelist_str_add(context, (char*) union_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
union_type = ede->subtype->func.str_direct_alloc(union_type);
|
||||
_eet_freelist_direct_str_add(context, (char*) union_type);
|
||||
}
|
||||
|
||||
ede->subtype->func.type_set(union_type,
|
||||
((char*) data) + ede->count - ede->offset,
|
||||
EINA_FALSE);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: generate node structure. */
|
||||
data_ret = _eet_data_descriptor_decode(context,
|
||||
ed, NULL,
|
||||
echnk->data, echnk->size);
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
on_error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
eet_data_put_inherit(Eet_Dictionary *ed, Eet_Data_Descriptor *edd, Eet_Data_Element *ede,
|
||||
Eet_Data_Stream *ds, void *data_in)
|
||||
{
|
||||
/* FIXME */
|
||||
fprintf(stderr, "wrong !!!\n");
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_inherit(Eet_Free_Context *context, const Eet_Dictionary *ed, Eet_Data_Descriptor *edd,
|
||||
Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
|
||||
int type, int group_type, void *data,
|
||||
char **p, int *size)
|
||||
{
|
||||
/* FIXME */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
eet_data_put_variant(Eet_Dictionary *ed,
|
||||
__UNUSED__ Eet_Data_Descriptor *edd,
|
||||
Eet_Data_Element *ede, Eet_Data_Stream *ds, void *data_in)
|
||||
{
|
||||
const char *union_type;
|
||||
void *data;
|
||||
Eina_Bool unknow = EINA_FALSE;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
EET_ASSERT(!((ede->type != EET_T_UNKNOW) || (!ede->subtype)), return );
|
||||
|
||||
union_type = ede->subtype->func.type_get(((char*) data_in) + ede->count - ede->offset,
|
||||
&unknow);
|
||||
|
||||
if (!union_type && unknow == EINA_FALSE) return ;
|
||||
|
||||
if (unknow)
|
||||
{
|
||||
/* Handle opaque internal representation */
|
||||
Eet_Variant_Unknow *evu;
|
||||
|
||||
data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
|
||||
if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
|
||||
|
||||
evu = (Eet_Variant_Unknow*) data_in;
|
||||
if (evu && EINA_MAGIC_CHECK(evu, EET_MAGIC_VARIANT))
|
||||
eet_data_encode(ed, ds, evu->data, ede->name, evu->size, ede->type, ede->group_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Search the structure of the union to encode. */
|
||||
for (i = 0; i < ede->subtype->elements.num; ++i)
|
||||
if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
|
||||
{
|
||||
Eet_Data_Element *sede;
|
||||
|
||||
/* Yeah we found it ! */
|
||||
data = eet_data_put_type(ed, EET_T_STRING, &union_type, &size);
|
||||
if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
|
||||
|
||||
sede = &(ede->subtype->elements.set[i]);
|
||||
|
||||
if (sede->group_type != EET_G_UNKNOWN)
|
||||
{
|
||||
Eet_Data_Stream *lds;
|
||||
|
||||
lds = eet_data_stream_new();
|
||||
eet_group_codec[sede->group_type - 100].put(ed,
|
||||
sede->subtype,
|
||||
sede,
|
||||
lds,
|
||||
data_in);
|
||||
if (lds->size != 0)
|
||||
{
|
||||
eet_data_encode(ed, ds, lds->data, ede->name, lds->pos,
|
||||
ede->type, ede->group_type);
|
||||
|
||||
lds->data = NULL;
|
||||
lds->size = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
eet_data_encode(ed, ds, NULL, ede->name, 0,
|
||||
EET_T_NULL, ede->group_type);
|
||||
}
|
||||
|
||||
eet_data_stream_free(lds);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = _eet_data_descriptor_encode(ed,
|
||||
sede->subtype,
|
||||
*(void**)data_in,
|
||||
&size);
|
||||
if (data) eet_data_encode(ed, ds, data, ede->name, size, ede->type, ede->group_type);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
eet_data_get_variant(Eet_Free_Context *context, const Eet_Dictionary *ed,
|
||||
__UNUSED__ Eet_Data_Descriptor *edd,
|
||||
Eet_Data_Element *ede, Eet_Data_Chunk *echnk,
|
||||
int type, int group_type, void *data,
|
||||
char **p, int *size)
|
||||
{
|
||||
const char *union_type;
|
||||
void *data_ret = NULL;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
/* Read type */
|
||||
ret = eet_data_get_type(ed,
|
||||
EET_T_STRING,
|
||||
echnk->data,
|
||||
((char *)echnk->data) + echnk->size,
|
||||
&union_type);
|
||||
if (ret <= 0) goto on_error;
|
||||
|
||||
/* Advance to next chunk */
|
||||
NEXT_CHUNK((*p), (*size), (*echnk), ed);
|
||||
memset(echnk, 0, sizeof(Eet_Data_Chunk));
|
||||
|
||||
/* Read value */
|
||||
eet_data_chunk_get(ed, echnk, *p, *size);
|
||||
if (!echnk->name) goto on_error;
|
||||
|
||||
if (ede)
|
||||
{
|
||||
EET_ASSERT(ede->subtype, goto on_error);
|
||||
|
||||
if ((!ed) || (!ede->subtype->func.str_direct_alloc))
|
||||
{
|
||||
union_type = ede->subtype->func.str_alloc(union_type);
|
||||
_eet_freelist_str_add(context, (char*) union_type);
|
||||
}
|
||||
else
|
||||
{
|
||||
union_type = ede->subtype->func.str_direct_alloc(union_type);
|
||||
_eet_freelist_direct_str_add(context, (char*) union_type);
|
||||
}
|
||||
|
||||
/* Search the structure of the union to decode */
|
||||
for (i = 0; i < ede->subtype->elements.num; ++i)
|
||||
if (strcmp(ede->subtype->elements.set[i].name, union_type) == 0)
|
||||
{
|
||||
Eet_Data_Element *sede;
|
||||
|
||||
/* Yeah we found it ! */
|
||||
sede = &(ede->subtype->elements.set[i]);
|
||||
|
||||
if (sede->group_type != EET_G_UNKNOWN)
|
||||
{
|
||||
Eet_Data_Chunk chnk;
|
||||
char *p2;
|
||||
int size2;
|
||||
int ret;
|
||||
|
||||
p2 = echnk->data;
|
||||
size2 = echnk->size;
|
||||
|
||||
/* Didn't find a proper way to provide this
|
||||
without duplicating code */
|
||||
while (size2 > 0)
|
||||
{
|
||||
memset(&chnk, 0, sizeof(Eet_Data_Chunk));
|
||||
eet_data_chunk_get(ed, &chnk, p2, size2);
|
||||
|
||||
if (!chnk.name) goto on_error;
|
||||
|
||||
ret = eet_group_codec[sede->group_type - 100].get(context,
|
||||
ed, sede->subtype,
|
||||
sede, &chnk,
|
||||
sede->type, sede->group_type,
|
||||
data, &p2, &size2);
|
||||
|
||||
if (ret <= 0) goto on_error;
|
||||
|
||||
/* advance to next chunk */
|
||||
NEXT_CHUNK(p2, size2, chnk, ed);
|
||||
}
|
||||
|
||||
/* Put garbage so that we will not put eet_variant_unknow in it */
|
||||
data_ret = (void*) data;
|
||||
|
||||
/* Set variant type. */
|
||||
ede->subtype->func.type_set(union_type,
|
||||
((char*) data) + ede->count - ede->offset,
|
||||
EINA_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
data_ret = _eet_data_descriptor_decode(context,
|
||||
ed,
|
||||
sede->subtype,
|
||||
echnk->data,
|
||||
echnk->size);
|
||||
if (!data_ret) break;
|
||||
|
||||
/* And point to the variant data. */
|
||||
*(void**) data = data_ret;
|
||||
|
||||
/* Set variant type. */
|
||||
ede->subtype->func.type_set(union_type,
|
||||
((char*) data) + ede->count - ede->offset,
|
||||
EINA_FALSE);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!data_ret)
|
||||
{
|
||||
Eet_Variant_Unknow *evu;
|
||||
|
||||
evu = calloc(1, sizeof (Eet_Variant_Unknow) + echnk->size - 1);
|
||||
if (!evu) goto on_error;
|
||||
|
||||
evu->size = echnk->size;
|
||||
memcpy(evu->data, echnk->data, evu->size);
|
||||
EINA_MAGIC_SET(evu, EET_MAGIC_VARIANT);
|
||||
|
||||
/* And point to the opaque internal data scructure */
|
||||
*(void**) data = evu;
|
||||
|
||||
/* Set variant type. */
|
||||
ede->subtype->func.type_set(union_type,
|
||||
((char*) data) + ede->count - ede->offset,
|
||||
EINA_TRUE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* FIXME: dump node structure. */
|
||||
data_ret = _eet_data_descriptor_decode(context,
|
||||
ed, NULL,
|
||||
echnk->data, echnk->size);
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
on_error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Eet_Node *
|
||||
eet_data_node_simple_type(int type, const char *name, void *dd)
|
||||
{
|
||||
|
|
|
@ -325,7 +325,7 @@ eet_dictionary_string_get_fp(const Eet_Dictionary *ed, int idx, Eina_F32p32 *res
|
|||
|
||||
str = ed->all[idx].str ? ed->all[idx].str : ed->all[idx].mmap;
|
||||
|
||||
if (!eina_convert_atofp(str, ed->all[idx].len, &fp))
|
||||
if (!eina_convert_atofp(str, ed->all[idx].len, &fp))
|
||||
return EINA_FALSE;
|
||||
|
||||
ed->all[idx].fp = fp;
|
||||
|
|
|
@ -1756,6 +1756,430 @@ START_TEST(eet_file_fp)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
typedef struct _Eet_Union_Test Eet_Union_Test;
|
||||
typedef struct _Eet_Variant_Test Eet_Variant_Test;
|
||||
typedef struct _Eet_Variant_Type Eet_Variant_Type;
|
||||
typedef struct _Eet_Inherit_Test1 Eet_Inherit_Test1;
|
||||
typedef struct _Eet_Inherit_Test2 Eet_Inherit_Test2;
|
||||
typedef struct _Eet_Inherit_Test3 Eet_Inherit_Test3;
|
||||
typedef struct _Eet_St1 Eet_St1;
|
||||
typedef struct _Eet_St2 Eet_St2;
|
||||
typedef struct _Eet_St3 Eet_St3;
|
||||
typedef struct _Eet_List Eet_List;
|
||||
|
||||
typedef enum _Eet_Union
|
||||
{
|
||||
EET_UNKNOWN,
|
||||
EET_ST1,
|
||||
EET_ST2,
|
||||
EET_ST3
|
||||
} Eet_Union;
|
||||
|
||||
struct {
|
||||
Eet_Union u;
|
||||
const char *name;
|
||||
} eet_mapping[] = {
|
||||
{ EET_ST1, "ST1" },
|
||||
{ EET_ST2, "ST2" },
|
||||
{ EET_ST3, "ST3" },
|
||||
{ EET_UNKNOWN, NULL }
|
||||
};
|
||||
|
||||
struct _Eet_St1
|
||||
{
|
||||
double val1;
|
||||
int stuff;
|
||||
char *s1;
|
||||
};
|
||||
|
||||
struct _Eet_St2
|
||||
{
|
||||
Eina_Bool b1;
|
||||
unsigned long long v1;
|
||||
};
|
||||
|
||||
struct _Eet_St3
|
||||
{
|
||||
int boby;
|
||||
};
|
||||
|
||||
struct _Eet_Union_Test
|
||||
{
|
||||
Eet_Union type;
|
||||
|
||||
union {
|
||||
Eet_St1 st1;
|
||||
Eet_St2 st2;
|
||||
Eet_St3 st3;
|
||||
} u;
|
||||
};
|
||||
|
||||
struct _Eet_Variant_Type
|
||||
{
|
||||
const char *type;
|
||||
Eina_Bool unknow : 1;
|
||||
};
|
||||
|
||||
struct _Eet_Variant_Test
|
||||
{
|
||||
Eet_Variant_Type t;
|
||||
|
||||
void *data;
|
||||
Eina_List *data_list;
|
||||
};
|
||||
|
||||
struct _Eet_Inherit_Test1
|
||||
{
|
||||
Eet_Union type;
|
||||
Eet_St1 st1;
|
||||
};
|
||||
struct _Eet_Inherit_Test2
|
||||
{
|
||||
Eet_Union type;
|
||||
Eet_St2 st2;
|
||||
};
|
||||
struct _Eet_Inherit_Test3
|
||||
{
|
||||
Eet_Union type;
|
||||
Eet_St3 st3;
|
||||
};
|
||||
|
||||
struct _Eet_List
|
||||
{
|
||||
Eina_List *list;
|
||||
};
|
||||
|
||||
static const char *
|
||||
_eet_union_type_get(const void *data, Eina_Bool *unknow)
|
||||
{
|
||||
const Eet_Union *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;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eet_union_type_set(const char *type, void *data, Eina_Bool unknow)
|
||||
{
|
||||
Eet_Union *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;
|
||||
}
|
||||
|
||||
static const char *
|
||||
_eet_variant_type_get(const void *data, Eina_Bool *unknow)
|
||||
{
|
||||
const Eet_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;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_eet_variant_type_set(const char *type, void *data, Eina_Bool unknow)
|
||||
{
|
||||
Eet_Variant_Type *vt = data;
|
||||
|
||||
vt->type = type;
|
||||
vt->unknow = unknow;
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
static Eet_Data_Descriptor*
|
||||
_eet_st1_dd(void)
|
||||
{
|
||||
Eet_Data_Descriptor_Class eddc;
|
||||
Eet_Data_Descriptor *res;
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_St1);
|
||||
res = eet_data_descriptor_stream_new(&eddc);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St1, "val1", val1, EET_T_DOUBLE);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St1, "stuff", stuff, EET_T_INT);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St1, "s1", s1, EET_T_STRING);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st1_set(Eet_St1 *st1, int i)
|
||||
{
|
||||
st1->val1 = EET_TEST_DOUBLE;
|
||||
st1->stuff = EET_TEST_INT + i;
|
||||
st1->s1 = EET_TEST_STRING;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st1_cmp(Eet_St1 *st1, int i)
|
||||
{
|
||||
double tmp;
|
||||
|
||||
fail_if(!st1);
|
||||
|
||||
tmp = st1->val1 - EET_TEST_DOUBLE;
|
||||
if (tmp < 0) tmp = -tmp;
|
||||
fail_if(tmp > 0.005);
|
||||
fail_if(st1->stuff != EET_TEST_INT + i);
|
||||
fail_if(strcmp(st1->s1, EET_TEST_STRING));
|
||||
}
|
||||
|
||||
static Eet_Data_Descriptor*
|
||||
_eet_st2_dd(void)
|
||||
{
|
||||
Eet_Data_Descriptor_Class eddc;
|
||||
Eet_Data_Descriptor *res;
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_St2);
|
||||
res = eet_data_descriptor_stream_new(&eddc);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St2, "b1", b1, EET_T_UCHAR);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St2, "v1", v1, EET_T_ULONG_LONG);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st2_set(Eet_St2 *st2, int i)
|
||||
{
|
||||
st2->b1 = EINA_TRUE;
|
||||
st2->v1 = EET_TEST_LONG_LONG + i;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st2_cmp(Eet_St2 *st2, int i)
|
||||
{
|
||||
fail_if(!st2->b1);
|
||||
fail_if(st2->v1 != EET_TEST_LONG_LONG + i);
|
||||
}
|
||||
|
||||
static Eet_Data_Descriptor*
|
||||
_eet_st3_dd(void)
|
||||
{
|
||||
Eet_Data_Descriptor_Class eddc;
|
||||
Eet_Data_Descriptor *res;
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_St3);
|
||||
res = eet_data_descriptor_stream_new(&eddc);
|
||||
EET_DATA_DESCRIPTOR_ADD_BASIC(res, Eet_St3, "boby", boby, EET_T_INT);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st3_set(Eet_St3 *st3, int i)
|
||||
{
|
||||
st3->boby = EET_TEST_INT + i;
|
||||
}
|
||||
|
||||
static void
|
||||
_eet_st3_cmp(Eet_St3 *st3, int i)
|
||||
{
|
||||
fail_if(st3->boby != EET_TEST_INT + i);
|
||||
}
|
||||
|
||||
START_TEST(eet_test_union)
|
||||
{
|
||||
Eet_Union_Test *eut;
|
||||
Eet_List *l;
|
||||
Eet_Data_Descriptor_Class eddc;
|
||||
Eet_Data_Descriptor *edd;
|
||||
Eet_Data_Descriptor *unified;
|
||||
Eet_Data_Descriptor *m;
|
||||
void *blob;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
eina_init();
|
||||
eet_init();
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_Union_Test);
|
||||
edd = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_Union_Test);
|
||||
m = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
|
||||
eddc.func.type_get = _eet_union_type_get;
|
||||
eddc.func.type_set = _eet_union_type_set;
|
||||
unified = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST1", _eet_st1_dd());
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST2", _eet_st2_dd());
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST3", _eet_st3_dd());
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_UNION(edd, Eet_Union_Test, "u", u, type, unified);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_LIST(m, Eet_List, "list", list, edd);
|
||||
|
||||
l = calloc(1, sizeof (Eet_List));
|
||||
|
||||
#define EUT_NEW(Type_Index) \
|
||||
eut = calloc(1, sizeof (Eet_Union_Test)); \
|
||||
eut->type = EET_ST##Type_Index; \
|
||||
_eet_st##Type_Index##_set(&(eut->u.st##Type_Index), i);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
EUT_NEW(1);
|
||||
l->list = eina_list_append(l->list, eut);
|
||||
|
||||
EUT_NEW(2);
|
||||
l->list = eina_list_append(l->list, eut);
|
||||
|
||||
EUT_NEW(3);
|
||||
l->list = eina_list_append(l->list, eut);
|
||||
}
|
||||
|
||||
blob = eet_data_descriptor_encode(m, l, &size);
|
||||
fail_if(!blob || size <= 0);
|
||||
|
||||
l = eet_data_descriptor_decode(m, blob, size);
|
||||
fail_if(!l);
|
||||
|
||||
fail_if(eina_list_count(l->list) != 9);
|
||||
|
||||
#define EUT_CMP(Type_Index) \
|
||||
eut = eina_list_nth(l->list, i * 3 + Type_Index - 1); \
|
||||
fail_if(eut->type != EET_ST##Type_Index); \
|
||||
_eet_st##Type_Index##_cmp(&(eut->u.st##Type_Index), i);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
EUT_CMP(1);
|
||||
EUT_CMP(2);
|
||||
EUT_CMP(3);
|
||||
}
|
||||
|
||||
eet_shutdown();
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eet_test_variant)
|
||||
{
|
||||
Eet_Variant_Test *evt;
|
||||
Eet_List *l;
|
||||
Eet_St1 *st1;
|
||||
Eet_St2 *st2;
|
||||
Eet_St3 *st3;
|
||||
Eet_Data_Descriptor_Class eddc;
|
||||
Eet_Data_Descriptor *edd;
|
||||
Eet_Data_Descriptor *unified;
|
||||
Eet_Data_Descriptor *m;
|
||||
void *blob;
|
||||
int size;
|
||||
int i;
|
||||
|
||||
eina_init();
|
||||
eet_init();
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_Variant_Test);
|
||||
edd = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
EET_EINA_STREAM_DATA_DESCRIPTOR_CLASS_SET(&eddc, Eet_Variant_Test);
|
||||
m = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
|
||||
eddc.func.type_get = _eet_variant_type_get;
|
||||
eddc.func.type_set = _eet_variant_type_set;
|
||||
unified = eet_data_descriptor_stream_new(&eddc);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST1", _eet_st1_dd());
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST2", _eet_st2_dd());
|
||||
EET_DATA_DESCRIPTOR_ADD_MAPPING(unified, "ST3", _eet_st3_dd());
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, Eet_Variant_Test, "data", data, t, unified);
|
||||
|
||||
unified = eet_data_descriptor_stream_new(&eddc);
|
||||
eet_data_descriptor_element_add(unified, "ST1",
|
||||
EET_T_UNKNOW, EET_G_LIST,
|
||||
0, 0, NULL, _eet_st1_dd());
|
||||
eet_data_descriptor_element_add(unified, "ST2",
|
||||
EET_T_UNKNOW, EET_G_LIST,
|
||||
0, 0, NULL, _eet_st2_dd());
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_VARIANT(edd, Eet_Variant_Test,
|
||||
"data_list", data_list, t, unified);
|
||||
|
||||
EET_DATA_DESCRIPTOR_ADD_LIST(m, Eet_List, "list", list, edd);
|
||||
|
||||
l = calloc(1, sizeof (Eet_List));
|
||||
|
||||
#define EVT_NEW(Type_Index) \
|
||||
evt = calloc(1, sizeof (Eet_Variant_Test)); \
|
||||
evt->t.type = eet_mapping[Type_Index - 1].name; \
|
||||
st##Type_Index = calloc(1, sizeof (Eet_St##Type_Index)); \
|
||||
_eet_st##Type_Index##_set(st##Type_Index, i); \
|
||||
evt->data = st##Type_Index;
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
EVT_NEW(1);
|
||||
l->list = eina_list_append(l->list, evt);
|
||||
|
||||
st1 = calloc(1, sizeof (Eet_St1));
|
||||
_eet_st1_set(st1, i);
|
||||
evt->data_list = eina_list_append(evt->data_list, st1);
|
||||
|
||||
EVT_NEW(2);
|
||||
l->list = eina_list_append(l->list, evt);
|
||||
|
||||
EVT_NEW(3);
|
||||
l->list = eina_list_append(l->list, evt);
|
||||
}
|
||||
|
||||
blob = eet_data_descriptor_encode(m, l, &size);
|
||||
fail_if(!blob || size <= 0);
|
||||
|
||||
l = eet_data_descriptor_decode(m, blob, size);
|
||||
fail_if(!l);
|
||||
|
||||
fail_if(eina_list_count(l->list) != 9);
|
||||
|
||||
#define EVT_CMP(Type_Index) \
|
||||
evt = eina_list_nth(l->list, i * 3 + Type_Index - 1); \
|
||||
fail_if(strcmp(evt->t.type, eet_mapping[Type_Index - 1].name) != 0); \
|
||||
_eet_st##Type_Index##_cmp(evt->data, i);
|
||||
|
||||
for (i = 0; i < 3; ++i)
|
||||
{
|
||||
EVT_CMP(1);
|
||||
|
||||
fail_if(!evt->data_list);
|
||||
fail_if(eina_list_count(evt->data_list) != 1);
|
||||
|
||||
st1 = eina_list_data_get(evt->data_list);
|
||||
_eet_st1_cmp(st1, i);
|
||||
|
||||
EVT_CMP(2);
|
||||
EVT_CMP(3);
|
||||
}
|
||||
|
||||
eet_shutdown();
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
Suite *
|
||||
eet_suite(void)
|
||||
{
|
||||
|
@ -1773,6 +2197,8 @@ eet_suite(void)
|
|||
tcase_add_test(tc, eet_test_data_type_encoding_decoding);
|
||||
tcase_add_test(tc, eet_test_data_type_dump_undump);
|
||||
tcase_add_test(tc, eet_fp);
|
||||
tcase_add_test(tc, eet_test_union);
|
||||
tcase_add_test(tc, eet_test_variant);
|
||||
suite_add_tcase(s, tc);
|
||||
|
||||
tc = tcase_create("Eet File");
|
||||
|
|
Loading…
Reference in New Issue