diff options
Diffstat (limited to 'README.markdown')
-rw-r--r-- | README.markdown | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/README.markdown b/README.markdown index f01fa6e..a7488a0 100644 --- a/README.markdown +++ b/README.markdown @@ -158,6 +158,232 @@ This sets `utils` to a table with the following functions. been scheduled to run. +The Stream Library +------------------ + +Import the module using something like + + local streams = require 'lem.streams' + +This sets `streams` to a table with the following functions. + +* __streams.open(path, [mode])__ + + Opens a given `path` and returns a new stream object. + This should be a path to a device, named pipe or named socket. + The function does work on regular files, but non-blocking IO doesn't, + so you might as well use `io.open()`. + This is a property of POSIX, sorry. + + The `mode` argument supports the same strings as `io.open()`. + If `mode` is not specified it defaults to `"r"`. + +* __streams.popen(cmd, [mode])__ + + This function works just like `io.popen()` except it returns a + stream object (which can be read or written to with blocking the + main loop). + +* __streams.tcp_connect(address, port)__ + + This function connects to the specified address and port + over TCP and if successful returns a new stream object. + +* __streams.tcp_listen(address, port)__ + + This function creates a new server object which can be used to receive + incoming TCP connections on the specified address and port. + +* __streams.sendfile(path)__ + + This function opens a file and returns a new object to be used by the + `streams:sendfile()` method. The path should point to a regular file or + `streams:sendfile()` will fail. + +The above functions return either a new stream object, a new server object, +a new sendfile object or `nil` and an error message indicating what went wrong. +The metatable of those objects can be found under __streams.Stream__, +__streams.Server__ and __streams.SendFile__ respectively. + +The following methods are available on streams. + +* __stream:closed()__ + + Returns `true` when the stream is closed, `false` otherwise. + +* __stream:busy()__ + + Returns `true` when another coroutine is waiting for IO on this stream, + `false` otherwise. + +* __stream:close()__ + + Closes the stream. If the stream is busy, this also interrupts the IO + action on the stream. + + Returns `true` on succes or otherwise `nil` followed by an error message. + If the stream is already closed the error message will be `'already closed'`. + +* __stream:interrupt()__ + + Interrupt any coroutine waiting for IO on the stream. + + Returns `true` on success and `nil, 'not busy'` if no coroutine is waiting + for connections on the server object. + +* __stream:read([mode])__ + + Read data from the stream. The `mode` argument can be one of the following: + + - a number: read the given number of bytes from the stream + - "\*a": read all data from stream until the stream is closed + - "\*l": read a line (read up to and including the next '\n' character) + + If there is not enough data immediately available the current coroutine will + be suspended until there is. + + However if the method is called without the mode argument, it will return + what is immediately available on the stream (up to a certain size limit). + Only if there is no data immediately available will the current coroutine + be suspended until there is. + + On success this method will return the data read from stream in a Lua string. + Otherwise it will return `nil` followed by an error message. + If another coroutine is waiting for IO on the stream the error message + will be `'busy'`. + If the stream was interrupted (eg. by another coroutine calling + `stream:interrupt()`, or `stream:close()`) the error message will be + `'interrupted'`. + If the stream is closed either before calling the method or closed + from the other end during the read the error message will be `'closed'`. + +* __stream:write(data)__ + + Write the given data, which must be a Lua string, to the stream. + If the data cannot be immediately written to the stream the current + coroutine will be suspended until all data is written. + + Returns `true` on success or otherwise `nil` followed by an error message. + If another coroutine is waiting for IO on the stream the error message + will be `'busy'`. + If the stream was interrupted (eg. by another coroutine calling + `stream:interrupt()`, or `stream:close()`) the error message will be + `'interrupted'`. + If the stream is closed either before calling the method or closed + from the other end during the write the error message will be `'closed'`. + +* __stream:sendfile(file, [offset])__ + + Write the given file to the stream. This is more effektive than reading + from a file and writing to the socket since the data doesn't have to go + through userspace. It only works on socket streams though. + + The file must be a sendfile object as returned by `streams.sendfile()`. + + If the offset argument is given the transfer will begin at the given + offset into the file. + + Returns `true` on success or otherwise `nil` followed by an error message. + If another coroutine is waiting for IO on the stream the error message + will be `'busy'`. + If the stream was interrupted (eg. by another coroutine calling + `stream:interrupt()`, or `stream:close()`) the error message will be + `'interrupted'`. + If the stream is closed either before calling the method or closed + from the other end during the write the error message will be `'closed'`. + If the file is closed the error message will be `'file closed'`. + +* __stream:cork()__ + + Sets the `TCP_CORK` attribute on the stream. This will of course fail + on streams which are not TCP connections. + + Returns `true` on success or otherwise `nil` followed by an error message. + If another coroutine is waiting for IO on the stream the error message + will be `'busy'`. + If the stream is closed the error message will be `'closed'`. + +* __stream:uncork()__ + + Removes the `TCP_CORK` attribute on the stream. This will of course fail + on streams which are not TCP connections. + + Returns `true` on success or otherwise `nil` followed by an error message. + If another coroutine is waiting for IO on the stream the error message + will be `'busy'`. + If the stream is closed the error message will be `'closed'`. + + +The following methods are available on server objects. + +* __server:closed()__ + + Returns `true` if the server is closed, `false` otherwise. + +* __server:busy()__ + + Returns `true` if another coroutine is listening on the server object, + `false` otherwise. + +* __server:close()__ + + Closes the server object. If another coroutine is waiting for connections + on the object it will be interrupted. + + Returns `true` on succes or otherwise `nil` followed by an error message. + If the server is already closed the error message will be `'already closed'`. + +* __server:interrupt()__ + + Interrupt any coroutine waiting for new connections on the server object. + + Returns `true` on success and `nil, 'not busy'` if no coroutine is waiting + for connections on the server object. + +* __server:accept()__ + + This method will get a stream object of a new incoming connection. + If there are no incoming connections immediately available, + the current coroutine will be suspended until there is. + + Returns a new stream object on succes or otherwise `nil` followed by an + error message. + If another coroutine is already waiting for new connections on the server + object the error message will be `'busy'`. + If the server was interrupted (eg. by another coroutine calling + `server:interrupt()`, or `server:close()`) the error message will be + `'interrupted'`. + If the server object is closed the error message will be `'closed'`. + +* __server:autospawn(handler)__ + + This method will suspend the currently running coroutine while + listening for new connections to the server object. + When a new client connects it will automatically spawn a new + coroutine running the `handler` function with a stream object + for the new connection as first argument. + + If an error occurs the method will return `nil` followed by an error message. + If another coroutine is already waiting for new connections on the server + object the error message will be `'busy'`. + If the server was interrupted (eg. by another coroutine calling + `server:interrupt()`, or `server:close()`) the error message will be + `'interrupted'`. + If the server object is closed the error message will be `'closed'`. + +The following methods are available on sendfile objects. + +* __file:close()__ + + Closes the gives file. + + Returns `true` on success or otherwise `nil` followed by an error message. + +* __file:size()__ + + Returns the size of the file. + + License ------- |