7 a_u32 (*eval
)(a_u32
const table
[0x100], void const *pdata
, a_size nbyte
, a_u32 value
);
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
)
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
; }
27 reversed
= JS_ToBool(ctx
, argv
[1]);
28 if (reversed
< 0) { goto fail
; }
32 a_crc32l_init(self
->table
, poly
);
33 self
->eval
= a_crc32l
;
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
);
49 JS_FreeValue(ctx
, clazz
);
53 static JSValue
liba_crc32_gen(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
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
; }
62 reversed
= JS_ToBool(ctx
, argv
[1]);
63 if (reversed
< 0) { return JS_EXCEPTION
; }
67 a_crc32l_init(self
->table
, poly
);
68 self
->eval
= a_crc32l
;
72 a_crc32m_init(self
->table
, poly
);
73 self
->eval
= a_crc32m
;
78 static JSValue
liba_crc32_eval(JSContext
*ctx
, JSValueConst this_val
, int argc
, JSValueConst
*argv
)
82 struct crc32
*const self
= (struct crc32
*)JS_GetOpaque2(ctx
, this_val
, liba_crc32_class_id
);
83 if (!self
) { return JS_EXCEPTION
; }
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
); }
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
;
109 struct crc32
*const self
= (struct crc32
*)JS_GetOpaque2(ctx
, this_val
, liba_crc32_class_id
);
110 if (!self
) { return JS_EXCEPTION
; }
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
); }
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);
125 JS_FreeCString(ctx
, s
);
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
);