Streams and Listeners
Changed in version 1.3.0: Streams were redesigned significantly.
The high-level API in Tinlok consists of two parts:
Streams, for objects that read or write incoming or outgoing data.
Listeners, for objects that produce Streams.
Listeners
New in version 1.3.0.
Listeners have only one type, the Listener
interface, and one method, unsafeAccept
.
Listeners can technically produce any object, not just streams, but it is recommended to at least
only produce Closeable
instances. As with most Unsafe operations, Listener
has some helper
extension functions:
// where someListener is a Listener<out Closeable>
val result = someListener.accept {
...
}
ClosingScope {
val obb = someListener.accept(it)
}
Streams
Streams are objects that perform actual I/O, e.g. a file stream or a socket stream. Streams use a set of base interfaces:
Readable
; an object that can be read from.Writeable
; an object that can be written to.ReadWrite
; an object that is bothReadable
andWriteable
.
A Stream is a combination of either Readable
, Writeable
or ReadWrite
, and Closeable
.
They come in several flavours:
ReadableStream
; a stream that can be read from.WriteableStream
; a stream that can be written to.BidirectionalStream
; a stream that is both aReadableStream
andWriteableStream
.HalfcloseableStream
; aBidirectionalStream
that can have one half closed independently.
Streams have both a very high-level API and a low-level API. Implementors of a Stream
need only
implement the low-level API, as the very high-level API
The very high-level API
The very high-level API for streams operates on Bytestrings. This is similar to Python’s I/O system, as an example.
Readable.readUpTo(count)
readscount
bytes from areadable
, returning aByteString
object containing the result.Writeable.writeAll(bs)
writes all bytes from the passedByteString
.
For end-user applications, this is the preferred API due to its simplicity.
The low-level API
The low-level API involves ByteArray
and Buffer
objects. See Buffers for more
information on buffers.
Readable.readInto(arr, size, offset)
- Readssize
bytes intoarr
, starting atoffset
.Readable.readInto(buffer, size)
- Readssize
bytes intobuffer
.Writeable.writeAllFrom(ba, size, offset)
- Writessize
bytes fromarr
, starting atoffset
, into this writeable.Writeable.writeAllFrom(buffer, size)
- Writessize
bytes frombuffer
into this writeable.
If implementing your own Readable
or Writeable
, it is recommended to read Buffers for
details of how to efficiently pass data to and from your underlying calls.