summaryrefslogtreecommitdiff
path: root/legacy/eet/src/lib/eet_connection.c
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2010-04-02 14:30:06 +0000
committerCedric BAIL <cedric.bail@free.fr>2010-04-02 14:30:06 +0000
commitc20cd7715ab176366b3b7b92eeb2584080789ad1 (patch)
tree869def75f4e4a9d1c4a454414598aebf0394b059 /legacy/eet/src/lib/eet_connection.c
parentaa015979bbdf5f27fb43256898aa4fdb3b2dcfac (diff)
* eet: oops, forgot to add the file.
SVN revision: 47690
Diffstat (limited to 'legacy/eet/src/lib/eet_connection.c')
-rw-r--r--legacy/eet/src/lib/eet_connection.c229
1 files changed, 229 insertions, 0 deletions
diff --git a/legacy/eet/src/lib/eet_connection.c b/legacy/eet/src/lib/eet_connection.c
new file mode 100644
index 0000000000..ed90d75bcb
--- /dev/null
+++ b/legacy/eet/src/lib/eet_connection.c
@@ -0,0 +1,229 @@
1/*
2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3 */
4
5#ifdef HAVE_CONFIG_H
6# include <config.h>
7#endif
8
9#if HAVE___ATTRIBUTE__
10# define __UNUSED__ __attribute__((unused))
11#else
12# define __UNUSED__
13#endif
14
15#include <string.h>
16#include <stdlib.h>
17
18#ifdef HAVE_NETINET_IN_H
19# include <netinet/in.h>
20#endif
21
22#if defined(_WIN32) && ! defined(__CEGCC__)
23# include <winsock2.h>
24#endif
25#include <Eina.h>
26
27#include "Eet.h"
28#include "Eet_private.h"
29
30#define MAGIC_EET_DATA_PACKET 0x4270ACE1
31
32typedef struct _Eet_Message Eet_Message;
33struct _Eet_Message {
34 int magic;
35 int size;
36};
37
38struct _Eet_Connection
39{
40 Eet_Read_Cb *eet_read_cb;
41 Eet_Write_Cb *eet_write_cb;
42 void *user_data;
43
44 size_t allocated;
45 size_t size;
46 size_t received;
47
48 void *buffer;
49};
50
51Eet_Connection *
52eet_connection_new(Eet_Read_Cb *eet_read_cb,
53 Eet_Write_Cb *eet_write_cb,
54 const void *user_data)
55{
56 Eet_Connection *conn;
57
58 if (!eet_read_cb || !eet_write_cb)
59 return NULL;
60
61 conn = calloc(1, sizeof (Eet_Connection));
62 if (!conn)
63 return NULL;
64
65 conn->eet_read_cb = eet_read_cb;
66 conn->eet_write_cb = eet_write_cb;
67 conn->user_data = (void*) user_data;
68
69 return conn;
70}
71
72int
73eet_connection_received(Eet_Connection *conn, const void *data, size_t size)
74{
75 if (!conn || !data || !size)
76 return size;
77
78 do {
79 size_t copy_size;
80
81 if (conn->size == 0)
82 {
83 const Eet_Message *msg;
84 size_t packet_size;
85
86 if (size < sizeof (Eet_Message))
87 break;
88
89 msg = data;
90 /* Check the magic */
91 if (ntohl(msg->magic) != MAGIC_EET_DATA_PACKET)
92 break;
93
94 packet_size = ntohl(msg->size);
95 /* Message should always be under 64K */
96 if (packet_size > 64 * 1024)
97 break;
98
99 data = (void*) (msg + 1);
100 size -= sizeof (msg);
101 if ((size_t) packet_size <= size)
102 {
103 /* Not a partial receive, go the quick way. */
104 if (!conn->eet_read_cb(data, packet_size, conn->user_data))
105 break;
106
107 data = (void*) ((char *) data + packet_size);
108 size -= packet_size;
109
110 conn->received = 0;
111 continue;
112 }
113
114 conn->size = packet_size;
115 if (conn->allocated < conn->size)
116 {
117 void *tmp;
118
119 tmp = realloc(conn->buffer, conn->size);
120 if (!tmp)
121 break;
122
123 conn->buffer = tmp;
124 conn->allocated = conn->size;
125 }
126 }
127
128 /* Partial receive */
129 copy_size = (conn->size - conn->received >= size) ? size : conn->size - conn->received;
130 memcpy((char*) conn->buffer + conn->received, data, copy_size);
131
132 conn->received += copy_size;
133 data = (void*)((char *) data + copy_size);
134 size -= copy_size;
135
136 if (conn->received == conn->size)
137 {
138 size_t data_size;
139
140 data_size = conn->size;
141 conn->size = 0;
142 conn->received = 0;
143
144 /* Completed a packet. */
145 if (!conn->eet_read_cb(conn->buffer, data_size, conn->user_data))
146 {
147 /* Something goes wrong. Stop now. */
148 size += data_size;
149 break;
150 }
151 }
152 } while (size > 0);
153
154 return size;
155}
156
157static Eina_Bool
158_eet_connection_raw_send(Eet_Connection *conn, void *data, int data_size)
159{
160 Eet_Message *message;
161
162 /* Message should never be above 64K */
163 if (data_size > 64 * 1024)
164 return EINA_FALSE;
165
166 message = alloca(data_size + sizeof (Eet_Message));
167 message->magic = htonl(MAGIC_EET_DATA_PACKET);
168 message->size = htonl(data_size);
169
170 memcpy(message + 1, data, data_size);
171
172 conn->eet_write_cb(message, data_size + sizeof (Eet_Message), conn->user_data);
173 return EINA_TRUE;
174}
175
176Eina_Bool
177eet_connection_send(Eet_Connection *conn, Eet_Data_Descriptor *edd, const void *data_in, const char *cipher_key)
178{
179 void *flat_data;
180 int data_size;
181 Eina_Bool ret = EINA_FALSE;
182
183 flat_data = eet_data_descriptor_encode_cipher(edd, data_in, cipher_key, &data_size);
184 if (!flat_data)
185 return EINA_FALSE;
186
187 if (_eet_connection_raw_send(conn, flat_data, data_size))
188 ret = EINA_TRUE;
189
190 free(flat_data);
191 return ret;
192}
193
194Eina_Bool
195eet_connection_node_send(Eet_Connection *conn, Eet_Node *node, const char *cipher_key)
196{
197 void *data;
198 int data_size;
199 Eina_Bool ret = EINA_FALSE;
200
201 data = eet_data_node_encode_cipher(node, cipher_key, &data_size);
202 if (!data)
203 return EINA_FALSE;
204
205 if (_eet_connection_raw_send(conn, data, data_size))
206 ret = EINA_TRUE;
207
208 free(data);
209 return ret;
210}
211
212void *
213eet_connection_close(Eet_Connection *conn, Eina_Bool *on_going)
214{
215 void *user_data;
216
217 if (!conn)
218 return NULL;
219
220 if (on_going)
221 *on_going = conn->received == 0 ? EINA_FALSE : EINA_TRUE;
222
223 user_data = conn->user_data;
224
225 free(conn->buffer);
226 free(conn);
227
228 return user_data;
229}