From 2e8f052ceaba79c2377bf8475cdf06f6bf15bf3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 2 Dec 2024 11:15:02 +0100 Subject: [PATCH] Add ability to load file as Uint8Array in std.loadFile --- docs/docs/stdlib.md | 6 +++-- quickjs-libc.c | 55 +++++++++++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 21 deletions(-) diff --git a/docs/docs/stdlib.md b/docs/docs/stdlib.md index 1e383e82..1cb447ec 100644 --- a/docs/docs/stdlib.md +++ b/docs/docs/stdlib.md @@ -311,7 +311,7 @@ The worker class has the following static properties: worker and is used to send or receive messages. The worker instances have the following properties: - + - `postMessage(msg)` - Send a message to the corresponding worker. `msg` is cloned in the destination worker using an algorithm similar to the `HTML` structured clone algorithm. `SharedArrayBuffer` are shared @@ -348,11 +348,13 @@ optional properties: Evaluate the file `filename` as a script (global eval). -### `loadFile(filename)` +### `loadFile(filename, [options])` Load the file `filename` and return it as a string assuming UTF-8 encoding. Return `null` in case of I/O error. +If `options.binary` is set to `true` a `Uint8Array` is returned instead. + ### `open(filename, flags, errorObj = undefined)` Open a file (wrapper to the libc `fopen()`). Return the FILE diff --git a/quickjs-libc.c b/quickjs-libc.c index c1107de6..1f21b464 100644 --- a/quickjs-libc.c +++ b/quickjs-libc.c @@ -478,14 +478,41 @@ static JSValue js_loadScript(JSContext *ctx, JSValue this_val, return ret; } -/* load a file as a UTF-8 encoded string */ +static int get_bool_option(JSContext *ctx, BOOL *pbool, + JSValue obj, + const char *option) +{ + JSValue val; + val = JS_GetPropertyStr(ctx, obj, option); + if (JS_IsException(val)) + return -1; + if (!JS_IsUndefined(val)) { + *pbool = JS_ToBool(ctx, val); + } + JS_FreeValue(ctx, val); + return 0; +} + +static void free_buf(JSRuntime *rt, void *opaque, void *ptr) { + js_free_rt(rt, ptr); +} + +/* load a file as a UTF-8 encoded string or Uint8Array */ static JSValue js_std_loadFile(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) { uint8_t *buf; const char *filename; - JSValue ret; + JSValue ret, options_obj; size_t buf_len; + BOOL binary = FALSE; + + if (argc >= 2) { + options_obj = argv[1]; + if (get_bool_option(ctx, &binary, options_obj, + "binary")) + return JS_EXCEPTION; + } filename = JS_ToCString(ctx, argv[0]); if (!filename) @@ -494,8 +521,13 @@ static JSValue js_std_loadFile(JSContext *ctx, JSValue this_val, JS_FreeCString(ctx, filename); if (!buf) return JS_NULL; - ret = JS_NewStringLen(ctx, (char *)buf, buf_len); - js_free(ctx, buf); + if (binary) { + ret = JS_NewUint8Array(ctx, buf, buf_len, free_buf, NULL, FALSE); + } else { + ret = JS_NewStringLen(ctx, (char *)buf, buf_len); + js_free(ctx, buf); + } + return ret; } @@ -822,21 +854,6 @@ static int interrupt_handler(JSRuntime *rt, void *opaque) return (os_pending_signals >> SIGINT) & 1; } -static int get_bool_option(JSContext *ctx, BOOL *pbool, - JSValue obj, - const char *option) -{ - JSValue val; - val = JS_GetPropertyStr(ctx, obj, option); - if (JS_IsException(val)) - return -1; - if (!JS_IsUndefined(val)) { - *pbool = JS_ToBool(ctx, val); - } - JS_FreeValue(ctx, val); - return 0; -} - static JSValue js_evalScript(JSContext *ctx, JSValue this_val, int argc, JSValue *argv) {