Annotate

util-src/struct.c @ 13267:7ae000fc8c07 0.12

mod_muc_mam: Improve wording of enable setting Suggested by jstein in the chat This option label is used by XMPP clients to explain what the option does. a) The user should know where the data is archived. b) The user needs a statement that can be enabled/disabled by the variable. A question would have the wrong logic here.
author Kim Alvefur <zash@zash.se>
date Sun, 15 Oct 2023 14:43:11 +0200
parent 12387:05c250fa335a
child 12575:1f6f05a98fcd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
12354
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
1 /*
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
2 ** {======================================================
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
3 ** Library for packing/unpacking structures.
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
4 ** $Id: struct.c,v 1.8 2018/05/16 11:00:23 roberto Exp $
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
5 ** See Copyright Notice at the end of this file
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
6 ** =======================================================
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
7 */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
8 /*
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
9 ** Valid formats:
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
10 ** > - big endian
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
11 ** < - little endian
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
12 ** ![num] - alignment
12387
05c250fa335a Spelling: Fix various spelling mistakes (thanks timeless)
Kim Alvefur <zash@zash.se>
parents: 12354
diff changeset
13 ** x - padding
12354
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
14 ** b/B - signed/unsigned byte
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
15 ** h/H - signed/unsigned short
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
16 ** l/L - signed/unsigned long
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
17 ** T - size_t
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
18 ** i/In - signed/unsigned integer with size 'n' (default is size of int)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
19 ** cn - sequence of 'n' chars (from/to a string); when packing, n==0 means
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
20 the whole string; when unpacking, n==0 means use the previous
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
21 read number as the string length
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
22 ** s - zero-terminated string
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
23 ** f - float
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
24 ** d - double
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
25 ** ' ' - ignored
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
26 */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
27
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
28
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
29 #include <ctype.h>
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
30 #include <limits.h>
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
31 #include <stddef.h>
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
32 #include <string.h>
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
33
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
34
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
35 #include "lua.h"
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
36 #include "lauxlib.h"
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
37
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
38
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
39 #if (LUA_VERSION_NUM >= 502)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
40
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
41 #define luaL_register(L,n,f) luaL_newlib(L,f)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
42
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
43 #endif
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
44
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
45
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
46 /* basic integer type */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
47 #if !defined(STRUCT_INT)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
48 #define STRUCT_INT long
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
49 #endif
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
50
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
51 typedef STRUCT_INT Inttype;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
52
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
53 /* corresponding unsigned version */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
54 typedef unsigned STRUCT_INT Uinttype;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
55
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
56
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
57 /* maximum size (in bytes) for integral types */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
58 #define MAXINTSIZE 32
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
59
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
60 /* is 'x' a power of 2? */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
61 #define isp2(x) ((x) > 0 && ((x) & ((x) - 1)) == 0)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
62
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
63 /* dummy structure to get alignment requirements */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
64 struct cD {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
65 char c;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
66 double d;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
67 };
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
68
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
69
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
70 #define PADDING (sizeof(struct cD) - sizeof(double))
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
71 #define MAXALIGN (PADDING > sizeof(int) ? PADDING : sizeof(int))
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
72
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
73
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
74 /* endian options */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
75 #define BIG 0
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
76 #define LITTLE 1
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
77
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
78
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
79 static union {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
80 int dummy;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
81 char endian;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
82 } const native = {1};
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
83
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
84
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
85 typedef struct Header {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
86 int endian;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
87 int align;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
88 } Header;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
89
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
90
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
91 static int getnum (const char **fmt, int df) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
92 if (!isdigit(**fmt)) /* no number? */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
93 return df; /* return default value */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
94 else {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
95 int a = 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
96 do {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
97 a = a*10 + *((*fmt)++) - '0';
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
98 } while (isdigit(**fmt));
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
99 return a;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
100 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
101 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
102
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
103
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
104 #define defaultoptions(h) ((h)->endian = native.endian, (h)->align = 1)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
105
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
106
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
107
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
108 static size_t optsize (lua_State *L, char opt, const char **fmt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
109 switch (opt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
110 case 'B': case 'b': return sizeof(char);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
111 case 'H': case 'h': return sizeof(short);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
112 case 'L': case 'l': return sizeof(long);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
113 case 'T': return sizeof(size_t);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
114 case 'f': return sizeof(float);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
115 case 'd': return sizeof(double);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
116 case 'x': return 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
117 case 'c': return getnum(fmt, 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
118 case 'i': case 'I': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
119 int sz = getnum(fmt, sizeof(int));
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
120 if (sz > MAXINTSIZE)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
121 luaL_error(L, "integral size %d is larger than limit of %d",
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
122 sz, MAXINTSIZE);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
123 return sz;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
124 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
125 default: return 0; /* other cases do not need alignment */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
126 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
127 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
128
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
129
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
130 /*
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
131 ** return number of bytes needed to align an element of size 'size'
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
132 ** at current position 'len'
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
133 */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
134 static int gettoalign (size_t len, Header *h, int opt, size_t size) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
135 if (size == 0 || opt == 'c') return 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
136 if (size > (size_t)h->align)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
137 size = h->align; /* respect max. alignment */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
138 return (size - (len & (size - 1))) & (size - 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
139 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
140
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
141
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
142 /*
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
143 ** options to control endianess and alignment
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
144 */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
145 static void controloptions (lua_State *L, int opt, const char **fmt,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
146 Header *h) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
147 switch (opt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
148 case ' ': return; /* ignore white spaces */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
149 case '>': h->endian = BIG; return;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
150 case '<': h->endian = LITTLE; return;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
151 case '!': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
152 int a = getnum(fmt, MAXALIGN);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
153 if (!isp2(a))
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
154 luaL_error(L, "alignment %d is not a power of 2", a);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
155 h->align = a;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
156 return;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
157 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
158 default: {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
159 const char *msg = lua_pushfstring(L, "invalid format option '%c'", opt);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
160 luaL_argerror(L, 1, msg);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
161 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
162 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
163 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
164
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
165
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
166 static void putinteger (lua_State *L, luaL_Buffer *b, int arg, int endian,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
167 int size) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
168 lua_Number n = luaL_checknumber(L, arg);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
169 Uinttype value;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
170 char buff[MAXINTSIZE];
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
171 if (n < 0)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
172 value = (Uinttype)(Inttype)n;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
173 else
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
174 value = (Uinttype)n;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
175 if (endian == LITTLE) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
176 int i;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
177 for (i = 0; i < size; i++) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
178 buff[i] = (value & 0xff);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
179 value >>= 8;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
180 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
181 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
182 else {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
183 int i;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
184 for (i = size - 1; i >= 0; i--) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
185 buff[i] = (value & 0xff);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
186 value >>= 8;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
187 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
188 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
189 luaL_addlstring(b, buff, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
190 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
191
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
192
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
193 static void correctbytes (char *b, int size, int endian) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
194 if (endian != native.endian) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
195 int i = 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
196 while (i < --size) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
197 char temp = b[i];
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
198 b[i++] = b[size];
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
199 b[size] = temp;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
200 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
201 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
202 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
203
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
204
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
205 static int b_pack (lua_State *L) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
206 luaL_Buffer b;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
207 const char *fmt = luaL_checkstring(L, 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
208 Header h;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
209 int arg = 2;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
210 size_t totalsize = 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
211 defaultoptions(&h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
212 lua_pushnil(L); /* mark to separate arguments from string buffer */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
213 luaL_buffinit(L, &b);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
214 while (*fmt != '\0') {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
215 int opt = *fmt++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
216 size_t size = optsize(L, opt, &fmt);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
217 int toalign = gettoalign(totalsize, &h, opt, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
218 totalsize += toalign;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
219 while (toalign-- > 0) luaL_addchar(&b, '\0');
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
220 switch (opt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
221 case 'b': case 'B': case 'h': case 'H':
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
222 case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
223 putinteger(L, &b, arg++, h.endian, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
224 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
225 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
226 case 'x': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
227 luaL_addchar(&b, '\0');
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
228 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
229 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
230 case 'f': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
231 float f = (float)luaL_checknumber(L, arg++);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
232 correctbytes((char *)&f, size, h.endian);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
233 luaL_addlstring(&b, (char *)&f, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
234 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
235 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
236 case 'd': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
237 double d = luaL_checknumber(L, arg++);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
238 correctbytes((char *)&d, size, h.endian);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
239 luaL_addlstring(&b, (char *)&d, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
240 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
241 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
242 case 'c': case 's': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
243 size_t l;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
244 const char *s = luaL_checklstring(L, arg++, &l);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
245 if (size == 0) size = l;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
246 luaL_argcheck(L, l >= (size_t)size, arg, "string too short");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
247 luaL_addlstring(&b, s, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
248 if (opt == 's') {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
249 luaL_addchar(&b, '\0'); /* add zero at the end */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
250 size++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
251 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
252 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
253 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
254 default: controloptions(L, opt, &fmt, &h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
255 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
256 totalsize += size;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
257 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
258 luaL_pushresult(&b);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
259 return 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
260 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
261
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
262
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
263 static lua_Number getinteger (const char *buff, int endian,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
264 int issigned, int size) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
265 Uinttype l = 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
266 int i;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
267 if (endian == BIG) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
268 for (i = 0; i < size; i++) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
269 l <<= 8;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
270 l |= (Uinttype)(unsigned char)buff[i];
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
271 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
272 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
273 else {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
274 for (i = size - 1; i >= 0; i--) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
275 l <<= 8;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
276 l |= (Uinttype)(unsigned char)buff[i];
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
277 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
278 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
279 if (!issigned)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
280 return (lua_Number)l;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
281 else { /* signed format */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
282 Uinttype mask = (Uinttype)(~((Uinttype)0)) << (size*8 - 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
283 if (l & mask) /* negative value? */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
284 l |= mask; /* signal extension */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
285 return (lua_Number)(Inttype)l;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
286 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
287 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
288
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
289
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
290 static int b_unpack (lua_State *L) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
291 Header h;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
292 const char *fmt = luaL_checkstring(L, 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
293 size_t ld;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
294 const char *data = luaL_checklstring(L, 2, &ld);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
295 size_t pos = (size_t)luaL_optinteger(L, 3, 1) - 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
296 int n = 0; /* number of results */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
297 luaL_argcheck(L, pos <= ld, 3, "initial position out of string");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
298 defaultoptions(&h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
299 while (*fmt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
300 int opt = *fmt++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
301 size_t size = optsize(L, opt, &fmt);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
302 pos += gettoalign(pos, &h, opt, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
303 luaL_argcheck(L, size <= ld - pos, 2, "data string too short");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
304 /* stack space for item + next position */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
305 luaL_checkstack(L, 2, "too many results");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
306 switch (opt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
307 case 'b': case 'B': case 'h': case 'H':
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
308 case 'l': case 'L': case 'T': case 'i': case 'I': { /* integer types */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
309 int issigned = islower(opt);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
310 lua_Number res = getinteger(data+pos, h.endian, issigned, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
311 lua_pushnumber(L, res); n++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
312 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
313 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
314 case 'x': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
315 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
316 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
317 case 'f': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
318 float f;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
319 memcpy(&f, data+pos, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
320 correctbytes((char *)&f, sizeof(f), h.endian);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
321 lua_pushnumber(L, f); n++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
322 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
323 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
324 case 'd': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
325 double d;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
326 memcpy(&d, data+pos, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
327 correctbytes((char *)&d, sizeof(d), h.endian);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
328 lua_pushnumber(L, d); n++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
329 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
330 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
331 case 'c': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
332 if (size == 0) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
333 if (n == 0 || !lua_isnumber(L, -1))
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
334 luaL_error(L, "format 'c0' needs a previous size");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
335 size = lua_tonumber(L, -1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
336 lua_pop(L, 1); n--;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
337 luaL_argcheck(L, size <= ld - pos, 2, "data string too short");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
338 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
339 lua_pushlstring(L, data+pos, size); n++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
340 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
341 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
342 case 's': {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
343 const char *e = (const char *)memchr(data+pos, '\0', ld - pos);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
344 if (e == NULL)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
345 luaL_error(L, "unfinished string in data");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
346 size = (e - (data+pos)) + 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
347 lua_pushlstring(L, data+pos, size - 1); n++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
348 break;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
349 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
350 default: controloptions(L, opt, &fmt, &h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
351 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
352 pos += size;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
353 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
354 lua_pushinteger(L, pos + 1); /* next position */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
355 return n + 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
356 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
357
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
358
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
359 static int b_size (lua_State *L) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
360 Header h;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
361 const char *fmt = luaL_checkstring(L, 1);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
362 size_t pos = 0;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
363 defaultoptions(&h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
364 while (*fmt) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
365 int opt = *fmt++;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
366 size_t size = optsize(L, opt, &fmt);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
367 pos += gettoalign(pos, &h, opt, size);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
368 if (opt == 's')
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
369 luaL_argerror(L, 1, "option 's' has no fixed size");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
370 else if (opt == 'c' && size == 0)
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
371 luaL_argerror(L, 1, "option 'c0' has no fixed size");
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
372 if (!isalnum(opt))
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
373 controloptions(L, opt, &fmt, &h);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
374 pos += size;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
375 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
376 lua_pushinteger(L, pos);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
377 return 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
378 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
379
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
380 /* }====================================================== */
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
381
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
382
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
383
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
384 static const struct luaL_Reg thislib[] = {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
385 {"pack", b_pack},
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
386 {"unpack", b_unpack},
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
387 {"size", b_size},
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
388 {NULL, NULL}
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
389 };
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
390
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
391
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
392 LUALIB_API int luaopen_util_struct (lua_State *L);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
393
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
394 LUALIB_API int luaopen_util_struct (lua_State *L) {
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
395 luaL_register(L, "struct", thislib);
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
396 return 1;
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
397 }
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
398
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
399
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
400 /******************************************************************************
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
401 * Copyright (C) 2010-2018 Lua.org, PUC-Rio. All rights reserved.
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
402 *
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
403 * Permission is hereby granted, free of charge, to any person obtaining
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
404 * a copy of this software and associated documentation files (the
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
405 * "Software"), to deal in the Software without restriction, including
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
406 * without limitation the rights to use, copy, modify, merge, publish,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
407 * distribute, sublicense, and/or sell copies of the Software, and to
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
408 * permit persons to whom the Software is furnished to do so, subject to
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
409 * the following conditions:
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
410 *
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
411 * The above copyright notice and this permission notice shall be
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
412 * included in all copies or substantial portions of the Software.
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
413 *
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
414 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
415 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
416 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
417 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
418 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
419 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
420 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
421 ******************************************************************************/
3ce3633527af util.struct: Import Roberto 'struct' library v0.3
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
422