Efl.Io.{Queue,Buffer,Buffered_Stream}: slice_get is now a property.

Previously we couldn't return a slice, instead required the user to
pass a slice and we'd fill it since Eolian couldn't generate fallbacks
for structures.

Since @q66 fixed eolian, we can now return the structure itself as
initially wanted, ditching some TODO from the code.
This commit is contained in:
Gustavo Sverzut Barbieri 2016-12-19 14:46:37 -02:00
parent 6f9deb976a
commit 25a9e1d886
17 changed files with 119 additions and 161 deletions

View File

@ -70,11 +70,7 @@ _on_data(void *data, const Efl_Event *event)
Eo *dialer = event->object;
Eina_Slice slice;
if (!efl_io_buffered_stream_slice_get(dialer, &slice))
{
fprintf(stderr, "ERROR: could not get buffered stream slice\n");
goto error;
}
slice = efl_io_buffered_stream_slice_get(dialer);
if (slice.len == 0) return;
if (eet_connection_received(ec, slice.mem, slice.len) != 0)

View File

@ -24,9 +24,7 @@ received_data(Eo *sock, void (*handle)(void *data, const char op[static 4], cons
Eina_Slice slice, payload;
Efl_Debug_Message_Header msgheader;
if (!efl_io_buffered_stream_slice_get(sock, &slice))
return EINA_TRUE;
slice = efl_io_buffered_stream_slice_get(sock);
if (slice.len < sizeof(msgheader))
return EINA_TRUE;

View File

@ -38,9 +38,7 @@ _command_next(void)
static void
_receiver_data(void *data EINA_UNUSED, const Efl_Event *event)
{
Eina_Slice slice;
if (!efl_io_buffered_stream_slice_get(event->object, &slice)) return;
Eina_Slice slice = efl_io_buffered_stream_slice_get(event->object);
/* this will happen when we're called when we issue our own
* efl_io_buffered_stream_clear() below.

View File

@ -43,13 +43,7 @@ EFL_CALLBACKS_ARRAY_DEFINE(output_cbs,
static void
_output_buffer_reallocated(void *data EINA_UNUSED, const Efl_Event *event)
{
Eina_Slice slice;
if (!efl_io_buffer_slice_get(event->object, &slice))
{
fprintf(stderr, "ERROR: could not get buffer slice\n");
return;
}
Eina_Slice slice = efl_io_buffer_slice_get(event->object);
fprintf(stderr, "INFO: output buffer reallocated=" EINA_SLICE_FMT "\n",
EINA_SLICE_PRINT(slice));
@ -196,17 +190,13 @@ _copier_done(void *data EINA_UNUSED, const Efl_Event *event)
* an Eina_Binbuf, you own the ownership and must call
* eina_binbuf_free() to release it.
*/
Eina_Slice slice;
if (!efl_io_buffer_slice_get(destination, &slice))
fprintf(stderr, "ERROR: could not get buffer slice\n");
else
fprintf(stderr,
"INFO: :memory: resulted in slice=" EINA_SLICE_FMT ":"
"\n--BEGIN DATA--\n"
EINA_SLICE_STR_FMT
"\n--END DATA--\n",
EINA_SLICE_PRINT(slice), EINA_SLICE_STR_PRINT(slice));
Eina_Slice slice = efl_io_buffer_slice_get(destination);
fprintf(stderr,
"INFO: :memory: resulted in slice=" EINA_SLICE_FMT ":"
"\n--BEGIN DATA--\n"
EINA_SLICE_STR_FMT
"\n--END DATA--\n",
EINA_SLICE_PRINT(slice), EINA_SLICE_STR_PRINT(slice));
}
fprintf(stderr, "INFO: done\n");

View File

@ -39,9 +39,7 @@ _command_next(void)
static void
_receiver_data(void *data EINA_UNUSED, const Efl_Event *event)
{
Eina_Slice slice;
if (!efl_io_queue_slice_get(event->object, &slice)) return;
Eina_Slice slice = efl_io_queue_slice_get(event->object);
/* this will happen when we're called when we issue our own
* efl_io_queue_clear() below.

View File

@ -28,22 +28,17 @@ _connected(void *data EINA_UNUSED, const Efl_Event *event)
static void
_eos(void *data EINA_UNUSED, const Efl_Event *event)
{
Eina_Slice s;
fprintf(stderr, "INFO: end of stream.\n");
/* on _error() we close it, then do not read as it has nothing */
if (efl_io_closer_closed_get(event->object))
return;
if (efl_io_buffered_stream_slice_get(event->object, &s))
{
fprintf(stderr,
"-- BEGIN RECEIVED DATA --\n"
EINA_SLICE_STR_FMT
"-- END RECEIVED DATA--\n",
EINA_SLICE_STR_PRINT(s));
}
fprintf(stderr,
"-- BEGIN RECEIVED DATA --\n"
EINA_SLICE_STR_FMT
"-- END RECEIVED DATA--\n",
EINA_SLICE_STR_PRINT(efl_io_buffered_stream_slice_get(event->object)));
}
static void

View File

@ -142,19 +142,16 @@ _send_copier_done(void *data, const Efl_Event *event)
Eo *buffer = efl_io_copier_source_get(copier);
Eo *client = efl_io_copier_destination_get(copier);
Send_Recv_Data *d = data;
Eina_Slice slice;
Eina_Slice slice = efl_io_buffer_slice_get(buffer);
/* show what we sent, just for debug */
if (!efl_io_buffer_slice_get(buffer, &slice))
fprintf(stderr, "ERROR: could not get buffer slice\n");
else
fprintf(stderr,
"INFO: sent to %s %zd bytes:"
"\n--BEGIN SENT DATA--\n"
EINA_SLICE_STR_FMT
"\n--END SENT DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
fprintf(stderr,
"INFO: sent to %s %zd bytes:"
"\n--BEGIN SENT DATA--\n"
EINA_SLICE_STR_FMT
"\n--END SENT DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
if (d->recv_copier)
{
@ -175,7 +172,7 @@ _send_copier_error(void *data, const Efl_Event *event)
const Eina_Error *perr = event->info;
Send_Recv_Data *d = data;
uint64_t offset;
Eina_Slice slice;
Eina_Slice slice, remaining;
if (*perr == ETIMEDOUT)
{
@ -188,30 +185,26 @@ _send_copier_error(void *data, const Efl_Event *event)
retval = EXIT_FAILURE;
offset = efl_io_buffer_position_read_get(buffer);
if (!efl_io_buffer_slice_get(buffer, &slice))
fprintf(stderr, "ERROR: could not get buffer slice\n");
else
{
Eina_Slice remaining = slice;
slice = efl_io_buffer_slice_get(buffer);
remaining.bytes += offset;
remaining.len -= offset;
remaining = slice;
remaining.bytes += offset;
remaining.len -= offset;
slice.len = offset;
slice.len = offset;
fprintf(stderr,
"ERROR: sent to %s only %zd bytes:"
"\n--BEGIN SENT DATA--\n"
EINA_SLICE_STR_FMT
"\n--END SENT DATA--\n"
"Remaining %zd bytes:"
"\n--BEGIN REMAINING DATA--\n"
EINA_SLICE_STR_FMT
"\n--END REMAINING DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice),
remaining.len, EINA_SLICE_STR_PRINT(remaining));
}
fprintf(stderr,
"ERROR: sent to %s only %zd bytes:"
"\n--BEGIN SENT DATA--\n"
EINA_SLICE_STR_FMT
"\n--END SENT DATA--\n"
"Remaining %zd bytes:"
"\n--BEGIN REMAINING DATA--\n"
EINA_SLICE_STR_FMT
"\n--END REMAINING DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice),
remaining.len, EINA_SLICE_STR_PRINT(remaining));
fprintf(stderr, "ERROR: send copier %p failed %d '%s', check if should close..\n",
copier, *perr, eina_error_msg_get(*perr));
@ -229,7 +222,7 @@ _recv_copier_done(void *data, const Efl_Event *event)
Eo *client = efl_io_copier_source_get(copier);
Eo *buffer = efl_io_copier_destination_get(copier);
Send_Recv_Data *d = data;
Eina_Slice slice;
Eina_Slice slice = efl_io_buffer_slice_get(buffer);
/* show case, you could use a copier to Efl_Io_Stdout, a
* file... and get progressive processing.
@ -240,16 +233,13 @@ _recv_copier_done(void *data, const Efl_Event *event)
* You could also steal the binbuf with
* efl_io_buffer_binbuf_steal()
*/
if (!efl_io_buffer_slice_get(buffer, &slice))
fprintf(stderr, "ERROR: could not get buffer slice\n");
else
fprintf(stderr,
"INFO: recv from %s %zd bytes:"
"\n--BEGIN RECV DATA--\n"
EINA_SLICE_STR_FMT "\n"
"\n--END RECV DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
fprintf(stderr,
"INFO: recv from %s %zd bytes:"
"\n--BEGIN RECV DATA--\n"
EINA_SLICE_STR_FMT "\n"
"\n--END RECV DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
fprintf(stderr, "INFO: receive copier done, check if should close %p\n", copier);
_send_recv_done(d, copier);
@ -275,16 +265,14 @@ _recv_copier_error(void *data, const Efl_Event *event)
retval = EXIT_FAILURE;
if (!efl_io_buffer_slice_get(buffer, &slice))
fprintf(stderr, "ERROR: could not get buffer slice\n");
else
fprintf(stderr,
"ERROR: recv to %s only %zd bytes:"
"\n--BEGIN RECV DATA--\n"
EINA_SLICE_STR_FMT "\n"
"\n--END RECV DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
slice = efl_io_buffer_slice_get(buffer);
fprintf(stderr,
"ERROR: recv to %s only %zd bytes:"
"\n--BEGIN RECV DATA--\n"
EINA_SLICE_STR_FMT "\n"
"\n--END RECV DATA--\n",
efl_net_socket_address_remote_get(client),
slice.len, EINA_SLICE_STR_PRINT(slice));
fprintf(stderr, "ERROR: receive copier %p failed %d '%s', check if should close..\n",
copier, *perr, eina_error_msg_get(*perr));

View File

@ -37,22 +37,17 @@ _client_eos(void *data EINA_UNUSED, const Efl_Event *event)
static void
_client_read_finished(void *data EINA_UNUSED, const Efl_Event *event)
{
Eina_Slice s;
/* on _error() we close it, then do not read as it has nothing */
if (efl_io_closer_closed_get(event->object))
return;
if (echo) return;
if (efl_io_buffered_stream_slice_get(event->object, &s))
{
fprintf(stderr,
"-- BEGIN RECEIVED DATA --\n"
EINA_SLICE_STR_FMT
"-- END RECEIVED DATA--\n",
EINA_SLICE_STR_PRINT(s));
}
fprintf(stderr,
"-- BEGIN RECEIVED DATA --\n"
EINA_SLICE_STR_FMT
"-- END RECEIVED DATA--\n",
EINA_SLICE_STR_PRINT(efl_io_buffered_stream_slice_get(event->object)));
}
static void

View File

@ -533,19 +533,15 @@ _efl_io_buffered_stream_progress_get(Eo *o EINA_UNUSED, Efl_Io_Buffered_Stream_D
if (pw) *pw = w;
}
EOLIAN static Eina_Bool
_efl_io_buffered_stream_slice_get(Eo *o EINA_UNUSED, Efl_Io_Buffered_Stream_Data *pd, Eina_Slice *slice)
EOLIAN static Eina_Slice
_efl_io_buffered_stream_slice_get(Eo *o EINA_UNUSED, Efl_Io_Buffered_Stream_Data *pd)
{
if (!pd->incoming)
{
if (slice)
{
slice->mem = NULL;
slice->len = 0;
}
return EINA_FALSE;
}
return efl_io_queue_slice_get(pd->incoming, slice);
Eina_Slice slice = { };
if (pd->incoming)
slice = efl_io_queue_slice_get(pd->incoming);
return slice;
}
EOLIAN static void

View File

@ -19,13 +19,13 @@ class Efl.Io.Buffered_Stream (Efl.Loop_User, Efl.Io.Reader, Efl.Io.Writer, Efl.I
Reading is also much simpler since incoming data is kept in an
@Efl.Io.Queue, thus its size can be queried with @.pending_read
and read with @Efl.Io.Reader.read or peeked with @.slice_get,
and read with @Efl.Io.Reader.read or peeked with @.slice,
then discarded with @.discard or @.clear.
Then when waiting for a complete message, just peek at its
contents, if not complete do nothing and wait, if complete then
either @Efl.Io.Reader.read to get a copy or manipulate a
read-only reference from @.slice_get and then @.discard
read-only reference from @.slice and then @.discard
The actual I/O is set with the constructor method @.inner_io.set
and can be retrieved with @.inner_io.get, which should be used
@ -155,17 +155,17 @@ class Efl.Io.Buffered_Stream (Efl.Loop_User, Efl.Io.Reader, Efl.Io.Writer, Efl.I
}
}
slice_get { // TODO: property and return of Eina.Slice (not pointer)
@property slice {
[[Get a temporary access to input queue's internal read memory.
The memory pointed by slice may be changed by other
methods of this class. The event "slice,changed" will be
called in those situations.
]]
params {
@out slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Reader.read are called. It is the full slice available for reading.]]
get { }
values {
slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Reader.read are called. It is the full slice available for reading.]]
}
return: bool (false); [[$true on success, $false otherwise]]
}
discard {
@ -175,12 +175,12 @@ class Efl.Io.Buffered_Stream (Efl.Loop_User, Efl.Io.Reader, Efl.Io.Writer, Efl.I
given amount of bytes, without executing the actual
copy.
It's often paired with @.slice_get, if users read the
It's often paired with @.slice, if users read the
information from the slice and once they're done, that
data must be discarded.
As an example, some protocols provide messages with a
"size" header, then @.slice_get is used to peek into the
"size" header, then @.slice is used to peek into the
available memory to see if there is a "size" and if the
rest of the slice is the full payload, in this case the
slice may be handled to some processing function. When
@ -241,8 +241,8 @@ class Efl.Io.Buffered_Stream (Efl.Loop_User, Efl.Io.Reader, Efl.Io.Writer, Efl.I
finished; [[Both read and write are finished.]]
error: Eina.Error; [[An error happened and the I/O stopped]]
progress; [[Property @.progress changed]]
slice,changed; [[The read-slice returned by @.slice_get may have changed.]]
line: ptr(const(Eina.Slice)); [[If @.line_delimiter is set, will be emitted with current line. The memory is only valid during event callback dispatched and should not be modified. Note that the line slice may not be inside @.slice_get, don't assume that!]]
slice,changed; [[The read-slice returned by @.slice may have changed.]]
line: ptr(const(Eina.Slice)); [[If @.line_delimiter is set, will be emitted with current line. The memory is only valid during event callback dispatched and should not be modified. Note that the line slice may not be inside @.slice, don't assume that!]]
}
implements {

View File

@ -530,7 +530,7 @@ _ecore_con_client_socket_slice_changed(void *data, const Efl_Event *event EINA_U
if (cl->delete_me) return;
if (cl->ssl.upgrading) return;
if (!efl_io_buffered_stream_slice_get(cl->socket, &ro_slice)) return;
ro_slice = efl_io_buffered_stream_slice_get(cl->socket);
if (ro_slice.len == 0) return;
rw_slice = eina_slice_dup(ro_slice);
@ -1211,7 +1211,7 @@ _ecore_con_server_dialer_slice_changed(void *data, const Efl_Event *event EINA_U
if (svr->delete_me) return;
if (svr->ssl.upgrading) return;
if (!efl_io_buffered_stream_slice_get(svr->dialer, &ro_slice)) return;
ro_slice = efl_io_buffered_stream_slice_get(svr->dialer);
if (ro_slice.len == 0) return;
rw_slice = eina_slice_dup(ro_slice);

View File

@ -20,14 +20,14 @@ class Efl.Net.Dialer.Simple (Efl.Net.Socket.Simple, Efl.Net.Dialer) {
@Efl.Io.Queue, thus its size can be queried with
@Efl.Io.Buffered_Stream.pending_read and read with
@Efl.Io.Reader.read or peeked with
@Efl.Io.Buffered_Stream.slice_get, then discarded with
@Efl.Io.Buffered_Stream.slice, then discarded with
@Efl.Io.Buffered_Stream.discard or
@Efl.Io.Buffered_Stream.clear.
Then when waiting for a complete message, just peek at its
contents, if not complete do nothing, if complete then either
@Efl.Io.Reader.read to get a copy or manipulate a read-only
reference from @Efl.Io.Buffered_Stream.slice_get and then
reference from @Efl.Io.Buffered_Stream.slice and then
@Efl.Io.Buffered_Stream.discard
The actual dialer is created using the class given as the

View File

@ -19,14 +19,14 @@ class Efl.Net.Socket.Simple (Efl.Io.Buffered_Stream, Efl.Net.Socket) {
@Efl.Io.Queue, thus its size can be queried with
@Efl.Io.Buffered_Stream.pending_read and read with
@Efl.Io.Reader.read or peeked with
@Efl.Io.Buffered_Stream.slice_get, then discarded with
@Efl.Io.Buffered_Stream.slice, then discarded with
@Efl.Io.Buffered_Stream.discard or
@Efl.Io.Buffered_Stream.clear.
Then when waiting for a complete message, just peek at its
contents, if not complete do nothing, if complete then either
@Efl.Io.Reader.read to get a copy or manipulate a read-only
reference from @Efl.Io.Buffered_Stream.slice_get and then
reference from @Efl.Io.Buffered_Stream.slice and then
@Efl.Io.Buffered_Stream.discard
The actual socket is set with the constructor method

View File

@ -107,16 +107,18 @@ _efl_io_buffer_limit_get(Eo *o EINA_UNUSED, Efl_Io_Buffer_Data *pd)
return pd->limit;
}
EOLIAN static Eina_Bool
_efl_io_buffer_slice_get(Eo *o, Efl_Io_Buffer_Data *pd, Eina_Slice *slice)
EOLIAN static Eina_Slice
_efl_io_buffer_slice_get(Eo *o, Efl_Io_Buffer_Data *pd)
{
if (slice)
Eina_Slice slice = { };
if (!efl_io_closer_closed_get(o))
{
slice->mem = pd->bytes;
slice->len = efl_io_sizer_size_get(o);
slice.mem = pd->bytes;
slice.len = efl_io_sizer_size_get(o);
}
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINA_FALSE);
return EINA_TRUE;
return slice;
}
EOLIAN static Eina_Binbuf *

View File

@ -6,7 +6,7 @@ class Efl.Io.Buffer (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer, Ef
use different offsets/position internally.
One can get temporary direct access to internal buffer with
@.slice_get or steal the buffer with @.binbuf_steal.
@.slice or steal the buffer with @.binbuf_steal.
A fixed sized buffer can be implemented by setting @.limit
followed by @.preallocate
@ -78,17 +78,17 @@ class Efl.Io.Buffer (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer, Ef
}
}
slice_get { // TODO: property and return of Eina.Slice (not pointer)
@property slice {
[[Get a temporary access to buffer's internal memory.
The memory pointed by slice may be changed by other
methods of this class. The event "reallocated" will be
called in those situations.
]]
params {
@out slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Sizer.resize are called. It is the full slice, not a partial one starting at current position.]]
get { }
values {
slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Sizer.resize are called. It is the full slice, not a partial one starting at current position.]]
}
return: bool (false); [[$true on success, $false otherwise]]
}
binbuf_steal {
@ -103,7 +103,7 @@ class Efl.Io.Buffer (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer, Ef
events {
position_read,changed; [[Notifies @.position_read changed]]
position_write,changed; [[Notifies @.position_write changed]]
reallocated; [[Notifies the internal buffer was reallocated, thus whatever was returned by @.slice_get becomes invalid]]
reallocated; [[Notifies the internal buffer was reallocated, thus whatever was returned by @.slice becomes invalid]]
}
implements {

View File

@ -200,16 +200,18 @@ _efl_io_queue_usage_get(Eo *o EINA_UNUSED, Efl_Io_Queue_Data *pd)
return pd->position_write - pd->position_read;
}
EOLIAN static Eina_Bool
_efl_io_queue_slice_get(Eo *o, Efl_Io_Queue_Data *pd, Eina_Slice *slice)
EOLIAN static Eina_Slice
_efl_io_queue_slice_get(Eo *o, Efl_Io_Queue_Data *pd)
{
if (slice)
Eina_Slice slice = { };
if (!efl_io_closer_closed_get(o))
{
slice->mem = pd->bytes + pd->position_read;
slice->len = efl_io_queue_usage_get(o);
slice.mem = pd->bytes + pd->position_read;
slice.len = efl_io_queue_usage_get(o);
}
EINA_SAFETY_ON_TRUE_RETURN_VAL(efl_io_closer_closed_get(o), EINA_FALSE);
return EINA_TRUE;
return slice;
}
EOLIAN static void

View File

@ -45,17 +45,17 @@ class Efl.Io.Queue (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) {
}
}
slice_get { // TODO: property and return of Eina.Slice (not pointer)
@property slice {
[[Get a temporary access to queue's internal read memory.
The memory pointed by slice may be changed by other
methods of this class. The event "slice,changed" will be
called in those situations.
]]
params {
@out slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Reader.read are called. It is the full slice available for reading.]]
get { }
values {
slice: Eina.Slice; [[Slice of the current buffer, may be invalidated if @Efl.Io.Writer.write, @Efl.Io.Closer.close or @Efl.Io.Reader.read are called. It is the full slice available for reading.]]
}
return: bool (false); [[$true on success, $false otherwise]]
}
discard {
@ -65,12 +65,12 @@ class Efl.Io.Queue (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) {
given amount of bytes, without executing the actual
copy.
It's often paired with @.slice_get, if users read the
It's often paired with @.slice, if users read the
information from the slice and once they're done, that
data must be discarded.
As an example, some protocols provide messages with a
"size" header, then @.slice_get is used to peek into the
"size" header, then @.slice is used to peek into the
available memory to see if there is a "size" and if the
rest of the slice is the full payload, in this case the
slice may be handled to some processing function. When
@ -102,7 +102,7 @@ class Efl.Io.Queue (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) {
}
events {
slice,changed; [[The read-slice returned by @.slice_get may have changed.]]
slice,changed; [[The read-slice returned by @.slice may have changed.]]
}
implements {