rename other to that
[liba.git] / quickjs / src / crc32.c
blob76c86b3e8ee9e31c82a2bcb20f818e9c55d6bce8
1 #include "a.h"
2 #include "a/crc.h"
4 struct crc32
6 a_u32 table[0x100];
7 a_u32 (*eval)(a_u32 const table[0x100], void const *pdata, a_size nbyte, a_u32 value);
8 };
10 static JSClassID liba_crc32_class_id;
12 static void liba_crc32_finalizer(JSRuntime *rt, JSValue val)
14 js_free_rt(rt, JS_GetOpaque(val, liba_crc32_class_id));
17 static JSClassDef liba_crc32_class = {"crc32", .finalizer = liba_crc32_finalizer};
19 static JSValue liba_crc32_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
21 JSValue proto, clazz = JS_UNDEFINED;
22 struct crc32 *const self = (struct crc32 *)js_mallocz(ctx, sizeof(struct crc32));
23 if (!self) { return JS_EXCEPTION; }
24 a_u32 poly = 0;
25 if (JS_ToUint32(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_crc32l_init(self->table, poly);
35 self->eval = a_crc32l;
37 else
39 a_crc32m_init(self->table, poly);
40 self->eval = a_crc32m;
42 proto = JS_GetPropertyStr(ctx, new_target, "prototype");
43 if (JS_IsException(proto)) { goto fail; }
44 clazz = JS_NewObjectProtoClass(ctx, proto, liba_crc32_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_crc32_get(JSContext *ctx, JSValueConst this_val, int magic)
57 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
58 if (!self) { return JS_EXCEPTION; }
59 if (magic == 0)
61 return js_array_u32_new(ctx, self->table, 0x100);
63 return JS_UNDEFINED;
66 static JSValue liba_crc32_gen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
68 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
69 if (!self) { return JS_EXCEPTION; }
70 a_u32 poly = 0;
71 if (JS_ToUint32(ctx, &poly, argv[0])) { return JS_EXCEPTION; }
72 int reversed = 0;
73 if (argc > 1)
75 reversed = JS_ToBool(ctx, argv[1]);
76 if (reversed < 0) { return JS_EXCEPTION; }
78 if (reversed)
80 a_crc32l_init(self->table, poly);
81 self->eval = a_crc32l;
83 else
85 a_crc32m_init(self->table, poly);
86 self->eval = a_crc32m;
88 return JS_UNDEFINED;
91 static JSValue liba_crc32_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
93 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
94 if (!self) { return JS_EXCEPTION; }
95 a_u32 value = 0;
96 if (argc > 1)
98 if (JS_ToUint32(ctx, &value, argv[1])) { return JS_EXCEPTION; }
100 size_t n = 0;
101 if (JS_IsArray(ctx, argv[0]))
103 a_byte *p = JS_GetArrayBuffer(ctx, &n, argv[0]);
104 if (p) { value = self->eval(self->table, p, n, value); }
106 else
108 char const *const p = JS_ToCStringLen(ctx, &n, argv[0]);
109 value = self->eval(self->table, p, n, value);
110 JS_FreeCString(ctx, p);
112 return JS_NewUint32(ctx, value);
115 static JSValue liba_crc32_pack(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
117 JSValue val = JS_UNDEFINED;
118 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
119 if (!self) { return JS_EXCEPTION; }
120 a_u32 value = 0;
121 if (argc > 1)
123 if (JS_ToUint32(ctx, &value, argv[1])) { return JS_EXCEPTION; }
125 size_t n = 0;
126 char const *const s = JS_ToCStringLen(ctx, &n, argv[0]);
127 value = self->eval(self->table, s, n, value);
128 a_byte *p = (a_byte *)js_malloc(ctx, n + 4);
129 if (p) { a_copy(p, s, n); }
130 else { goto fail; }
131 self->eval == a_crc32m
132 ? a_u32_setb(p + n, value)
133 : a_u32_setl(p + n, value);
134 val = js_array_u8_new(ctx, p, (uint32_t)n + 4);
135 fail:
136 JS_FreeCString(ctx, s);
137 js_free(ctx, p);
138 return val;
141 static JSCFunctionListEntry const liba_crc32_proto[] = {
142 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.crc32", 0),
143 JS_CGETSET_MAGIC_DEF("table", liba_crc32_get, NULL, 0),
144 JS_CFUNC_DEF("gen", 2, liba_crc32_gen),
145 JS_CFUNC_DEF("eval", 2, liba_crc32_eval),
146 JS_CFUNC_DEF("pack", 2, liba_crc32_pack),
149 int js_liba_crc32_init(JSContext *ctx, JSModuleDef *m)
151 JS_NewClassID(&liba_crc32_class_id);
152 JS_NewClass(JS_GetRuntime(ctx), liba_crc32_class_id, &liba_crc32_class);
154 JSValue const proto = JS_NewObject(ctx);
155 JS_SetPropertyFunctionList(ctx, proto, liba_crc32_proto, A_LEN(liba_crc32_proto));
157 JSValue const clazz = JS_NewCFunction2(ctx, liba_crc32_ctor, "crc32", 2, JS_CFUNC_constructor, 0);
158 JS_SetConstructor(ctx, clazz, proto);
159 JS_SetClassProto(ctx, liba_crc32_class_id, proto);
161 return JS_SetModuleExport(ctx, m, "crc32", clazz);