1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
|
<html><body>
<!-- $Id: struct.html,v 1.7 2018/05/11 22:03:40 roberto Exp $ -->
<h1>Library for Converting Data to and from C Structs for Lua 5.1/5.2</h1>
<h4>(<a href="http://www.inf.puc-rio.br/~roberto/struct/struct-0.3.tar.gz">download</a>)</h4>
<p>
This library offers basic facilities to convert Lua values to and
from C structs.
Its main functions are
<code><a href="#pack">struct.pack</a></code>,
which packs multiple Lua values into a struct-like string;
and <code><a href="#unpack">struct.unpack</a></code>,
which unpacks multiple Lua values from a given struct-like string.
</p>
<p>
The fist argument to both functions is a
<em>format string</em>,
which describes the layout of the structure.
The format string is a sequence of conversion elements,
which respect the current endianess and the current alignment requirements.
Initially, the current endianess 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.
</p>
<p>
The elements in the format string are as follows:
</p>
<ul>
<li><code>" "</code> (empty space) ignored.
<li><code>"!<em>n</em>"</code>
flag to set the current alignment requirement to <em>n</em>
(necessarily a power of 2);
an absent <em>n</em> means the machine's native alignment.
<li><code>">"</code> flag to set mode to big endian.
<li><code>"<"</code> flag to set mode to little endian.
<li><code>"x"</code> a padding zero byte with no corresponding Lua value.
<li><code>"b"</code> a signed <code>char</code>.
<li><code>"B"</code> an unsigned <code>char</code>.
<li><code>"h"</code> a signed <code>short</code> (native size).
<li><code>"H"</code> an unsigned <code>short</code> (native size).
<li><code>"l"</code> a signed <code>long</code> (native size).
<li><code>"L"</code> an unsigned <code>long</code> (native size).
<li><code>"T"</code> a <code>size_t</code> (native size).
<li><code>"i<em>n</em>"</code> a signed integer with <em>n</em> bytes.
An absent <em>n</em> means the native size of an <code>int</code>.
<li><code>"I<em>n</em>"</code> like <code>"i<em>n</em>"</code> but unsigned.
<li><code>"f"</code> a <code>float</code> (native size).
<li><code>"d"</code> a <code>double</code> (native size).
<li><code>"s"</code> a zero-terminated string.
<li><code>"c<em>n</em>"</code> a sequence of exactly <em>n</em> chars
corresponding to a single Lua string.
An absent <em>n</em> means 1.
When packing, the given string must have at least <em>n</em> characters
(extra characters are discarded).
<li><code>"c0"</code> this is like <code>"c<em>n</em>"</code>,
except that the <em>n</em> is given by other means:
When packing, <em>n</em> is the length of the given string;
when unpacking, <em>n</em> is the value of the previous unpacked value
(which must be a number).
In that case, this previous value is not returned.
</ul>
<h2>Lua API</h2>
<ul>
<a name="pack">
<li><code>struct.pack (fmt, d1, d2, ...)</code>
<p>
Returns a string containing the values <code>d1</code>, <code>d2</code>, etc.
packed according to the format string <code>fmt</code>.
</p></li>
<a name="unpack">
<li><code>struct.unpack (fmt, s, [i])</code>
<p>
Returns the values packed in string <code>s</code> according to the
format string <code>fmt</code>.
An optional <code>i</code> marks where in <code>s</code> to start
reading (default is 1).
After the read values,
this function also returns the index in <code>s</code>
where it stopped reading,
which is also where you should start to read the rest of the string.
</p></li>
<li><code>struct.size (fmt)</code>
<p>
Returns the size of a string formatted according to the
format string <code>fmt</code>.
The format string should contain neither
the option <code>s</code> nor the option <code>c0</code>.
</p></li>
</ul>
<h2>Examples</h2>
<ul>
<li><p>
The code <code>print(struct.size("i"))</code> prints the
size of a machine's native <code>int</code>.
</p></li>
<li><p>
To pack and unpack the structure
<pre>
struct Str {
char b;
int i[4];
};
</pre>
you can use the string <code>"<!4biiii"</code>.
</p></li>
<li><p>
If you need to code a structure with a large array,
you may use <code>string.rep</code> to automatically
generate part of the string format.
For instance, for the structure
<pre>
struct Str {
double x;
int i[400];
};
</pre>
you can build the format string with
the code <code>"d"..string.rep("i", 400)</code>.
</p></li>
<li><p>
To pack a string with its length coded in its first byte,
use the following code:
<pre>
x = struct.pack("Bc0", string.len(s), s)
</pre>
To unpack that string, do as follows:
<pre>
s = struct.unpack("Bc0", x)
</pre>
Note that the length (read by the element <code>"B"</code>)
is not returned.
</p></li>
<li><p>
Suppose we have to decode a string <code>s</code>
with an unknown number of doubles;
the end is marked by a zero value.
We can use the following code:
<pre>
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
</pre>
</p></li>
<li><p>
To pack a string in a fixed-width field of 10 characters
padded with blanks, do as follows:
<pre>
x = struct.pack("c10", s .. string.rep(" ", 10))
</pre>
</p></li>
</ul>
<h2>License</h2>
<p>
This package is distributed under the MIT license.
See copyright notice at the end of file <code>struct.c</code>.
</p>
</body></html>
|