diff --git a/ChangeLog b/ChangeLog index 7dce8d30af..d963400da4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2013-07-15 Cedric Bail + + * Eet: Add support for EET_T_VALUE to serialize Eina_Value pointer. + 2013-07-11 Chris Michael * Ecore_Evas: Added functions to retieve the pixmap depth, visual, and colormap diff --git a/NEWS b/NEWS index a19952a65d..6069904e85 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,7 @@ Additions: * Eet: - Add eet_mmap() - Add eet_data_descriptor_name_get() + - Add support EET_T_VALUE * Eo: - Add generic efl object infrastructure - Add debugging facility diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h index bb527f5b5a..935afead9c 100644 --- a/src/lib/eet/Eet.h +++ b/src/lib/eet/Eet.h @@ -2381,7 +2381,8 @@ eet_identity_certificate_print(const unsigned char *certificate, #define EET_T_F32P32 14 /**< Data type: fixed point 32.32 */ #define EET_T_F16P16 15 /**< Data type: fixed point 16.16 */ #define EET_T_F8P24 16 /**< Data type: fixed point 8.24 */ -#define EET_T_LAST 17 /**< Last data type */ +#define EET_T_VALUE 17 /**< Data type: pointer to Eina_Value @since 1.8 */ +#define EET_T_LAST 18 /**< Last data type */ #define EET_G_UNKNOWN 100 /**< Unknown group data encoding type */ #define EET_G_ARRAY 101 /**< Fixed size array group type */ diff --git a/src/lib/eet/eet_data.c b/src/lib/eet/eet_data.c index 4e8a82bd09..b8172eac59 100644 --- a/src/lib/eet/eet_data.c +++ b/src/lib/eet/eet_data.c @@ -341,6 +341,17 @@ eet_data_put_null(Eet_Dictionary *ed, const void *src, int *size_ret); +static int +eet_data_get_value(const Eet_Dictionary *ed, + const void *src, + const void *src_end, + void *dst); + +static void * +eet_data_put_value(Eet_Dictionary *ed, + const void *src, + int *size_ret); + static int eet_data_get_type(const Eet_Dictionary *ed, int type, @@ -525,7 +536,8 @@ static const Eet_Data_Basic_Type_Codec eet_basic_codec[] = {sizeof(void *), "NULL", eet_data_get_null, eet_data_put_null }, {sizeof(Eina_F32p32), "f32p32", eet_data_get_f32p32, eet_data_put_f32p32 }, {sizeof(Eina_F16p16), "f16p16", eet_data_get_f16p16, eet_data_put_f16p16 }, - {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 } + {sizeof(Eina_F8p24), "f8p24", eet_data_get_f8p24, eet_data_put_f8p24 }, + {sizeof(Eina_Value*), "eina_value*", eet_data_get_value, eet_data_put_value } }; static const Eet_Data_Group_Type_Codec eet_group_codec[] = @@ -580,7 +592,7 @@ static int _eet_data_words_bigendian = -1; #define CONV64(x) {if (_eet_data_words_bigendian) {SWAP64(x); }} #define IS_SIMPLE_TYPE(Type) (Type > EET_T_UNKNOW && Type < EET_T_LAST) -#define IS_POINTER_TYPE(Type) (Type >= EET_T_STRING && Type <= EET_T_NULL) +#define IS_POINTER_TYPE(Type) ((Type >= EET_T_STRING && Type <= EET_T_NULL) || Type == EET_T_VALUE) #define POINTER_TYPE_DECODE(Context, \ Ed, \ @@ -1232,6 +1244,141 @@ eet_data_put_f8p24(Eet_Dictionary *ed, return eet_data_put_f32p32(ed, &tmp, size_ret); } +static struct { + const Eina_Value_Type **eina_type; + int eet_type; +} eina_value_to_eet_type[] = { + { &EINA_VALUE_TYPE_UCHAR, EET_T_UCHAR }, + { &EINA_VALUE_TYPE_USHORT, EET_T_USHORT }, + { &EINA_VALUE_TYPE_UINT, EET_T_UINT }, +#if SIZEOF_LONG == SIZEOF_INT + { &EINA_VALUE_TYPE_ULONG, EET_T_UINT }, + { &EINA_VALUE_TYPE_TIMESTAMP, EET_T_UINT }, +#else + { &EINA_VALUE_TYPE_ULONG, EET_T_ULONG_LONG }, + { &EINA_VALUE_TYPE_TIMESTAMP, EET_T_ULONG_LONG }, +#endif + { &EINA_VALUE_TYPE_UINT64, EET_T_ULONG_LONG }, + { &EINA_VALUE_TYPE_CHAR, EET_T_CHAR }, + { &EINA_VALUE_TYPE_SHORT, EET_T_SHORT }, + { &EINA_VALUE_TYPE_INT, EET_T_INT }, +#if SIZEOF_LONG == SIZEOF_INT + { &EINA_VALUE_TYPE_LONG, EET_T_INT }, +#else + { &EINA_VALUE_TYPE_LONG, EET_T_LONG_LONG }, +#endif + { &EINA_VALUE_TYPE_INT64, EET_T_LONG_LONG }, + { &EINA_VALUE_TYPE_FLOAT, EET_T_FLOAT }, + { &EINA_VALUE_TYPE_DOUBLE, EET_T_DOUBLE }, + { &EINA_VALUE_TYPE_STRING, EET_T_STRING }, + { &EINA_VALUE_TYPE_STRINGSHARE, EET_T_STRING }, +}; + +static int +eet_data_get_value(const Eet_Dictionary *ed, + const void *src, + const void *src_end, + void *dst) +{ + void *tmp; + int eet_type; + int eet_size, type_size; + unsigned int i; + + eet_size = eet_data_get_int(ed, src, src_end, &eet_type); + if (eet_size < 0 || + eet_type <= EET_T_UNKNOW || + eet_type >= EET_T_VALUE) + return -1; + + tmp = alloca(eet_basic_codec[eet_type - 1].size); + type_size = eet_basic_codec[eet_type - 1].get(ed, (char*) src + eet_size, src_end, tmp); + + if (eet_type == EET_T_NULL) + { + Eina_Value **value = dst; + + *value = NULL; + + return eet_size + type_size; + } + + for (i = 0; i < sizeof (eina_value_to_eet_type) / sizeof (eina_value_to_eet_type[0]); ++i) + if (eet_type == eina_value_to_eet_type[i].eet_type) + { + Eina_Value **value = dst; + + *value = eina_value_new(*eina_value_to_eet_type[i].eina_type); + eina_value_pset(*value, tmp); + + return eet_size + type_size; + } + + return -1; +} + +static void * +eet_data_put_value(Eet_Dictionary *ed, + const void *src, + int *size_ret) +{ + const Eina_Value *value = *(void**)src; + const Eina_Value_Type *value_type; + void *int_data; + void *type_data; + int int_size, type_size; + int eet_type = EET_T_STRING; // always fallback to try a conversion to string if possible + void *tmp; + unsigned int i; + Eina_Bool v2s = EINA_FALSE; + + // map empty Eina_Value to EET_T_NULL; + if (!value) + { + eet_type = EET_T_NULL; + goto lookup_done; + } + + value_type = eina_value_type_get(value); + + for (i = 0; i < sizeof (eina_value_to_eet_type) / sizeof (eina_value_to_eet_type[0]); ++i) + if (value_type == *eina_value_to_eet_type[i].eina_type) + { + eet_type = eina_value_to_eet_type[i].eet_type; + break; + } + + lookup_done: + tmp = alloca(eet_basic_codec[eet_type - 1].size); + if (value) eina_value_get(value, tmp); + else *(void**) tmp = NULL; + + // handle non simple case by forcing them to convert to string + if ((eet_type == EET_T_STRING) && + (*(char**)tmp == NULL)) + { + *(char**)tmp = eina_value_to_string(value); + v2s = EINA_TRUE; + } + + int_data = eet_data_put_int(ed, &eet_type, &int_size); + type_data = eet_basic_codec[eet_type - 1].put(ed, tmp, &type_size); + + // free temporary string as it is not needed anymore + if (v2s) free(*(char**)tmp); + + // pack data with type first, then the data + *size_ret = int_size + type_size; + tmp = malloc(*size_ret); + memcpy(tmp, int_data, int_size); + memcpy(((char*)tmp) + int_size, type_data, type_size); + + free(int_data); + free(type_data); + + return tmp; +} + static inline int eet_data_get_type(const Eet_Dictionary *ed, int type, @@ -2787,6 +2934,7 @@ _eet_data_dump_encode(int parent_type, break; + case EET_T_VALUE: case EET_T_NULL: continue; @@ -2849,6 +2997,7 @@ _eet_data_dump_encode(int parent_type, break; + case EET_T_VALUE: case EET_T_NULL: continue; @@ -2922,6 +3071,7 @@ _eet_data_dump_encode(int parent_type, break; + case EET_T_VALUE: case EET_T_NULL: continue; @@ -2945,6 +3095,7 @@ _eet_data_dump_encode(int parent_type, return cdata; + case EET_T_VALUE: case EET_T_NULL: break; @@ -3369,6 +3520,7 @@ _eet_data_descriptor_decode(Eet_Free_Context *context, case EET_T_INLINED_STRING: return eet_node_inlined_string_new(chnk.name, chnk.data); + case EET_T_VALUE: case EET_T_NULL: return eet_node_null_new(chnk.name); @@ -3422,6 +3574,11 @@ _eet_data_descriptor_decode(Eet_Free_Context *context, eet_data_type_match(echnk.type, ede->type)) /* Needed when converting on the fly from FP to Float */ type = ede->type; + else if (IS_SIMPLE_TYPE(echnk.type) && + echnk.type == EET_T_NULL && + ede->type == EET_T_VALUE) +/* EET_T_NULL can become an EET_T_VALUE as EET_T_VALUE are pointer to */ + type = echnk.type; else if ((echnk.group_type > EET_G_UNKNOWN) && (echnk.group_type < EET_G_LAST) && (echnk.group_type == ede->group_type)) @@ -4281,6 +4438,9 @@ case Eet_Type: \ case EET_T_NULL: return eet_node_null_new(name); + case EET_T_VALUE: + return eet_node_null_new(name); + default: ERR("Unknow type passed to eet_data_node_simple_type"); return NULL; diff --git a/src/tests/eet/eet_suite.c b/src/tests/eet/eet_suite.c index db16719837..6bc5687180 100644 --- a/src/tests/eet/eet_suite.c +++ b/src/tests/eet/eet_suite.c @@ -51,6 +51,7 @@ struct _Eet_Test_Basic_Type unsigned short us; unsigned int ui; unsigned long long ul; + Eina_Value *vp; Eet_Test_Basic_Type *empty; Eet_Test_Basic_Type *with; }; @@ -145,6 +146,8 @@ _eet_test_basic_set(Eet_Test_Basic_Type *res, res->ul = EET_TEST_LONG_LONG; res->empty = NULL; res->with = NULL; + res->vp = eina_value_new(EINA_VALUE_TYPE_INT); + eina_value_set(res->vp, EET_TEST_INT + i); if (i == 0) { @@ -169,13 +172,16 @@ _eet_test_basic_set(Eet_Test_Basic_Type *res, tmp->ul = EET_TEST_LONG_LONG; tmp->empty = NULL; tmp->with = NULL; + tmp->vp = NULL; } } /* _eet_test_basic_set */ static void _eet_test_basic_check(Eet_Test_Basic_Type *result, - int i) + int i, + Eina_Bool dumper) { + int test = -1; float tmp; fail_if(result->c != EET_TEST_CHAR); @@ -188,6 +194,16 @@ _eet_test_basic_check(Eet_Test_Basic_Type *result, fail_if(result->us != EET_TEST_SHORT); fail_if(result->ui != EET_TEST_INT); fail_if(result->ul != EET_TEST_LONG_LONG); + if (!dumper) + { + fail_if(result->vp == NULL); + eina_value_get(result->vp, &test); + fail_if(test != EET_TEST_INT + i); + } + else + { + fail_if(result->vp != NULL); + } tmp = (result->f1 + EET_TEST_FLOAT); if (tmp < 0) @@ -225,6 +241,7 @@ _eet_test_basic_check(Eet_Test_Basic_Type *result, fail_if(tmp2->us != EET_TEST_SHORT); fail_if(tmp2->ui != EET_TEST_INT); fail_if(tmp2->ul != EET_TEST_LONG_LONG); + fail_if(tmp2->vp != NULL); } else fail_if(result->with != NULL); @@ -298,6 +315,11 @@ _eet_build_basic_descriptor(Eet_Data_Descriptor *edd) "ul", ul, EET_T_ULONG_LONG); + EET_DATA_DESCRIPTOR_ADD_BASIC(edd, + Eet_Test_Basic_Type, + "vp", + vp, + EET_T_VALUE); EET_DATA_DESCRIPTOR_ADD_SUB(edd, Eet_Test_Basic_Type, "empty", empty, edd); EET_DATA_DESCRIPTOR_ADD_SUB(edd, Eet_Test_Basic_Type, "with", with, edd); @@ -331,7 +353,7 @@ START_TEST(eet_test_basic_data_type_encoding_decoding) result = eet_data_descriptor_decode(edd, transfert, size); fail_if(!result); - _eet_test_basic_check(result, 0); + _eet_test_basic_check(result, 0, EINA_FALSE); free(result->str); free(result); @@ -598,7 +620,8 @@ _eet_test_ex_set(Eet_Test_Ex_Type *res, static int _eet_test_ex_check(Eet_Test_Ex_Type *stuff, - int offset) + int offset, + Eina_Bool dumper) { double tmp; unsigned int i; @@ -680,13 +703,15 @@ _eet_test_ex_check(Eet_Test_Ex_Type *stuff, for (i = 0; i < 10; ++i) { - _eet_test_basic_check(stuff->sarray1 + i, i); - _eet_test_basic_check(stuff->varray2 + i, i); + _eet_test_basic_check(stuff->sarray1 + i, i, dumper); + _eet_test_basic_check(stuff->varray2 + i, i, dumper); } return 0; } /* _eet_test_ex_check */ +static Eina_Bool _dump_call = EINA_FALSE; + static Eina_Bool func(EINA_UNUSED const Eina_Hash *hash, const void *key, @@ -699,7 +724,7 @@ func(EINA_UNUSED const Eina_Hash *hash, && strcmp(key, EET_TEST_KEY2) != 0) *res = 1; - if (_eet_test_ex_check(data, 2)) + if (_eet_test_ex_check(data, 2, _dump_call)) *res = 1; return EINA_TRUE; @@ -765,8 +790,8 @@ START_TEST(eet_test_data_type_encoding_decoding) result = eet_data_descriptor_decode(edd, transfert, size); fail_if(!result); - fail_if(_eet_test_ex_check(result, 0) != 0); - fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1) != 0); + fail_if(_eet_test_ex_check(result, 0, EINA_FALSE) != 0); + fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1, EINA_FALSE) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); @@ -870,8 +895,8 @@ START_TEST(eet_test_data_type_dump_undump) result = eet_data_descriptor_decode(edd, transfert2, size2); fail_if(!result); - fail_if(_eet_test_ex_check(result, 0) != 0); - fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1) != 0); + fail_if(_eet_test_ex_check(result, 0, EINA_TRUE) != 0); + fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1, EINA_TRUE) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); @@ -881,8 +906,10 @@ START_TEST(eet_test_data_type_dump_undump) fail_if(strcmp(result->charray[0], "test") != 0); test = 0; + _dump_call = EINA_TRUE; if (result->hash) eina_hash_foreach(result->hash, func, &test); + _dump_call = EINA_FALSE; fail_if(test != 0); if (result->ihash) @@ -1039,7 +1066,7 @@ START_TEST(eet_file_data_test) fail_if(!result); /* Test the resulting data. */ - fail_if(_eet_test_ex_check(result, 0) != 0); + fail_if(_eet_test_ex_check(result, 0, EINA_FALSE) != 0); eet_close(ef); @@ -1060,8 +1087,8 @@ START_TEST(eet_file_data_test) fail_if(eet_dictionary_string_check(ed, result->istr)); /* Test the resulting data. */ - fail_if(_eet_test_ex_check(result, 0) != 0); - fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1) != 0); + fail_if(_eet_test_ex_check(result, 0, EINA_FALSE) != 0); + fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1, EINA_FALSE) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); @@ -1186,8 +1213,8 @@ START_TEST(eet_file_data_dump_test) eet_close(ef); /* Test the resulting data. */ - fail_if(_eet_test_ex_check(result, 0) != 0); - fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1) != 0); + fail_if(_eet_test_ex_check(result, 0, EINA_TRUE) != 0); + fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1, EINA_TRUE) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); @@ -1197,8 +1224,10 @@ START_TEST(eet_file_data_dump_test) fail_if(strcmp(result->charray[0], "test") != 0); test = 0; + _dump_call = EINA_TRUE; if (result->hash) eina_hash_foreach(result->hash, func, &test); + _dump_call = EINA_FALSE; fail_if(test != 0); if (result->ihash) @@ -1961,8 +1990,8 @@ _eet_connection_read(const void *eet_data, /* Test the resulting data. */ fail_if(!node); - fail_if(_eet_test_ex_check(result, 0) != 0); - fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1) != 0); + fail_if(_eet_test_ex_check(result, 0, _dump_call) != 0); + fail_if(_eet_test_ex_check(eina_list_data_get(result->list), 1, _dump_call) != 0); fail_if(eina_list_data_get(result->ilist) == NULL); fail_if(*((int *)eina_list_data_get(result->ilist)) != 42); fail_if(eina_list_data_get(result->slist) == NULL); @@ -1984,7 +2013,9 @@ _eet_connection_read(const void *eet_data, if (!dt->test) { dt->test = EINA_TRUE; + _dump_call = EINA_TRUE; fail_if(!eet_connection_node_send(dt->conn, node, NULL)); + _dump_call = EINA_FALSE; } return EINA_TRUE;