summaryrefslogtreecommitdiff
path: root/js/io.ts
diff options
context:
space:
mode:
authorBartek IwaƄczuk <biwanczuk@gmail.com>2019-05-11 16:05:56 +0200
committerRyan Dahl <ry@tinyclouds.org>2019-05-11 10:05:56 -0400
commit2c6b93e0a0c7927dc4dd66c1f681a78a6d79b8f1 (patch)
treebd68b9304f17ba9bcbc3941e51d7cb930523fb99 /js/io.ts
parentcb93246f6d02c34306e7c9e9c567f96b9bffc875 (diff)
fix: edge case in toAsyncIterator (#2335)
Diffstat (limited to 'js/io.ts')
-rw-r--r--js/io.ts16
1 files changed, 15 insertions, 1 deletions
diff --git a/js/io.ts b/js/io.ts
index 0b59a0849..60b7e442c 100644
--- a/js/io.ts
+++ b/js/io.ts
@@ -144,6 +144,14 @@ export async function copy(dst: Writer, src: Reader): Promise<number> {
*/
export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
const b = new Uint8Array(1024);
+ // Keep track if end-of-file has been reached, then
+ // signal that iterator is done during subsequent next()
+ // call. This is required because `r` can return a `ReadResult`
+ // with data read and EOF reached. But if iterator returns
+ // `done` then `value` is discarded.
+ //
+ // See https://github.com/denoland/deno/issues/2330 for reference.
+ let sawEof = false;
return {
[Symbol.asyncIterator](): AsyncIterableIterator<Uint8Array> {
@@ -151,10 +159,16 @@ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
},
async next(): Promise<IteratorResult<Uint8Array>> {
+ if (sawEof) {
+ return { value: new Uint8Array(), done: true };
+ }
+
const result = await r.read(b);
+ sawEof = result.eof;
+
return {
value: b.subarray(0, result.nread),
- done: result.eof
+ done: false
};
}
};