2018-11-07 14:17:36 -05:00
|
|
|
// 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.
|
|
|
|
|
2018-11-07 13:16:07 -05:00
|
|
|
import * as deno from "deno";
|
|
|
|
import { test, assertEqual } from "http://deno.land/x/testing/testing.ts";
|
2018-11-07 23:19:08 -05:00
|
|
|
import { BufReader, BufState } from "./bufio.ts";
|
2018-11-07 13:16:07 -05:00
|
|
|
import { Buffer } from "./buffer.ts";
|
2018-11-07 20:28:01 -05:00
|
|
|
import * as iotest from "./iotest.ts";
|
2018-11-07 23:19:08 -05:00
|
|
|
import { charCode } from "./util.ts";
|
2018-11-07 13:16:07 -05:00
|
|
|
|
2018-11-07 21:01:32 -05:00
|
|
|
async function readBytes(buf: BufReader): Promise<string> {
|
2018-11-07 13:16:07 -05:00
|
|
|
const b = new Uint8Array(1000);
|
|
|
|
let nb = 0;
|
|
|
|
while (true) {
|
|
|
|
let c = await buf.readByte();
|
|
|
|
if (c < 0) {
|
|
|
|
break; // EOF
|
|
|
|
}
|
|
|
|
b[nb] = c;
|
|
|
|
nb++;
|
|
|
|
}
|
|
|
|
const decoder = new TextDecoder();
|
|
|
|
return decoder.decode(b.subarray(0, nb));
|
|
|
|
}
|
|
|
|
|
|
|
|
function stringsReader(s: string): deno.Reader {
|
|
|
|
const encoder = new TextEncoder();
|
|
|
|
const ui8 = encoder.encode(s);
|
|
|
|
return new Buffer(ui8.buffer as ArrayBuffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
test(async function bufioReaderSimple() {
|
|
|
|
const data = "hello world";
|
2018-11-07 21:01:32 -05:00
|
|
|
const b = new BufReader(stringsReader(data));
|
2018-11-07 13:16:07 -05:00
|
|
|
const s = await readBytes(b);
|
|
|
|
assertEqual(s, data);
|
|
|
|
});
|
2018-11-07 14:17:36 -05:00
|
|
|
|
|
|
|
type ReadMaker = { name: string; fn: (r: deno.Reader) => deno.Reader };
|
|
|
|
|
|
|
|
const readMakers: ReadMaker[] = [
|
2018-11-07 20:28:01 -05:00
|
|
|
{ name: "full", fn: r => r },
|
|
|
|
{ name: "byte", fn: r => new iotest.OneByteReader(r) },
|
2018-11-07 23:19:08 -05:00
|
|
|
{ name: "half", fn: r => new iotest.HalfReader(r) }
|
2018-11-07 20:28:01 -05:00
|
|
|
// TODO { name: "data+err", r => new iotest.DataErrReader(r) },
|
|
|
|
// { name: "timeout", fn: r => new iotest.TimeoutReader(r) },
|
2018-11-07 14:17:36 -05:00
|
|
|
];
|
|
|
|
|
2018-11-07 21:01:32 -05:00
|
|
|
function readLines(b: BufReader): string {
|
2018-11-07 20:28:01 -05:00
|
|
|
let s = "";
|
|
|
|
while (true) {
|
2018-11-07 23:19:08 -05:00
|
|
|
let s1 = b.readString("\n");
|
2018-11-07 20:28:01 -05:00
|
|
|
if (s1 == null) {
|
|
|
|
break; // EOF
|
|
|
|
}
|
|
|
|
s += s1;
|
|
|
|
}
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
|
2018-11-07 14:17:36 -05:00
|
|
|
// Call read to accumulate the text of a file
|
2018-11-07 21:01:32 -05:00
|
|
|
async function reads(buf: BufReader, m: number): Promise<string> {
|
2018-11-07 14:17:36 -05:00
|
|
|
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) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const decoder = new TextDecoder();
|
|
|
|
return decoder.decode(b.subarray(0, nb));
|
|
|
|
}
|
|
|
|
|
2018-11-07 21:01:32 -05:00
|
|
|
type NamedBufReader = { name: string; fn: (r: BufReader) => Promise<string> };
|
2018-11-07 14:17:36 -05:00
|
|
|
|
2018-11-07 21:01:32 -05:00
|
|
|
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) },
|
2018-11-07 23:19:08 -05:00
|
|
|
{ name: "bytes", fn: readBytes }
|
2018-11-07 20:28:01 -05:00
|
|
|
// { name: "lines", fn: readLines },
|
2018-11-07 14:17:36 -05:00
|
|
|
];
|
|
|
|
|
|
|
|
const MIN_READ_BUFFER_SIZE = 16;
|
|
|
|
const bufsizes: number[] = [
|
|
|
|
0,
|
|
|
|
MIN_READ_BUFFER_SIZE,
|
|
|
|
23,
|
|
|
|
32,
|
|
|
|
46,
|
|
|
|
64,
|
|
|
|
93,
|
|
|
|
128,
|
|
|
|
1024,
|
|
|
|
4096
|
|
|
|
];
|
|
|
|
|
2018-11-07 21:01:32 -05:00
|
|
|
test(async function bufioBufReader() {
|
2018-11-07 14:17:36 -05:00
|
|
|
const texts = new Array<string>(31);
|
|
|
|
let str = "";
|
|
|
|
let all = "";
|
|
|
|
for (let i = 0; i < texts.length - 1; i++) {
|
|
|
|
texts[i] = str + "\n";
|
|
|
|
all += texts[i];
|
|
|
|
str += String.fromCharCode(i % 26 + 97);
|
|
|
|
}
|
|
|
|
texts[texts.length - 1] = all;
|
|
|
|
|
|
|
|
for (let text of texts) {
|
|
|
|
for (let readmaker of readMakers) {
|
|
|
|
for (let bufreader of bufreaders) {
|
|
|
|
for (let bufsize of bufsizes) {
|
|
|
|
const read = readmaker.fn(stringsReader(text));
|
2018-11-07 21:01:32 -05:00
|
|
|
const buf = new BufReader(read, bufsize);
|
2018-11-07 14:17:36 -05:00
|
|
|
const s = await bufreader.fn(buf);
|
|
|
|
const debugStr =
|
|
|
|
`reader=${readmaker.name} ` +
|
|
|
|
`fn=${bufreader.name} bufsize=${bufsize} want=${text} got=${s}`;
|
|
|
|
assertEqual(s, text, debugStr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2018-11-07 23:19:08 -05:00
|
|
|
|
|
|
|
test(async function bufioBufferFull() {
|
|
|
|
const longString =
|
|
|
|
"And now, hello, world! It is the time for all good men to come to the aid of their party";
|
|
|
|
const buf = new BufReader(stringsReader(longString), MIN_READ_BUFFER_SIZE);
|
|
|
|
let [line, state] = await buf.readSlice(charCode("!"));
|
|
|
|
|
|
|
|
const decoder = new TextDecoder();
|
|
|
|
let actual = decoder.decode(line);
|
|
|
|
assertEqual(state, BufState.BufferFull);
|
|
|
|
assertEqual(actual, "And now, hello, ");
|
|
|
|
|
|
|
|
[line, state] = await buf.readSlice(charCode("!"));
|
|
|
|
actual = decoder.decode(line);
|
|
|
|
assertEqual(actual, "world!");
|
|
|
|
assertEqual(state, BufState.Ok);
|
|
|
|
});
|