From aa015979bbdf5f27fb43256898aa4fdb3b2dcfac Mon Sep 17 00:00:00 2001 From: Cedric BAIL Date: Fri, 2 Apr 2010 13:51:00 +0000 Subject: [PATCH] * eet: Add Eet_Connection. This will help people that want to use Eet over any kind of link. SVN revision: 47688 --- legacy/eet/ChangeLog | 5 ++ legacy/eet/src/lib/Eet.h | 111 +++++++++++++++++++++++++++ legacy/eet/src/lib/Makefile.am | 3 +- legacy/eet/src/tests/eet_suite.c | 128 +++++++++++++++++++++++++++++++ 4 files changed, 246 insertions(+), 1 deletion(-) diff --git a/legacy/eet/ChangeLog b/legacy/eet/ChangeLog index 0fa83ed8a3..43f52a8399 100644 --- a/legacy/eet/ChangeLog +++ b/legacy/eet/ChangeLog @@ -341,3 +341,8 @@ 2010-03-15 Adam Simpkins / Cedric BAIL * Fix clearcache race condition. + +2010-04-02 Cedric BAIL + + * Fix eet_data_node_read_cipher return type. + * Add Eet_Connection. diff --git a/legacy/eet/src/lib/Eet.h b/legacy/eet/src/lib/Eet.h index 607d459048..23f1997e82 100644 --- a/legacy/eet/src/lib/Eet.h +++ b/legacy/eet/src/lib/Eet.h @@ -2643,6 +2643,117 @@ extern "C" { EAPI void *eet_node_walk(void *parent, const char *name, Eet_Node *root, Eet_Node_Walk *cb, void *user_data); + /*******/ + + /** + * @defgroup Eet_Connection_Group Helper function to use eet over a network link + * + * Function that reconstruct and prepare packet of @ref Eet_Data_Group to be send. + * + */ + + /** + * @typedef Eet_Connection + * Opaque handle to track paquet for a specific connection. + * + * @ingroup Eet_Connection_Group + */ + typedef struct _Eet_Connection Eet_Connection; + + /** + * @typedef Eet_Read_Cb + * Called back when an @ref Eet_Data_Group has been received completly and could be used. + * + * @ingroup Eet_Connection_Group + */ + typedef Eina_Bool Eet_Read_Cb(const void *eet_data, size_t size, void *user_data); + + /** + * @typedef Eet_Write_Cb + * Called back when a packet containing @ref Eet_Data_Group data is ready to be send. + * + * @ingroup Eet_Connection_Group + */ + typedef Eina_Bool Eet_Write_Cb(const void *data, size_t size, void *user_data); + + /** + * Instanciate a new connection to track. + * @oaram eet_read_cb Function to call when one Eet_Data packet has been fully assemble. + * @param eet_write_cb Function to call when one Eet_Data packet is ready to be send over the wire. + * @param user_data Pointer provided to both functions to be used as a context handler. + * @return NULL on failure, or a valid Eet_Connection handler. + * + * For every connection to track you will need a separate Eet_Connection provider. + * + * @since 1.2.4 + * @ingroup Eet_Connection_Group + */ + Eet_Connection *eet_connection_new(Eet_Read_Cb *eet_read_cb, Eet_Write_Cb *eet_write_cb, const void *user_data); + + /** + * Process a raw packet received over the link + * @oaram conn Connection handler to track. + * @param data Raw data packet. + * @param size The size of that packet. + * @return 0 on complete success, any other value indicate where in the stream it got wrong (It could be before that packet). + * + * Every time you receive a packet related to your connection, you should pass + * it to that function so that it could process and assemble packet has you + * receive it. It will automatically call Eet_Read_Cb when one is fully received. + * + * @since 1.2.4 + * @ingroup Eet_Connection_Group + */ + int eet_connection_received(Eet_Connection *conn, const void *data, size_t size); + + /** + * Convert a complex structure and prepare it to be send. + * @oaram conn Connection handler to track. + * @param edd The data descriptor to use when encoding. + * @param data_in The pointer to the struct to encode into data. + * @param cipher_key The key to use as cipher. + * @return EINA_TRUE if the data where correctly send, EINA_FALSE if they don't. + * + * This function serialize data_in with edd, assemble the packet and call + * Eet_Write_Cb when ready. The data passed Eet_Write_Cb are temporary allocated + * and will vanish just after the return of the callback. + * + * @see eet_data_descriptor_encode_cipher + * + * @since 1.2.4 + * @ingroup Eet_Connection_Group + */ + Eina_Bool eet_connection_send(Eet_Connection *conn, Eet_Data_Descriptor *edd, const void *data_in, const char *cipher_key); + + /** + * Convert a Eet_Node tree and prepare it to be send. + * @oaram conn Connection handler to track. + * @param node The data tree to use when encoding. + * @param cipher_key The key to use as cipher. + * @return EINA_TRUE if the data where correctly send, EINA_FALSE if they don't. + * + * This function serialize node, assemble the packet and call + * Eet_Write_Cb when ready. The data passed Eet_Write_Cb are temporary allocated + * and will vanish just after the return of the callback. + * + * @see eet_data_node_encode_cipher + * + * @since 1.2.4 + * @ingroup Eet_Connection_Group + */ + Eina_Bool eet_connection_node_send(Eet_Connection *conn, Eet_Node *node, const char *cipher_key); + + /** + * Close a connection and lost its track. + * @oaram conn Connection handler to close. + * @param on_going Signal if a partial packet wasn't completed. + * @return the user_data passed to both callback. + * + * @since 1.2.4 + * @ingroup Eet_Connection_Group + */ + void *eet_connection_close(Eet_Connection *conn, Eina_Bool *on_going); + /***************************************************************************/ #ifdef __cplusplus diff --git a/legacy/eet/src/lib/Makefile.am b/legacy/eet/src/lib/Makefile.am index 54835077ea..35bff744ec 100644 --- a/legacy/eet/src/lib/Makefile.am +++ b/legacy/eet/src/lib/Makefile.am @@ -27,7 +27,8 @@ eet_image.c \ eet_cipher.c \ eet_dictionary.c \ eet_node.c \ -eet_utils.c +eet_utils.c \ +eet_connection.c if EET_AMALGAMATION nodist_libeet_la_SOURCES = eet_amalgamation.c diff --git a/legacy/eet/src/tests/eet_suite.c b/legacy/eet/src/tests/eet_suite.c index 8ace0d00cb..1176c4cbd3 100644 --- a/legacy/eet/src/tests/eet_suite.c +++ b/legacy/eet/src/tests/eet_suite.c @@ -1470,6 +1470,130 @@ START_TEST(eet_cache_concurrency) } END_TEST +typedef struct _Eet_Connection_Data Eet_Connection_Data; +struct _Eet_Connection_Data +{ + Eet_Connection *conn; + Eet_Data_Descriptor *edd; + Eina_Bool test; +}; + +static Eina_Bool +_eet_connection_read(const void *eet_data, size_t size, void *user_data) +{ + Eet_Connection_Data *dt = user_data; + Eet_Test_Ex_Type *result; + Eet_Node *node; + int test; + + result = eet_data_descriptor_decode(dt->edd, eet_data, size); + node = eet_data_node_decode_cipher(eet_data, NULL, size); + + /* 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(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); + fail_if(strcmp(eina_list_data_get(result->slist), "test") != 0); + fail_if(eina_hash_find(result->shash, EET_TEST_KEY1) == NULL); + fail_if(strcmp(eina_hash_find(result->shash, EET_TEST_KEY1), "test") != 0); + fail_if(strcmp(result->charray[0], "test") != 0); + + test = 0; + if (result->hash) eina_hash_foreach(result->hash, func, &test); + fail_if(test != 0); + if (result->ihash) eina_hash_foreach(result->ihash, func7, &test); + fail_if(test != 0); + + if (!dt->test) + { + dt->test = EINA_TRUE; + fail_if(!eet_connection_node_send(dt->conn, node, NULL)); + } + + return EINA_TRUE; +} + +static Eina_Bool +_eet_connection_write(const void *data, size_t size, void *user_data) +{ + Eet_Connection_Data *dt = user_data; + int still; + + if (!dt->test) + { + int step = size / 3; + + eet_connection_received(dt->conn, data, step); + eet_connection_received(dt->conn, (char*) data + step, step); + size -= 2 * step; + still = eet_connection_received(dt->conn, (char*) data + 2 * step, size); + } + else + still = eet_connection_received(dt->conn, data, size); + fail_if(still); + + return EINA_TRUE; +} + +START_TEST(eet_connection_check) +{ + Eet_Connection *conn; + Eet_Data_Descriptor *edd; + Eet_Data_Descriptor_Class eddc; + Eet_Connection_Data ecd; + Eet_Test_Ex_Type etbt; + Eina_Bool on_going; + + eet_init(); + + _eet_test_ex_set(&etbt, 0); + etbt.list = eina_list_prepend(etbt.list, _eet_test_ex_set(NULL, 1)); + etbt.list = eina_list_prepend(etbt.list, _eet_test_ex_set(NULL, 1)); + etbt.hash = eina_hash_string_superfast_new(NULL); + eina_hash_add(etbt.hash, EET_TEST_KEY1, _eet_test_ex_set(NULL, 2)); + eina_hash_add(etbt.hash, EET_TEST_KEY2, _eet_test_ex_set(NULL, 2)); + etbt.ilist = eina_list_prepend(etbt.ilist, &i42); + etbt.ilist = eina_list_prepend(etbt.ilist, &i42); + etbt.ihash = eina_hash_string_superfast_new(NULL); + eina_hash_add(etbt.ihash, EET_TEST_KEY1, &i7); + eina_hash_add(etbt.ihash, EET_TEST_KEY2, &i7); + etbt.slist = eina_list_prepend(NULL, "test"); + etbt.shash = eina_hash_string_superfast_new(NULL); + eina_hash_add(etbt.shash, EET_TEST_KEY1, "test"); + memset(&etbt.charray, 0, sizeof(etbt.charray)); + etbt.charray[0] = "test"; + + eet_eina_file_data_descriptor_class_set(&eddc, "Eet_Test_Ex_Type", sizeof(Eet_Test_Ex_Type)); + + edd = eet_data_descriptor_file_new(&eddc); + fail_if(!edd); + + _eet_build_ex_descriptor(edd); + + /* Create a connection. */ + conn = eet_connection_new(_eet_connection_read, _eet_connection_write, &ecd); + fail_if(!conn); + + /* Init context. */ + ecd.test = EINA_FALSE; + ecd.conn = conn; + ecd.edd = edd; + + /* Test the connection. */ + fail_if(!eet_connection_send(conn, edd, &etbt, NULL)); + + fail_if(!ecd.test); + + fail_if(!eet_connection_close(conn, &on_going)); + + fail_if(on_going); + + eet_shutdown(); +} +END_TEST Suite * eet_suite(void) @@ -1519,6 +1643,10 @@ eet_suite(void) tcase_add_test(tc, eet_cache_concurrency); suite_add_tcase(s, tc); + tc = tcase_create("Eet Connection"); + tcase_add_test(tc, eet_connection_check); + suite_add_tcase(s, tc); + return s; }