eet: add support for EET_T_VALUE.
authorCedric Bail <cedric.bail@samsung.com>
Mon, 15 Jul 2013 08:02:53 +0000 (17:02 +0900)
committerCedric Bail <cedric.bail@samsung.com>
Mon, 15 Jul 2013 08:04:34 +0000 (17:04 +0900)
Add the moment, it only support simple type. Need iterator for more
complex type. It also expect a pointer to an Eina_Value and not directly
an Eina_Value, let me know if you prefer the opposite and maybe I
should rename it EET_T_PVALUE.

ChangeLog
NEWS
src/lib/eet/Eet.h
src/lib/eet/eet_data.c
src/tests/eet/eet_suite.c

index 7dce8d30afd188092bea626e4367b0fcfec8db34..d963400da4aa2ac051973f1fc4975e654b6685bd 100644 (file)
--- 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 a19952a65d02e65f9ffcea6a1d8cfeb2e6f6761d..6069904e852c955a80c2f75789e9db03ecb52446 100644 (file)
--- 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
index bb527f5b5afae1bf44fac23edebe48011db842de..935afead9ce376a309dbc540b80682b371a2e84b 100644 (file)
@@ -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 */
index 4e8a82bd0916244d3d59e54a4cb33311b11ca7b8..b8172eac59fe452993f376a9260c985daa02d323 100644 (file)
@@ -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;
index db16719837dc052f9cd5f38a8dbd4ace1e74aa9a..6bc56871804265584a4285d0a3b75764e4f4e01c 100644 (file)
@@ -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;