fix atan2,rename {hypot,hypot3} to {norm2,norm3}
[liba.git] / lua / src / crc32.c
blob86264d6ec020b8d730726759f5dafc547a00dd9c
1 /***
2 32-bit Cyclic Redundancy Check
3 @module liba.crc32
4 */
6 #include "crc32.h"
7 #include "a/crc.h"
9 struct crc32
11 a_u32 table[0x100];
12 a_u32 (*eval)(a_u32 const table[0x100], void const *pdata, a_size nbyte, a_u32 value);
15 /***
16 constructor for 32-bit Cyclic Redundancy Check
17 @tparam integer poly polynomial that is CRC's divisor
18 @tparam boolean reversed whether or not to reverse
19 @treturn a.crc32 32-bit Cyclic Redundancy Check userdata
20 @function new
22 int liba_crc32_new(lua_State *L)
24 a_u32 poly = 0;
25 int reversed = 0;
26 struct crc32 *ctx;
27 int top = lua_gettop(L);
28 if (top > 1)
30 luaL_checktype(L, 2, LUA_TBOOLEAN);
31 reversed = lua_toboolean(L, 2);
33 poly = lua_u32_get(L, 1);
34 ctx = lua_newclass(L, struct crc32);
35 lua_registry_get(L, liba_crc32_new);
36 lua_setmetatable(L, -2);
37 if (reversed)
39 a_crc32l_init(ctx->table, poly);
40 ctx->eval = a_crc32l;
42 else
44 a_crc32m_init(ctx->table, poly);
45 ctx->eval = a_crc32m;
47 return 1;
50 /***
51 generate for 32-bit Cyclic Redundancy Check
52 @tparam a.crc32 ctx 32-bit Cyclic Redundancy Check userdata
53 @tparam integer poly polynomial that is CRC's divisor
54 @tparam boolean reversed whether or not to reverse
55 @treturn a.crc32 32-bit Cyclic Redundancy Check userdata
56 @function gen
58 int liba_crc32_gen(lua_State *L)
60 a_u32 poly = 0;
61 int reversed = 0;
62 struct crc32 *ctx;
63 int top = lua_gettop(L);
64 if (top > 2)
66 luaL_checktype(L, 3, LUA_TBOOLEAN);
67 reversed = lua_toboolean(L, 3);
69 poly = lua_u32_get(L, 2);
70 ctx = (struct crc32 *)lua_touserdata(L, 1);
71 if (reversed)
73 a_crc32l_init(ctx->table, poly);
74 ctx->eval = a_crc32l;
76 else
78 a_crc32m_init(ctx->table, poly);
79 ctx->eval = a_crc32m;
81 lua_pushvalue(L, 1);
82 return 1;
85 /***
86 calculate for 32-bit Cyclic Redundancy Check
87 @tparam a.crc32 ctx 32-bit Cyclic Redundancy Check userdata
88 @tparam string block block to be processed
89 @tparam integer value initial value
90 @treturn integer output value
91 @function eval
93 int liba_crc32_eval(lua_State *L)
95 struct crc32 *const ctx = (struct crc32 *)lua_touserdata(L, 1);
96 if (ctx)
98 size_t n = 0;
99 a_u32 value = 0;
100 char const *const p = luaL_checklstring(L, 2, &n);
101 if (lua_gettop(L) > 2) { value = lua_u32_get(L, 3); }
102 lua_u32_new(L, ctx->eval(ctx->table, p, n, value));
103 return 1;
105 return 0;
108 /***
109 pack a block and its 32-bit Cyclic Redundancy Check value
110 @tparam a.crc32 ctx 32-bit Cyclic Redundancy Check userdata
111 @tparam string block block to be processed
112 @tparam integer value initial value
113 @treturn string packed block
114 @function pack
116 int liba_crc32_pack(lua_State *L)
118 struct crc32 *const ctx = (struct crc32 *)lua_touserdata(L, 1);
119 if (ctx)
121 union
123 char const *s;
124 a_byte *p;
125 } u;
126 size_t n = 0;
127 a_u32 value = 0;
128 char const *p = luaL_checklstring(L, 2, &n);
129 if (lua_gettop(L) > 2) { value = lua_u32_get(L, 3); }
130 value = ctx->eval(ctx->table, p, n, value);
131 u.s = lua_pushfstring(L, "%s ", p) + n;
132 ctx->eval == a_crc32m
133 ? a_u32_setb(u.p, value)
134 : a_u32_setl(u.p, value);
135 return 1;
137 return 0;
140 static int liba_crc32_set(lua_State *L)
142 switch (a_hash_bkdr(lua_tostring(L, 2), 0))
144 case 0xE8859EEB: /* __name */
145 case 0xE70C48C6: /* __call */
146 case 0xA65758B2: /* __index */
147 case 0xAEB551C6: /* __newindex */
148 break;
149 default:
150 lua_getmetatable(L, 1);
151 lua_replace(L, 1);
152 lua_rawset(L, 1);
154 return 0;
157 static int liba_crc32_get(lua_State *L)
159 struct crc32 const *const ctx = (struct crc32 const *)lua_touserdata(L, 1);
160 switch (a_hash_bkdr(lua_tostring(L, 2), 0))
162 case 0x014FE58A: /* table */
163 lua_array_u32_new(L, ctx->table, 0x100);
164 break;
165 case 0xA65758B2: /* __index */
166 lua_registry_get(L, liba_crc32_new);
167 lua_pushstring(L, "table");
168 lua_array_u32_new(L, ctx->table, 0x100);
169 lua_rawset(L, -3);
170 break;
171 default:
172 lua_getmetatable(L, 1);
173 lua_replace(L, 1);
174 lua_rawget(L, 1);
176 return 1;
179 static int liba_crc32_(lua_State *L)
181 lua_pushcfunction(L, liba_crc32_new);
182 lua_replace(L, 1);
183 lua_call(L, lua_gettop(L) - 1, 1);
184 return 1;
187 int luaopen_liba_crc32(lua_State *L)
189 static lua_fun const funcs[] = {
190 {"new", liba_crc32_new},
191 {"gen", liba_crc32_gen},
192 {"eval", liba_crc32_eval},
193 {"pack", liba_crc32_pack},
195 static lua_fun const metas[] = {
196 {"__newindex", liba_crc32_set},
197 {"__index", liba_crc32_get},
198 {"__call", liba_crc32_eval},
201 lua_createtable(L, 0, A_LEN(funcs));
202 lua_fun_reg(L, -1, funcs, A_LEN(funcs));
203 lua_createtable(L, 0, 1);
204 lua_fun_set(L, -1, "__call", liba_crc32_);
205 lua_setmetatable(L, -2);
207 lua_createtable(L, 0, A_LEN(metas) + A_LEN(funcs) + 1);
208 lua_fun_reg(L, -1, metas, A_LEN(metas));
209 lua_fun_reg(L, -1, funcs, A_LEN(funcs));
210 lua_str_set(L, -1, "__name", "a.crc32");
211 lua_registry_set(L, liba_crc32_new);
213 return 1;