fix(std/io): Make BufWriter/BufWriterSync.flush write all chunks (#6269)

This commit is contained in:
Marcos Casagrande 2020-06-25 14:17:33 +02:00 committed by GitHub
parent a455a0babf
commit 3f710108f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 33 deletions

View file

@ -426,17 +426,6 @@ abstract class AbstractBufBase {
buffered(): number {
return this.usedBufferBytes;
}
checkBytesWritten(numBytesWritten: number): void {
if (numBytesWritten < this.usedBufferBytes) {
if (numBytesWritten > 0) {
this.buf.copyWithin(0, numBytesWritten, this.usedBufferBytes);
this.usedBufferBytes -= numBytesWritten;
}
this.err = new Error("Short write");
throw this.err;
}
}
}
/** BufWriter implements buffering for an deno.Writer object.
@ -474,9 +463,9 @@ export class BufWriter extends AbstractBufBase implements Writer {
if (this.err !== null) throw this.err;
if (this.usedBufferBytes === 0) return;
let numBytesWritten = 0;
try {
numBytesWritten = await this.writer.write(
await Deno.writeAll(
this.writer,
this.buf.subarray(0, this.usedBufferBytes)
);
} catch (e) {
@ -484,8 +473,6 @@ export class BufWriter extends AbstractBufBase implements Writer {
throw e;
}
this.checkBytesWritten(numBytesWritten);
this.buf = new Uint8Array(this.buf.length);
this.usedBufferBytes = 0;
}
@ -569,9 +556,9 @@ export class BufWriterSync extends AbstractBufBase implements WriterSync {
if (this.err !== null) throw this.err;
if (this.usedBufferBytes === 0) return;
let numBytesWritten = 0;
try {
numBytesWritten = this.writer.writeSync(
Deno.writeAllSync(
this.writer,
this.buf.subarray(0, this.usedBufferBytes)
);
} catch (e) {
@ -579,8 +566,6 @@ export class BufWriterSync extends AbstractBufBase implements WriterSync {
throw e;
}
this.checkBytesWritten(numBytesWritten);
this.buf = new Uint8Array(this.buf.length);
this.usedBufferBytes = 0;
}

View file

@ -498,3 +498,58 @@ Deno.test({
assertEquals(actual, "hello\nworld\nhow\nare\nyou?\n\nfoobar\n\n");
},
});
Deno.test({
name: "BufWriter.flush should write all bytes",
async fn(): Promise<void> {
const bufSize = 16 * 1024;
const data = new Uint8Array(bufSize);
data.fill("a".charCodeAt(0));
const cache: Uint8Array[] = [];
const writer: Deno.Writer = {
write(p: Uint8Array): Promise<number> {
cache.push(p.subarray(0, 1));
// Writer that only writes 1 byte at a time
return Promise.resolve(1);
},
};
const bufWriter = new BufWriter(writer);
await bufWriter.write(data);
await bufWriter.flush();
const buf = new Uint8Array(cache.length);
for (let i = 0; i < cache.length; i++) buf.set(cache[i], i);
assertEquals(data, buf);
},
});
Deno.test({
name: "BufWriterSync.flush should write all bytes",
fn(): void {
const bufSize = 16 * 1024;
const data = new Uint8Array(bufSize);
data.fill("a".charCodeAt(0));
const cache: Uint8Array[] = [];
const writer: Deno.WriterSync = {
writeSync(p: Uint8Array): number {
cache.push(p.subarray(0, 1));
// Writer that only writes 1 byte at a time
return 1;
},
};
const bufWriter = new BufWriterSync(writer);
bufWriter.writeSync(data);
bufWriter.flush();
const buf = new Uint8Array(cache.length);
for (let i = 0; i < cache.length; i++) buf.set(cache[i], i);
assertEquals(data, buf);
},
});