summaryrefslogtreecommitdiff
path: root/src/lib/ecore_con/efl_net_server_simple.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/ecore_con/efl_net_server_simple.c')
-rw-r--r--src/lib/ecore_con/efl_net_server_simple.c243
1 files changed, 243 insertions, 0 deletions
diff --git a/src/lib/ecore_con/efl_net_server_simple.c b/src/lib/ecore_con/efl_net_server_simple.c
new file mode 100644
index 0000000..e42d4fc
--- /dev/null
+++ b/src/lib/ecore_con/efl_net_server_simple.c
@@ -0,0 +1,243 @@
1#define EFL_NET_SERVER_PROTECTED 1
2
3#ifdef HAVE_CONFIG_H
4# include <config.h>
5#endif
6
7#include "Ecore.h"
8#include "Ecore_Con.h"
9#include "ecore_con_private.h"
10
11typedef struct
12{
13 const Efl_Class *inner_class;
14 Eo *inner_server;
15} Efl_Net_Server_Simple_Data;
16
17#define MY_CLASS EFL_NET_SERVER_SIMPLE_CLASS
18
19static void
20_efl_net_server_simple_client_event_closed(void *data, const Efl_Event *event)
21{
22 Eo *server = data;
23 Eo *client = event->object;
24
25 efl_event_callback_del(client, EFL_IO_CLOSER_EVENT_CLOSED, _efl_net_server_simple_client_event_closed, server);
26 if (efl_parent_get(client) == server)
27 efl_parent_set(client, NULL);
28
29 /* do NOT change count as we're using the underlying server's count */
30 //efl_net_server_clients_count_set(server, efl_net_server_clients_count_get(server) - 1);
31}
32
33static Eina_Bool
34_efl_net_server_simple_efl_net_server_client_announce(Eo *o, Efl_Net_Server_Simple_Data *pd EINA_UNUSED, Eo *client)
35{
36 EINA_SAFETY_ON_NULL_RETURN_VAL(client, EINA_FALSE);
37 EINA_SAFETY_ON_FALSE_GOTO(efl_isa(client, EFL_NET_SOCKET_SIMPLE_CLASS), wrong_type);
38 EINA_SAFETY_ON_FALSE_GOTO(efl_parent_get(client) == o, wrong_parent);
39
40 efl_event_callback_call(o, EFL_NET_SERVER_EVENT_CLIENT_ADD, client);
41
42 if (efl_parent_get(client) != o)
43 {
44 DBG("client %s was reparented! Ignoring it...",
45 efl_net_socket_address_remote_get(client));
46 return EINA_TRUE;
47 }
48
49 if (efl_ref_get(client) == 1) /* users must take a reference themselves */
50 {
51 DBG("client %s was not handled, closing it...",
52 efl_net_socket_address_remote_get(client));
53 efl_del(client);
54 return EINA_FALSE;
55 }
56 else if (efl_io_closer_closed_get(client))
57 {
58 DBG("client %s was closed from 'client,add', delete it...",
59 efl_net_socket_address_remote_get(client));
60 efl_del(client);
61 return EINA_FALSE;
62 }
63
64 /* do NOT change count as we're using the underlying server's count */
65 //efl_net_server_clients_count_set(o, efl_net_server_clients_count_get(o) + 1);
66 efl_event_callback_add(client, EFL_IO_CLOSER_EVENT_CLOSED, _efl_net_server_simple_client_event_closed, o);
67 return EINA_TRUE;
68
69 wrong_type:
70 ERR("%p client %p (%s) doesn't implement Efl.Net.Socket.Simple class, deleting it.", o, client, efl_class_name_get(efl_class_get(client)));
71 efl_del(client);
72 return EINA_FALSE;
73
74 wrong_parent:
75 ERR("%p client %p (%s) parent=%p is not our child, deleting it.", o, client, efl_class_name_get(efl_class_get(client)), efl_parent_get(client));
76 efl_del(client);
77 return EINA_FALSE;
78}
79
80static void
81_efl_net_server_simple_inner_server_client_add(void *data, const Efl_Event *event)
82{
83 Eo *o = data;
84 Eo *client_inner = event->info;
85 Eo *client_simple;
86 const char *addr = efl_net_socket_address_remote_get(client_inner);
87
88 client_simple = efl_add(EFL_NET_SOCKET_SIMPLE_CLASS, o,
89 efl_io_buffered_stream_inner_io_set(efl_added, client_inner));
90
91 if (!client_simple)
92 {
93 ERR("simple server %p could not wrap client %p '%s'", o, client_inner, addr);
94 efl_event_callback_call(o, EFL_NET_SERVER_EVENT_CLIENT_REJECTED, (void *)addr);
95 return;
96 }
97
98 efl_net_server_client_announce(o, client_simple);
99}
100
101static void
102_efl_net_server_simple_inner_server_client_rejected(void *data, const Efl_Event *event)
103{
104 Eo *o = data;
105 efl_event_callback_call(o, EFL_NET_SERVER_EVENT_CLIENT_REJECTED, event->info);
106}
107
108static void
109_efl_net_server_simple_inner_server_error(void *data, const Efl_Event *event)
110{
111 Eo *o = data;
112 efl_event_callback_call(o, EFL_NET_SERVER_EVENT_ERROR, event->info);
113}
114
115static void
116_efl_net_server_simple_inner_server_serving(void *data, const Efl_Event *event)
117{
118 Eo *o = data;
119 efl_event_callback_call(o, EFL_NET_SERVER_EVENT_SERVING, event->info);
120}
121
122EFL_CALLBACKS_ARRAY_DEFINE(_efl_net_server_simple_inner_server_cbs,
123 { EFL_NET_SERVER_EVENT_CLIENT_ADD, _efl_net_server_simple_inner_server_client_add },
124 { EFL_NET_SERVER_EVENT_CLIENT_REJECTED, _efl_net_server_simple_inner_server_client_rejected },
125 { EFL_NET_SERVER_EVENT_ERROR, _efl_net_server_simple_inner_server_error },
126 { EFL_NET_SERVER_EVENT_SERVING, _efl_net_server_simple_inner_server_serving });
127
128EOLIAN static Efl_Object *
129_efl_net_server_simple_efl_object_finalize(Eo *o, Efl_Net_Server_Simple_Data *pd)
130{
131 if (pd->inner_server) goto end;
132
133 if (!pd->inner_class)
134 {
135 ERR("no valid server was set with efl_net_server_simple_inner_server_set() and no class set with efl_net_server_simple_inner_class_set()!");
136 return NULL;
137 }
138 else
139 {
140 Eo *server = efl_add(pd->inner_class, o);
141 EINA_SAFETY_ON_NULL_RETURN_VAL(server, NULL);
142
143 if (!efl_isa(server, EFL_NET_SERVER_INTERFACE))
144 {
145 ERR("class %s=%p doesn't implement Efl.Net.Server interface!", efl_class_name_get(pd->inner_class), pd->inner_class);
146 efl_del(server);
147 return NULL;
148 }
149 DBG("created new inner server %p (%s)", server, efl_class_name_get(efl_class_get(server)));
150
151 efl_net_server_simple_inner_server_set(o, server);
152 }
153
154 end:
155 return efl_finalize(efl_super(o, MY_CLASS));
156}
157
158EOLIAN static void
159_efl_net_server_simple_efl_object_destructor(Eo *o, Efl_Net_Server_Simple_Data *pd)
160{
161 if (pd->inner_class) pd->inner_class = NULL;
162
163 if (pd->inner_server)
164 {
165 efl_event_callback_array_del(pd->inner_server, _efl_net_server_simple_inner_server_cbs(), o);
166 if (efl_parent_get(pd->inner_server) == o)
167 efl_parent_set(pd->inner_server, NULL);
168 }
169
170 efl_destructor(efl_super(o, MY_CLASS));
171}
172
173EOLIAN static Eina_Error
174_efl_net_server_simple_efl_net_server_serve(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd, const char *address)
175{
176 return efl_net_server_serve(pd->inner_server, address);
177}
178
179EOLIAN static const char *
180_efl_net_server_simple_efl_net_server_address_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd)
181{
182 return efl_net_server_address_get(pd->inner_server);
183}
184
185EOLIAN static unsigned int
186_efl_net_server_simple_efl_net_server_clients_count_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd)
187{
188 return efl_net_server_clients_count_get(pd->inner_server);
189}
190
191EOLIAN static void
192_efl_net_server_simple_efl_net_server_clients_limit_set(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd, unsigned int limit, Eina_Bool reject_excess)
193{
194 efl_net_server_clients_limit_set(pd->inner_server, limit, reject_excess);
195}
196
197EOLIAN static void
198_efl_net_server_simple_efl_net_server_clients_limit_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd, unsigned int *limit, Eina_Bool *reject_excess)
199{
200 efl_net_server_clients_limit_get(pd->inner_server, limit, reject_excess);
201}
202
203EOLIAN static Eina_Bool
204_efl_net_server_simple_efl_net_server_serving_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd)
205{
206 return efl_net_server_serving_get(pd->inner_server);
207}
208
209EOLIAN static void
210_efl_net_server_simple_inner_class_set(Eo *o, Efl_Net_Server_Simple_Data *pd, const Efl_Class *klass)
211{
212 EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(o));
213 EINA_SAFETY_ON_NULL_RETURN(klass);
214 pd->inner_class = klass;
215 DBG("%p inner_class=%p %s", o, klass, efl_class_name_get(klass));
216}
217
218EOLIAN static const Efl_Class *
219_efl_net_server_simple_inner_class_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd)
220{
221 return pd->inner_class;
222}
223
224EOLIAN static void
225_efl_net_server_simple_inner_server_set(Eo *o, Efl_Net_Server_Simple_Data *pd, Efl_Object *server)
226{
227 EINA_SAFETY_ON_TRUE_RETURN(efl_finalized_get(o));
228 EINA_SAFETY_ON_NULL_RETURN(server);
229 EINA_SAFETY_ON_TRUE_RETURN(pd->inner_server != NULL);
230 EINA_SAFETY_ON_FALSE_RETURN(efl_isa(server, EFL_NET_SERVER_INTERFACE));
231
232 pd->inner_server = efl_ref(server);
233 efl_event_callback_array_add(server, _efl_net_server_simple_inner_server_cbs(), o);
234 DBG("%p inner_server=%p (%s)", o, server, efl_class_name_get(efl_class_get(server)));
235}
236
237EOLIAN static Efl_Object *
238_efl_net_server_simple_inner_server_get(Eo *o EINA_UNUSED, Efl_Net_Server_Simple_Data *pd)
239{
240 return pd->inner_server;
241}
242
243#include "efl_net_server_simple.eo.c"