mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-06 08:23:19 +08:00
Add no empty chunk to a byte-mode Readable's buffer (#2217)
This commit is contained in:
+6
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"order": [
|
||||
"<repo>/tests/corpus/7516-readable-empty-push.ts"
|
||||
],
|
||||
"diags": []
|
||||
}
|
||||
@@ -954,8 +954,14 @@ static bool scr_stream_add_chunk(ScrStream *s, ScrBytes *chunk, bool front) {
|
||||
}
|
||||
entry = dec; /* owned */
|
||||
} else {
|
||||
entry = scr_bytes_retain(chunk);
|
||||
entry_len = chunk->len;
|
||||
if (entry_len == 0) {
|
||||
/* Node's readableAddChunk adds no empty chunk outside object mode:
|
||||
* it clears reading and may read more */
|
||||
if (!front) scr_stream_maybe_read_more(s);
|
||||
return !st->r.ended && (st->r.length < st->r.hwm || st->r.length == 0);
|
||||
}
|
||||
entry = scr_bytes_retain(chunk);
|
||||
}
|
||||
if (entry_len > 0 &&
|
||||
st->r.flowing == 1 && st->r.length == 0 && !st->r.in_read_sync && !front &&
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
// readable.push() of an empty Buffer outside object mode adds nothing, as
|
||||
// in Node: the chunks pushed after it still reach 'data' listeners,
|
||||
// readline and read(), and push(null) still ends the stream. In object
|
||||
// mode an empty Buffer is a value like any other.
|
||||
import { createInterface } from "node:readline";
|
||||
import { Readable } from "node:stream";
|
||||
|
||||
function lines(chunks: string[]): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
const src = new Readable({ read() {} });
|
||||
const rl = createInterface({ input: src, crlfDelay: Infinity });
|
||||
rl.on("line", (line: string) => console.log("line", JSON.stringify(line)));
|
||||
rl.on("close", () => {
|
||||
console.log("readline closed");
|
||||
resolve();
|
||||
});
|
||||
for (const chunk of chunks) src.push(Buffer.from(chunk, "utf8"));
|
||||
src.push(null);
|
||||
});
|
||||
}
|
||||
|
||||
function data(): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
const src = new Readable({ read() {} });
|
||||
src.on("data", (chunk: Buffer) => console.log("data", JSON.stringify(String(chunk))));
|
||||
src.on("end", () => {
|
||||
console.log("data end");
|
||||
resolve();
|
||||
});
|
||||
console.log("push a", src.push(Buffer.from("a")));
|
||||
console.log("push empty", src.push(Buffer.alloc(0)));
|
||||
console.log("push b", src.push(Buffer.from("b")));
|
||||
src.push(null);
|
||||
});
|
||||
}
|
||||
|
||||
function paused(): void {
|
||||
const src = new Readable({ read() {} });
|
||||
src.push(Buffer.from("x"));
|
||||
src.push(Buffer.alloc(0));
|
||||
src.push(Buffer.from("y"));
|
||||
console.log("readableLength", src.readableLength);
|
||||
console.log("read", JSON.stringify(String(src.read())));
|
||||
}
|
||||
|
||||
function objectMode(): Promise<void> {
|
||||
return new Promise<void>((resolve) => {
|
||||
const src = new Readable({ objectMode: true, read() {} });
|
||||
src.on("data", (chunk: Buffer) => console.log("object chunk length", chunk.length));
|
||||
src.on("end", () => {
|
||||
console.log("object end");
|
||||
resolve();
|
||||
});
|
||||
src.push(Buffer.alloc(0));
|
||||
src.push(Buffer.from("z"));
|
||||
src.push(null);
|
||||
});
|
||||
}
|
||||
|
||||
async function main(): Promise<void> {
|
||||
await lines(["a\nb", "", "c\n"]);
|
||||
await lines(["", "", "only\n"]);
|
||||
await data();
|
||||
paused();
|
||||
await objectMode();
|
||||
console.log("done");
|
||||
}
|
||||
|
||||
main();
|
||||
@@ -0,0 +1 @@
|
||||
{ "plain": 2200, "san": 3200 }
|
||||
Reference in New Issue
Block a user