Hi all, To satisfy both ecore-con and ecore-con-url work I'm doing we need to define basic I/O interfaces. My suggestion is to keep them split into specific purpose (one for each), but if you think it's a big overhead with Eo, we can pack them in a single one and let people implement just some, returning errors on the others.
They also assume the Eina_Slice (RDONLY) and Eina_Rw_Slice (RW) proposed in another email thread. src/lib/efl/interfaces/efl_io_reader.eo: interface Efl.Io.Reader { methods { read { [[Reads data into a pre-allocated buffer. This operation will be executed immediately and may or may not block the caller thread for some time. The details of blocking behavior is to be defined by the implementation and may be subject to other parameters such as non-blocking flags, maximum timeout or even retry attempts. You can understand this interface as read(2) libc function. ]] params { @in buffer: slice; [[Writable memory to store read bytes. Must be pre-allocated and defines the maximum amount to read, it won't be resized]] @out used: size; [[returns the amount of buffer that was used during read]] } return: Eina.Error; [[0 on success, a mapping of errno otherwise]] } } } src/lib/efl/interfaces/efl_io_writer.eo: interface Efl.Io.Writer { methods { write { [[Writes data from a pre-populated buffer. This operation will be executed immediately and may or may not block the caller thread for some time. The details of blocking behavior is to be defined by the implementation and may be subject to other parameters such as non-blocking flags, maximum timeout or even retry attempts. You can understand this interface as write(2) libc function. ]] params { @in buffer: const(slice); [[Memory to read bytes from. Must be pre-populated to its full length]] @out used: size; [[returns the amount of buffer that was used during write]] } return: Eina.Error; [[0 on success, a mapping of errno otherwise]] } } } src/lib/efl/interfaces/efl_io_closer.eo: interface Efl.Io.Closer { methods { close { [[Closes the object resources. This operation will be executed immediately and may or may not block the caller thread for some time. The details of blocking behavior is to be defined by the implementation and may be subject to other parameters such as non-blocking flags, maximum timeout or even retry attempts. You can understand this interface as close(2) libc function. ]] return: Eina.Error; [[0 on success, a mapping of errno otherwise]] } } } Likely we'll need an Efl.Io.Sizer that returns the size of the contents, will be useful to manage requests where you have benefit to predefine the contents size (like serving http-requests or doing a HTTP POST). My plan is to write specializations in classes: Efl.Io.Reader.Fd, Efl.Io.Writer.Fd and Efl.Io.Closer.Fd (Please suggest better names!) that would all be based on a common Efl.Io.Fd interface that provides a property "fd". These classes would execute read(2), write(2) and close(2). These would be used by most classes as: Efl.Io.Pipe object may create two child objects, one Reader+Closer and one Writer+Closer, or simply offer itself a Reader+Writer+Closer which would proxy the calls to correct child object. (Not to be implemented right now, just an example) Efl.Net.Socket would be a Reader+Writer+Closer (all using .Fd specializations) as well as Efl.Loop_Fd, then all that is left to do is provide meaningful properties and a "finalize" method that creates the actual socket and sets the internal fd. Efl.Net.Http.Client.Get would be a Reader+Closer. Efl.Net.Http.Client.Post would be a Reader+Writer+Closer. Since these are using libcurl, they would not be using ".Fd" specializations). Efl.Io.Copier would be a class that receives a Reader and a Writer, then copies from reader to writer. It could check if the objects supports Closer in order to close-at-end, as well as if they are Efl.Loop_Fd in order to monitor for events read/write/error, otherwise reverting to a busy wait loop -- These behavior will be discussed later, consider this as a vague idea. The idea of Efl.Io.Copier is that we can avoid things like "ecore_con_url_fd_set()" that is used to save the contents to a file. Instead of having to create such method inside the Efl.Net.Http.Client.Get itself, we'd just use two objects, one for the HTTP and the other for an actual file and use Efl.Io.Copier with them. Likewise, we can provide a HTTP/POST or FTP upload simply by using the File as Reader, HTTP or FTP as Writer and use Efl.Io.Copier. It also solve things like "I need to do an HTTP get and receive as a custom function", that is to expose https://curl.haxx.se/libcurl/c/CURLOPT_READFUNCTION.html, in this case you create your own class that will implement the Reader interface, or you use eo_override(). OR what do you do is to manually listen for Efl.Loop_Fd read events, then call Efl.Io.Reader.read manually -- your call! OTOH, to read to a buffer, we can offer a class that uses Eina_Binbuf internally and implements Reader and Writer interfaces. Thus Efl.Io.Copier will do the work no matter what :-) You can see an example of such interfaces at Go: https://golang.org/pkg/io/ (Reader, Writer, Closer and combinations such as ReadWriter...) -- Gustavo Sverzut Barbieri http://profusion.mobi embedded systems -------------------------------------- MSN, GTalk, FaceTime: barbi...@gmail.com Skype: gsbarbieri 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 enlightenment-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-devel