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 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.
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.
Functions (primitive types serialization)
These functions operate in terms of bytes, and are endianness-aware. 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 16-bit integer (big
endian order) and return the result.
get_u16le(self) → integer
Interpret self
(must be 2 bytes long) as an unsigned 16-bit integer (little
endian order) and return the result.
get_u24be(self) → integer
Interpret self
(must be 3 bytes long) as an unsigned 24-bit integer (big
endian order) and return the result.
get_u24le(self) → integer
Interpret self
(must be 3 bytes long) as an unsigned 24-bit integer (little
endian order) and return the result.
get_u32be(self) → integer
Interpret self
(must be 4 bytes long) as an unsigned 32-bit integer (big
endian order) and return the result.
get_u32le(self) → integer
Interpret self
(must be 4 bytes long) as an unsigned 32-bit integer (little
endian order) and return the result.
get_u40be(self) → integer
Interpret self
(must be 5 bytes long) as an unsigned 40-bit integer (big
endian order) and return the result.
get_u40le(self) → integer
Interpret self
(must be 5 bytes long) as an unsigned 40-bit integer (little
endian order) and return the result.
get_u48be(self) → integer
Interpret self
(must be 6 bytes long) as an unsigned 48-bit integer (big
endian order) and return the result.
get_u48le(self) → integer
Interpret self
(must be 6 bytes long) as an unsigned 48-bit integer (little
endian order) and return the result.
get_i8(self) → integer
Interpret self
(must be 1 byte long) as a signed 8-bit 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 16-bit integer (big endian
order) and return the result.
get_i16le(self) → integer
Interpret self
(must be 2 bytes long) as an signed 16-bit integer (little
endian order) and return the result.
get_i24be(self) → integer
Interpret self
(must be 3 bytes long) as an signed 24-bit integer (big endian
order) and return the result.
get_i24le(self) → integer
Interpret self
(must be 3 bytes long) as an signed 24-bit integer (little
endian order) and return the result.
get_i32be(self) → integer
Interpret self
(must be 4 bytes long) as an signed 32-bit integer (big endian
order) and return the result.
get_i32le(self) → integer
Interpret self
(must be 4 bytes long) as an signed 32-bit integer (little
endian order) and return the result.
get_i40be(self) → integer
Interpret self
(must be 5 bytes long) as an signed 40-bit integer (big endian
order) and return the result.
get_i40le(self) → integer
Interpret self
(must be 5 bytes long) as an signed 40-bit integer (little
endian order) and return the result.
get_i48be(self) → integer
Interpret self
(must be 6 bytes long) as an signed 48-bit integer (big endian
order) and return the result.
get_i48le(self) → integer
Interpret self
(must be 6 bytes long) as an signed 48-bit integer (little
endian order) and return the result.
get_f32be(self) → number
Interpret self
(must be 4 bytes long) as a 32-bit floating point number (big
endian order) and return the result.
get_f32le(self) → number
Interpret self
(must be 4 bytes long) as a 32-bit floating point number
(little endian order) and return the result.
get_f64be(self) → number
Interpret self
(must be 8 bytes long) as a 64-bit floating point number (big
endian order) and return the result.
get_f64le(self) → number
Interpret self
(must be 8 bytes long) as a 64-bit 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
16-bit integer (big endian order) n
.
set_u16le(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the unsigned
16-bit integer (little endian order) n
.
set_u24be(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the unsigned
24-bit integer (big endian order) n
.
set_u24le(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the unsigned
24-bit integer (little endian order) n
.
set_u32be(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the unsigned
32-bit integer (big endian order) n
.
set_u32le(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the unsigned
32-bit integer (little endian order) n
.
set_u40be(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the unsigned
40-bit integer (big endian order) n
.
set_u40le(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the unsigned
40-bit integer (little endian order) n
.
set_u48be(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the unsigned
48-bit integer (big endian order) n
.
set_u48le(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the unsigned
48-bit 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
16-bit integer (big endian order) n
.
set_i16le(self, n: integer)
Set the stored byte sequence (must be 2 bytes long) to represent the signed
16-bit integer (little endian order) n
.
set_i24be(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the signed
24-bit integer (big endian order) n
.
set_i24le(self, n: integer)
Set the stored byte sequence (must be 3 bytes long) to represent the signed
24-bit integer (little endian order) n
.
set_i32be(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the signed
32-bit integer (big endian order) n
.
set_i32le(self, n: integer)
Set the stored byte sequence (must be 4 bytes long) to represent the signed
32-bit integer (little endian order) n
.
set_i40be(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the signed
40-bit integer (big endian order) n
.
set_i40le(self, n: integer)
Set the stored byte sequence (must be 5 bytes long) to represent the signed
40-bit integer (little endian order) n
.
set_i48be(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the signed
48-bit integer (big endian order) n
.
set_i48le(self, n: integer)
Set the stored byte sequence (must be 6 bytes long) to represent the signed
48-bit integer (little endian order) n
.
set_f32be(self, n: number)
Set the stored byte sequence (must be 4 bytes long) to represent the 32-bit
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 32-bit
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.