166 lines
5.1 KiB
Markdown
166 lines
5.1 KiB
Markdown
|
# Struct Module
|
||
|
| Since | Origin / Contributor | Maintainer | Source |
|
||
|
| :----- | :-------------------- | :---------- | :------ |
|
||
|
| 2015-02-13 | [Roberto Ierusalimschy](http://www.inf.puc-rio.br/~roberto/struct/), [Philip Gladstone](https://github.com/pjsg) | [Philip Gladstone](https://github.com/pjsg) | [struct.c](../../app/modules/struct.c)|
|
||
|
|
||
|
This module offers basic facilities to convert Lua values to and from C structs. Its main functions are `struct.pack`, which packs multiple Lua values into a struct-like string; and `struct.unpack`, which unpacks multiple Lua values from a given struct-like string.
|
||
|
|
||
|
The first argument to both functions is a *format string*, which describes the layout of the structure. The format string is a sequence of conversion elements, which respect the current endianness and the current alignment requirements. Initially, the current endianness is the machine's native endianness and the current alignment requirement is 1 (meaning no alignment at all). You can change these settings with appropriate directives in the format string.
|
||
|
|
||
|
Note that the float and double conversions are only available with a floating point NodeMCU build.
|
||
|
|
||
|
### Format String
|
||
|
|
||
|
The elements in the format string are as follows:
|
||
|
|
||
|
- `" "` (empty space) ignored.
|
||
|
- `"!n"` flag to set the current alignment requirement to *n*
|
||
|
(necessarily a power of 2); an absent *n* means the machine's native
|
||
|
alignment.
|
||
|
- `">"` flag to set mode to big endian.
|
||
|
- `"<"` flag to set mode to little endian.
|
||
|
- `"x"` a padding zero byte with no corresponding Lua value.
|
||
|
- `"b"` a signed `char`.
|
||
|
- `"B"` an unsigned `char`.
|
||
|
- `"h"` a signed `short` (native size).
|
||
|
- `"H"` an unsigned `short` (native size).
|
||
|
- `"l"` a signed `long` (native size).
|
||
|
- `"L"` an unsigned `long` (native size).
|
||
|
- `"T"` a `size_t` (native size).
|
||
|
- `"in"` a signed integer with *n* bytes. An absent *n* means the
|
||
|
native size of an `int`.
|
||
|
- `"In"` like `"in"` but unsigned.
|
||
|
- `"f"` a `float` (native size).
|
||
|
- `"d"` a `double` (native size).
|
||
|
- `"s"` a zero-terminated string.
|
||
|
- `"cn"` a sequence of exactly *n* chars corresponding to a single Lua
|
||
|
string. An absent *n* means 1. When packing, the given string must
|
||
|
have at least *n* characters (extra characters are discarded).
|
||
|
- `"c0"` this is like `"cn"`, except that the *n* is given by other
|
||
|
means: When packing, *n* is the length of the given string; when
|
||
|
unpacking, *n* is the value of the previous unpacked value (which
|
||
|
must be a number). In that case, this previous value is not
|
||
|
returned.
|
||
|
|
||
|
#### Examples
|
||
|
|
||
|
To pack and unpack the structure
|
||
|
|
||
|
struct Str {
|
||
|
char b;
|
||
|
int i[4];
|
||
|
};
|
||
|
|
||
|
you can use the string `"<!4biiii"`.
|
||
|
|
||
|
To pack a string with its length coded in its first byte, use the
|
||
|
following code:
|
||
|
|
||
|
x = struct.pack("Bc0", string.len(s), s)
|
||
|
|
||
|
To unpack that string, do as follows:
|
||
|
|
||
|
s = struct.unpack("Bc0", x)
|
||
|
|
||
|
Note that the length (read by the element `"B"`) is not returned.
|
||
|
|
||
|
To pack a string in a fixed-width field of 10 characters padded with
|
||
|
blanks, do as follows:
|
||
|
|
||
|
x = struct.pack("c10", s .. string.rep(" ", 10))
|
||
|
|
||
|
|
||
|
## struct.pack()
|
||
|
|
||
|
Returns a string containing the values `d1`, `d2`, etc. packed
|
||
|
according to the format string `fmt`.
|
||
|
|
||
|
#### Syntax
|
||
|
|
||
|
`struct.pack (fmt, d1, d2, ...)`
|
||
|
|
||
|
#### Parameters
|
||
|
|
||
|
- `fmt` The format string in the format above
|
||
|
- `d1` The first data item to be packed
|
||
|
- `d2` The second data item to be packed etc.
|
||
|
|
||
|
#### Returns
|
||
|
|
||
|
The packed string.
|
||
|
|
||
|
#### Example
|
||
|
|
||
|
```
|
||
|
s = struct.pack("I", 0x41424344)
|
||
|
print(s)
|
||
|
```
|
||
|
|
||
|
## struct.unpack()
|
||
|
|
||
|
Returns the values packed in string `s` according to the format
|
||
|
string `fmt`. An optional `offset` marks where in `s` to start reading
|
||
|
(default is 1). After the read values, this function also returns
|
||
|
the index in `s` where it stopped reading, which is also where you
|
||
|
should start to read the rest of the string.
|
||
|
|
||
|
#### Syntax
|
||
|
|
||
|
`struct.unpack (fmt, s[, offset])`
|
||
|
|
||
|
#### Parameters
|
||
|
|
||
|
- `fmt` The format string in the format above
|
||
|
- `s` The string holding the data to be unpacked
|
||
|
- `offset` The position to start in the string (default is 1)
|
||
|
|
||
|
#### Returns
|
||
|
|
||
|
All the unpacked data and index in `s` where it stoppped reading.
|
||
|
|
||
|
#### Example
|
||
|
|
||
|
Suppose we have to decode a string `s` with an unknown number of
|
||
|
doubles; the end is marked by a zero value. We can use the following
|
||
|
code:
|
||
|
|
||
|
local a = {}
|
||
|
local i = 1 -- index where to read
|
||
|
while true do
|
||
|
local d
|
||
|
d, i = struct.unpack("d", s, i)
|
||
|
if d == 0 then break end
|
||
|
a[#a + 1] = d
|
||
|
end
|
||
|
|
||
|
## struct.size()
|
||
|
|
||
|
Returns the size of a string formatted according to the format
|
||
|
string `fmt`. The format string should contain neither the option
|
||
|
`s` nor the option `c0`.
|
||
|
|
||
|
#### Syntax
|
||
|
|
||
|
`struct.size (fmt)`
|
||
|
|
||
|
#### Parameters
|
||
|
|
||
|
- `fmt` The format string in the format above
|
||
|
|
||
|
#### Returns
|
||
|
|
||
|
The size of the string that would be output in a pack operation with this format string.
|
||
|
|
||
|
#### Example
|
||
|
|
||
|
```
|
||
|
print(struct.size("i"))
|
||
|
```
|
||
|
|
||
|
This prints the size of the native integer type.
|
||
|
|
||
|
### License
|
||
|
|
||
|
This package is distributed under the MIT license. See copyright notice
|
||
|
at the end of file `struct.c`.
|