bump copyright year to 2025
[liba.git] / quickjs / src / crc32.c
blob21b7a98edc51683c9846cbe48fb7983ccf368292
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 JSValue liba_crc32_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
19 a_u32 poly = 0;
20 int reversed = 0;
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 if (JS_ToUint32(ctx, &poly, argv[0])) { goto fail; }
25 if (argc > 1)
27 reversed = JS_ToBool(ctx, argv[1]);
28 if (reversed < 0) { goto fail; }
30 if (reversed)
32 a_crc32l_init(self->table, poly);
33 self->eval = a_crc32l;
35 else
37 a_crc32m_init(self->table, poly);
38 self->eval = a_crc32m;
40 proto = JS_GetPropertyStr(ctx, new_target, "prototype");
41 if (JS_IsException(proto)) { goto fail; }
42 clazz = JS_NewObjectProtoClass(ctx, proto, liba_crc32_class_id);
43 JS_FreeValue(ctx, proto);
44 if (JS_IsException(clazz)) { goto fail; }
45 JS_SetOpaque(clazz, self);
46 return clazz;
47 fail:
48 js_free(ctx, self);
49 JS_FreeValue(ctx, clazz);
50 return JS_UNDEFINED;
53 static JSValue liba_crc32_gen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
55 a_u32 poly = 0;
56 int reversed = 0;
57 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
58 if (!self) { return JS_EXCEPTION; }
59 if (JS_ToUint32(ctx, &poly, argv[0])) { return JS_EXCEPTION; }
60 if (argc > 1)
62 reversed = JS_ToBool(ctx, argv[1]);
63 if (reversed < 0) { return JS_EXCEPTION; }
65 if (reversed)
67 a_crc32l_init(self->table, poly);
68 self->eval = a_crc32l;
70 else
72 a_crc32m_init(self->table, poly);
73 self->eval = a_crc32m;
75 return JS_UNDEFINED;
78 static JSValue liba_crc32_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
80 size_t n = 0;
81 a_u32 value = 0;
82 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
83 if (!self) { return JS_EXCEPTION; }
84 if (argc > 1)
86 if (JS_ToUint32(ctx, &value, argv[1])) { return JS_EXCEPTION; }
88 if (JS_IsArray(ctx, argv[0]))
90 a_byte *p = JS_GetArrayBuffer(ctx, &n, argv[0]);
91 if (p) { value = self->eval(self->table, p, n, value); }
93 else
95 char const *const p = JS_ToCStringLen(ctx, &n, argv[0]);
96 value = self->eval(self->table, p, n, value);
97 JS_FreeCString(ctx, p);
99 return JS_NewUint32(ctx, value);
102 static JSValue liba_crc32_pack(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
104 JSValue val = JS_UNDEFINED;
105 a_u32 value = 0;
106 size_t n = 0;
107 char const *s;
108 a_byte *p;
109 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
110 if (!self) { return JS_EXCEPTION; }
111 if (argc > 1)
113 if (JS_ToUint32(ctx, &value, argv[1])) { return JS_EXCEPTION; }
115 s = JS_ToCStringLen(ctx, &n, argv[0]);
116 value = self->eval(self->table, s, n, value);
117 p = (a_byte *)js_malloc(ctx, n + 4);
118 if (p) { a_copy(p, s, n); }
119 else { goto fail; }
120 self->eval == a_crc32m
121 ? a_u32_setb(p + n, value)
122 : a_u32_setl(p + n, value);
123 val = js_array_u8_new(ctx, p, (uint32_t)n + 4);
124 fail:
125 JS_FreeCString(ctx, s);
126 js_free(ctx, p);
127 return val;
130 static JSValue liba_crc32_get(JSContext *ctx, JSValueConst this_val)
132 struct crc32 *const self = (struct crc32 *)JS_GetOpaque2(ctx, this_val, liba_crc32_class_id);
133 if (!self) { return JS_EXCEPTION; }
134 return js_array_u32_new(ctx, self->table, 0x100);
137 static JSClassDef liba_crc32_class;
138 static JSCFunctionListEntry const liba_crc32_proto[] = {
139 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.crc32", 0),
140 JS_CGETSET_DEF("table", liba_crc32_get, NULL),
141 JS_CFUNC_DEF("gen", 2, liba_crc32_gen),
142 JS_CFUNC_DEF("eval", 2, liba_crc32_eval),
143 JS_CFUNC_DEF("pack", 2, liba_crc32_pack),
146 int js_liba_crc32_init(JSContext *ctx, JSModuleDef *m)
148 JSValue proto, clazz;
149 liba_crc32_class.class_name = "crc32";
150 liba_crc32_class.finalizer = liba_crc32_finalizer;
152 JS_NewClassID(&liba_crc32_class_id);
153 JS_NewClass(JS_GetRuntime(ctx), liba_crc32_class_id, &liba_crc32_class);
155 proto = JS_NewObject(ctx);
156 JS_SetPropertyFunctionList(ctx, proto, liba_crc32_proto, A_LEN(liba_crc32_proto));
158 clazz = JS_NewCFunction2(ctx, liba_crc32_ctor, "crc32", 2, JS_CFUNC_constructor, 0);
159 JS_SetClassProto(ctx, liba_crc32_class_id, proto);
160 JS_SetConstructor(ctx, clazz, proto);
162 return JS_SetModuleExport(ctx, m, "crc32", clazz);