0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-10-30 09:08:00 -04:00

Add BufReader.peek()

Original: 90cbca40be
This commit is contained in:
Ryan Dahl 2018-11-08 04:01:20 -05:00
parent d35e13e6be
commit e97fdcac47
4 changed files with 120 additions and 5 deletions

View file

@ -2,6 +2,6 @@ test:
deno test.ts
fmt:
prettier *.ts --write
prettier *.md *.ts --write
.PHONY: test fmt

View file

@ -2,9 +2,12 @@
[![Build Status](https://travis-ci.com/denoland/net.svg?branch=master)](https://travis-ci.com/denoland/net)
Usage:
```typescript
import { Reader } from "https://deno.land/x/net/bufio.ts";
// TODO Example.
import { serve } from "https://deno.land/x/net/http.ts";
const s = serve("0.0.0.0:8000");
for await (const req of s) {
req.respond({ body: "Hello World\n" });
}
```

View file

@ -47,7 +47,6 @@ export class BufReader implements Reader {
}
// Reads a new chunk into the buffer.
// Returns true if EOF, false on successful read.
private async _fill(): Promise<void> {
// Slide existing data to beginning.
if (this.r > 0) {
@ -287,4 +286,40 @@ export class BufReader implements Reader {
return [line, err];
}
/** Peek returns the next n bytes without advancing the reader. The bytes stop
* being valid at the next read call. If Peek returns fewer than n bytes, it
* also returns an error explaining why the read is short. The error is
* ErrBufferFull if n is larger than b's buffer size.
*/
async peek(n: number): Promise<[Uint8Array, BufState]> {
if (n < 0) {
throw Error("negative count");
}
while (
this.w - this.r < n &&
this.w - this.r < this.buf.byteLength &&
this.err == null
) {
await this._fill(); // this.w - this.r < len(this.buf) => buffer is not full
}
if (n > this.buf.byteLength) {
return [this.buf.subarray(this.r, this.w), "BufferFull"];
}
// 0 <= n <= len(this.buf)
let err: BufState;
let avail = this.w - this.r;
if (avail < n) {
// not enough data in buffer
n = avail;
err = this._readErr();
if (!err) {
err = "BufferFull";
}
}
return [this.buf.subarray(this.r, this.r + n), err];
}
}

View file

@ -217,3 +217,80 @@ test(async function bufioReadLine() {
await testReadLine(testInput);
await testReadLine(testInputrn);
});
test(async function bufioPeek() {
const decoder = new TextDecoder();
let p = new Uint8Array(10);
// string is 16 (minReadBufferSize) long.
let buf = new BufReader(
stringsReader("abcdefghijklmnop"),
MIN_READ_BUFFER_SIZE
);
let [actual, err] = await buf.peek(1);
assertEqual(decoder.decode(actual), "a");
assert(err == null);
[actual, err] = await buf.peek(4);
assertEqual(decoder.decode(actual), "abcd");
assert(err == null);
[actual, err] = await buf.peek(32);
assertEqual(decoder.decode(actual), "abcdefghijklmnop");
assertEqual(err, "BufferFull");
await buf.read(p.subarray(0, 3));
assertEqual(decoder.decode(p.subarray(0, 3)), "abc");
[actual, err] = await buf.peek(1);
assertEqual(decoder.decode(actual), "d");
assert(err == null);
[actual, err] = await buf.peek(1);
assertEqual(decoder.decode(actual), "d");
assert(err == null);
[actual, err] = await buf.peek(1);
assertEqual(decoder.decode(actual), "d");
assert(err == null);
[actual, err] = await buf.peek(2);
assertEqual(decoder.decode(actual), "de");
assert(err == null);
let { eof } = await buf.read(p.subarray(0, 3));
assertEqual(decoder.decode(p.subarray(0, 3)), "def");
assert(!eof);
assert(err == null);
[actual, err] = await buf.peek(4);
assertEqual(decoder.decode(actual), "ghij");
assert(err == null);
await buf.read(p);
assertEqual(decoder.decode(p), "ghijklmnop");
[actual, err] = await buf.peek(0);
assertEqual(decoder.decode(actual), "");
assert(err == null);
[actual, err] = await buf.peek(1);
assertEqual(decoder.decode(actual), "");
assert(err == "EOF");
/* TODO
// Test for issue 3022, not exposing a reader's error on a successful Peek.
buf = NewReaderSize(dataAndEOFReader("abcd"), 32)
if s, err := buf.Peek(2); string(s) != "ab" || err != nil {
t.Errorf(`Peek(2) on "abcd", EOF = %q, %v; want "ab", nil`, string(s), err)
}
if s, err := buf.Peek(4); string(s) != "abcd" || err != nil {
t.Errorf(`Peek(4) on "abcd", EOF = %q, %v; want "abcd", nil`, string(s), err)
}
if n, err := buf.Read(p[0:5]); string(p[0:n]) != "abcd" || err != nil {
t.Fatalf("Read after peek = %q, %v; want abcd, EOF", p[0:n], err)
}
if n, err := buf.Read(p[0:1]); string(p[0:n]) != "" || err != io.EOF {
t.Fatalf(`second Read after peek = %q, %v; want "", EOF`, p[0:n], err)
}
*/
});