byte_span

local byte_span = require 'byte_span'

A span of bytes. In Emilua, they’re used as network buffers.

Plugin authors

This class is intended for network buffers in a proactor-based network API (i.e. true asynchronous IO). A NIC could be writing to this memory region while the program is running. This has the same effect of another thread writing to the same memory region.

If you’re writing state machines, do not construct the state machine on top of the memory region pointed by a byte_span. It’s not safe to store state here as buggy Lua applications could mutate this area in a racy way. Only use the memory region as the result of operations.

A future Emilua release could introduce read-write locks, but as of now I’m unconvinced of their advantages here.

It’s modeled after Golang’s slices. However 1-indexed access is used.

Functions

new(length: integer[, capacity: integer]) → byte_span

Constructor.

When the capacity argument is omitted, it defaults to the specified length.

slice(self[, start: integer, end: integer]) → byte_span

Returns a new byte_span that points to a slice of the same memory region.

The start and end indices are optional; they default to 1 and the byte_span's length respectively.

We can grow a byte_span to its capacity by slicing it again.

Invalid ranges (e.g. start below 1, a byte_span running beyond its capacity, negative indexes, …​) will raise EINVAL.

copy(self, src: byte_span|string) → integer

Copy src into self.

Returns the number of elements copied.

Copying between slices of different lengths is supported (it’ll copy only up to the smaller number of elements). In addition it can handle source and destination spans that share the same underlying memory, handling overlapping spans correctly.

append() → byte_span

function append(self, ...: byte_span|string|nil) -> byte_span (1)
function append(...: byte_span|string|nil) -> byte_span       (2)

Returns a new byte_span by appending trailing arguments into self. If self's capacity is enough to hold all data, the underlying memory is modified in place. Otherwise the returned byte_span will point to newly allocated memory[1].

For the second overload (non-member function), a new byte span is created from scratch.

Functions (string algorithms)

These functions operate in terms of octets/bytes (kinda like an 8-bit ASCII) and have no concept of UTF-8 encoding.

starts_with(self, prefix: string|byte_span) → boolean

Returns whether self begins with prefix.

ends_with(self, suffix: string|byte_span) → boolean

Returns whether self ends with suffix.

find(self, tgt: string|byte_span[, start: integer]) → integer|nil

Finds the first substring equals to tgt and returns its index, or nil if not found.

rfind(self, tgt: string|byte_span[, end_: integer]) → integer|nil

Finds the last substring equals to tgt and returns its index, or nil if not found.

find_first_of(self, strlist: string|byte_span[, start: integer]) → integer|nil

Finds the first octet equals to any of the octets within strlist and returns its index, or nil if not found.

find_last_of(self, strlist: string|byte_span[, end_: integer]) → integer|nil

Finds the last octet equals to any of the octets within strlist and returns its index, or nil if not found.

find_first_not_of(self, strlist: string|byte_span[, start: integer]) → integer|nil

Finds the first octet not equals to any of the octets within strlist and returns its index, or nil if not found.

find_last_not_of(self, strlist: string|byte_span[, end: integer]) → integer|nil

Finds the last octet not equals to any of the octets within strlist and returns its index, or nil if not found.

trimmed(self[, lws: string|byte_span = " \f\n\r\t\v"]) → byte_span

Returns a slice from self that doesn’t start nor ends with any octet from lws.

Properties

capacity: integer

The capacity.

Metamethods

  • __tostring()

  • __len()

  • __index()

  • __newindex()

  • __eq()

You can index the spans by numerical valued keys and the numerical (ASCII) value for the underlying byte will be returned (or assigned on __newindex()).

1. Allocation strategy (the new byte_span's capacity) is left unspecified and may change among Emilua releases.