Skip to content

Commit 58fd683

Browse files
fix stdin for multiple read
1 parent d361125 commit 58fd683

File tree

4 files changed

+50
-14
lines changed

4 files changed

+50
-14
lines changed

src/features/fd.ts

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,33 @@ class WritableTextProxy implements FdEntry {
3030
close(): void {}
3131
}
3232

33-
class ReadableTextProxy implements FdEntry {
33+
export class ReadableTextProxy implements FdEntry {
3434
private encoder = new TextEncoder();
35-
private pending: Uint8Array | null;
35+
private pending: Uint8Array | null = null;
3636
constructor(private readonly consume: () => string) { }
3737

3838
writev(_iovs: Uint8Array[]): number {
3939
return 0;
4040
}
41+
consumePending(pending: Uint8Array, requestLength: number): Uint8Array {
42+
if (pending.byteLength < requestLength) {
43+
this.pending = null
44+
return pending;
45+
} else {
46+
const result = pending.slice(0, requestLength);
47+
this.pending = pending.slice(requestLength);
48+
return result;
49+
}
50+
}
4151
readv(iovs: Uint8Array[]): number {
4252
let read = 0;
4353
for (const buffer of iovs) {
4454
let remaining = buffer.byteLength;
4555
if (this.pending) {
46-
const reading = Math.min(remaining, this.pending.byteLength);
47-
buffer.set(this.pending.slice(0, reading), 0);
48-
remaining -= reading;
49-
if (remaining < this.pending.byteLength) {
50-
this.pending = this.pending.slice(reading);
51-
continue;
52-
} else {
53-
this.pending = null;
54-
}
56+
const consumed = this.consumePending(this.pending, remaining);
57+
buffer.set(consumed, 0);
58+
remaining -= consumed.byteLength;
59+
read += consumed.byteLength;
5560
}
5661
while (remaining > 0) {
5762
const newText = this.consume();

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export * from "./features/all";
55
export * from "./features/args";
66
export * from "./features/clock";
77
export * from "./features/environ";
8-
export * from "./features/fd";
8+
export { useFS, useStdio } from "./features/fd";
99
export * from "./features/proc";
1010
export * from "./features/random";
1111
export * from "./features/tracing";

test/fd.test.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { ReadableTextProxy } from "../src/features/fd"
2+
3+
describe("fd.ReadableTextProxy", () => {
4+
it("readv single buffer", () => {
5+
const input = "hello";
6+
const inputs = [input];
7+
const proxy = new ReadableTextProxy(() => inputs.shift() || "");
8+
const buffer = new Uint8Array(10);
9+
const read = proxy.readv([buffer]);
10+
expect(read).toBe(5);
11+
const expected = new TextEncoder().encode(input)
12+
expect(buffer.slice(0, 5)).toEqual(expected);
13+
})
14+
15+
it("readv 2 buffer", () => {
16+
const input = "hello";
17+
const inputs = [input];
18+
const proxy = new ReadableTextProxy(() => inputs.shift() || "");
19+
const buf0 = new Uint8Array(2);
20+
const buf1 = new Uint8Array(2);
21+
const read = proxy.readv([buf0, buf1]);
22+
expect(read).toBe(4);
23+
const expected = new TextEncoder().encode(input)
24+
expect(buf0).toEqual(expected.slice(0, 2));
25+
expect(buf1).toEqual(expected.slice(2, 4));
26+
})
27+
})

test/wasi-test-suite/harness.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { readFile } from "fs/promises";
66
export async function runTest(filePath: string) {
77
let stdout = "";
88
let stderr = "";
9-
const stdin = await (async () => {
9+
let stdin = await (async () => {
1010
const path = filePath.replace(/\.wasm$/, ".stdin");
1111
if (!existsSync(path)) {
1212
return "";
@@ -16,7 +16,11 @@ export async function runTest(filePath: string) {
1616
const features = [
1717
useEnviron, useArgs, useClock, useProc,
1818
useRandom(), useStdio({
19-
stdin: () => { return stdin },
19+
stdin: () => {
20+
const result = stdin;
21+
stdin = "";
22+
return result;
23+
},
2024
stdout: (lines) => { stdout += lines },
2125
stderr: (lines) => { stderr += lines },
2226
})

0 commit comments

Comments
 (0)