rename A_VERSION_{C,EX} to A_VERSION_{0,1,2,3,4}
[liba.git] / quickjs / src / crc64.c
blob867192d69e5fd776a201e6ed7f3454f88a243145
1 #include "a.h"
2 #include "a/crc.h"
4 struct crc64
6 a_u64 table[0x100];
7 a_u64 (*eval)(a_u64 const table[0x100], void const *pdata, a_size nbyte, a_u64 value);
8 };
10 static JSClassID liba_crc64_class_id;
12 static void liba_crc64_finalizer(JSRuntime *rt, JSValue val)
14 js_free_rt(rt, JS_GetOpaque(val, liba_crc64_class_id));
17 static JSClassDef liba_crc64_class = {"crc64", .finalizer = liba_crc64_finalizer};
19 static JSValue liba_crc64_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
21 JSValue proto, clazz = JS_UNDEFINED;
22 struct crc64 *const self = (struct crc64 *)js_mallocz(ctx, sizeof(struct crc64));
23 if (!self) { return JS_EXCEPTION; }
24 a_i64 poly = 0;
25 if (JS_ToInt64Ext(ctx, &poly, argv[0])) { goto fail; }
26 int reversed = 0;
27 if (argc > 1)
29 reversed = JS_ToBool(ctx, argv[1]);
30 if (reversed < 0) { goto fail; }
32 if (reversed)
34 a_crc64l_init(self->table, (a_u64)poly);
35 self->eval = a_crc64l;
37 else
39 a_crc64m_init(self->table, (a_u64)poly);
40 self->eval = a_crc64m;
42 proto = JS_GetPropertyStr(ctx, new_target, "prototype");
43 if (JS_IsException(proto)) { goto fail; }
44 clazz = JS_NewObjectProtoClass(ctx, proto, liba_crc64_class_id);
45 JS_FreeValue(ctx, proto);
46 if (JS_IsException(clazz)) { goto fail; }
47 JS_SetOpaque(clazz, self);
48 return clazz;
49 fail:
50 js_free(ctx, self);
51 JS_FreeValue(ctx, clazz);
52 return JS_UNDEFINED;
55 static JSValue liba_crc64_gen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
57 struct crc64 *const self = (struct crc64 *)JS_GetOpaque2(ctx, this_val, liba_crc64_class_id);
58 if (!self) { return JS_EXCEPTION; }
59 a_i64 poly = 0;
60 if (JS_ToInt64Ext(ctx, &poly, argv[0])) { return JS_EXCEPTION; }
61 int reversed = 0;
62 if (argc > 1)
64 reversed = JS_ToBool(ctx, argv[1]);
65 if (reversed < 0) { return JS_EXCEPTION; }
67 if (reversed)
69 a_crc64l_init(self->table, (a_u64)poly);
70 self->eval = a_crc64l;
72 else
74 a_crc64m_init(self->table, (a_u64)poly);
75 self->eval = a_crc64m;
77 return JS_UNDEFINED;
80 static JSValue liba_crc64_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
82 struct crc64 *const self = (struct crc64 *)JS_GetOpaque2(ctx, this_val, liba_crc64_class_id);
83 if (!self) { return JS_EXCEPTION; }
84 a_u64 value = 0;
85 if (argc > 1)
87 a_i64 x = 0;
88 if (JS_ToInt64Ext(ctx, &x, argv[1])) { return JS_EXCEPTION; }
89 value = (a_u64)x;
91 size_t n = 0;
92 if (JS_IsArray(ctx, argv[0]))
94 a_byte *p = JS_GetArrayBuffer(ctx, &n, argv[0]);
95 if (p) { value = self->eval(self->table, p, n, value); }
97 else
99 char const *const p = JS_ToCStringLen(ctx, &n, argv[0]);
100 value = self->eval(self->table, p, n, value);
101 JS_FreeCString(ctx, p);
103 return JS_NewBigUint64(ctx, value);
106 static JSValue liba_crc64_pack(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
108 JSValue val = JS_UNDEFINED;
109 struct crc64 *const self = (struct crc64 *)JS_GetOpaque2(ctx, this_val, liba_crc64_class_id);
110 if (!self) { return JS_EXCEPTION; }
111 a_u64 value = 0;
112 if (argc > 1)
114 a_i64 x = 0;
115 if (JS_ToInt64Ext(ctx, &x, argv[1])) { return JS_EXCEPTION; }
116 value = (a_u64)x;
118 size_t n = 0;
119 char const *const s = JS_ToCStringLen(ctx, &n, argv[0]);
120 value = self->eval(self->table, s, n, value);
121 a_byte *p = (a_byte *)js_malloc(ctx, n + 8);
122 if (p) { a_copy(p, s, n); }
123 else { goto fail; }
124 self->eval == a_crc64m
125 ? a_u64_setb(p + n, value)
126 : a_u64_setl(p + n, value);
127 val = js_array_u8_new(ctx, p, (uint32_t)n + 8);
128 fail:
129 JS_FreeCString(ctx, s);
130 js_free(ctx, p);
131 return val;
134 enum
136 self_table_,
139 static JSValue liba_crc64_get(JSContext *ctx, JSValueConst this_val, int magic)
141 struct crc64 *const self = (struct crc64 *)JS_GetOpaque2(ctx, this_val, liba_crc64_class_id);
142 if (!self) { return JS_EXCEPTION; }
143 if (magic == self_table_)
145 return js_array_u64_new(ctx, self->table, 0x100);
147 return JS_UNDEFINED;
150 static JSCFunctionListEntry const liba_crc64_proto[] = {
151 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.crc64", 0),
152 JS_CGETSET_MAGIC_DEF("table", liba_crc64_get, NULL, self_table_),
153 JS_CFUNC_DEF("gen", 2, liba_crc64_gen),
154 JS_CFUNC_DEF("eval", 2, liba_crc64_eval),
155 JS_CFUNC_DEF("pack", 2, liba_crc64_pack),
158 int js_liba_crc64_init(JSContext *ctx, JSModuleDef *m)
160 JS_NewClassID(&liba_crc64_class_id);
161 JS_NewClass(JS_GetRuntime(ctx), liba_crc64_class_id, &liba_crc64_class);
163 JSValue const proto = JS_NewObject(ctx);
164 JS_SetPropertyFunctionList(ctx, proto, liba_crc64_proto, A_LEN(liba_crc64_proto));
166 JSValue const clazz = JS_NewCFunction2(ctx, liba_crc64_ctor, "crc64", 2, JS_CFUNC_constructor, 0);
167 JS_SetConstructor(ctx, clazz, proto);
168 JS_SetClassProto(ctx, liba_crc64_class_id, proto);
170 return JS_SetModuleExport(ctx, m, "crc64", clazz);