summaryrefslogtreecommitdiff
path: root/testes/tpack.lua
diff options
context:
space:
mode:
Diffstat (limited to 'testes/tpack.lua')
-rw-r--r--testes/tpack.lua322
1 files changed, 322 insertions, 0 deletions
diff --git a/testes/tpack.lua b/testes/tpack.lua
new file mode 100644
index 00000000..96bb4da4
--- /dev/null
+++ b/testes/tpack.lua
@@ -0,0 +1,322 @@
1-- $Id: tpack.lua,v 1.13 2016/11/07 13:11:28 roberto Exp $
2-- See Copyright Notice in file all.lua
3
4local pack = string.pack
5local packsize = string.packsize
6local unpack = string.unpack
7
8print "testing pack/unpack"
9
10-- maximum size for integers
11local NB = 16
12
13local sizeshort = packsize("h")
14local sizeint = packsize("i")
15local sizelong = packsize("l")
16local sizesize_t = packsize("T")
17local sizeLI = packsize("j")
18local sizefloat = packsize("f")
19local sizedouble = packsize("d")
20local sizenumber = packsize("n")
21local little = (pack("i2", 1) == "\1\0")
22local align = packsize("!xXi16")
23
24assert(1 <= sizeshort and sizeshort <= sizeint and sizeint <= sizelong and
25 sizefloat <= sizedouble)
26
27print("platform:")
28print(string.format(
29 "\tshort %d, int %d, long %d, size_t %d, float %d, double %d,\n\z
30 \tlua Integer %d, lua Number %d",
31 sizeshort, sizeint, sizelong, sizesize_t, sizefloat, sizedouble,
32 sizeLI, sizenumber))
33print("\t" .. (little and "little" or "big") .. " endian")
34print("\talignment: " .. align)
35
36
37-- check errors in arguments
38function checkerror (msg, f, ...)
39 local status, err = pcall(f, ...)
40 -- print(status, err, msg)
41 assert(not status and string.find(err, msg))
42end
43
44-- minimum behavior for integer formats
45assert(unpack("B", pack("B", 0xff)) == 0xff)
46assert(unpack("b", pack("b", 0x7f)) == 0x7f)
47assert(unpack("b", pack("b", -0x80)) == -0x80)
48
49assert(unpack("H", pack("H", 0xffff)) == 0xffff)
50assert(unpack("h", pack("h", 0x7fff)) == 0x7fff)
51assert(unpack("h", pack("h", -0x8000)) == -0x8000)
52
53assert(unpack("L", pack("L", 0xffffffff)) == 0xffffffff)
54assert(unpack("l", pack("l", 0x7fffffff)) == 0x7fffffff)
55assert(unpack("l", pack("l", -0x80000000)) == -0x80000000)
56
57
58for i = 1, NB do
59 -- small numbers with signal extension ("\xFF...")
60 local s = string.rep("\xff", i)
61 assert(pack("i" .. i, -1) == s)
62 assert(packsize("i" .. i) == #s)
63 assert(unpack("i" .. i, s) == -1)
64
65 -- small unsigned number ("\0...\xAA")
66 s = "\xAA" .. string.rep("\0", i - 1)
67 assert(pack("<I" .. i, 0xAA) == s)
68 assert(unpack("<I" .. i, s) == 0xAA)
69 assert(pack(">I" .. i, 0xAA) == s:reverse())
70 assert(unpack(">I" .. i, s:reverse()) == 0xAA)
71end
72
73do
74 local lnum = 0x13121110090807060504030201
75 local s = pack("<j", lnum)
76 assert(unpack("<j", s) == lnum)
77 assert(unpack("<i" .. sizeLI + 1, s .. "\0") == lnum)
78 assert(unpack("<i" .. sizeLI + 1, s .. "\0") == lnum)
79
80 for i = sizeLI + 1, NB do
81 local s = pack("<j", -lnum)
82 assert(unpack("<j", s) == -lnum)
83 -- strings with (correct) extra bytes
84 assert(unpack("<i" .. i, s .. ("\xFF"):rep(i - sizeLI)) == -lnum)
85 assert(unpack(">i" .. i, ("\xFF"):rep(i - sizeLI) .. s:reverse()) == -lnum)
86 assert(unpack("<I" .. i, s .. ("\0"):rep(i - sizeLI)) == -lnum)
87
88 -- overflows
89 checkerror("does not fit", unpack, "<I" .. i, ("\x00"):rep(i - 1) .. "\1")
90 checkerror("does not fit", unpack, ">i" .. i, "\1" .. ("\x00"):rep(i - 1))
91 end
92end
93
94for i = 1, sizeLI do
95 local lstr = "\1\2\3\4\5\6\7\8\9\10\11\12\13"
96 local lnum = 0x13121110090807060504030201
97 local n = lnum & (~(-1 << (i * 8)))
98 local s = string.sub(lstr, 1, i)
99 assert(pack("<i" .. i, n) == s)
100 assert(pack(">i" .. i, n) == s:reverse())
101 assert(unpack(">i" .. i, s:reverse()) == n)
102end
103
104-- sign extension
105do
106 local u = 0xf0
107 for i = 1, sizeLI - 1 do
108 assert(unpack("<i"..i, "\xf0"..("\xff"):rep(i - 1)) == -16)
109 assert(unpack(">I"..i, "\xf0"..("\xff"):rep(i - 1)) == u)
110 u = u * 256 + 0xff
111 end
112end
113
114-- mixed endianness
115do
116 assert(pack(">i2 <i2", 10, 20) == "\0\10\20\0")
117 local a, b = unpack("<i2 >i2", "\10\0\0\20")
118 assert(a == 10 and b == 20)
119 assert(pack("=i4", 2001) == pack("i4", 2001))
120end
121
122print("testing invalid formats")
123
124checkerror("out of limits", pack, "i0", 0)
125checkerror("out of limits", pack, "i" .. NB + 1, 0)
126checkerror("out of limits", pack, "!" .. NB + 1, 0)
127checkerror("%(17%) out of limits %[1,16%]", pack, "Xi" .. NB + 1)
128checkerror("invalid format option 'r'", pack, "i3r", 0)
129checkerror("16%-byte integer", unpack, "i16", string.rep('\3', 16))
130checkerror("not power of 2", pack, "!4i3", 0);
131checkerror("missing size", pack, "c", "")
132checkerror("variable%-length format", packsize, "s")
133checkerror("variable%-length format", packsize, "z")
134
135-- overflow in option size (error will be in digit after limit)
136checkerror("invalid format", packsize, "c1" .. string.rep("0", 40))
137
138if packsize("i") == 4 then
139 -- result would be 2^31 (2^3 repetitions of 2^28 strings)
140 local s = string.rep("c268435456", 2^3)
141 checkerror("too large", packsize, s)
142 -- one less is OK
143 s = string.rep("c268435456", 2^3 - 1) .. "c268435455"
144 assert(packsize(s) == 0x7fffffff)
145end
146
147-- overflow in packing
148for i = 1, sizeLI - 1 do
149 local umax = (1 << (i * 8)) - 1
150 local max = umax >> 1
151 local min = ~max
152 checkerror("overflow", pack, "<I" .. i, -1)
153 checkerror("overflow", pack, "<I" .. i, min)
154 checkerror("overflow", pack, ">I" .. i, umax + 1)
155
156 checkerror("overflow", pack, ">i" .. i, umax)
157 checkerror("overflow", pack, ">i" .. i, max + 1)
158 checkerror("overflow", pack, "<i" .. i, min - 1)
159
160 assert(unpack(">i" .. i, pack(">i" .. i, max)) == max)
161 assert(unpack("<i" .. i, pack("<i" .. i, min)) == min)
162 assert(unpack(">I" .. i, pack(">I" .. i, umax)) == umax)
163end
164
165-- Lua integer size
166assert(unpack(">j", pack(">j", math.maxinteger)) == math.maxinteger)
167assert(unpack("<j", pack("<j", math.mininteger)) == math.mininteger)
168assert(unpack("<J", pack("<j", -1)) == -1) -- maximum unsigned integer
169
170if little then
171 assert(pack("f", 24) == pack("<f", 24))
172else
173 assert(pack("f", 24) == pack(">f", 24))
174end
175
176print "testing pack/unpack of floating-point numbers"
177
178for _, n in ipairs{0, -1.1, 1.9, 1/0, -1/0, 1e20, -1e20, 0.1, 2000.7} do
179 assert(unpack("n", pack("n", n)) == n)
180 assert(unpack("<n", pack("<n", n)) == n)
181 assert(unpack(">n", pack(">n", n)) == n)
182 assert(pack("<f", n) == pack(">f", n):reverse())
183 assert(pack(">d", n) == pack("<d", n):reverse())
184end
185
186-- for non-native precisions, test only with "round" numbers
187for _, n in ipairs{0, -1.5, 1/0, -1/0, 1e10, -1e9, 0.5, 2000.25} do
188 assert(unpack("<f", pack("<f", n)) == n)
189 assert(unpack(">f", pack(">f", n)) == n)
190 assert(unpack("<d", pack("<d", n)) == n)
191 assert(unpack(">d", pack(">d", n)) == n)
192end
193
194print "testing pack/unpack of strings"
195do
196 local s = string.rep("abc", 1000)
197 assert(pack("zB", s, 247) == s .. "\0\xF7")
198 local s1, b = unpack("zB", s .. "\0\xF9")
199 assert(b == 249 and s1 == s)
200 s1 = pack("s", s)
201 assert(unpack("s", s1) == s)
202
203 checkerror("does not fit", pack, "s1", s)
204
205 checkerror("contains zeros", pack, "z", "alo\0");
206
207 for i = 2, NB do
208 local s1 = pack("s" .. i, s)
209 assert(unpack("s" .. i, s1) == s and #s1 == #s + i)
210 end
211end
212
213do
214 local x = pack("s", "alo")
215 checkerror("too short", unpack, "s", x:sub(1, -2))
216 checkerror("too short", unpack, "c5", "abcd")
217 checkerror("out of limits", pack, "s100", "alo")
218end
219
220do
221 assert(pack("c0", "") == "")
222 assert(packsize("c0") == 0)
223 assert(unpack("c0", "") == "")
224 assert(pack("<! c3", "abc") == "abc")
225 assert(packsize("<! c3") == 3)
226 assert(pack(">!4 c6", "abcdef") == "abcdef")
227 assert(pack("c3", "123") == "123")
228 assert(pack("c0", "") == "")
229 assert(pack("c8", "123456") == "123456\0\0")
230 assert(pack("c88", "") == string.rep("\0", 88))
231 assert(pack("c188", "ab") == "ab" .. string.rep("\0", 188 - 2))
232 local a, b, c = unpack("!4 z c3", "abcdefghi\0xyz")
233 assert(a == "abcdefghi" and b == "xyz" and c == 14)
234 checkerror("longer than", pack, "c3", "1234")
235end
236
237
238-- testing multiple types and sequence
239do
240 local x = pack("<b h b f d f n i", 1, 2, 3, 4, 5, 6, 7, 8)
241 assert(#x == packsize("<b h b f d f n i"))
242 local a, b, c, d, e, f, g, h = unpack("<b h b f d f n i", x)
243 assert(a == 1 and b == 2 and c == 3 and d == 4 and e == 5 and f == 6 and
244 g == 7 and h == 8)
245end
246
247print "testing alignment"
248do
249 assert(pack(" < i1 i2 ", 2, 3) == "\2\3\0") -- no alignment by default
250 local x = pack(">!8 b Xh i4 i8 c1 Xi8", -12, 100, 200, "\xEC")
251 assert(#x == packsize(">!8 b Xh i4 i8 c1 Xi8"))
252 assert(x == "\xf4" .. "\0\0\0" ..
253 "\0\0\0\100" ..
254 "\0\0\0\0\0\0\0\xC8" ..
255 "\xEC" .. "\0\0\0\0\0\0\0")
256 local a, b, c, d, pos = unpack(">!8 c1 Xh i4 i8 b Xi8 XI XH", x)
257 assert(a == "\xF4" and b == 100 and c == 200 and d == -20 and (pos - 1) == #x)
258
259 x = pack(">!4 c3 c4 c2 z i4 c5 c2 Xi4",
260 "abc", "abcd", "xz", "hello", 5, "world", "xy")
261 assert(x == "abcabcdxzhello\0\0\0\0\0\5worldxy\0")
262 local a, b, c, d, e, f, g, pos = unpack(">!4 c3 c4 c2 z i4 c5 c2 Xh Xi4", x)
263 assert(a == "abc" and b == "abcd" and c == "xz" and d == "hello" and
264 e == 5 and f == "world" and g == "xy" and (pos - 1) % 4 == 0)
265
266 x = pack(" b b Xd b Xb x", 1, 2, 3)
267 assert(packsize(" b b Xd b Xb x") == 4)
268 assert(x == "\1\2\3\0")
269 a, b, c, pos = unpack("bbXdb", x)
270 assert(a == 1 and b == 2 and c == 3 and pos == #x)
271
272 -- only alignment
273 assert(packsize("!8 xXi8") == 8)
274 local pos = unpack("!8 xXi8", "0123456701234567"); assert(pos == 9)
275 assert(packsize("!8 xXi2") == 2)
276 local pos = unpack("!8 xXi2", "0123456701234567"); assert(pos == 3)
277 assert(packsize("!2 xXi2") == 2)
278 local pos = unpack("!2 xXi2", "0123456701234567"); assert(pos == 3)
279 assert(packsize("!2 xXi8") == 2)
280 local pos = unpack("!2 xXi8", "0123456701234567"); assert(pos == 3)
281 assert(packsize("!16 xXi16") == 16)
282 local pos = unpack("!16 xXi16", "0123456701234567"); assert(pos == 17)
283
284 checkerror("invalid next option", pack, "X")
285 checkerror("invalid next option", unpack, "XXi", "")
286 checkerror("invalid next option", unpack, "X i", "")
287 checkerror("invalid next option", pack, "Xc1")
288end
289
290do -- testing initial position
291 local x = pack("i4i4i4i4", 1, 2, 3, 4)
292 for pos = 1, 16, 4 do
293 local i, p = unpack("i4", x, pos)
294 assert(i == pos//4 + 1 and p == pos + 4)
295 end
296
297 -- with alignment
298 for pos = 0, 12 do -- will always round position to power of 2
299 local i, p = unpack("!4 i4", x, pos + 1)
300 assert(i == (pos + 3)//4 + 1 and p == i*4 + 1)
301 end
302
303 -- negative indices
304 local i, p = unpack("!4 i4", x, -4)
305 assert(i == 4 and p == 17)
306 local i, p = unpack("!4 i4", x, -7)
307 assert(i == 4 and p == 17)
308 local i, p = unpack("!4 i4", x, -#x)
309 assert(i == 1 and p == 5)
310
311 -- limits
312 for i = 1, #x + 1 do
313 assert(unpack("c0", x, i) == "")
314 end
315 checkerror("out of string", unpack, "c0", x, 0)
316 checkerror("out of string", unpack, "c0", x, #x + 2)
317 checkerror("out of string", unpack, "c0", x, -(#x + 1))
318
319end
320
321print "OK"
322