Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions docs/docs/stdlib.md
Original file line number Diff line number Diff line change
Expand Up @@ -566,15 +566,15 @@ Return true if there was an error.

Clear the error indication.

#### `read(buffer, position, length)`
#### `read(buffer, position = 0, length = buffer.length)`

Read `length` bytes from the file to the ArrayBuffer `buffer` at byte
position `position` (wrapper to the libc `fread`).
position `position`. Wrapper to the libc function `fread`.

#### `write(buffer, position, length)`
#### `write(buffer, position = 0, length = buffer.length)`

Write `length` bytes to the file from the ArrayBuffer `buffer` at byte
position `position` (wrapper to the libc `fwrite`).
Write `length` bytes to the file from the ArrayBuffer or string `buffer`
at byte position `position`. Wrapper to the libc function `fwrite`.

#### `getline()`

Expand Down
32 changes: 24 additions & 8 deletions quickjs-libc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1519,25 +1519,41 @@ static JSValue js_std_file_read_write(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int magic)
{
FILE *f = js_std_file_get(ctx, this_val);
bool is_write = (magic != 0);
uint64_t pos, len;
size_t size, ret;
const char *str;
uint8_t *buf;

if (!f)
return JS_EXCEPTION;
if (JS_ToIndex(ctx, &pos, argv[1]))
pos = 0;
if (argc > 1 && JS_ToIndex(ctx, &pos, argv[1]))
return JS_EXCEPTION;
if (JS_ToIndex(ctx, &len, argv[2]))
len = 0;
if (argc > 2 && JS_ToIndex(ctx, &len, argv[2]))
return JS_EXCEPTION;
buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
if (is_write && JS_IsString(argv[0])) {
str = JS_ToCStringLen(ctx, &size, argv[0]);
buf = (void *)str;
} else {
str = NULL;
buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
}
if (!buf)
return JS_EXCEPTION;
if (pos > size)
pos = size;
if (argc < 3)
len = size - pos;
if (pos + len > size)
return JS_ThrowRangeError(ctx, "read/write array buffer overflow");
if (magic)
len = size - pos;
if (is_write) {
ret = fwrite(buf + pos, 1, len, f);
else
} else {
ret = fread(buf + pos, 1, len, f);
}
JS_FreeCString(ctx, str);
return JS_NewInt64(ctx, ret);
}

Expand Down Expand Up @@ -1909,8 +1925,8 @@ static const JSCFunctionListEntry js_std_file_proto_funcs[] = {
JS_CFUNC_DEF("fileno", 0, js_std_file_fileno ),
JS_CFUNC_DEF("error", 0, js_std_file_error ),
JS_CFUNC_DEF("clearerr", 0, js_std_file_clearerr ),
JS_CFUNC_MAGIC_DEF("read", 3, js_std_file_read_write, 0 ),
JS_CFUNC_MAGIC_DEF("write", 3, js_std_file_read_write, 1 ),
JS_CFUNC_MAGIC_DEF("read", 1, js_std_file_read_write, 0 ),
JS_CFUNC_MAGIC_DEF("write", 1, js_std_file_read_write, 1 ),
JS_CFUNC_DEF("getline", 0, js_std_file_getline ),
JS_CFUNC_MAGIC_DEF("readAsArrayBuffer", 0, js_std_file_readAs, 0 ),
JS_CFUNC_MAGIC_DEF("readAsString", 0, js_std_file_readAs, 1 ),
Expand Down
13 changes: 12 additions & 1 deletion tests/test_std.js
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,18 @@ function test_os()
[fpath, fd] = os.mkstemp(`${fdir}/XXXXXX`);
assert(fdir.startsWith(`${fdir}`));
assert(fd >= 0);
os.close(fd);

const f = std.fdopen(fd, "w+");
f.write("xyzzy");
f.flush();
const b = new Uint8Array(5);
f.seek(0, std.SEEK_SET);
assert(5, f.read(b.buffer));
const s = [...b].map(c => String.fromCharCode(c)).join("");
assert(s, "xyzzy");
f.seek(0, std.SEEK_SET);
assert(0, f.read(b.buffer, 5, 42));
f.close();

assert(os.remove(fpath), 0);
assert(os.remove(fdir), 0);
Expand Down