On Thu, Aug 11, 2016 at 3:29 AM, Carsten Haitzler <[email protected]> wrote:
> On Tue, 9 Aug 2016 18:31:37 -0300 Gustavo Sverzut Barbieri
> <[email protected]>
> said:
>
> i think we should re-use binbuf/strbuf here and add whatever is missing to
> them...
>
> in fact at a raw level they have everything needed even to point to mmaped
> memory and use multiple binbufs to point to slices of it without any memcpy's
> etc.
>
> we have a lot of api in efl. let's not add more if we don't NEED it. it's
> complex enough to learn! :)
Well, the purpose of Slice can indeed be satisfied with Eina_Binbuf,
but I'd still keep the slice for the following reasons:
- super-lightweight: no need to alloc, we can pass value, not
pointer. (see my examples in the original email)
- type independent: if we have a string or a strbuf and we expect
binbuf, we'd need to convert to them (which results in an alloc/free).
With slice we can have "_slice_get()" methods in most functions that
used to return memory+size, like binbuf/strbuf (string_get() +
length_get()), or stringshare (it's the memory and offers
eina_stringshare_strlen()).
- easily usable in tokenization/parsers, like how to split "a:b:c" at
":" without alloc? you can create a slice for "a:b:c" and then on each
loop fill the proper segment.
- clear purpose that memory is pre-defined in content and length. Say
the "Efl.Io.Reader.read()" method, if we give a slice, it's clear that
will read up to slice.len. If you receive 'Eina_Binbuf', do I need to
pre-allocate its size (no binbuf_resize(), would need to add)? If it
will grow dynamically, how do I limit that amount? By using
yet-another parameter?
With slices one can easily use the stack buffers as Tasn mentioned or
binbuf. We can still add binbuf_resize()/grow() so we can later use a
slice from within that new memory and read straight into it, like:
size_t oldlen = eina_binbuf_length_get(buf);
eina_binbuf_grow(buf, 4096); // you control how much you want to
grow at once
Eina_Rw_Slice rw_slice = eina_binbuf_rw_slice_get(buf);
rw_slice.mem = (uint8_t *)rw_slice.mem + oldlen; // these 2 lines
can be an eina_rw_slice static inline helper
rw_slice.len -= oldlen;
size_t used;
Eina_Error error = efl_io_reader_read(obj, rw_slice, &used); //
reads straight into buffer, no copies
eina_binbuf_length_set(buf, oldlen + used);
Or in more common code:
char buf[4096];
Eina_Rw_Slice rw_slice = {.mem = buf, .len = sizeof(buf) - 1}; //
these 2 lines can be made easier with a macro
size_t used;
Eina_Error error = efl_io_reader_read(obj, rw_slice, &used);
buf[used] = '\0';
printf("got: %s\n", buf);
RDONLY slices used for Write are even easier:
size_t used;
Eina_Error error = efl_io_writer_write(obj,
eina_slice_from_str("hello world"), &used);
You could do these with Eina_Binbuf by using the managed version and
setting "ro" flag, but you always need to allocate the binbuf and free
it, even for a simple operation like the one above.
Did you change your mind or should I go with solely Eina_Binbuf?
--
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890
------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are
consuming the most bandwidth. Provides multi-vendor support for NetFlow,
J-Flow, sFlow and other flows. Make informed decisions using capacity
planning reports. http://sdm.link/zohodev2dev
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel