1
#define EFL_BETA_API_SUPPORT
3
#include <Ecore_Getopt.h>
5
static Eina_List *waiting = NULL;
6
static Eina_List *commands = NULL;
7
static Eina_Slice line_delimiter;
8
static Eo *send_queue, *receive_queue;
18
efl_io_queue_eos_mark(send_queue);
23
commands = eina_list_remove_list(commands, commands);
25
slice = (Eina_Slice)EINA_SLICE_STR(cmd);
26
efl_io_writer_write(send_queue, &slice, NULL);
27
fprintf(stderr, "INFO: sent '" EINA_SLICE_STR_FMT "'\n",
28
EINA_SLICE_STR_PRINT(slice));
31
slice = line_delimiter;
32
efl_io_writer_write(send_queue, &slice, NULL);
37
_receiver_data(void *data EINA_UNUSED, const Efl_Event *event)
39
Eina_Slice slice = efl_io_queue_slice_get(event->object);
44
if (slice.len == 0) return;
53
if (!eina_slice_endswith(slice, line_delimiter))
55
fprintf(stderr, "WARNING: received without line-delimiter '"
56
EINA_SLICE_STR_FMT "'\n",
57
EINA_SLICE_STR_PRINT(slice));
61
slice.len -= line_delimiter.len;
62
fprintf(stderr, "INFO: received '" EINA_SLICE_STR_FMT "'\n",
63
EINA_SLICE_STR_PRINT(slice));
66
efl_io_queue_clear(event->object);
71
_dialer_connected(void *data EINA_UNUSED, const Efl_Event *event)
73
fprintf(stderr, "INFO: connected to %s (%s)\n",
74
efl_net_dialer_address_dial_get(event->object),
75
efl_net_socket_address_remote_get(event->object));
81
_copier_done(void *data EINA_UNUSED, const Efl_Event *event)
83
fprintf(stderr, "INFO: %s done\n", efl_name_get(event->object));
85
waiting = eina_list_remove(waiting, event->object);
87
efl_loop_quit(efl_loop_get(event->object), EINA_VALUE_EMPTY);
91
_copier_error(void *data EINA_UNUSED, const Efl_Event *event)
93
const Eina_Error *perr = event->info;
94
fprintf(stderr, "INFO: %s error: #%d '%s'\n",
95
efl_name_get(event->object), *perr, eina_error_msg_get(*perr));
97
efl_loop_quit(efl_loop_get(event->object), eina_value_int_init(EXIT_FAILURE));
100
EFL_CALLBACKS_ARRAY_DEFINE(copier_cbs,
101
{ EFL_IO_COPIER_EVENT_DONE, _copier_done },
102
{ EFL_IO_COPIER_EVENT_ERROR, _copier_error });
105
_unescape(const char *str)
107
char *ret = strdup(str);
109
Eina_Bool escaped = EINA_FALSE;
111
for (c = ret, w = ret; *c != '\0'; c++)
115
escaped = EINA_FALSE;
118
case 'n': *w = '\n'; break;
119
case 'r': *w = '\r'; break;
120
case 't': *w = '\t'; break;
137
static const Ecore_Getopt options = {
138
"efl_io_queue_example",
141
"(C) 2016 Enlightenment Project",
144
"Example of Efl_Io_Queue usage.\n"
146
"This uses Efl_Io_Queue to easily interface with Efl_Io_Copier in order to "
147
"send commands to a TCP server.",
150
ECORE_GETOPT_STORE_STR('d', "line-delimiter",
151
"Changes the line delimiter to be used in both send and receive. Defaults to \\r\\n"),
152
ECORE_GETOPT_STORE_ULONG('l', "buffer-limit",
153
"If set will limit buffer size to this limit of bytes. If used alongside with --line-delimiter and that delimiter was not found but bffer limit was reached, the line event will be triggered without the delimiter at the end."),
154
ECORE_GETOPT_VERSION('V', "version"),
155
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
156
ECORE_GETOPT_LICENSE('L', "license"),
157
ECORE_GETOPT_HELP('h', "help"),
159
ECORE_GETOPT_STORE_METAVAR_STR(0, NULL,
160
"The server address as\n"
161
"IP:PORT to connect using TCP and an IPv4 (A.B.C.D:PORT) or IPv6 ([A:B:C:D::E]:PORT).\n",
163
ECORE_GETOPT_APPEND_METAVAR(0, NULL,
166
ECORE_GETOPT_TYPE_STR),
167
ECORE_GETOPT_SENTINEL
172
efl_pause(void *data EINA_UNUSED,
173
const Efl_Event *ev EINA_UNUSED)
178
efl_resume(void *data EINA_UNUSED,
179
const Efl_Event *ev EINA_UNUSED)
184
efl_terminate(void *data EINA_UNUSED,
185
const Efl_Event *ev EINA_UNUSED)
189
fprintf(stderr, "ERROR: %d operations were waiting!\n",
190
eina_list_count(waiting));
191
eina_list_free(waiting);
197
efl_main(void *data EINA_UNUSED,
200
char *address = NULL;
201
char *line_delimiter_str = NULL;
203
unsigned long buffer_limit = 0;
204
Eina_Bool quit_option = EINA_FALSE;
205
Ecore_Getopt_Value values[] = {
206
ECORE_GETOPT_VALUE_STR(line_delimiter_str),
207
ECORE_GETOPT_VALUE_ULONG(buffer_limit),
210
ECORE_GETOPT_VALUE_BOOL(quit_option),
211
ECORE_GETOPT_VALUE_BOOL(quit_option),
212
ECORE_GETOPT_VALUE_BOOL(quit_option),
213
ECORE_GETOPT_VALUE_BOOL(quit_option),
216
ECORE_GETOPT_VALUE_STR(address),
217
ECORE_GETOPT_VALUE_LIST(commands),
219
ECORE_GETOPT_VALUE_NONE
223
Eo *dialer, *sender, *receiver, *loop;
225
args = ecore_getopt_parse(&options, values, 0, NULL);
228
fputs("ERROR: Could not parse command line options.\n", stderr);
232
if (quit_option) goto end;
234
args = ecore_getopt_parse_positional(&options, values, 0, NULL, args);
237
fputs("ERROR: Could not parse positional arguments.\n", stderr);
241
line_delimiter_str = _unescape(line_delimiter_str ? line_delimiter_str : "\\r\\n");
245
fputs("ERROR: missing commands to send.\n", stderr);
249
line_delimiter = (Eina_Slice)EINA_SLICE_STR(line_delimiter_str);
262
send_queue = efl_add_ref(EFL_IO_QUEUE_CLASS, NULL,
263
efl_name_set(efl_added, "send_queue"),
264
efl_io_queue_limit_set(efl_added, buffer_limit));
267
fprintf(stderr, "ERROR: could not create Efl_Io_Queue (send)\n");
283
receive_queue = efl_add_ref(EFL_IO_QUEUE_CLASS, NULL,
284
efl_name_set(efl_added, "receive_queue"),
285
efl_io_queue_limit_set(efl_added, buffer_limit),
286
efl_event_callback_add(efl_added, EFL_IO_QUEUE_EVENT_SLICE_CHANGED, _receiver_data, NULL));
289
fprintf(stderr, "ERROR: could not create Efl_Io_Queue (receive)\n");
290
goto error_receive_queue;
306
dialer = efl_add(EFL_NET_DIALER_TCP_CLASS, loop,
307
efl_name_set(efl_added, "dialer"),
308
efl_event_callback_add(efl_added, EFL_NET_DIALER_EVENT_DIALER_CONNECTED, _dialer_connected, NULL));
311
fprintf(stderr, "ERROR: could not create Efl_Net_Dialer_Tcp\n");
316
sender = efl_add(EFL_IO_COPIER_CLASS, loop,
317
efl_name_set(efl_added, "sender"),
318
efl_io_copier_line_delimiter_set(efl_added, line_delimiter),
319
efl_io_copier_source_set(efl_added, send_queue),
320
efl_io_copier_destination_set(efl_added, dialer),
321
efl_event_callback_array_add(efl_added, copier_cbs(), NULL));
324
fprintf(stderr, "ERROR: could not create Efl_Io_Copier (sender)\n");
329
receiver = efl_add(EFL_IO_COPIER_CLASS, loop,
330
efl_name_set(efl_added, "receiver"),
331
efl_io_copier_line_delimiter_set(efl_added, line_delimiter),
332
efl_io_copier_source_set(efl_added, dialer),
333
efl_io_copier_destination_set(efl_added, receive_queue),
334
efl_event_callback_array_add(efl_added, copier_cbs(), NULL));
337
fprintf(stderr, "ERROR: could not create Efl_Io_Copier (receiver)\n");
341
err = efl_net_dialer_dial(dialer, address);
344
fprintf(stderr, "ERROR: could not dial %s: %s\n",
345
address, eina_error_msg_get(err));
349
waiting = eina_list_append(waiting, sender);
350
waiting = eina_list_append(waiting, receiver);
355
efl_io_closer_close(receiver);
358
efl_io_closer_close(sender);
363
efl_unref(receive_queue);
365
efl_unref(send_queue);
367
EINA_LIST_FREE(commands, cmd)
369
fprintf(stderr, "ERROR: unsent command: %s\n", cmd);
373
efl_loop_quit(efl_loop_get(ev->object), eina_value_int_init(EXIT_FAILURE));