a_linalg_{Tnn,Tmn}->{T1,T2}
[liba.git] / quickjs / src / crc16.c
blobb001a856935335b608ca7df0eb21900d84c81c8f
1 #include "a.h"
2 #include "a/crc.h"
4 struct crc16
6 a_u16 table[0x100];
7 a_u16 (*eval)(a_u16 const table[0x100], void const *pdata, a_size nbyte, a_u16 value);
8 };
10 static JSClassID liba_crc16_class_id;
12 static void liba_crc16_finalizer(JSRuntime *rt, JSValue val)
14 js_free_rt(rt, JS_GetOpaque(val, liba_crc16_class_id));
17 static JSValue liba_crc16_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 crc16 *const self = (struct crc16 *)js_mallocz(ctx, sizeof(struct crc16));
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_crc16l_init(self->table, (a_u16)poly);
33 self->eval = a_crc16l;
35 else
37 a_crc16m_init(self->table, (a_u16)poly);
38 self->eval = a_crc16m;
40 proto = JS_GetPropertyStr(ctx, new_target, "prototype");
41 if (JS_IsException(proto)) { goto fail; }
42 clazz = JS_NewObjectProtoClass(ctx, proto, liba_crc16_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_crc16_gen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
55 a_u32 poly = 0;
56 int reversed = 0;
57 struct crc16 *const self = (struct crc16 *)JS_GetOpaque2(ctx, this_val, liba_crc16_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_crc16l_init(self->table, (a_u16)poly);
68 self->eval = a_crc16l;
70 else
72 a_crc16m_init(self->table, (a_u16)poly);
73 self->eval = a_crc16m;
75 return JS_UNDEFINED;
78 static JSValue liba_crc16_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
80 size_t n = 0;
81 a_u16 value = 0;
82 struct crc16 *const self = (struct crc16 *)JS_GetOpaque2(ctx, this_val, liba_crc16_class_id);
83 if (!self) { return JS_EXCEPTION; }
84 if (argc > 1)
86 a_u32 x = 0;
87 if (JS_ToUint32(ctx, &x, argv[1])) { return JS_EXCEPTION; }
88 value = (a_u16)x;
90 if (JS_IsArray(ctx, argv[0]))
92 a_byte *p = JS_GetArrayBuffer(ctx, &n, argv[0]);
93 if (p) { value = self->eval(self->table, p, n, value); }
95 else
97 char const *const p = JS_ToCStringLen(ctx, &n, argv[0]);
98 value = self->eval(self->table, p, n, value);
99 JS_FreeCString(ctx, p);
101 return JS_NewUint32(ctx, value);
104 static JSValue liba_crc16_pack(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
106 JSValue val = JS_UNDEFINED;
107 a_u16 value = 0;
108 size_t n = 0;
109 char const *s;
110 a_byte *p;
111 struct crc16 *const self = (struct crc16 *)JS_GetOpaque2(ctx, this_val, liba_crc16_class_id);
112 if (!self) { return JS_EXCEPTION; }
113 if (argc > 1)
115 a_u32 x = 0;
116 if (JS_ToUint32(ctx, &x, argv[1])) { return JS_EXCEPTION; }
117 value = (a_u16)x;
119 s = JS_ToCStringLen(ctx, &n, argv[0]);
120 value = self->eval(self->table, s, n, value);
121 p = (a_byte *)js_malloc(ctx, n + 2);
122 if (p) { a_copy(p, s, n); }
123 else { goto fail; }
124 self->eval == a_crc16m
125 ? a_u16_setb(p + n, value)
126 : a_u16_setl(p + n, value);
127 val = js_array_u8_new(ctx, p, (uint32_t)n + 2);
128 fail:
129 JS_FreeCString(ctx, s);
130 js_free(ctx, p);
131 return val;
134 static JSValue liba_crc16_get(JSContext *ctx, JSValueConst this_val)
136 struct crc16 *const self = (struct crc16 *)JS_GetOpaque2(ctx, this_val, liba_crc16_class_id);
137 if (!self) { return JS_EXCEPTION; }
138 return js_array_u16_new(ctx, self->table, 0x100);
141 static JSClassDef liba_crc16_class;
142 static JSCFunctionListEntry const liba_crc16_proto[] = {
143 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.crc16", 0),
144 JS_CGETSET_DEF("table", liba_crc16_get, NULL),
145 JS_CFUNC_DEF("gen", 2, liba_crc16_gen),
146 JS_CFUNC_DEF("eval", 2, liba_crc16_eval),
147 JS_CFUNC_DEF("pack", 2, liba_crc16_pack),
150 int js_liba_crc16_init(JSContext *ctx, JSModuleDef *m)
152 JSValue proto, clazz;
153 liba_crc16_class.class_name = "crc16";
154 liba_crc16_class.finalizer = liba_crc16_finalizer;
156 JS_NewClassID(&liba_crc16_class_id);
157 JS_NewClass(JS_GetRuntime(ctx), liba_crc16_class_id, &liba_crc16_class);
159 proto = JS_NewObject(ctx);
160 JS_SetPropertyFunctionList(ctx, proto, liba_crc16_proto, A_LEN(liba_crc16_proto));
162 clazz = JS_NewCFunction2(ctx, liba_crc16_ctor, "crc16", 2, JS_CFUNC_constructor, 0);
163 JS_SetClassProto(ctx, liba_crc16_class_id, proto);
164 JS_SetConstructor(ctx, clazz, proto);
166 return JS_SetModuleExport(ctx, m, "crc16", clazz);