struct
import struct
This module provides functions for converting between Zuri values and C/C++/Rust structs and vice-versa in the binary format.
The pack and unpack functions behave similarly as the pack and
unpack functions from Perl and PHP (more similar to the PHP version)
with few major extensions to their format language.
Format language
A format string is a sequence of /-separated segments. Each segment is
one or more CODE[COUNT] groups, optionally followed by :NAME to
label the field(s) that group produces when unpacking:
"Nsize:len/A16:name/C4"
CODEis one of the format characters in the table below. -COUNTis a decimal integer, or*to mean “the rest” (the whole remaining argument for a string-like code, or every remaining argument/byte for a numeric code). Omitted means1.:NAMEnames the field(s) produced by that ONE group when unpacking. A count > 1 numbers the keysNAME1,NAME2, … A segment carrying a:NAMEmay only contain a single group. - A group with no:NAMEgets a purely numeric key that runs once, globally, for the whole format string; it never resets and so never silently overwrites an earlier unnamed field.
Format codes
Code | Bytes | Meaning —–|—––|–––– a | count | NUL-padded
string A | count | SPACE-padded string (trailing NUL/space trimmed on
unpack) Z | count | NUL-padded, NUL-terminated string (C-string
semantics) h | ceil(count/2) | Hex string, low nibble first H |
ceil(count/2) | Hex string, high nibble first c | 1 | signed 8-bit
integer C | 1 | unsigned 8-bit integer ? | 1 | boolean s | 2 |
signed 16-bit integer, native byte order S | 2 | unsigned 16-bit
integer, native byte order n | 2 | unsigned 16-bit integer, big-endian
v | 2 | unsigned 16-bit integer, little-endian i | 4 | signed 32-bit
integer, native byte order I | 4 | unsigned 32-bit integer, native
byte order l | 4 | signed 32-bit integer, native byte order L | 4 |
unsigned 32-bit integer, native byte order N | 4 | unsigned 32-bit
integer, big-endian V | 4 | unsigned 32-bit integer, little-endian q
| 8 | signed 64-bit integer, native byte order Q | 8 | unsigned 64-bit
integer, native byte order J | 8 | unsigned 64-bit integer, big-endian
P | 8 | unsigned 64-bit integer, little-endian u | 16 | signed
128-bit integer, little-endian U | 16 | unsigned 128-bit integer,
little-endian f | 4 | float, native byte order g | 4 | float,
little-endian G | 4 | float, big-endian d | 8 | double, native byte
order e | 8 | double, little-endian E | 8 | double, big-endian w |
2 | IEEE-754 half-precision float, little-endian W | 2 | IEEE-754
half-precision float, big-endian x | count | NUL byte(s); consumes no
argument X | count | back up count byte(s) Z |; | (see above) @
|; | seek/pad to absolute position count
Integer precision
Zuri numbers are IEEE-754 doubles, which can only represent integers
exactly up to 2^53. Every integer-producing code here (q/Q/J/P,
and the new u/U) automatically promotes its result to a bigint
Value instead of a number whenever the unpacked value falls outside
that safe range, rather than silently losing precision. Packing accepts
either a number or a bigint for every integer code.
The struct API
Every public name in struct, wherever it is declared. Each links to
the page that documents it.
| Name | Kind | Summary |
|---|---|---|
struct.calcsize | function | Calculates the size of the buffer needed to pack the given values according to the specified format. |
struct.iter_unpack | function | Unpacks a buffer as a repeated sequence of fixed-size records until exhausted, returning a list of… |
struct.pack | function | Packs the given arguments into a bytes object according to the specified format. |
struct.pack_from | function | Same as pack() except that instead of accepting arbitrary values after format, it expects the values to be… |
struct.pack_into | function | Packs directly into an existing bytes object at offset, growing it (zero-padded) if it isn’t long enough… |
struct.unpack | function | Unpacks from bytes or a string into a dictionary based on the given format. |
struct.unpack_from | function | The pack_from() equivalent of unpack(). |
Functions
pack()
struct.pack(format: string, ...values: list) -> bytes
Packs the given arguments into a bytes object according to the specified format.
Parameters
format(string)any...— args
Returns bytes
unpack()
struct.unpack(format: string, data: bytes|string, offset: ?number) -> any
Unpacks from bytes or a string into a dictionary based on the given format.
-
You may have to name the different format codes and separate them by a slash
/to return a string indexed dictionary for easy reference of the destructed parts. If a repeater argument is present, then each of the dictionary keys will have a sequence number behind the given name. -
offsetis the index of the bytes/string to begin unpacking from
Important If you do not name an element, numeric indices starting from 1 are used. Be aware that if you have more than one unnamed element, some data is overwritten because the numbering restarts from 1 for each element.
Parameters
format(string)data(bytes|string)offset(?number) — Default value is0
Returns any
pack_from()
struct.pack_from(format: string, args: list) -> bytes
Same as pack() except that instead of accepting arbitrary values after
format, it expects the values to be in a list.
Parameters
format(string)args(list)
Returns bytes
unpack_from()
struct.unpack_from(format: string, data: bytes|string, offset: ?number) -> any
The pack_from() equivalent of unpack(). This function is essentially
the same as unpack() and was kept for symmetry with pack_from().
Parameters
format(string)data(bytes|string)offset(?number) — Default value is0
Returns any
See also: unpack()
pack_into()
struct.pack_into(format: string, buffer: bytes, offset: number, ...values: list) -> number
Packs directly into an existing bytes object at offset, growing it
(zero-padded) if it isn’t long enough and returns the number of elements
written.
This function avoids an allocate-then-copy round trip when assembling a larger buffer field by field.
Parameters
format(string)buffer(bytes)offset(number)any...— values
Returns number
calcsize()
struct.calcsize(format: string) -> number
Calculates the size of the buffer needed to pack the given values
according to the specified format. It raises an error if the format is
invalid or if the values cannot be packed according to the format or if
it contains a * repeat anywhere, since that has no size independent of
actual data.
Parameters
format(string)
Returns number
Raises Error
iter_unpack()
struct.iter_unpack(format: string, data: bytes|string) -> list
Unpacks a buffer as a repeated sequence of fixed-size records until
exhausted, returning a list of dictionaries. The format string must not
contain any * repeaters, since that would make the record size
variable.
Parameters
format(string)data(bytes|string)
Returns list
2022, Richard Ore and The Zuri Contributors