diff options
Diffstat (limited to 'io')
-rw-r--r-- | io/bufio.ts | 63 | ||||
-rw-r--r-- | io/bufio_test.ts | 33 | ||||
-rw-r--r-- | io/iotest.ts | 9 | ||||
-rw-r--r-- | io/ioutil.ts | 25 | ||||
-rw-r--r-- | io/ioutil_test.ts | 5 | ||||
-rw-r--r-- | io/readers.ts | 19 | ||||
-rw-r--r-- | io/readers_test.ts | 16 |
7 files changed, 84 insertions, 86 deletions
diff --git a/io/bufio.ts b/io/bufio.ts index 29ca5435d..9a7bf1dc1 100644 --- a/io/bufio.ts +++ b/io/bufio.ts @@ -4,7 +4,6 @@ // license that can be found in the LICENSE file. type Reader = Deno.Reader; -type ReadResult = Deno.ReadResult; type Writer = Deno.Writer; import { charCode, copyBytes } from "./util.ts"; import { assert } from "../testing/asserts.ts"; @@ -29,9 +28,6 @@ export class UnexpectedEOFError extends Error { } } -export const EOF: unique symbol = Symbol("EOF"); -export type EOF = typeof EOF; - /** Result type returned by of BufReader.readLine(). */ export interface ReadLineResult { line: Uint8Array; @@ -84,14 +80,14 @@ export class BufReader implements Reader { // Read new data: try a limited number of times. for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) { - let rr: ReadResult = await this.rd.read(this.buf.subarray(this.w)); - assert(rr.nread >= 0, "negative read"); - this.w += rr.nread; - if (rr.eof) { + const rr = await this.rd.read(this.buf.subarray(this.w)); + if (rr === Deno.EOF) { this.eof = true; return; } - if (rr.nread > 0) { + assert(rr >= 0, "negative read"); + this.w += rr; + if (rr > 0) { return; } } @@ -122,8 +118,8 @@ export class BufReader implements Reader { * hence n may be less than len(p). * To read exactly len(p) bytes, use io.ReadFull(b, p). */ - async read(p: Uint8Array): Promise<ReadResult> { - let rr: ReadResult = { nread: p.byteLength, eof: false }; + async read(p: Uint8Array): Promise<number | Deno.EOF> { + let rr: number | Deno.EOF = p.byteLength; if (p.byteLength === 0) return rr; if (this.r === this.w) { @@ -131,7 +127,8 @@ export class BufReader implements Reader { // Large read, empty buffer. // Read directly into p to avoid copy. const rr = await this.rd.read(p); - assert(rr.nread >= 0, "negative read"); + const nread = rr === Deno.EOF ? 0 : rr; + assert(nread >= 0, "negative read"); // if (rr.nread > 0) { // this.lastByte = p[rr.nread - 1]; // this.lastCharSize = -1; @@ -144,17 +141,17 @@ export class BufReader implements Reader { this.r = 0; this.w = 0; rr = await this.rd.read(this.buf); - assert(rr.nread >= 0, "negative read"); - if (rr.nread === 0) return rr; - this.w += rr.nread; + if (rr === 0 || rr === Deno.EOF) return rr; + assert(rr >= 0, "negative read"); + this.w += rr; } // copy as much as we can - rr.nread = copyBytes(p, this.buf.subarray(this.r, this.w), 0); - this.r += rr.nread; + const copied = copyBytes(p, this.buf.subarray(this.r, this.w), 0); + this.r += copied; // this.lastByte = this.buf[this.r - 1]; // this.lastCharSize = -1; - return rr; + return copied; } /** reads exactly `p.length` bytes into `p`. @@ -171,19 +168,19 @@ export class BufReader implements Reader { * * Ported from https://golang.org/pkg/io/#ReadFull */ - async readFull(p: Uint8Array): Promise<Uint8Array | EOF> { + async readFull(p: Uint8Array): Promise<Uint8Array | Deno.EOF> { let bytesRead = 0; while (bytesRead < p.length) { try { const rr = await this.read(p.subarray(bytesRead)); - bytesRead += rr.nread; - if (rr.eof) { + if (rr === Deno.EOF) { if (bytesRead === 0) { - return EOF; + return Deno.EOF; } else { throw new UnexpectedEOFError(); } } + bytesRead += rr; } catch (err) { err.partial = p.subarray(0, bytesRead); throw err; @@ -193,9 +190,9 @@ export class BufReader implements Reader { } /** Returns the next byte [0, 255] or `EOF`. */ - async readByte(): Promise<number | EOF> { + async readByte(): Promise<number | Deno.EOF> { while (this.r === this.w) { - if (this.eof) return EOF; + if (this.eof) return Deno.EOF; await this._fill(); // buffer is empty. } const c = this.buf[this.r]; @@ -214,7 +211,7 @@ export class BufReader implements Reader { * delim. * For simple uses, a Scanner may be more convenient. */ - async readString(_delim: string): Promise<string | EOF> { + async readString(_delim: string): Promise<string | Deno.EOF> { throw new Error("Not implemented"); } @@ -240,8 +237,8 @@ export class BufReader implements Reader { * read (possibly a character belonging to the line end) even if that byte is * not part of the line returned by `readLine()`. */ - async readLine(): Promise<ReadLineResult | EOF> { - let line: Uint8Array | EOF; + async readLine(): Promise<ReadLineResult | Deno.EOF> { + let line: Uint8Array | Deno.EOF; try { line = await this.readSlice(LF); @@ -274,8 +271,8 @@ export class BufReader implements Reader { return { line: partial, more: !this.eof }; } - if (line === EOF) { - return EOF; + if (line === Deno.EOF) { + return Deno.EOF; } if (line.byteLength === 0) { @@ -308,7 +305,7 @@ export class BufReader implements Reader { * Because the data returned from `readSlice()` will be overwritten by the * next I/O operation, most clients should use `readString()` instead. */ - async readSlice(delim: number): Promise<Uint8Array | EOF> { + async readSlice(delim: number): Promise<Uint8Array | Deno.EOF> { let s = 0; // search start index let slice: Uint8Array; @@ -325,7 +322,7 @@ export class BufReader implements Reader { // EOF? if (this.eof) { if (this.r === this.w) { - return EOF; + return Deno.EOF; } slice = this.buf.subarray(this.r, this.w); this.r = this.w; @@ -370,7 +367,7 @@ export class BufReader implements Reader { * an error with the `partial` property set to a slice of the buffer that * contains the bytes that were available before the error occurred. */ - async peek(n: number): Promise<Uint8Array | EOF> { + async peek(n: number): Promise<Uint8Array | Deno.EOF> { if (n < 0) { throw Error("negative count"); } @@ -387,7 +384,7 @@ export class BufReader implements Reader { } if (avail === 0 && this.eof) { - return EOF; + return Deno.EOF; } else if (avail < n && this.eof) { return this.buf.subarray(this.r, this.r + avail); } else if (avail < n) { diff --git a/io/bufio_test.ts b/io/bufio_test.ts index 1ea664c5c..6f50e2876 100644 --- a/io/bufio_test.ts +++ b/io/bufio_test.ts @@ -5,7 +5,6 @@ const { Buffer } = Deno; type Reader = Deno.Reader; -type ReadResult = Deno.ReadResult; import { test, runIfMain } from "../testing/mod.ts"; import { assert, @@ -16,7 +15,6 @@ import { import { BufReader, BufWriter, - EOF, BufferFullError, UnexpectedEOFError } from "./bufio.ts"; @@ -25,8 +23,8 @@ import { charCode, copyBytes, stringsReader } from "./util.ts"; const encoder = new TextEncoder(); -function assertNotEOF<T extends {}>(val: T | EOF): T { - assertNotEquals(val, EOF); +function assertNotEOF<T extends {}>(val: T | Deno.EOF): T { + assertNotEquals(val, Deno.EOF); return val as T; } @@ -35,7 +33,7 @@ async function readBytes(buf: BufReader): Promise<string> { let nb = 0; while (true) { let c = await buf.readByte(); - if (c === EOF) { + if (c === Deno.EOF) { break; // EOF } b[nb] = c; @@ -73,11 +71,11 @@ async function reads(buf: BufReader, m: number): Promise<string> { const b = new Uint8Array(1000); let nb = 0; while (true) { - const { nread, eof } = await buf.read(b.subarray(nb, nb + m)); - nb += nread; - if (eof) { + const result = await buf.read(b.subarray(nb, nb + m)); + if (result === Deno.EOF) { break; } + nb += result; } const decoder = new TextDecoder(); return decoder.decode(b.subarray(0, nb)); @@ -175,7 +173,7 @@ const testOutput = encoder.encode("0123456789abcdefghijklmnopqrstuvwxy"); class TestReader implements Reader { constructor(private data: Uint8Array, private stride: number) {} - async read(buf: Uint8Array): Promise<ReadResult> { + async read(buf: Uint8Array): Promise<number | Deno.EOF> { let nread = this.stride; if (nread > this.data.byteLength) { nread = this.data.byteLength; @@ -183,13 +181,12 @@ class TestReader implements Reader { if (nread > buf.byteLength) { nread = buf.byteLength; } + if (nread === 0) { + return Deno.EOF; + } copyBytes(buf as Uint8Array, this.data); this.data = this.data.subarray(nread); - let eof = false; - if (this.data.byteLength == 0) { - eof = true; - } - return { nread, eof }; + return nread; } } @@ -200,7 +197,7 @@ async function testReadLine(input: Uint8Array): Promise<void> { let l = new BufReader(reader, input.byteLength + 1); while (true) { const r = await l.readLine(); - if (r === EOF) { + if (r === Deno.EOF) { break; } const { line, more } = r; @@ -267,9 +264,9 @@ test(async function bufioPeek(): Promise<void> { actual = assertNotEOF(await buf.peek(2)); assertEquals(decoder.decode(actual), "de"); - let { eof } = await buf.read(p.subarray(0, 3)); + let res = await buf.read(p.subarray(0, 3)); assertEquals(decoder.decode(p.subarray(0, 3)), "def"); - assert(!eof); + assert(res !== Deno.EOF); actual = assertNotEOF(await buf.peek(4)); assertEquals(decoder.decode(actual), "ghij"); @@ -281,7 +278,7 @@ test(async function bufioPeek(): Promise<void> { assertEquals(decoder.decode(actual), ""); const r = await buf.peek(1); - assert(r === EOF); + assert(r === Deno.EOF); /* TODO Test for issue 3022, not exposing a reader's error on a successful Peek. buf = NewReaderSize(dataAndEOFReader("abcd"), 32) diff --git a/io/iotest.ts b/io/iotest.ts index 9973562a7..8d2cee6e2 100644 --- a/io/iotest.ts +++ b/io/iotest.ts @@ -3,7 +3,6 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. type Reader = Deno.Reader; -type ReadResult = Deno.ReadResult; /** OneByteReader returns a Reader that implements * each non-empty Read by reading one byte from r. @@ -11,9 +10,9 @@ type ReadResult = Deno.ReadResult; export class OneByteReader implements Reader { constructor(readonly r: Reader) {} - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { if (p.byteLength === 0) { - return { nread: 0, eof: false }; + return 0; } if (!(p instanceof Uint8Array)) { throw Error("expected Uint8Array"); @@ -28,7 +27,7 @@ export class OneByteReader implements Reader { export class HalfReader implements Reader { constructor(readonly r: Reader) {} - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { if (!(p instanceof Uint8Array)) { throw Error("expected Uint8Array"); } @@ -51,7 +50,7 @@ export class TimeoutReader implements Reader { count = 0; constructor(readonly r: Reader) {} - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { this.count++; if (this.count === 2) { throw new ErrTimeout(); diff --git a/io/ioutil.ts b/io/ioutil.ts index c13eff0d4..f1ca54e14 100644 --- a/io/ioutil.ts +++ b/io/ioutil.ts @@ -1,5 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import { BufReader, EOF, UnexpectedEOFError } from "./bufio.ts"; +import { BufReader, UnexpectedEOFError } from "./bufio.ts"; type Reader = Deno.Reader; type Writer = Deno.Writer; import { assert } from "../testing/asserts.ts"; @@ -18,13 +18,14 @@ export async function copyN( if (size - bytesRead < 1024) { buf = new Uint8Array(size - bytesRead); } - const { nread, eof } = await r.read(buf); + const result = await r.read(buf); + const nread = result === Deno.EOF ? 0 : result; bytesRead += nread; if (nread > 0) { const n = await dest.write(buf.slice(0, nread)); assert(n === nread, "could not write"); } - if (eof) { + if (result === Deno.EOF) { break; } } @@ -32,31 +33,31 @@ export async function copyN( } /** Read big endian 16bit short from BufReader */ -export async function readShort(buf: BufReader): Promise<number | EOF> { +export async function readShort(buf: BufReader): Promise<number | Deno.EOF> { const high = await buf.readByte(); - if (high === EOF) return EOF; + if (high === Deno.EOF) return Deno.EOF; const low = await buf.readByte(); - if (low === EOF) throw new UnexpectedEOFError(); + if (low === Deno.EOF) throw new UnexpectedEOFError(); return (high << 8) | low; } /** Read big endian 32bit integer from BufReader */ -export async function readInt(buf: BufReader): Promise<number | EOF> { +export async function readInt(buf: BufReader): Promise<number | Deno.EOF> { const high = await readShort(buf); - if (high === EOF) return EOF; + if (high === Deno.EOF) return Deno.EOF; const low = await readShort(buf); - if (low === EOF) throw new UnexpectedEOFError(); + if (low === Deno.EOF) throw new UnexpectedEOFError(); return (high << 16) | low; } const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER); /** Read big endian 64bit long from BufReader */ -export async function readLong(buf: BufReader): Promise<number | EOF> { +export async function readLong(buf: BufReader): Promise<number | Deno.EOF> { const high = await readInt(buf); - if (high === EOF) return EOF; + if (high === Deno.EOF) return Deno.EOF; const low = await readInt(buf); - if (low === EOF) throw new UnexpectedEOFError(); + if (low === Deno.EOF) throw new UnexpectedEOFError(); const big = (BigInt(high) << 32n) | BigInt(low); // We probably should provide a similar API that returns BigInt values. if (big > MAX_SAFE_INTEGER) { diff --git a/io/ioutil_test.ts b/io/ioutil_test.ts index 4e34f5698..97ab244c0 100644 --- a/io/ioutil_test.ts +++ b/io/ioutil_test.ts @@ -1,7 +1,6 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. const { Buffer } = Deno; type Reader = Deno.Reader; -type ReadResult = Deno.ReadResult; import { test } from "../testing/mod.ts"; import { assertEquals } from "../testing/asserts.ts"; import { @@ -19,10 +18,10 @@ class BinaryReader implements Reader { constructor(private bytes: Uint8Array = new Uint8Array(0)) {} - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { p.set(this.bytes.subarray(this.index, p.byteLength)); this.index += p.byteLength; - return { nread: p.byteLength, eof: false }; + return p.byteLength; } } diff --git a/io/readers.ts b/io/readers.ts index 2ebfc6b15..0208de413 100644 --- a/io/readers.ts +++ b/io/readers.ts @@ -1,6 +1,5 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. type Reader = Deno.Reader; -type ReadResult = Deno.ReadResult; import { encode } from "../strings/mod.ts"; /** Reader utility for strings */ @@ -10,11 +9,14 @@ export class StringReader implements Reader { constructor(private readonly s: string) {} - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { const n = Math.min(p.byteLength, this.buf.byteLength - this.offs); p.set(this.buf.slice(this.offs, this.offs + n)); this.offs += n; - return { nread: n, eof: this.offs === this.buf.byteLength }; + if (n === 0) { + return Deno.EOF; + } + return n; } } @@ -27,13 +29,14 @@ export class MultiReader implements Reader { this.readers = readers; } - async read(p: Uint8Array): Promise<ReadResult> { + async read(p: Uint8Array): Promise<number | Deno.EOF> { const r = this.readers[this.currentIndex]; - if (!r) return { nread: 0, eof: true }; - const { nread, eof } = await r.read(p); - if (eof) { + if (!r) return Deno.EOF; + const result = await r.read(p); + if (result === Deno.EOF) { this.currentIndex++; + return 0; } - return { nread, eof: false }; + return result; } } diff --git a/io/readers_test.ts b/io/readers_test.ts index e4f159c74..f80bfd55f 100644 --- a/io/readers_test.ts +++ b/io/readers_test.ts @@ -8,21 +8,23 @@ import { decode } from "../strings/mod.ts"; test(async function ioStringReader(): Promise<void> { const r = new StringReader("abcdef"); - const { nread, eof } = await r.read(new Uint8Array(6)); - assertEquals(nread, 6); - assertEquals(eof, true); + const res0 = await r.read(new Uint8Array(6)); + assertEquals(res0, 6); + const res1 = await r.read(new Uint8Array(6)); + assertEquals(res1, Deno.EOF); }); test(async function ioStringReader(): Promise<void> { const r = new StringReader("abcdef"); const buf = new Uint8Array(3); let res1 = await r.read(buf); - assertEquals(res1.nread, 3); - assertEquals(res1.eof, false); + assertEquals(res1, 3); assertEquals(decode(buf), "abc"); let res2 = await r.read(buf); - assertEquals(res2.nread, 3); - assertEquals(res2.eof, true); + assertEquals(res2, 3); + assertEquals(decode(buf), "def"); + let res3 = await r.read(buf); + assertEquals(res3, Deno.EOF); assertEquals(decode(buf), "def"); }); |