On this page
tecs.io
Input, output, and cooperative network transport.
A Stream describes binary storage without keeping a cursor. A Reader and Writer are the caller-owned directional endpoints opened from it. Strings, buffers, borrowed bytes, paths, and handles all use that one descriptor contract.
A Lua FILE is also a basic reader and writer. transfer accepts files directly and uses readInto or writeFrom accelerators when an endpoint provides them. Transform constructors take ownership of either a Tecs endpoint or a file and close it with the wrapper.
Readers, writers, transforms, and whole-source operations return their result directly. A memory operation completes inline. An unresolved file, socket, or process operation suspends a normal system and resumes at the call; the same call blocks its caller outside a world update. They return nil and a reason when an endpoint cannot be opened, read, written, flushed, or closed:
tecs.scoped(
"read save",
function(scope: tecs.Scope)
local save <const> = scope:own(
tecs.io.newFileStream("save.bin")
)
local bytes <const> = assert(save:transferToBuffer())
scope:own(bytes)
print(bytes:length())
end
)TCP is an ordered byte stream: one write may take several reads to receive, several writes may arrive in one read, and message framing belongs to the caller. UDP preserves one send as one datagram, but the network may lose, duplicate, or reorder it. General immutable URIs live under tecs.io.URI; HTTP and HTTPS live under tecs.io.http; the MCP debug server lives under tecs.io.mcp.
Hot TCP loops can reuse a Buffer. TCPSocket:readInto lets the native socket fill its FFI allocation directly, and TCPSocket:writeFrom queues a buffer range without constructing an intermediate Lua string. UDPSocket:receiveInto is the datagram form: it fills a reused buffer, reports its sender through sourceHost and sourcePort, and allocates no packet, address, or payload string. UDPSocket:source builds an owned address from the recorded sender when a reply needs one. Buffer:view retains an immutable zero-copy snapshot. writeView on sockets, writers, and writable streams consumes that retained range directly, while ByteView:newStream gives it replayable stream behavior without copying payload bytes.
Transform readers and writers compose those endpoints without materializing a whole source. newInflateReader, newBase64DecodeReader, newHexDecodeReader, and newTranscodeReader pull transformed bytes as their consumer asks. The corresponding deflate, encode, and transcode writers push transformed chunks toward a destination and finish format trailers or partial character state on close. Each wrapper owns the endpoint it wraps. Memory endpoints lend source pointers and reserve destination ranges directly; other endpoints reuse pooled chunks, so a warmed transfer allocates no intermediate payload storage.
Ownership is explicit at construction boundaries. A stream over a buffer or Lua file handle borrows that resource and never closes it. A stream over a byte view retains its own immutable view. Transform readers and writers take ownership of the endpoint they wrap and close it with themselves. Opening a buffer or byte-view reader retains an immutable snapshot that outlives later closure; opening a buffer writer borrows the mutable buffer, clears its logical length, and requires it to remain open through the writer's close.
Network operations return their values directly. Inside a system, resolution, connection, acceptance, socket reads, and datagram receives transparently suspend only while the requested operation cannot make progress:
world:addSystem({
name = "game.ReceiveCommand",
phase = tecs.ecs.phases.Update,
run = function()
tecs.scoped(
"serve client",
function(scope)
local client <const> = scope:own(
assert(listener:accept())
)
local command <const> = assert(client:read())
applyCommand(command)
end
)
end,
})The Application owns progress; there is no public pump to drive. Resolution, connection, reads, acceptance, sends, and receives all block appropriately for their context. A call never changes into a WouldBlock result merely because it ran outside a system. The explicit wait methods remain timeout and readiness checks rather than a second transfer API.
One endpoint permits one suspended readiness operation at a time. Do not park both read and drain on one TCP socket, both accept and wait on one listener, or both receive and wait on one UDP socket. Use one owner to serialize operations on an endpoint; a second overlapping wait fails at that call instead of replacing the first waiter.
The ready path performs the native operation immediately. Only a native WouldBlock arms a one-shot watch in the process-wide mio reactor. The reactor never calls Lua; the Application drains its tokens on the main thread and the scheduler resumes the same system. Socket writes finish when their bounded local queue accepts the bytes; drain is the explicit transport delivery boundary.
Every address, TCP socket, listener, UDP socket, and UDP packet owns a resource. Close it explicitly. A GC finalizer releases an abandoned network handle as a last resort, but cannot report a close error. Closing is idempotent; using a closed value returns a failure.
Naming tecs.io loads none of its children. Reading files, http, mcp, Path, Process, URI, or watcher loads only that child.
Declares the directional binary interfaces published by tecs.io.
This module is the cycle-safe home of Reader, Writer, and the stream descriptor interfaces. It is not a second public namespace: tecs.io re-exports the contracts, while resource modules require them without requiring their public parent.
Module contents
Submodules
| Submodule | Description |
|---|---|
tecs.io.Path |
Immutable UTF-8 filesystem paths with platform-native semantics. |
tecs.io.Process |
Streaming child processes with cooperative waits and backpressured standard I/O. |
tecs.io.URI |
Immutable absolute URIs with component-aware modification. |
tecs.io.files |
Asset, persistent, and cache paths with direct and worker-backed file operations |
tecs.io.http |
Cooperative HTTP requests, streaming bodies, connection pools, and ECS request entities |
tecs.io.mcp |
MCP server setup, world inspection, safe mutation, custom tools, and transport |
tecs.io.watcher |
Development-time polling and reload dispatch for loaded content |
Constructors
| Constructor | Description |
|---|---|
newBase64DecodeReader |
Creates a reader that incrementally decodes RFC 4648 Base64 text. |
newBase64EncodeWriter |
Creates a writer that incrementally encodes bytes as RFC 4648 Base64. |
newBuffer |
Creates an owned growable byte buffer. |
newByteReader |
Creates a reader over borrowed FFI memory. |
newByteStream |
Creates a replayable read-only stream over borrowed FFI bytes. |
newDeflateWriter |
Creates a writer that incrementally deflates bytes into a destination. |
newEmptyStream |
Creates a replayable readable empty stream. |
newFileStream |
Creates a replayable file stream. |
newHandleStream |
Creates a one-shot stream over a borrowed Lua file handle. |
newHexDecodeReader |
Creates a reader that incrementally decodes hexadecimal text. |
newHexEncodeWriter |
Creates a writer that incrementally encodes bytes as lowercase hexadecimal text. |
newInflateReader |
Creates a reader that incrementally inflates a compressed source. |
newStringReader |
Creates a reader over an immutable Lua string. |
newStringStream |
Creates a replayable read-only string stream. |
newTranscodeReader |
Creates a reader that incrementally converts character encodings. |
newTranscodeWriter |
Creates a writer that incrementally converts character encodings. |
Types
| Type | Kind | Description |
|---|---|---|
Address |
record | An Address owns one resolved network address. |
Buffer |
interface | A Buffer is owned growable FFI-backed byte storage. |
ByteView |
interface | A ByteView retains an immutable zero-copy range from a buffer. |
DeflateWriterOptions |
record | Options control an incremental deflate writer. |
InflateReaderOptions |
record | Options control an incremental inflate reader. |
ReadableStream |
interface | A ReadableStream opens readers and supplies whole-source transfers. |
Reader |
interface | A Reader supplies bytes in order and releases its owned state on close. |
ReadWriteStream |
interface | A ReadWriteStream supports both directional interfaces. |
Seekable |
interface | Seekable supplies random-access cursor operations shared by readers and writers. |
SeekableReader |
interface | A SeekableReader supplies bytes through a repositionable cursor. |
SeekableWriter |
interface | A SeekableWriter patches a destination through a repositionable cursor. |
Stream |
interface | A Stream describes binary storage without retaining a cursor. |
TCPListener |
record | A TCPListener listens for TCP clients. |
TCPSocket |
record | A TCPSocket owns one connected TCP byte stream. |
UDPPacket |
record | A UDPPacket owns one received UDP datagram and its source address. |
UDPSocket |
record | A UDPSocket sends and receives UDP packets. |
WritableStream |
interface | A WritableStream opens writers and supplies whole-destination transfers. |
Writer |
interface | A Writer accepts bytes in order and finishes its destination on close. |
Functions
| Function | Kind | Description |
|---|---|---|
bind |
Static | Binds a UDP socket. |
connect |
Static | Connects to a resolved address. |
init |
Static | Starts networking for this module. |
listen |
Static | Binds a TCP listener. |
pending |
Static | Returns the number of pending network operations and readiness watches. |
resolve |
Static | Resolves a hostname. |
shutdown |
Static | Stops this module's networking instance. |
transfer |
Static | Transfers every remaining byte between directional endpoints. |
Constructors
tecs.io.newBase64DecodeReader Static
Creates a reader that incrementally decodes RFC 4648 Base64 text.
The reader owns source and retains at most one undecoded quantum between source reads.
Arguments
| Name | Type | Description |
|---|---|---|
source |
types.Reader | FILE |
The caller supplies the reader of Base64 text. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader of decoded bytes. |
Examples
tecs.scoped(
"decode base64",
function(scope: tecs.Scope)
local reader <const> = scope:own(
tecs.io.newBase64DecodeReader(
tecs.io.newStringReader("c25hcHNob3QgYnl0ZXM=")
)
)
local decoded <const>, reason = reader:read(1024)
assert(decoded, reason)
assert(decoded == "snapshot bytes")
end
)tecs.io.newBase64EncodeWriter Static
Creates a writer that incrementally encodes bytes as RFC 4648 Base64.
The writer owns destination. close emits padding for the final partial quantum before closing the destination.
Arguments
| Name | Type | Description |
|---|---|---|
destination |
types.Writer | FILE |
The caller supplies the writer receiving Base64 text. |
Returns
| Type | Description |
|---|---|
types.Writer |
Returns a caller-owned writer that accepts unencoded bytes. |
Examples
tecs.scoped(
"encode base64",
function(scope: tecs.Scope)
local encoded <const> = scope:own(tecs.io.newBuffer())
local writer <const> = scope:own(
tecs.io.newBase64EncodeWriter(encoded:newWriter())
)
assert(writer:write("snapshot bytes"))
assert(writer:close())
assert(encoded:getString() == "c25hcHNob3QgYnl0ZXM=")
end
)tecs.io.newBuffer Static
Creates an owned growable byte buffer.
function tecs.io.newBuffer(initial: integer | string): IOBufferArguments
| Name | Type | Description |
|---|---|---|
initial |
integer | string |
The caller supplies a non-negative zero-filled logical length, a string to copy, or nil for an empty buffer. |
Returns
| Type | Description |
|---|---|
IOBuffer |
Returns a caller-owned buffer. |
Examples
local bytes <const> = tecs.io.newBuffer("save data")
print(bytes:length())
bytes:close()tecs.io.newByteReader Static
Creates a reader over borrowed FFI memory.
The reader never frees or modifies the allocation. The caller keeps its owner reachable and the bytes unchanged until the reader closes.
function tecs.io.newByteReader(
pointer: loader.CValue, length: integer
): types.ReaderArguments
| Name | Type | Description |
|---|---|---|
pointer |
loader.CValue |
The caller supplies the first readable byte. |
length |
integer |
The caller supplies the non-negative readable byte count. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader whose cursor starts at zero. |
Examples
local ffi <const> = require("ffi")
local bytes <const> = "borrowed bytes"
local pointer <const> = ffi.cast("const uint8_t *", bytes)
local reader <const> = tecs.io.newByteReader(pointer as any, #bytes)
assert(reader:read(1024) == bytes)
reader:close()tecs.io.newByteStream Static
Creates a replayable read-only stream over borrowed FFI bytes.
Closing the stream or its readers never frees the allocation.
function tecs.io.newByteStream(
pointer: loader.CValue, length: integer, contentType: string
): types.ReadableStreamArguments
| Name | Type | Description |
|---|---|---|
pointer |
loader.CValue |
The caller keeps the backing allocation alive and unchanged until every reader closes and every transfer returns. |
length |
integer |
The caller supplies the non-negative byte count. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
types.ReadableStream |
Returns a readable stream. |
Examples
local ffi <const> = require("ffi")
local bytes <const> = "borrowed bytes"
local pointer <const> = ffi.cast("const uint8_t *", bytes)
local source <const> = tecs.io.newByteStream(pointer as any, #bytes)
print(source:readAll())
source:close()tecs.io.newDeflateWriter Static
Creates a writer that incrementally deflates bytes into a destination.
The writer owns destination. flush emits a synchronization point without ending the compressed stream, and close emits its trailer before closing the destination.
function tecs.io.newDeflateWriter(
destination: types.Writer | FILE,
options: types.DeflateWriterOptions
): types.WriterArguments
| Name | Type | Description |
|---|---|---|
destination |
types.Writer | FILE |
The caller supplies the writer receiving compressed bytes. |
options |
types.DeflateWriterOptions |
The caller selects raw framing and a compression level or omits it for zlib framing and zlib's default level. |
Returns
| Type | Description |
|---|---|
types.Writer |
Returns a caller-owned writer that accepts uncompressed bytes. |
Examples
tecs.scoped(
"deflate save",
function(scope: tecs.Scope)
local compressed <const> = scope:own(tecs.io.newBuffer())
local writer <const> = scope:own(
tecs.io.newDeflateWriter(compressed:newWriter())
)
assert(writer:write("snapshot "))
assert(writer:write("bytes"))
assert(writer:close())
assert(compressed:length() > 0)
end
)tecs.io.newEmptyStream Static
Creates a replayable readable empty stream.
function tecs.io.newEmptyStream(
contentType: string
): types.ReadableStreamArguments
| Name | Type | Description |
|---|---|---|
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
types.ReadableStream |
Returns a source whose length is zero. |
Examples
local source <const> = tecs.io.newEmptyStream(
"application/octet-stream"
)
print(source:readAll())
source:close()tecs.io.newFileStream Static
Creates a replayable file stream.
Readers open the current path through tecs.io.files; writers replace it. A descriptor keeps no open file between endpoints. HTTP uploads on the SDL storage backend reopen the path directly on the native HTTP lane and stream it without retaining the complete file in Lua.
function tecs.io.newFileStream(
path: string | Path, contentType: string
): types.ReadWriteStreamArguments
| Name | Type | Description |
|---|---|---|
path |
string | Path |
The caller supplies the source or destination as a string or Path. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
types.ReadWriteStream |
Returns a readable and writable stream. |
Examples
local path <const> = tecs.io.Path.new("save.bin")
local save <const> = tecs.io.newFileStream(
path, "application/octet-stream"
)
assert(save:writeAll("save data"))
print(save:readAll())
save:close()tecs.io.newHandleStream Static
Creates a one-shot stream over a borrowed Lua file handle.
The first reader or writer claims its current cursor. Closing the stream or endpoint does not close the caller's handle.
function tecs.io.newHandleStream(
handle: FILE, length: integer, contentType: string
): types.ReadWriteStreamArguments
| Name | Type | Description |
|---|---|---|
handle |
FILE |
The caller keeps the Lua file handle open through the endpoint's close. |
length |
integer |
The caller supplies the remaining byte count when known. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
types.ReadWriteStream |
Returns a non-replayable readable and writable stream. |
Examples
local handle <const> = assert(io.open("save.bin", "rb"))
local source <const> = tecs.io.newHandleStream(handle)
print(source:readAll())
source:close()
handle:close()tecs.io.newHexDecodeReader Static
Creates a reader that incrementally decodes hexadecimal text.
The reader owns source and carries one unmatched nibble across source reads.
Arguments
| Name | Type | Description |
|---|---|---|
source |
types.Reader | FILE |
The caller supplies the reader of hexadecimal text. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader of decoded bytes. |
Examples
tecs.scoped(
"decode hexadecimal",
function(scope: tecs.Scope)
local reader <const> = scope:own(
tecs.io.newHexDecodeReader(
tecs.io.newStringReader("73617665")
)
)
local decoded <const>, reason = reader:read(1024)
assert(decoded, reason)
assert(decoded == "save")
end
)tecs.io.newHexEncodeWriter Static
Creates a writer that incrementally encodes bytes as lowercase hexadecimal text.
The writer owns destination and forwards each encoded chunk without retaining input bytes.
Arguments
| Name | Type | Description |
|---|---|---|
destination |
types.Writer | FILE |
The caller supplies the writer receiving hexadecimal text. |
Returns
| Type | Description |
|---|---|
types.Writer |
Returns a caller-owned writer that accepts unencoded bytes. |
Examples
tecs.scoped(
"encode hexadecimal",
function(scope: tecs.Scope)
local encoded <const> = scope:own(tecs.io.newBuffer())
local writer <const> = scope:own(
tecs.io.newHexEncodeWriter(encoded:newWriter())
)
assert(writer:write("save"))
assert(writer:close())
assert(encoded:getString() == "73617665")
end
)tecs.io.newInflateReader Static
Creates a reader that incrementally inflates a compressed source.
The reader owns source and closes it when the wrapper closes. Reads retain only bounded compressed and decompressed chunks. A raw stream has no zlib header, trailer, or checksum.
function tecs.io.newInflateReader(
source: types.Reader | FILE, options: types.InflateReaderOptions
): types.ReaderArguments
| Name | Type | Description |
|---|---|---|
source |
types.Reader | FILE |
The caller supplies the reader of compressed bytes. |
options |
types.InflateReaderOptions |
The caller selects raw framing and an output ceiling or omits it for a zlib stream and the default ceiling. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader of decompressed bytes. |
Examples
tecs.scoped(
"inflate save",
function(scope: tecs.Scope)
local compressed <const> = scope:own(tecs.io.newBuffer())
local restored <const> = scope:own(tecs.io.newBuffer())
local compressor <const> = scope:own(
tecs.io.newDeflateWriter(compressed:newWriter())
)
assert(compressor:write("snapshot bytes"))
assert(compressor:close())
local reader <const> = scope:own(
tecs.io.newInflateReader(compressed:newReader())
)
local sink <const> = scope:own(restored:newWriter())
local count <const>, reason = tecs.io.transfer(reader, sink)
assert(count, reason)
assert(restored:getString() == "snapshot bytes")
end
)tecs.io.newStringReader Static
Creates a reader over an immutable Lua string.
The reader retains bytes without copying it. Closing the reader drops that retained reference; there is no separate resource to close.
function tecs.io.newStringReader(bytes: string): types.ReaderArguments
| Name | Type | Description |
|---|---|---|
bytes |
string |
The caller supplies complete binary contents. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader whose cursor starts at zero. |
Examples
local reader <const> = tecs.io.newStringReader("snapshot bytes")
assert(reader:read(1024) == "snapshot bytes")
reader:close()tecs.io.newStringStream Static
Creates a replayable read-only string stream.
The stream retains the immutable string without copying it.
function tecs.io.newStringStream(
bytes: string, contentType: string
): types.ReadableStreamArguments
| Name | Type | Description |
|---|---|---|
bytes |
string |
The caller supplies complete binary contents. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
types.ReadableStream |
Returns a readable stream. |
Examples
local source <const> = tecs.io.newStringStream("hello", "text/plain")
print(source:readAll())
source:close()tecs.io.newTranscodeReader Static
Creates a reader that incrementally converts character encodings.
The reader owns source. It preserves conversion state and carries an incomplete multibyte character across source reads.
function tecs.io.newTranscodeReader(
source: types.Reader | FILE,
fromEncoding: string,
toEncoding: string
): types.ReaderArguments
| Name | Type | Description |
|---|---|---|
source |
types.Reader | FILE |
The caller supplies the reader of encoded text. |
fromEncoding |
string |
The caller supplies an SDL iconv source encoding name such as UTF-8. |
toEncoding |
string |
The caller supplies an SDL iconv destination encoding name such as UTF-16LE. |
Returns
| Type | Description |
|---|---|
types.Reader |
Returns a caller-owned reader of converted text. |
Examples
tecs.scoped(
"transcode input",
function(scope: tecs.Scope)
local reader <const> = scope:own(
tecs.io.newTranscodeReader(
tecs.io.newStringReader("A\0\233\0"),
"UTF-16LE",
"UTF-8"
)
)
local utf8 <const>, reason = reader:read(1024)
assert(utf8, reason)
assert(utf8 == "A\195\169")
end
)tecs.io.newTranscodeWriter Static
Creates a writer that incrementally converts character encodings.
The writer owns destination. It preserves conversion state and carries an incomplete multibyte character across writes; close rejects a truncated final character and emits any target shift state.
function tecs.io.newTranscodeWriter(
destination: types.Writer | FILE,
fromEncoding: string,
toEncoding: string
): types.WriterArguments
| Name | Type | Description |
|---|---|---|
destination |
types.Writer | FILE |
The caller supplies the writer receiving converted text. |
fromEncoding |
string |
The caller supplies an SDL iconv source encoding name such as UTF-8. |
toEncoding |
string |
The caller supplies an SDL iconv destination encoding name such as UTF-16LE. |
Returns
| Type | Description |
|---|---|
types.Writer |
Returns a caller-owned writer that accepts bytes in fromEncoding. |
Examples
tecs.scoped(
"transcode output",
function(scope: tecs.Scope)
local utf16 <const> = scope:own(tecs.io.newBuffer())
local writer <const> = scope:own(
tecs.io.newTranscodeWriter(
utf16:newWriter(), "UTF-8", "UTF-16LE"
)
)
assert(writer:write("A\195"))
assert(writer:write("\169"))
assert(writer:close())
assert(utf16:getString() == "A\0\233\0")
end
)Types
tecs.io.Address record
An Address owns one resolved network address. Closing it releases the address and remains safe to repeat.
record tecs.io.Address is Closeable
host: string
text: string
close: function(self): boolean, string
isClosed: function(self): boolean
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Address.host field
Read-only. Networking sets host at resolution or peer lookup. It contains the requested hostname or numeric peer address.
tecs.io.Address.text field
Read-only. Networking sets text to the printable numeric address when it creates the object.
tecs.io.Address:close Instance
function tecs.io.Address.close(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Address |
Returns
| Type | Description |
|---|---|
boolean |
|
string |
tecs.io.Address:isClosed Instance
Returns whether close has released this address.
function tecs.io.Address.isClosed(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Address |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
tecs.io.Buffer interface
A Buffer is owned growable FFI-backed byte storage.
interface tecs.io.Buffer is Closeable
interface WriteRange is Closeable
capacity: function(self): integer
commit: function(self, used: integer)
getFFIPointer: function(self): loader.BytePointer
end
capacity: function(self): integer
clear: function(self)
ensureCapacity: function(self, minimum: integer)
getFFIPointer: function(self): loader.BytePointer
getString: function(self, offset: integer, count: integer): string
isReleased: function(self): boolean
length: function(self): integer
newReader: function(self): Reader
newStream: function(self, contentType: string): ReadWriteStream
newWriter: function(self): Writer
reserveRange: function(
self, offset: integer, minimum: integer
): WriteRange
resize: function(self, length: integer)
setString: function(self, bytes: string, offset: integer)
view: function(self, offset: integer, count: integer): ByteView
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Buffer.WriteRange interface
An exclusive, zero-copy writable range reserved from a Buffer. Closing abandons the range without changing the buffer's logical length.
interface tecs.io.Buffer.WriteRange is Closeable
capacity: function(self): integer
commit: function(self, used: integer)
getFFIPointer: function(self): loader.BytePointer
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Buffer.WriteRange:capacity Instance
Returns the maximum byte count the native writer may fill.
function tecs.io.Buffer.WriteRange.capacity(self): integerArguments
| Name | Type | Description |
|---|---|---|
self |
WriteRange |
The open range to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the reserved byte capacity. |
tecs.io.Buffer.WriteRange:commit Instance
Commits bytes written through the borrowed pointer.
The call closes the range. A gap before the committed bytes is zero-filled.
function tecs.io.Buffer.WriteRange.commit(self, used: integer)Arguments
| Name | Type | Description |
|---|---|---|
self |
WriteRange |
The open range to commit. |
used |
integer |
The caller supplies the written count up to capacity. |
Returns
None.
tecs.io.Buffer.WriteRange:getFFIPointer Instance
Borrows the reserved range's writable address.
function tecs.io.Buffer.WriteRange.getFFIPointer(
self
): loader.BytePointerArguments
| Name | Type | Description |
|---|---|---|
self |
WriteRange |
The open range whose storage to borrow. |
Returns
| Type | Description |
|---|---|
loader.BytePointer |
Returns a pointer valid until commit or close. |
tecs.io.Buffer:capacity Instance
Returns the allocated byte capacity.
function tecs.io.Buffer.capacity(self): integerArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the byte count available without reallocating. |
Examples
local bytes <const> = tecs.io.newBuffer("data")
assert(bytes:capacity() >= bytes:length())
bytes:close()tecs.io.Buffer:clear Instance
Removes every logical byte without releasing the allocation.
function tecs.io.Buffer.clear(self)Arguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to clear. |
Returns
None.
Examples
local bytes <const> = tecs.io.newBuffer("reusable")
local capacity <const> = bytes:capacity()
bytes:clear()
assert(bytes:length() == 0)
assert(bytes:capacity() == capacity)
bytes:close()tecs.io.Buffer:ensureCapacity Instance
Ensures at least minimum bytes fit without another allocation.
Growth is geometric. A call at or below the current capacity leaves pointers returned by getFFIPointer valid.
function tecs.io.Buffer.ensureCapacity(self, minimum: integer)Arguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to grow. |
minimum |
integer |
The caller supplies a non-negative byte count. |
Returns
None.
Examples
local bytes <const> = tecs.io.newBuffer("data")
bytes:ensureCapacity(1024)
assert(bytes:capacity() >= 1024)
assert(bytes:length() == 4)
bytes:close()tecs.io.Buffer:getFFIPointer Instance
Borrows the address of the first byte.
The pointer is invalid after capacity grows or close runs. The buffer must remain reachable for the whole native call that uses it.
function tecs.io.Buffer.getFFIPointer(self): loader.BytePointerArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer whose storage to borrow. |
Returns
| Type | Description |
|---|---|
loader.BytePointer |
Returns a mutable FFI byte pointer. |
Examples
local bytes <const> = tecs.io.newBuffer("native bytes")
local pointer <const> = bytes:getFFIPointer()
print(pointer)
bytes:close()tecs.io.Buffer:getString Instance
Copies a range into a Lua string.
function tecs.io.Buffer.getString(
self, offset: integer, count: integer
): stringArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The source buffer. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
string |
Returns a fresh binary string. |
Examples
local bytes <const> = tecs.io.newBuffer("headerpayload")
print(bytes:getString(6, 7))
bytes:close()tecs.io.Buffer:isReleased Instance
Returns whether close has given up the allocation.
function tecs.io.Buffer.isReleased(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to inspect. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
Examples
local bytes <const> = tecs.io.newBuffer()
assert(not bytes:isReleased())
bytes:close()
assert(bytes:isReleased())tecs.io.Buffer:length Instance
Returns the number of logical bytes.
function tecs.io.Buffer.length(self): integerArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes visible to getString. |
Examples
local bytes <const> = tecs.io.newBuffer("four")
print(bytes:length())
bytes:close()tecs.io.Buffer:newReader Instance
Opens a reader over an immutable snapshot of the current bytes.
The reader retains the allocation independently, so the caller may close or mutate the buffer after this call. Its cursor starts at zero.
function tecs.io.Buffer.newReader(self): ReaderArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The open source buffer. |
Returns
| Type | Description |
|---|---|
Reader |
Returns a caller-owned reader. |
Examples
local bytes <const> = tecs.io.newBuffer("snapshot")
local reader <const> = bytes:newReader()
bytes:close()
assert(reader:read(1024) == "snapshot")
reader:close()tecs.io.Buffer:newStream Instance
Creates a stream sharing this buffer.
The stream borrows this buffer. The caller keeps it open while using the stream and closes it separately. Closing the stream never closes the buffer. transferToBuffer returns this same borrowed object without transferring ownership.
function tecs.io.Buffer.newStream(
self, contentType: string
): ReadWriteStreamArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The open buffer the stream borrows. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
ReadWriteStream |
Returns a caller-owned readable and writable stream. |
Examples
local bytes <const> = tecs.io.newBuffer("old")
local stream <const> = bytes:newStream()
assert(stream:writeAll("new"))
print(bytes:getString())
stream:close()
bytes:close()tecs.io.Buffer:newWriter Instance
Opens a writer that replaces the current bytes.
The call clears the logical length while retaining capacity. The caller keeps the buffer open until the writer closes.
function tecs.io.Buffer.newWriter(self): WriterArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The open destination buffer. |
Returns
| Type | Description |
|---|---|
Writer |
Returns a caller-owned writer. |
Examples
local bytes <const> = tecs.io.newBuffer("old")
local writer <const> = bytes:newWriter()
assert(writer:write("new"))
assert(writer:close())
assert(bytes:getString() == "new")
bytes:close()tecs.io.Buffer:reserveRange Instance
Reserves an exclusive range for a native writer without an intermediate string.
The buffer detaches from retained views before exposing mutable storage.
function tecs.io.Buffer.reserveRange(
self, offset: integer, minimum: integer
): WriteRangeArguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The open buffer to reserve. |
offset |
integer |
The caller supplies a zero-based write offset. |
minimum |
integer |
The caller supplies the minimum writable capacity. |
Returns
| Type | Description |
|---|---|
WriteRange |
Returns a caller-owned exclusive range. |
tecs.io.Buffer:resize Instance
Changes the logical length.
Expansion fills every newly visible byte with zero. Shrinking keeps the allocation for reuse.
function tecs.io.Buffer.resize(self, length: integer)Arguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The buffer to resize. |
length |
integer |
The caller supplies a non-negative byte count. |
Returns
None.
Examples
local bytes <const> = tecs.io.newBuffer("data")
bytes:resize(6)
assert(bytes:getString() == "data\0\0")
bytes:resize(2)
assert(bytes:getString() == "da")
bytes:close()tecs.io.Buffer:setString Instance
Copies a Lua string into the buffer.
The write extends the logical length as needed. A gap between the old end and offset is zero-filled.
function tecs.io.Buffer.setString(self, bytes: string, offset: integer)Arguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The destination buffer. |
bytes |
string |
The caller supplies a binary string. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
Returns
None.
Examples
local bytes <const> = tecs.io.newBuffer("abcdefgh")
bytes:setString("XY", 3)
assert(bytes:getString() == "abcXYfgh")
bytes:setString("!", 10)
assert(bytes:getString(8, 3) == "\0\0!")
bytes:close()tecs.io.Buffer:view Instance
Returns a zero-copy immutable snapshot of a byte range.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Buffer |
The open buffer to retain. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
ByteView |
Returns a caller-owned retained view. |
tecs.io.ByteView interface
A ByteView retains an immutable zero-copy range from a buffer.
interface tecs.io.ByteView is Closeable
getFFIPointer: function(self): loader.BytePointer
getString: function(self): string
isReleased: function(self): boolean
length: function(self): integer
newReader: function(self): Reader
newStream: function(self, contentType: string): ReadableStream
view: function(self, offset: integer, count: integer): ByteView
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.ByteView:getFFIPointer Instance
Borrows the retained range's read-only address.
LuaJIT FFI cannot enforce constness. Writing through a cast pointer is unsafe and breaks the snapshot guarantee.
function tecs.io.ByteView.getFFIPointer(self): loader.BytePointerArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open view whose storage to borrow. |
Returns
| Type | Description |
|---|---|
loader.BytePointer |
Returns a pointer valid until close. |
tecs.io.ByteView:getString Instance
Copies the retained range into a Lua string.
function tecs.io.ByteView.getString(self): stringArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open view to copy. |
Returns
| Type | Description |
|---|---|
string |
Returns a fresh binary string. |
tecs.io.ByteView:isReleased Instance
Returns whether the view has released its retained allocation.
function tecs.io.ByteView.isReleased(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The view to inspect. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
tecs.io.ByteView:length Instance
Returns the retained range's byte length.
function tecs.io.ByteView.length(self): integerArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open view to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the number of readable bytes. |
tecs.io.ByteView:newReader Instance
Opens a reader over this immutable range.
The reader retains the allocation independently, so the caller may close this view immediately after the call. Its cursor starts at zero.
function tecs.io.ByteView.newReader(self): ReaderArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open source view. |
Returns
| Type | Description |
|---|---|
Reader |
Returns a caller-owned reader. |
Examples
local bytes <const> = tecs.io.newBuffer("headerpayload")
local payload <const> = bytes:view(6)
local reader <const> = payload:newReader()
payload:close()
bytes:close()
assert(reader:read(1024) == "payload")
reader:close()tecs.io.ByteView:newStream Instance
Creates a replayable read-only stream retaining this view.
The stream retains its own view, so the caller may close this view immediately after construction. Closing the stream closes its retained view after already-open readers close theirs.
function tecs.io.ByteView.newStream(
self, contentType: string
): ReadableStreamArguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open immutable byte view. |
contentType |
string |
The caller supplies optional media type metadata. |
Returns
| Type | Description |
|---|---|
ReadableStream |
Returns a caller-owned readable stream. |
Examples
local bytes <const> = tecs.io.newBuffer("headerpayload")
local payload <const> = bytes:view(6)
local source <const> = payload:newStream("application/octet-stream")
payload:close()
bytes:close()
assert(source:readAll() == "payload")
source:close()tecs.io.ByteView:view Instance
Retains a zero-copy subrange.
Arguments
| Name | Type | Description |
|---|---|---|
self |
ByteView |
The open source view. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
ByteView |
Returns a caller-owned view retaining the same allocation. |
tecs.io.DeflateWriterOptions record
Options control an incremental deflate writer.
tecs.io.DeflateWriterOptions.raw field
Caller-writable. Selects raw DEFLATE when true and zlib framing when false or omitted.
tecs.io.DeflateWriterOptions.raw: booleantecs.io.DeflateWriterOptions.level field
Caller-writable. Sets zlib's compression level from minus one through nine or uses its default when omitted.
tecs.io.DeflateWriterOptions.level: integertecs.io.InflateReaderOptions record
Options control an incremental inflate reader.
tecs.io.InflateReaderOptions.raw field
Caller-writable. Selects raw DEFLATE when true and zlib framing when false or omitted.
tecs.io.InflateReaderOptions.raw: booleantecs.io.InflateReaderOptions.maxBytes field
Caller-writable. Sets the hard decompressed-byte ceiling or uses 268,435,456 bytes when omitted.
tecs.io.InflateReaderOptions.maxBytes: integertecs.io.ReadableStream interface
A ReadableStream opens readers and supplies whole-source transfers.
interface tecs.io.ReadableStream is Stream, Closeable
discard: function(self): integer, string
newReader: function(self): Reader, string
readAll: function(self, maxBytes: integer): string, string
transferTo: function(
self, destination: WritableStream
): integer, string
transferToBuffer: function(self, maxBytes: integer): Buffer, string
transferToFile: function(self, path: string): integer, string
endInterfaces
| Interface |
|---|
Stream |
Closeable |
tecs.io.ReadableStream:discard Instance
Reads and discards every source byte.
The operation opens, consumes, and closes one reader. On a non-replayable stream, this claims its one endpoint.
function tecs.io.ReadableStream.discard(self): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes discarded. |
string |
Returns the source's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newFileStream("download.tmp")
local count <const> = source:discard()
print(count)
source:close()tecs.io.ReadableStream:newReader Instance
Opens a reader with a new cursor.
function tecs.io.ReadableStream.newReader(self): Reader, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
Returns
| Type | Description |
|---|---|
Reader |
Returns a caller-owned reader, or nil when unavailable. |
string |
Returns the reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("data")
local reader <const> = assert(source:newReader())
print(reader:read(4))
reader:close()
source:close()tecs.io.ReadableStream:readAll Instance
Reads the complete source into a Lua string.
The operation opens, consumes, and closes one reader. On a non-replayable stream, this claims its one endpoint.
function tecs.io.ReadableStream.readAll(
self, maxBytes: integer
): string, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
maxBytes |
integer |
The caller supplies a non-negative limit or omits it for no explicit limit. |
Returns
| Type | Description |
|---|---|
string |
Returns the complete bytes. |
string |
Returns the source's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("data")
local bytes <const> = source:readAll(1024)
print(bytes)
source:close()tecs.io.ReadableStream:transferTo Instance
Copies every source byte into destination.
The operation opens and closes one source reader and one destination writer. Either non-replayable descriptor is claimed by the call.
function tecs.io.ReadableStream.transferTo(
self, destination: WritableStream
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
destination |
WritableStream |
The caller supplies an available writable stream. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes written. |
string |
Returns the source or destination reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("data")
local output <const> = tecs.io.newBuffer()
local destination <const> = output:newStream()
local count <const> = source:transferTo(destination)
print(count, output:getString())
source:close()
destination:close()
output:close()tecs.io.ReadableStream:transferToBuffer Instance
Transfers the complete source into an owned buffer.
A stream created by Buffer:newStream returns that same borrowed buffer without copying and does not transfer ownership. Other streams return a newly allocated buffer owned by the caller. The operation opens, consumes, and closes one reader when it must copy. On a non-replayable stream, this claims its one endpoint.
function tecs.io.ReadableStream.transferToBuffer(
self, maxBytes: integer
): Buffer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
maxBytes |
integer |
The caller supplies a non-negative limit or omits it for no explicit limit. |
Returns
| Type | Description |
|---|---|
Buffer |
Returns a caller-owned buffer. |
string |
Returns the source's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newFileStream("save.bin")
local bytes <const> = source:transferToBuffer(1024 * 1024)
print(bytes:length())
bytes:close()
source:close()tecs.io.ReadableStream:transferToFile Instance
Copies every source byte into a file.
The operation opens and closes one source reader. On a non-replayable stream, this claims its one endpoint.
function tecs.io.ReadableStream.transferToFile(
self, path: string
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
ReadableStream |
The readable descriptor. |
path |
string |
The caller supplies the destination path to replace. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes written. |
string |
Returns the source or file reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("save data")
local count <const> = source:transferToFile("save.bin")
print(count)
source:close()tecs.io.Reader interface
A Reader supplies bytes in order and releases its owned state on close.
interface tecs.io.Reader is Closeable
read: function(self, count: integer): string, string
readInto: function(
self, destination: Buffer, offset: integer, count: integer
): integer, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Reader:read Instance
Caller-writable. Supplies the operation that reads the next bytes.
function tecs.io.Reader.read(self, count: integer): string, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Reader |
The reader whose cursor advances. |
count |
integer |
The maximum number of bytes to return when positive. Zero and negative counts are treated as one so the reader makes progress. |
Returns
| Type | Description |
|---|---|
string |
Returns up to max(1, count) bytes, fewer at the end, or an empty string after the source is exhausted. |
string |
Returns the source's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("abcdefgh")
local reader <const> = assert(source:newReader())
local chunk <const>, reason = reader:read(4)
assert(chunk, reason)
print(chunk)
reader:close()
source:close()tecs.io.Reader:readInto Instance
Reads bytes directly into a buffer and advances the cursor.
The operation grows the destination as needed and preserves bytes outside the written range. It returns zero after the source is exhausted.
function tecs.io.Reader.readInto(
self, destination: Buffer, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Reader |
The open reader whose cursor advances. |
destination |
Buffer |
The caller supplies an open destination buffer and keeps ownership of it. |
offset |
integer |
The caller supplies a non-negative zero-based destination offset or omits it for zero. |
count |
integer |
The caller supplies the maximum non-negative byte count or omits it for 16,384. |
Returns
| Type | Description |
|---|---|
integer |
Returns the number of bytes written into the destination. |
string |
Returns the source's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newStringStream("abcdefgh")
local reader <const> = assert(source:newReader())
local bytes <const> = tecs.io.newBuffer("prefix:")
local count <const>, reason = reader:readInto(bytes, bytes:length(), 4)
assert(count, reason)
print(bytes:getString())
reader:close()
source:close()
bytes:close()tecs.io.ReadWriteStream interface
A ReadWriteStream supports both directional interfaces.
interface tecs.io.ReadWriteStream is ReadableStream, Stream, Closeable, WritableStream
endInterfaces
| Interface |
|---|
ReadableStream |
Stream |
Closeable |
WritableStream |
tecs.io.Seekable interface
Seekable supplies random-access cursor operations shared by readers and writers.
interface tecs.io.Seekable
enum Origin
"current"
"end"
"start"
end
seek: function(
self, origin: Origin, offset: integer
): integer, string
size: function(self): integer, string
tell: function(self): integer, string
endtecs.io.Seekable.Origin enum
Origin selects the reference point for a seek.
enum tecs.io.Seekable.Origin
"current"
"end"
"start"
endtecs.io.Seekable:seek Instance
Repositions the cursor and returns its new absolute position.
"start" measures offset from byte zero, "current" measures it from the cursor, and "end" measures it from the current byte length. The offset defaults to zero and may be negative for the latter two origins. A result before byte zero or past the current end fails without moving the cursor.
Arguments
| Name | Type | Description |
|---|---|---|
self |
Seekable |
The open cursor to reposition. |
origin |
Origin |
The caller selects the reference point. |
offset |
integer |
The caller supplies a signed integer byte offset or omits it for zero. |
Returns
| Type | Description |
|---|---|
integer |
Returns the new zero-based cursor position. |
string |
Returns the storage reason when the first return is nil. |
tecs.io.Seekable:size Instance
Returns the storage's current byte length.
The result includes every write already accepted even when buffered bytes have not reached the underlying destination yet.
function tecs.io.Seekable.size(self): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Seekable |
The open cursor to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the current byte length. |
string |
Returns the storage reason when the first return is nil. |
tecs.io.Seekable:tell Instance
Returns the current zero-based cursor position.
function tecs.io.Seekable.tell(self): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Seekable |
The open cursor to inspect. |
Returns
| Type | Description |
|---|---|
integer |
Returns the cursor's byte position. |
string |
Returns the storage reason when the first return is nil. |
tecs.io.SeekableReader interface
A SeekableReader supplies bytes through a repositionable cursor.
Interfaces
| Interface |
|---|
Reader |
Closeable |
Seekable |
tecs.io.SeekableWriter interface
A SeekableWriter patches a destination through a repositionable cursor.
Interfaces
| Interface |
|---|
Writer |
Closeable |
Seekable |
tecs.io.Stream interface
A Stream describes binary storage without retaining a cursor.
interface tecs.io.Stream is Closeable
contentLength: function(self): integer | nil
contentType: function(self): string | nil
isReadable: function(self): boolean
isReplayable: function(self): boolean
isWritable: function(self): boolean
withMetadata: function<T is Stream>(
self,
contentType: string,
contentLength: integer,
isReplayable: boolean
): T
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Stream:contentLength Instance
Returns the byte length when it is known.
function tecs.io.Stream.contentLength(self): integer | nilArguments
| Name | Type | Description |
|---|---|---|
self |
Stream |
The descriptor to inspect. |
Returns
| Type | Description |
|---|---|
integer | nil |
Returns the current byte length, or nil when it cannot be known before reading. |
Examples
local source <const> = tecs.io.newStringStream("four")
local length <const> = source:contentLength()
if length ~= nil then
print(length)
end
source:close()tecs.io.Stream:contentType Instance
Returns the media type supplied at construction.
function tecs.io.Stream.contentType(self): string | nilArguments
| Name | Type | Description |
|---|---|---|
self |
Stream |
The descriptor to inspect. |
Returns
| Type | Description |
|---|---|
string | nil |
Returns the media type, or nil when none was supplied. |
Examples
local source <const> = tecs.io.newStringStream("{}", "application/json")
print(source:contentType())
source:close()tecs.io.Stream:isReadable Instance
Returns whether the descriptor can open a reader.
function tecs.io.Stream.isReadable(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Stream |
The descriptor to inspect. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when newReader is supported. |
Examples
local source <const> = tecs.io.newStringStream("data")
print(source:isReadable())
source:close()tecs.io.Stream:isReplayable Instance
Returns whether each reader starts from the beginning.
True means the descriptor can open independent readers repeatedly. False means opening an endpoint or running a whole-source operation may claim the descriptor permanently; newReader reports when it can no longer open one.
function tecs.io.Stream.isReplayable(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Stream |
The descriptor to inspect. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when opening a later reader replays all bytes. |
Examples
local source <const> = tecs.io.newStringStream("data")
print(source:isReplayable())
source:close()tecs.io.Stream:isWritable Instance
Returns whether the descriptor can open a writer.
function tecs.io.Stream.isWritable(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
Stream |
The descriptor to inspect. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when newWriter is supported. |
Examples
local save <const> = tecs.io.newFileStream("save.bin")
print(save:isWritable())
save:close()tecs.io.Stream:withMetadata Instance
Creates a lazy view that overrides this descriptor's metadata.
Nil inherits each value from the receiver. The view retains and delegates to the receiver, preserves its static and runtime directional interface, and closes the receiver when it closes. If every supplied value already matches, this returns the receiver.
function tecs.io.Stream.withMetadata<T is Stream>(
self,
contentType: string,
contentLength: integer,
isReplayable: boolean
): TType Parameters
| Name | Constraint | Description |
|---|---|---|
T |
Stream |
Arguments
| Name | Type | Description |
|---|---|---|
self |
T |
The stream whose storage and operations the view retains. |
contentType |
string |
The caller overrides the media type or omits it. |
contentLength |
integer |
The caller overrides the non-negative byte length or omits it. |
isReplayable |
boolean |
The caller overrides replayability or omits it. |
Returns
| Type | Description |
|---|---|
T |
Returns a metadata view with the receiver's stream type. |
Examples
local source <const> = tecs.io.newStringStream("{}")
local json <const> = source:withMetadata("application/json")
print(json:contentType())
json:close()tecs.io.TCPListener record
A TCPListener listens for TCP clients. Closing it stops listening, leaves accepted streams open, and remains safe to repeat. The listener permits one suspended accept or wait call at a time.
record tecs.io.TCPListener is Closeable
port: integer
accept: function(self): TCPSocket, string
close: function(self): boolean, string
isClosed: function(self): boolean
wait: function(self, timeoutMs: integer): boolean, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.TCPListener.port field
Read-only. Networking sets port from the value passed to listen and never changes it. Zero remains zero.
tecs.io.TCPListener.port: integertecs.io.TCPListener:accept Instance
Takes one client, waiting cooperatively inside a system.
Inside a system, the call suspends until a client is ready. Outside a system it blocks the caller. The caller owns the returned stream.
function tecs.io.TCPListener.accept(self): TCPSocket, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPListener |
Returns
| Type | Description |
|---|---|
TCPSocket |
Returns one caller-owned client, or nil when none waits or acceptance fails. |
string |
Returns the reason only when acceptance fails. |
tecs.io.TCPListener:close Instance
function tecs.io.TCPListener.close(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPListener |
Returns
| Type | Description |
|---|---|
boolean |
|
string |
tecs.io.TCPListener:isClosed Instance
Returns whether close has released this listener.
function tecs.io.TCPListener.isClosed(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
TCPListener |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
tecs.io.TCPListener:wait Instance
Waits up to timeoutMs for a client to become ready to accept.
Returns false without an error on timeout. This does not accept the client; call accept afterwards.
function tecs.io.TCPListener.wait(
self, timeoutMs: integer
): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPListener |
|
timeoutMs |
integer |
The caller supplies 0 to 2147483647 milliseconds or omits it for zero. Zero polls without blocking. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when at least one client waits. |
string |
Returns the reason on failure. Timeout returns false without a reason. |
tecs.io.TCPSocket record
A TCPSocket owns one connected TCP byte stream. Closing it may discard queued writes, so a caller drains delivery-sensitive output first. Repeated closure remains safe. One owner serializes operations because the socket permits one suspended readiness wait.
record tecs.io.TCPSocket is Closeable
close: function(self): boolean, string
drain: function(self, timeoutMs: integer): boolean, string
isClosed: function(self): boolean
peer: function(self): Address, string
pendingWrites: function(self): integer, string
read: function(self, maxBytes: integer): string, string
readInto: function(
self, destination: IOBuffer, offset: integer, maxBytes: integer
): integer, string
wait: function(self, timeoutMs: integer): boolean, string
write: function(self, bytes: string): boolean, string
writeFrom: function(
self, source: IOBuffer, offset: integer, count: integer
): integer, string
writeView: function(
self, source: types.ByteView, offset: integer, count: integer
): integer, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.TCPSocket:close Instance
function tecs.io.TCPSocket.close(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
Returns
| Type | Description |
|---|---|
boolean |
|
string |
tecs.io.TCPSocket:drain Instance
Waits up to timeoutMs for queued writes to be sent.
Returns false without an error on timeout.
function tecs.io.TCPSocket.drain(
self, timeoutMs: integer
): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
timeoutMs |
integer |
The caller supplies 0 to 2147483647 milliseconds or omits it for 5000. Zero polls without blocking. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when the local send queue reaches zero before timeout. |
string |
Returns the reason on failure. Timeout returns false without a reason. |
tecs.io.TCPSocket:isClosed Instance
Returns whether close has released this connection.
function tecs.io.TCPSocket.isClosed(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
tecs.io.TCPSocket:peer Instance
Returns a newly owned address for the remote peer.
The caller closes the returned address.
Arguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
Returns
| Type | Description |
|---|---|
Address |
Returns a caller-owned address that outlives the connection, or nil on failure. |
string |
Returns the reason when the first return is nil. |
tecs.io.TCPSocket:pendingWrites Instance
Returns bytes accepted but not yet sent.
function tecs.io.TCPSocket.pendingWrites(self): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
Returns
| Type | Description |
|---|---|
integer |
Returns the queued byte count, zero after sending, or nil on failure. |
string |
Returns the reason when the first return is nil. |
tecs.io.TCPSocket:read Instance
Reads up to maxBytes, waiting cooperatively inside a system.
Inside a system, the call suspends when the socket would block and resumes when it becomes readable. Outside a system the same call blocks its caller. A successful read may contain fewer bytes than requested.
function tecs.io.TCPSocket.read(
self, maxBytes: integer
): string, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
maxBytes |
integer |
The caller supplies a ceiling from 1 to 65536 bytes or omits it for 16384. Invalid values raise. |
Returns
| Type | Description |
|---|---|
string |
Returns a fresh string of available bytes, or nil when no bytes arrived or the read failed. |
string |
Returns the reason only when reading fails or the peer disconnects. |
tecs.io.TCPSocket:readInto Instance
Reads bytes directly into reusable FFI memory.
The call writes at a zero-based offset and extends the buffer through the last byte read. It suspends a system or blocks an ordinary caller when no bytes are ready. Reserving the requested range may still grow capacity. A zero count returns zero without consuming input.
function tecs.io.TCPSocket.readInto(
self, destination: IOBuffer, offset: integer, maxBytes: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
destination |
IOBuffer |
The caller supplies an open Buffer. |
offset |
integer |
The caller supplies a zero-based destination offset or omits it for zero. |
maxBytes |
integer |
The caller supplies a ceiling from 0 to 65536 bytes or omits it for 16384. Invalid values raise. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes read, zero for a zero-byte request, or nil when no bytes arrived or the read failed. |
string |
Returns the reason only when reading fails or the peer disconnects. |
tecs.io.TCPSocket:wait Instance
Waits up to timeoutMs for input or disconnection.
Returns false without an error on timeout. This does not consume input; call read afterwards.
function tecs.io.TCPSocket.wait(
self, timeoutMs: integer
): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
timeoutMs |
integer |
The caller supplies 0 to 2147483647 milliseconds or omits it for zero. Zero polls without blocking. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when input arrives or the peer disconnects. |
string |
Returns the reason on failure. Timeout returns false without a reason. |
tecs.io.TCPSocket:write Instance
Queues one chunk for reliable ordered delivery.
Inside a system, the call suspends until the local send queue drains. Outside a system, accepting the bytes does not mean the peer has received them; use pendingWrites or drain when that distinction matters.
function tecs.io.TCPSocket.write(self, bytes: string): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
bytes |
string |
The caller supplies at most 16777216 bytes. Larger values raise; an empty string succeeds without queuing data. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true only when the connection accepts the whole chunk. |
string |
Returns the reason when the first return is false. |
tecs.io.TCPSocket:writeFrom Instance
Queues a buffer range for reliable ordered delivery.
The native send queue copies the range before this call returns, so the caller may mutate or close the buffer afterwards. This avoids constructing an intermediate Lua string but does not bypass the queue's ownership copy. Inside a system, the call suspends until the local send queue drains.
function tecs.io.TCPSocket.writeFrom(
self, source: IOBuffer, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
source |
IOBuffer |
The caller supplies an open Buffer. |
offset |
integer |
The caller supplies a zero-based source offset or omits it for zero. |
count |
integer |
The caller supplies at most 16777216 bytes or omits it for the remainder. Invalid ranges raise. |
Returns
| Type | Description |
|---|---|
integer |
Returns the number of bytes accepted. |
string |
Returns the reason when the first return is nil. |
tecs.io.TCPSocket:writeView Instance
Queues a retained byte view without constructing an intermediate string.
The native send queue copies the range before this call returns.
function tecs.io.TCPSocket.writeView(
self, source: types.ByteView, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
TCPSocket |
|
source |
types.ByteView |
The caller supplies an open ByteView. |
offset |
integer |
The caller supplies a zero-based source offset or omits it for zero. |
count |
integer |
The caller supplies at most 16777216 bytes or omits it for the remainder. Invalid ranges raise. |
Returns
| Type | Description |
|---|---|
integer |
Returns the number of bytes accepted. |
string |
Returns the reason when the first return is nil. |
tecs.io.UDPPacket record
A UDPPacket owns one received UDP datagram and its source address. Closing it releases both the address and byte buffer and remains safe to repeat.
record tecs.io.UDPPacket is Closeable
address: Address
port: integer
bytes: IOBuffer
close: function(self): boolean, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.UDPPacket.address field
Read-only. Networking sets address when receiving the packet. The packet owns it until close.
tecs.io.UDPPacket.port field
Read-only. Networking sets port to the remote source port when receiving the packet.
tecs.io.UDPPacket.bytes field
Read-only. Networking sets bytes to one caller-owned Buffer containing the complete datagram. A zero-length datagram uses an empty buffer. close releases it.
tecs.io.UDPPacket:close Instance
function tecs.io.UDPPacket.close(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
UDPPacket |
Returns
| Type | Description |
|---|---|
boolean |
|
string |
tecs.io.UDPSocket record
A UDPSocket sends and receives UDP packets. Closing it releases the socket and remains safe to repeat. The socket permits one suspended send, receive, or wait call at a time.
record tecs.io.UDPSocket is Closeable
port: integer
sourceHost: string
sourcePort: integer
close: function(self): boolean, string
isClosed: function(self): boolean
receive: function(self): UDPPacket, string
receiveInto: function(
self, destination: IOBuffer, offset: integer, maxBytes: integer
): integer, string
send: function(
self, address: Address, port: integer, bytes: string
): boolean, string
source: function(self): Address, string
wait: function(self, timeoutMs: integer): boolean, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.UDPSocket.port field
Read-only. Networking sets port from the value passed to bind and never changes it. Zero remains zero.
tecs.io.UDPSocket.sourceHost field
Read-only. Networking sets sourceHost to the numeric address of the sender on each successful receiveInto and leaves it nil until the first one. receive reports its sender through the packet instead and leaves this field alone.
tecs.io.UDPSocket.sourceHost: stringtecs.io.UDPSocket.sourcePort field
Read-only. Networking sets sourcePort to the remote port of the sender on each successful receiveInto and leaves it nil until the first one.
tecs.io.UDPSocket.sourcePort: integertecs.io.UDPSocket:close Instance
function tecs.io.UDPSocket.close(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
Returns
| Type | Description |
|---|---|
boolean |
|
string |
tecs.io.UDPSocket:isClosed Instance
Returns whether close has released this socket.
function tecs.io.UDPSocket.isClosed(self): booleanArguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
Returns
| Type | Description |
|---|---|
boolean |
Returns true after close. |
tecs.io.UDPSocket:receive Instance
Takes one packet, waiting cooperatively inside a system.
Inside a system, the call suspends until a packet is ready. Outside a system it blocks the caller. The packet owns its source address, which the caller closes.
Arguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
Returns
| Type | Description |
|---|---|
UDPPacket |
Returns one caller-owned complete packet, or nil when none waits or reception fails. |
string |
Returns the reason only when reception fails. |
tecs.io.UDPSocket:receiveInto Instance
Takes one packet directly into reusable FFI memory.
The call writes at a zero-based offset and extends the buffer through the last byte received. It suspends a system or blocks an ordinary caller until a datagram arrives, and it allocates no packet, buffer, or address. A datagram longer than the requested ceiling keeps the leading bytes and loses the remainder, which is what the platform does. A zero-length datagram returns zero and leaves the buffer's contents unchanged.
Each success replaces sourceHost and sourcePort. Call source for an owned Address to reply to.
function tecs.io.UDPSocket.receiveInto(
self, destination: IOBuffer, offset: integer, maxBytes: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
|
destination |
IOBuffer |
The caller supplies an open Buffer. |
offset |
integer |
The caller supplies a zero-based destination offset or omits it for zero. |
maxBytes |
integer |
The caller supplies a ceiling from 0 to 65507 bytes or omits it for 65507. Invalid values raise. A zero ceiling returns zero and consumes no datagram. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes received, or nil when reception fails. |
string |
Returns the reason only when reception fails. |
tecs.io.UDPSocket:send Instance
Sends one packet, waiting cooperatively on backpressure in a system.
The call suspends a system or blocks an ordinary caller while the socket cannot accept the datagram.
function tecs.io.UDPSocket.send(
self, address: Address, port: integer, bytes: string
): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
|
address |
Address |
The caller supplies an open address from this module. |
port |
integer |
The caller supplies a remote port from 1 to 65535. |
bytes |
string |
The caller supplies one datagram of at most 65507 bytes. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when the network accepts the complete datagram. |
string |
Returns the reason when the first return is false. |
tecs.io.UDPSocket:source Instance
Returns a newly owned address for the most recent sender.
The caller closes the returned address. Both receive and receiveInto record the sender, and this call allocates the address only when a caller asks for one.
Arguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
Returns
| Type | Description |
|---|---|
Address |
Returns a caller-owned address that outlives the socket, or nil when the socket has received no datagram or the call fails. |
string |
Returns the reason when the first return is nil. |
tecs.io.UDPSocket:wait Instance
Waits up to timeoutMs for a packet.
Returns false without an error on timeout. This does not consume a packet; call receive afterwards.
function tecs.io.UDPSocket.wait(
self, timeoutMs: integer
): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
UDPSocket |
|
timeoutMs |
integer |
The caller supplies 0 to 2147483647 milliseconds or omits it for zero. Zero polls without blocking. |
Returns
| Type | Description |
|---|---|
boolean |
Returns true when at least one packet waits. |
string |
Returns the reason on failure. Timeout returns false without a reason. |
tecs.io.WritableStream interface
A WritableStream opens writers and supplies whole-destination transfers.
interface tecs.io.WritableStream is Stream, Closeable
newWriter: function(self): Writer, string
writeAll: function(self, bytes: string): integer, string
writeBuffer: function(
self, buffer: Buffer, offset: integer, count: integer
): integer, string
writeView: function(
self, view: ByteView, offset: integer, count: integer
): integer, string
endInterfaces
| Interface |
|---|
Stream |
Closeable |
tecs.io.WritableStream:newWriter Instance
Opens a writer with a new cursor.
Opening replaces the destination's previous bytes.
function tecs.io.WritableStream.newWriter(self): Writer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
WritableStream |
The writable descriptor. |
Returns
| Type | Description |
|---|---|
Writer |
Returns a caller-owned writer, or nil when unavailable. |
string |
Returns the reason when the first return is nil. |
Examples
local bytes <const> = tecs.io.newBuffer()
local destination <const> = bytes:newStream()
local writer <const> = assert(destination:newWriter())
assert(writer:write("data"))
assert(writer:close())
destination:close()
bytes:close()tecs.io.WritableStream:writeAll Instance
Replaces the destination with a Lua string.
The operation opens, finishes, and closes one writer. On a non-replayable stream, this claims its one endpoint.
function tecs.io.WritableStream.writeAll(
self, bytes: string
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
WritableStream |
The writable descriptor. |
bytes |
string |
The caller supplies the complete binary contents. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes written. |
string |
Returns the destination's reason when the first return is nil. |
Examples
local destination <const> = tecs.io.newFileStream("save.bin")
local count <const> = destination:writeAll("save data")
print(count)
destination:close()tecs.io.WritableStream:writeBuffer Instance
Replaces the destination with a buffer range.
The operation opens, finishes, and closes one writer. On a non-replayable stream, this claims its one endpoint.
function tecs.io.WritableStream.writeBuffer(
self, buffer: Buffer, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
WritableStream |
The writable descriptor. |
buffer |
Buffer |
The caller keeps the source buffer open and unchanged through the call. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes written. |
string |
Returns the destination's reason when the first return is nil. |
Examples
local bytes <const> = tecs.io.newBuffer("save data")
local destination <const> = tecs.io.newFileStream("save.bin")
local count <const> = destination:writeBuffer(bytes)
print(count)
destination:close()
bytes:close()tecs.io.WritableStream:writeView Instance
Replaces the destination with a retained immutable byte range.
The operation opens, finishes, and closes one writer. On a non-replayable stream, this claims its one endpoint.
The caller keeps view open through the call.
function tecs.io.WritableStream.writeView(
self, view: ByteView, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
WritableStream |
The writable descriptor. |
view |
ByteView |
The caller supplies an open ByteView. |
offset |
integer |
The caller supplies a zero-based offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
integer |
Returns the bytes written. |
string |
Returns the destination's reason when the first return is nil. |
tecs.io.Writer interface
A Writer accepts bytes in order and finishes its destination on close.
interface tecs.io.Writer is Closeable
flush: function(self): boolean, string
write: function(self, bytes: string): boolean, string
writeFrom: function(
self, source: Buffer, offset: integer, count: integer
): integer, string
writeView: function(
self, source: ByteView, offset: integer, count: integer
): integer, string
endInterfaces
| Interface |
|---|
Closeable |
tecs.io.Writer:flush Instance
Flushes buffered bytes without closing the destination.
function tecs.io.Writer.flush(self): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Writer |
The writer to flush. |
Returns
| Type | Description |
|---|---|
boolean |
Returns whether buffered bytes reached the destination. |
string |
Returns the destination's reason when the first return is false. |
Examples
local destination <const> = tecs.io.newFileStream("save.bin")
local writer <const> = assert(destination:newWriter())
assert(writer:write("checkpoint"))
assert(writer:flush())
assert(writer:close())
destination:close()tecs.io.Writer:write Instance
Caller-writable. Supplies the operation that writes the next bytes.
function tecs.io.Writer.write(self, bytes: string): boolean, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Writer |
The writer receiving the bytes. |
bytes |
string |
The binary string to append, including any embedded NUL bytes. |
Returns
| Type | Description |
|---|---|
boolean |
Returns whether every byte reached the destination. |
string |
Returns the destination's reason when the first return is false. |
Examples
local bytes <const> = tecs.io.newBuffer()
local writer <const> = bytes:newWriter()
local wrote <const>, reason = writer:write("data")
assert(wrote, reason)
assert(writer:close())
print(bytes:getString())
bytes:close()tecs.io.Writer:writeFrom Instance
Writes a complete buffer range and advances the cursor.
function tecs.io.Writer.writeFrom(
self, source: Buffer, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Writer |
The open writer whose cursor advances. |
source |
Buffer |
The caller supplies an open source buffer and retains ownership. |
offset |
integer |
The caller supplies a zero-based source offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
integer |
Returns the complete byte count. |
string |
Returns the destination's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newBuffer("header:data")
local destination <const> = tecs.io.newBuffer()
local writer <const> = destination:newWriter()
local count <const>, reason = writer:writeFrom(source, 7, 4)
assert(count, reason)
assert(writer:close())
print(destination:getString())
source:close()
destination:close()tecs.io.Writer:writeView Instance
Writes a complete immutable-view range and advances the cursor.
function tecs.io.Writer.writeView(
self, source: ByteView, offset: integer, count: integer
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
self |
Writer |
The open writer whose cursor advances. |
source |
ByteView |
The caller supplies an open source view and retains ownership. |
offset |
integer |
The caller supplies a zero-based source offset or omits it for zero. |
count |
integer |
The caller supplies a byte count or omits it for the remainder. |
Returns
| Type | Description |
|---|---|
integer |
Returns the complete byte count. |
string |
Returns the destination's reason when the first return is nil. |
Examples
local source <const> = tecs.io.newBuffer("header:data")
local view <const> = source:view(7, 4)
local destination <const> = tecs.io.newBuffer()
local writer <const> = destination:newWriter()
local count <const>, reason = writer:writeView(view)
assert(count, reason)
assert(writer:close())
print(destination:getString())
view:close()
source:close()
destination:close()Functions
tecs.io.bind Static
Binds a UDP socket. A nil address listens on all local interfaces.
Arguments
| Name | Type | Description |
|---|---|---|
port |
integer |
The caller supplies a local port from 0 to 65535. Zero lets the platform choose one but leaves UDPSocket.port at zero. |
address |
Address |
The caller supplies a local address or omits it for all interfaces. |
Returns
| Type | Description |
|---|---|
UDPSocket |
Returns a caller-owned socket, or nil on failure. |
string |
Returns the reason when the first return is nil. |
tecs.io.connect Static
Connects to a resolved address.
Arguments
| Name | Type | Description |
|---|---|---|
address |
Address |
The caller supplies an address from this module. A closed address raises. |
port |
integer |
The caller supplies a remote port from 1 to 65535. |
Returns
| Type | Description |
|---|---|
TCPSocket |
Returns a caller-owned connection. The call suspends its system while connecting, or blocks outside a world update. |
tecs.io.init Static
Starts networking for this module. Safe to call repeatedly.
resolve, connect, listen and bind start it automatically.
function tecs.io.init(): boolean, stringArguments
None.
Returns
| Type | Description |
|---|---|
boolean |
Returns true when networking runs. |
string |
Returns the startup reason when the first return is false. |
tecs.io.listen Static
Binds a TCP listener. A nil address listens on all local interfaces.
function tecs.io.listen(
port: integer, address: Address
): TCPListener, stringArguments
| Name | Type | Description |
|---|---|---|
port |
integer |
The caller supplies a local port from 0 to 65535. Zero lets the platform choose one but leaves TCPListener.port at zero. |
address |
Address |
The caller supplies a local address or omits it for all interfaces. |
Returns
| Type | Description |
|---|---|
TCPListener |
Returns a caller-owned listener, or nil on failure. |
string |
Returns the reason when the first return is nil. |
Examples
local listener <const>, listenReason = tecs.io.listen(8080)
assert(listener, listenReason)
-- `accept` and `read` return only when their operation completes. In a normal
-- system they park that logical update; in a headless server they block this
-- caller. A persistent server belongs in a headless host or an engine-owned
-- bounded service instead of waiting forever in a gameplay system.
local client <const>, acceptReason = listener:accept()
assert(client, acceptReason)
local request <const>, readReason = client:read()
assert(request, readReason)
local body <const> = "Hello from Tecs\n"
local response <const> = (
"HTTP/1.1 200 OK\r\nContent-Length: %d\r\n"
.. "Content-Type: text/plain\r\nConnection: close\r\n\r\n%s"
):format(#body, body)
local sent <const>, sendReason = client:write(response)
assert(sent, sendReason)
assert(client:drain(1000))
client:close()
listener:close()tecs.io.pending Static
Returns the number of pending network operations and readiness watches.
function tecs.io.pending(): integerArguments
None.
Returns
| Type | Description |
|---|---|
integer |
Returns zero after every operation settles or cancels. |
tecs.io.resolve Static
Resolves a hostname.
function tecs.io.resolve(host: string): AddressArguments
| Name | Type | Description |
|---|---|---|
host |
string |
The caller supplies a DNS name or numeric address of at most 253 bytes. Empty strings and embedded NUL bytes raise. |
Returns
| Type | Description |
|---|---|
Address |
Returns a caller-owned address. The call suspends its system while DNS is pending, or blocks outside a world update. |
tecs.io.shutdown Static
Stops this module's networking instance.
It refuses while an address, TCP socket, listener, UDP socket, packet or pending resolution, connection, or readiness watch remains live.
function tecs.io.shutdown(): boolean, stringArguments
None.
Returns
| Type | Description |
|---|---|
boolean |
Returns true after shutdown or when networking never started. |
string |
Returns the live-resource reason when shutdown refuses. |
tecs.io.transfer Static
Transfers every remaining byte between directional endpoints.
Lua files satisfy the basic endpoint protocol directly. Tecs readers and writers may additionally provide readInto and writeFrom fast paths, which this call selects without changing the source code using them. The call borrows both endpoints and closes neither one.
function tecs.io.transfer(
source: types.Reader | FILE, destination: types.Writer | FILE
): integer, stringArguments
| Name | Type | Description |
|---|---|---|
source |
types.Reader | FILE |
The caller supplies an open reader or Lua file positioned at its first byte to transfer. |
destination |
types.Writer | FILE |
The caller supplies an open writer or Lua file positioned where transferred bytes should begin. |
Returns
| Type | Description |
|---|---|
integer |
Returns the number of bytes written. |
string |
Returns the source or destination reason when the first return is nil. |
Examples
local source <const> = assert(tecs.io.files.open("save.bin"))
local destination <const> = assert(tecs.io.files.open("save.copy", "w"))
local count <const>, reason = tecs.io.transfer(source, destination)
assert(count, reason)
source:close()
destination:close()