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 proactorbased 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 A future Emilua release could introduce readwrite locks, but as of now I’m unconvinced of their advantages here. 
It’s modeled after Golang’s slices. However 1indexed 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_spanstring) → 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_spanstringnil) > byte_span (1)
function append(...: byte_spanstringnil) > 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 (nonmember function), a new byte span is created from scratch.
Functions (string algorithms)
These functions operate in terms of octets/bytes (kinda like an 8bit ASCII) and have no concept of UTF8 encoding.
find(self, tgt: stringbyte_span[, start: integer]) → integernil
Finds the first substring equals to tgt
and returns its index, or nil
if not
found.
rfind(self, tgt: stringbyte_span[, end_: integer]) → integernil
Finds the last substring equals to tgt
and returns its index, or nil
if not
found.
find_first_of(self, strlist: stringbyte_span[, start: integer]) → integernil
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: stringbyte_span[, end_: integer]) → integernil
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: stringbyte_span[, start: integer]) → integernil
Finds the first octet not equals to any of the octets within strlist
and
returns its index, or nil
if not found.
Functions (primitive types serialization)
These functions operate in terms of bytes, and are endiannessaware. They throw
EINVAL
if you use a byte_span
of the wrong size. Data doesn’t need to be
aligned.
get_u16be(self) → integer
Interpret self
(must be 2 bytes long) as an unsigned 16bit integer (big
endian order) and return the result.
get_u16le(self) → integer
Interpret self
(must be 2 bytes long) as an unsigned 16bit integer (little
endian order) and return the result.
get_u24be(self) → integer
Interpret self
(must be 3 bytes long) as an unsigned 24bit integer (big
endian order) and return the result.
get_u24le(self) → integer
Interpret self
(must be 3 bytes long) as an unsigned 24bit integer (little
endian order) and return the result.
get_u32be(self) → integer
Interpret self
(must be 4 bytes long) as an unsigned 32bit integer (big
endian order) and return the result.
get_u32le(self) → integer
Interpret self
(must be 4 bytes long) as an unsigned 32bit integer (little
endian order) and return the result.
get_u40be(self) → integer
Interpret self
(must be 5 bytes long) as an unsigned 40bit integer (big
endian order) and return the result.
get_u40le(self) → integer
Interpret self
(must be 5 bytes long) as an unsigned 40bit integer (little
endian order) and return the result.
get_u48be(self) → integer
Interpret self
(must be 6 bytes long) as an unsigned 48bit integer (big
endian order) and return the result.
get_u48le(self) → integer
Interpret self
(must be 6 bytes long) as an unsigned 48bit integer (little
endian order) and return the result.
get_i8(self) → integer
Interpret self
(must be 1 byte long) as a signed 8bit integer and return the
result.
get_u8() doesn’t exist as you can just index instead.

get_i16be(self) → integer
Interpret self
(must be 2 bytes long) as an signed 16bit integer (big endian
order) and return the result.
get_i16le(self) → integer
Interpret self
(must be 2 bytes long) as an signed 16bit integer (little
endian order) and return the result.
get_i24be(self) → integer
Interpret self
(must be 3 bytes long) as an signed 24bit integer (big endian
order) and return the result.
get_i24le(self) → integer
Interpret self
(must be 3 bytes long) as an signed 24bit integer (little
endian order) and return the result.
get_i32be(self) → integer
Interpret self
(must be 4 bytes long) as an signed 32bit integer (big endian
order) and return the result.
get_i32le(self) → integer
Interpret self
(must be 4 bytes long) as an signed 32bit integer (little
endian order) and return the result.
get_i40be(self) → integer
Interpret self
(must be 5 bytes long) as an signed 40bit integer (big endian
order) and return the result.
get_i40le(self) → integer
Interpret self
(must be 5 bytes long) as an signed 40bit integer (little
endian order) and return the result.
get_i48be(self) → integer
Interpret self
(must be 6 bytes long) as an signed 48bit integer (big endian
order) and return the result.
get_i48le(self) → integer
Interpret self
(must be 6 bytes long) as an signed 48bit integer (little
endian order) and return the result.
get_f32be(self) → number
Interpret self
(must be 4 bytes long) as a 32bit floating point number (big
endian order) and return the result.
get_f32le(self) → number
Interpret self
(must be 4 bytes long) as a 32bit floating point number
(little endian order) and return the result.
get_f64be(self) → number
Interpret self
(must be 8 bytes long) as a 64bit floating point number (big
endian order) and return the result.
get_f64le(self) → number
Interpret self
(must be 8 bytes long) as a 64bit floating point number
(little endian order) and return the result.
set_u16be(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the unsigned
16bit integer (big endian order) n
.
set_u16le(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the unsigned
16bit integer (little endian order) n
.
set_u24be(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the unsigned
24bit integer (big endian order) n
.
set_u24le(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the unsigned
24bit integer (little endian order) n
.
set_u32be(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the unsigned
32bit integer (big endian order) n
.
set_u32le(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the unsigned
32bit integer (little endian order) n
.
set_u40be(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the unsigned
40bit integer (big endian order) n
.
set_u40le(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the unsigned
40bit integer (little endian order) n
.
set_u48be(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the unsigned
48bit integer (big endian order) n
.
set_u48le(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the unsigned
48bit integer (little endian order) n
.
set_i8(self, n: integer)
Set the stored byte sequence (must be 1 bytes long) to represent the signed byte
n
.
set_u8() doesn’t exist as you can just index instead.

set_i16be(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the signed
16bit integer (big endian order) n
.
set_i16le(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the signed
16bit integer (little endian order) n
.
set_i24be(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the signed
24bit integer (big endian order) n
.
set_i24le(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the signed
24bit integer (little endian order) n
.
set_i32be(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the signed
32bit integer (big endian order) n
.
set_i32le(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the signed
32bit integer (little endian order) n
.
set_i40be(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the signed
40bit integer (big endian order) n
.
set_i40le(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the signed
40bit integer (little endian order) n
.
set_i48be(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the signed
48bit integer (big endian order) n
.
set_i48le(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the signed
48bit integer (little endian order) n
.
set_f32be(self, n: number)
Set the stored byte sequence (must be 4 bytes long) to represent the 32bit
floating point number (big endian order) n
.
set_f32le(self, n: number)
Set the stored byte sequence (must be 4 bytes long) to represent the 32bit
floating point number (little endian order) n
.
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() ).

byte_span
's capacity) is left unspecified and may change among Emilua releases.