diff options
| author | Ryan Dahl <ry@tinyclouds.org> | 2018-11-07 14:17:36 -0500 |
|---|---|---|
| committer | Ryan Dahl <ry@tinyclouds.org> | 2018-11-07 14:17:36 -0500 |
| commit | 280856f8d81c4b2e53fa8022aafae5a7c008747f (patch) | |
| tree | 07dd6f1acd98046c076a767b5105f91ea13d6d25 /bufio.ts | |
| parent | 8610e3578c923be2b7d758e75ea370801abf8574 (diff) | |
First pass at bufio.read tests.
Original: https://github.com/denoland/deno_std/commit/1eb57aa3948caf88e9064defc15e076b8a46fbd2
Diffstat (limited to 'bufio.ts')
| -rw-r--r-- | bufio.ts | 72 |
1 files changed, 66 insertions, 6 deletions
@@ -1,9 +1,22 @@ +// Ported to Deno from: +// Copyright 2009 The Go Authors. All rights reserved. +// 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 { assert, copyBytes } from "./util.ts"; const DEFAULT_BUF_SIZE = 4096; const MIN_BUF_SIZE = 16; const MAX_CONSECUTIVE_EMPTY_READS = 100; +export class ErrNegativeRead extends Error { + constructor() { + super("bufio: reader returned negative count from Read"); + this.name = "ErrNegativeRead"; + } +} + export class Reader implements deno.Reader { private buf: Uint8Array; private rd: deno.Reader; // Reader provided by caller. @@ -16,7 +29,7 @@ export class Reader implements deno.Reader { if (size < MIN_BUF_SIZE) { size = MIN_BUF_SIZE; } - this._reset(new Uint8Array(size), rd) + this._reset(new Uint8Array(size), rd); } /** Returns the size of the underlying buffer in bytes. */ @@ -42,7 +55,7 @@ export class Reader implements deno.Reader { for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) { const { nread, eof } = await this.rd.read(this.buf.subarray(this.w)); if (nread < 0) { - throw Error("negative read"); + throw new ErrNegativeRead(); } this.w += nread; if (eof) { @@ -69,9 +82,58 @@ export class Reader implements deno.Reader { this.lastCharSize = -1; } + /** reads data into p. + * It returns the number of bytes read into p. + * The bytes are taken from at most one Read on the underlying Reader, + * hence n may be less than len(p). + * 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<deno.ReadResult> { - throw Error("not implemented"); - return { nread: 0, eof: false }; + let rr: deno.ReadResult = { nread: p.byteLength, eof: false }; + if (rr.nread === 0) { + return rr; + } + + if (this.r === this.w) { + /* + if (this.err != null) { + throw this.readErr(); + } + */ + if (p.byteLength >= this.buf.byteLength) { + // Large read, empty buffer. + // Read directly into p to avoid copy. + rr = await this.rd.read(p); + if (rr.nread < 0) { + throw new ErrNegativeRead(); + } + if (rr.nread > 0) { + this.lastByte = p[rr.nread - 1]; + // this.lastRuneSize = -1; + } + return rr; + } + // One read. + // Do not use this.fill, which will loop. + this.r = 0; + this.w = 0; + rr = await this.rd.read(this.buf); + if (rr.nread < 0) { + throw new ErrNegativeRead(); + } + if (rr.nread === 0) { + return rr; + } + this.w += rr.nread; + } + + // copy as much as we can + rr.nread = copyBytes(p as Uint8Array, this.buf.subarray(this.r, this.w), 0); + this.r += rr.nread; + this.lastByte = this.buf[this.r - 1]; + // this.lastRuneSize = -1; + return rr; } /** Returns the next byte [0, 255] or -1 if EOF. */ @@ -88,5 +150,3 @@ export class Reader implements deno.Reader { return c; } } - - |
