rename dt to x
[liba.git] / lua / src / crc64.c
blob325d5bd48120aafe3e0dd1980996b12c55f98ff6
1 /***
2 64-bit Cyclic Redundancy Check
3 @module liba.crc64
4 */
6 #include "crc64.h"
7 #include "a/crc.h"
9 struct crc64
11 a_u64 table[0x100];
12 a_u64 (*eval)(a_u64 const table[0x100], void const *pdata, a_size nbyte, a_u64 value);
15 /***
16 constructor for 64-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.crc64 64-bit Cyclic Redundancy Check userdata
20 @function new
22 int liba_crc64_new(lua_State *L)
24 a_u64 poly = 0;
25 int reversed = 0;
26 struct crc64 *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_u64_get(L, 1);
34 ctx = lua_newclass(L, struct crc64);
35 lua_registry_get(L, liba_crc64_new);
36 lua_setmetatable(L, -2);
37 if (reversed)
39 a_crc64l_init(ctx->table, poly);
40 ctx->eval = a_crc64l;
42 else
44 a_crc64m_init(ctx->table, poly);
45 ctx->eval = a_crc64m;
47 return 1;
50 /***
51 generate for 64-bit Cyclic Redundancy Check
52 @tparam a.crc64 ctx 64-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.crc64 64-bit Cyclic Redundancy Check userdata
56 @function gen
58 int liba_crc64_gen(lua_State *L)
60 a_u64 poly = 0;
61 int reversed = 0;
62 struct crc64 *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_u64_get(L, 2);
70 ctx = (struct crc64 *)lua_touserdata(L, 1);
71 if (reversed)
73 a_crc64l_init(ctx->table, poly);
74 ctx->eval = a_crc64l;
76 else
78 a_crc64m_init(ctx->table, poly);
79 ctx->eval = a_crc64m;
81 lua_pushvalue(L, 1);
82 return 1;
85 /***
86 calculate for 64-bit Cyclic Redundancy Check
87 @tparam a.crc64 ctx 64-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_crc64_eval(lua_State *L)
95 struct crc64 *const ctx = (struct crc64 *)lua_touserdata(L, 1);
96 if (ctx)
98 size_t n = 0;
99 a_u64 value = 0;
100 char const *const p = luaL_checklstring(L, 2, &n);
101 if (lua_gettop(L) > 2) { value = lua_u64_get(L, 3); }
102 lua_u64_new(L, ctx->eval(ctx->table, p, n, value));
103 return 1;
105 return 0;
108 /***
109 pack a block and its 64-bit Cyclic Redundancy Check value
110 @tparam a.crc64 ctx 64-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_crc64_pack(lua_State *L)
118 struct crc64 *const ctx = (struct crc64 *)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_u64 value = 0;
128 char const *p = luaL_checklstring(L, 2, &n);
129 if (lua_gettop(L) > 2) { value = lua_u64_get(L, 3); }
130 u.s = lua_pushfstring(L, "%s ", p) + n;
131 value = ctx->eval(ctx->table, p, n, value);
132 ctx->eval == a_crc64m
133 ? a_u64_setb(u.p, value)
134 : a_u64_setl(u.p, value);
135 return 1;
137 return 0;
140 static int liba_crc64_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_crc64_get(lua_State *L)
159 struct crc64 const *const ctx = (struct crc64 const *)lua_touserdata(L, 1);
160 switch (a_hash_bkdr(lua_tostring(L, 2), 0))
162 case 0x014FE58A: // table
163 lua_array_u64_new(L, ctx->table, 0x100);
164 break;
165 case 0xA65758B2: // __index
166 lua_registry_get(L, liba_crc64_new);
167 lua_pushstring(L, "table");
168 lua_array_u64_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_crc64_(lua_State *L)
181 lua_pushcfunction(L, liba_crc64_new);
182 lua_replace(L, 1);
183 lua_call(L, lua_gettop(L) - 1, 1);
184 return 1;
187 int luaopen_liba_crc64(lua_State *L)
189 static lua_fun const funcs[] = {
190 {"new", liba_crc64_new},
191 {"gen", liba_crc64_gen},
192 {"eval", liba_crc64_eval},
193 {"pack", liba_crc64_pack},
195 lua_createtable(L, 0, A_LEN(funcs));
196 lua_fun_reg(L, -1, funcs, A_LEN(funcs));
197 lua_createtable(L, 0, 1);
198 lua_fun_set(L, -1, "__call", liba_crc64_);
199 lua_setmetatable(L, -2);
201 static lua_fun const metas[] = {
202 {"__newindex", liba_crc64_set},
203 {"__index", liba_crc64_get},
204 {"__call", liba_crc64_eval},
206 lua_createtable(L, 0, A_LEN(metas) + A_LEN(funcs) + 1);
207 lua_fun_reg(L, -1, metas, A_LEN(metas));
208 lua_fun_reg(L, -1, funcs, A_LEN(funcs));
209 lua_str_set(L, -1, "__name", "a.crc64");
210 lua_registry_set(L, liba_crc64_new);
212 return 1;