release 0.1.13
[liba.git] / quickjs / src / crc8.c
blob38e01972479cc55dc0823811564da4e40a9cdb8a
1 #include "a.h"
2 #include "a/crc.h"
4 struct crc8
6 a_u8 table[0x100];
7 };
9 static JSClassID liba_crc8_class_id;
11 static void liba_crc8_finalizer(JSRuntime *rt, JSValue val)
13 js_free_rt(rt, JS_GetOpaque(val, liba_crc8_class_id));
16 static JSClassDef liba_crc8_class = {"crc8", .finalizer = liba_crc8_finalizer};
18 static JSValue liba_crc8_ctor(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv)
20 JSValue proto, clazz = JS_UNDEFINED;
21 struct crc8 *const self = (struct crc8 *)js_mallocz(ctx, sizeof(struct crc8));
22 if (!self) { return JS_EXCEPTION; }
23 a_u32 poly = 0;
24 if (JS_ToUint32(ctx, &poly, argv[0])) { goto fail; }
25 int reversed = 0;
26 if (argc > 1)
28 reversed = JS_ToBool(ctx, argv[1]);
29 if (reversed < 0) { goto fail; }
31 reversed
32 ? a_crc8l_init(self->table, (a_u8)poly)
33 : a_crc8m_init(self->table, (a_u8)poly);
34 proto = JS_GetPropertyStr(ctx, new_target, "prototype");
35 if (JS_IsException(proto)) { goto fail; }
36 clazz = JS_NewObjectProtoClass(ctx, proto, liba_crc8_class_id);
37 JS_FreeValue(ctx, proto);
38 if (JS_IsException(clazz)) { goto fail; }
39 JS_SetOpaque(clazz, self);
40 return clazz;
41 fail:
42 js_free(ctx, self);
43 JS_FreeValue(ctx, clazz);
44 return JS_UNDEFINED;
47 static JSValue liba_crc8_gen(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
49 struct crc8 *const self = (struct crc8 *)JS_GetOpaque2(ctx, this_val, liba_crc8_class_id);
50 if (!self) { return JS_EXCEPTION; }
51 a_u32 poly = 0;
52 if (JS_ToUint32(ctx, &poly, argv[0])) { return JS_EXCEPTION; }
53 int reversed = 0;
54 if (argc > 1)
56 reversed = JS_ToBool(ctx, argv[1]);
57 if (reversed < 0) { return JS_EXCEPTION; }
59 reversed
60 ? a_crc8l_init(self->table, (a_u8)poly)
61 : a_crc8m_init(self->table, (a_u8)poly);
62 return JS_UNDEFINED;
65 static JSValue liba_crc8_eval(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
67 struct crc8 *const self = (struct crc8 *)JS_GetOpaque2(ctx, this_val, liba_crc8_class_id);
68 if (!self) { return JS_EXCEPTION; }
69 a_u8 value = 0;
70 if (argc > 1)
72 a_u32 x = 0;
73 if (JS_ToUint32(ctx, &x, argv[1])) { return JS_EXCEPTION; }
74 value = (a_u8)x;
76 size_t n = 0;
77 if (JS_IsArray(ctx, argv[0]))
79 a_byte *p = JS_GetArrayBuffer(ctx, &n, argv[0]);
80 if (p) { value = a_crc8(self->table, p, n, value); }
82 else
84 char const *const p = JS_ToCStringLen(ctx, &n, argv[0]);
85 value = a_crc8(self->table, p, n, value);
86 JS_FreeCString(ctx, p);
88 return JS_NewUint32(ctx, value);
91 static JSValue liba_crc8_pack(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv)
93 JSValue val = JS_UNDEFINED;
94 struct crc8 *const self = (struct crc8 *)JS_GetOpaque2(ctx, this_val, liba_crc8_class_id);
95 if (!self) { return JS_EXCEPTION; }
96 a_u8 value = 0;
97 if (argc > 1)
99 a_u32 x = 0;
100 if (JS_ToUint32(ctx, &x, argv[1])) { return JS_EXCEPTION; }
101 value = (a_u8)x;
103 size_t n = 0;
104 char const *const s = JS_ToCStringLen(ctx, &n, argv[0]);
105 value = a_crc8(self->table, s, n, value);
106 a_byte *p = (a_byte *)js_malloc(ctx, n + 1);
107 if (p) { a_copy(p, s, n); }
108 else { goto fail; }
109 p[n] = value;
110 val = js_array_u8_new(ctx, p, (uint32_t)n + 1);
111 fail:
112 JS_FreeCString(ctx, s);
113 js_free(ctx, p);
114 return val;
117 enum
119 self_table,
122 static JSValue liba_crc8_get(JSContext *ctx, JSValueConst this_val, int magic)
124 struct crc8 *const self = (struct crc8 *)JS_GetOpaque2(ctx, this_val, liba_crc8_class_id);
125 if (!self) { return JS_EXCEPTION; }
126 if (magic == self_table)
128 return js_array_u8_new(ctx, self->table, 0x100);
130 return JS_UNDEFINED;
133 static JSCFunctionListEntry const liba_crc8_proto[] = {
134 JS_PROP_STRING_DEF("[Symbol.toStringTag]", "a.crc8", 0),
135 JS_CGETSET_MAGIC_DEF("table", liba_crc8_get, NULL, self_table),
136 JS_CFUNC_DEF("gen", 2, liba_crc8_gen),
137 JS_CFUNC_DEF("eval", 2, liba_crc8_eval),
138 JS_CFUNC_DEF("pack", 2, liba_crc8_pack),
141 int js_liba_crc8_init(JSContext *ctx, JSModuleDef *m)
143 JS_NewClassID(&liba_crc8_class_id);
144 JS_NewClass(JS_GetRuntime(ctx), liba_crc8_class_id, &liba_crc8_class);
146 JSValue const proto = JS_NewObject(ctx);
147 JS_SetPropertyFunctionList(ctx, proto, liba_crc8_proto, A_LEN(liba_crc8_proto));
149 JSValue const clazz = JS_NewCFunction2(ctx, liba_crc8_ctor, "crc8", 2, JS_CFUNC_constructor, 0);
150 JS_SetConstructor(ctx, clazz, proto);
151 JS_SetClassProto(ctx, liba_crc8_class_id, proto);
153 return JS_SetModuleExport(ctx, m, "crc8", clazz);