diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..b94f157cc7 --- /dev/null +++ b/Makefile @@ -0,0 +1,4 @@ +test: + deno test.ts + +.PHONY: test diff --git a/bufio.ts b/bufio.ts index c1fcf9c473..06f2eb4320 100644 --- a/bufio.ts +++ b/bufio.ts @@ -3,7 +3,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -import * as deno from "deno"; +import { Reader, ReadResult } from "deno"; import { assert, copyBytes } from "./util.ts"; const DEFAULT_BUF_SIZE = 4096; @@ -17,16 +17,17 @@ export class ErrNegativeRead extends Error { } } -export class Reader implements deno.Reader { +/** BufReader implements buffering for a Reader object. */ +export class BufReader implements Reader { private buf: Uint8Array; - private rd: deno.Reader; // Reader provided by caller. + private rd: Reader; // Reader provided by caller. private r = 0; // buf read position. private w = 0; // buf write position. private lastByte: number; private lastCharSize: number; private err: null | Error; - constructor(rd: deno.Reader, size = DEFAULT_BUF_SIZE) { + constructor(rd: Reader, size = DEFAULT_BUF_SIZE) { if (size < MIN_BUF_SIZE) { size = MIN_BUF_SIZE; } @@ -38,6 +39,10 @@ export class Reader implements deno.Reader { return this.buf.byteLength; } + buffered(): number { + return this.w - this.r; + } + private _readErr(): Error { const err = this.err; this.err = null; @@ -60,7 +65,7 @@ export class Reader implements deno.Reader { // Read new data: try a limited number of times. for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) { - let rr: deno.ReadResult; + let rr: ReadResult; try { rr = await this.rd.read(this.buf.subarray(this.w)); } catch (e) { @@ -84,11 +89,11 @@ export class Reader implements deno.Reader { /** Discards any buffered data, resets all state, and switches * the buffered reader to read from r. */ - reset(r: deno.Reader): void { + reset(r: Reader): void { this._reset(this.buf, r); } - private _reset(buf: Uint8Array, rd: deno.Reader): void { + private _reset(buf: Uint8Array, rd: Reader): void { this.buf = buf; this.rd = rd; this.lastByte = -1; @@ -102,8 +107,8 @@ export class Reader implements deno.Reader { * At EOF, the count will be zero and err will be io.EOF. * To read exactly len(p) bytes, use io.ReadFull(b, p). */ - async read(p: ArrayBufferView): Promise { - let rr: deno.ReadResult = { nread: p.byteLength, eof: false }; + async read(p: ArrayBufferView): Promise { + let rr: ReadResult = { nread: p.byteLength, eof: false }; if (rr.nread === 0) { if (this.err) { throw this._readErr(); diff --git a/bufio_test.ts b/bufio_test.ts index dc16f5e69f..85be74fdc4 100644 --- a/bufio_test.ts +++ b/bufio_test.ts @@ -5,11 +5,11 @@ import * as deno from "deno"; import { test, assertEqual } from "http://deno.land/x/testing/testing.ts"; -import * as bufio from "./bufio.ts"; +import { BufReader } from "./bufio.ts"; import { Buffer } from "./buffer.ts"; import * as iotest from "./iotest.ts"; -async function readBytes(buf: bufio.Reader): Promise { +async function readBytes(buf: BufReader): Promise { const b = new Uint8Array(1000); let nb = 0; while (true) { @@ -32,7 +32,7 @@ function stringsReader(s: string): deno.Reader { test(async function bufioReaderSimple() { const data = "hello world"; - const b = new bufio.Reader(stringsReader(data)); + const b = new BufReader(stringsReader(data)); const s = await readBytes(b); assertEqual(s, data); }); @@ -42,15 +42,15 @@ type ReadMaker = { name: string; fn: (r: deno.Reader) => deno.Reader }; const readMakers: ReadMaker[] = [ { name: "full", fn: r => r }, { name: "byte", fn: r => new iotest.OneByteReader(r) }, - { name: "half", fn: r => new iotest.HalfReader(r) } + { name: "half", fn: r => new iotest.HalfReader(r) }, // TODO { name: "data+err", r => new iotest.DataErrReader(r) }, // { name: "timeout", fn: r => new iotest.TimeoutReader(r) }, ]; -function readLines(b: bufio.Reader): string { +function readLines(b: BufReader): string { let s = ""; while (true) { - let s1 = b.readString("\n"); + let s1 = b.readString('\n'); if (s1 == null) { break; // EOF } @@ -60,7 +60,7 @@ function readLines(b: bufio.Reader): string { } // Call read to accumulate the text of a file -async function reads(buf: bufio.Reader, m: number): Promise { +async function reads(buf: BufReader, m: number): Promise { const b = new Uint8Array(1000); let nb = 0; while (true) { @@ -74,16 +74,16 @@ async function reads(buf: bufio.Reader, m: number): Promise { return decoder.decode(b.subarray(0, nb)); } -type BufReader = { name: string; fn: (r: bufio.Reader) => Promise }; +type NamedBufReader = { name: string; fn: (r: BufReader) => Promise }; -const bufreaders: BufReader[] = [ - { name: "1", fn: (b: bufio.Reader) => reads(b, 1) }, - { name: "2", fn: (b: bufio.Reader) => reads(b, 2) }, - { name: "3", fn: (b: bufio.Reader) => reads(b, 3) }, - { name: "4", fn: (b: bufio.Reader) => reads(b, 4) }, - { name: "5", fn: (b: bufio.Reader) => reads(b, 5) }, - { name: "7", fn: (b: bufio.Reader) => reads(b, 7) }, - { name: "bytes", fn: readBytes } +const bufreaders: NamedBufReader[] = [ + { name: "1", fn: (b: BufReader) => reads(b, 1) }, + { name: "2", fn: (b: BufReader) => reads(b, 2) }, + { name: "3", fn: (b: BufReader) => reads(b, 3) }, + { name: "4", fn: (b: BufReader) => reads(b, 4) }, + { name: "5", fn: (b: BufReader) => reads(b, 5) }, + { name: "7", fn: (b: BufReader) => reads(b, 7) }, + { name: "bytes", fn: readBytes }, // { name: "lines", fn: readLines }, ]; @@ -101,7 +101,7 @@ const bufsizes: number[] = [ 4096 ]; -test(async function bufioReader() { +test(async function bufioBufReader() { const texts = new Array(31); let str = ""; let all = ""; @@ -117,7 +117,7 @@ test(async function bufioReader() { for (let bufreader of bufreaders) { for (let bufsize of bufsizes) { const read = readmaker.fn(stringsReader(text)); - const buf = new bufio.Reader(read, bufsize); + const buf = new BufReader(read, bufsize); const s = await bufreader.fn(buf); const debugStr = `reader=${readmaker.name} ` +