summaryrefslogtreecommitdiffstats
path: root/README.markdown
diff options
context:
space:
mode:
Diffstat (limited to 'README.markdown')
-rw-r--r--README.markdown226
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
-------