#include "cell.h" #include #include #define KIM_IMPLEMENTATION #include "kim.h" JSC_CCALL(kim_encode, const char *utf8_str = JS_ToCString(js, argv[0]); if (!utf8_str) return JS_EXCEPTION; // Count runes to estimate kim buffer size int rune_count = utf8_count(utf8_str); // Allocate kim buffer (worst case: 5 bytes per rune) size_t kim_size = rune_count * 5; char *kim_buffer = malloc(kim_size); char *kim_ptr = kim_buffer; // Encode utf8 to kim long long runes_encoded; utf8_to_kim(&utf8_str, &kim_ptr, &runes_encoded); // Calculate actual size used size_t actual_size = kim_ptr - kim_buffer; // Create blob with the encoded data ret = js_new_blob_stoned_copy(js, kim_buffer, actual_size); free(kim_buffer); JS_FreeCString(js, utf8_str); ) JSC_CCALL(kim_decode, size_t kim_len; void *kim_data = js_get_blob_data(js, &kim_len, argv[0]); if (kim_data == (void *)-1) return JS_EXCEPTION; if (!kim_data) return JS_NewString(js, ""); // Allocate UTF-8 buffer (worst case: 4 bytes per kim byte) size_t utf8_size = kim_len * 4; char *utf8_buffer = malloc(utf8_size + 1); // +1 for null terminator char *utf8_ptr = utf8_buffer; // Copy kim data since kim_to_utf8 modifies the pointer char *kim_copy = malloc(kim_len); memcpy(kim_copy, kim_data, kim_len); char *kim_ptr = kim_copy; // Count runes in kim data int rune_count = 0; char *temp_ptr = kim_copy; while (temp_ptr < kim_copy + kim_len) { decode_kim(&temp_ptr); rune_count++; } // Reset pointer and decode kim_ptr = kim_copy; kim_to_utf8(&kim_ptr, &utf8_ptr, rune_count); // Null terminate *utf8_ptr = '\0'; ret = JS_NewString(js, utf8_buffer); free(utf8_buffer); free(kim_copy); ) static const JSCFunctionListEntry js_kim_funcs[] = { MIST_FUNC_DEF(kim, encode, 1), MIST_FUNC_DEF(kim, decode, 1), }; JSValue js_kim_use(JSContext *js) { JSValue mod = JS_NewObject(js); JS_SetPropertyFunctionList(js, mod, js_kim_funcs, countof(js_kim_funcs)); return mod; }