summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
Diffstat (limited to 'js')
-rw-r--r--js/buffer.ts29
-rw-r--r--js/buffer_test.ts10
-rw-r--r--js/deno.ts2
m---------js/deps/https/deno.land/std0
-rw-r--r--js/fetch.ts2
-rw-r--r--js/files.ts29
-rw-r--r--js/files_test.ts13
-rw-r--r--js/io.ts49
-rw-r--r--js/net.ts4
-rw-r--r--js/net_test.ts27
-rw-r--r--js/process_test.ts25
-rw-r--r--js/xeval.ts11
12 files changed, 96 insertions, 105 deletions
diff --git a/js/buffer.ts b/js/buffer.ts
index 15a26fb28..1f597282d 100644
--- a/js/buffer.ts
+++ b/js/buffer.ts
@@ -4,8 +4,7 @@
// Copyright 2009 The Go Authors. All rights reserved. BSD license.
// https://github.com/golang/go/blob/master/LICENSE
-//import * as io from "./io";
-import { Reader, Writer, ReadResult, SyncReader, SyncWriter } from "./io";
+import { Reader, Writer, EOF, SyncReader, SyncWriter } from "./io";
import { assert } from "./util";
import { TextDecoder } from "./text_encoding";
import { DenoError, ErrorKind } from "./errors";
@@ -131,22 +130,22 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
* is drained. The return value n is the number of bytes read. If the
* buffer has no data to return, eof in the response will be true.
*/
- readSync(p: Uint8Array): ReadResult {
+ readSync(p: Uint8Array): number | EOF {
if (this.empty()) {
// Buffer is empty, reset to recover space.
this.reset();
if (p.byteLength === 0) {
// this edge case is tested in 'bufferReadEmptyAtEOF' test
- return { nread: 0, eof: false };
+ return 0;
}
- return { nread: 0, eof: true };
+ return EOF;
}
const nread = copyBytes(p, this.buf.subarray(this.off));
this.off += nread;
- return { nread, eof: false };
+ return nread;
}
- async read(p: Uint8Array): Promise<ReadResult> {
+ async read(p: Uint8Array): Promise<number | EOF> {
const rr = this.readSync(p);
return Promise.resolve(rr);
}
@@ -226,12 +225,12 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
const i = this._grow(MIN_READ);
this._reslice(i);
const fub = new Uint8Array(this.buf.buffer, i);
- const { nread, eof } = await r.read(fub);
- this._reslice(i + nread);
- n += nread;
- if (eof) {
+ const nread = await r.read(fub);
+ if (nread === EOF) {
return n;
}
+ this._reslice(i + nread);
+ n += nread;
} catch (e) {
return n;
}
@@ -247,12 +246,12 @@ export class Buffer implements Reader, SyncReader, Writer, SyncWriter {
const i = this._grow(MIN_READ);
this._reslice(i);
const fub = new Uint8Array(this.buf.buffer, i);
- const { nread, eof } = r.readSync(fub);
- this._reslice(i + nread);
- n += nread;
- if (eof) {
+ const nread = r.readSync(fub);
+ if (nread === EOF) {
return n;
}
+ this._reslice(i + nread);
+ n += nread;
} catch (e) {
return n;
}
diff --git a/js/buffer_test.ts b/js/buffer_test.ts
index b4ed3a58a..3b2f5d312 100644
--- a/js/buffer_test.ts
+++ b/js/buffer_test.ts
@@ -60,10 +60,10 @@ async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise<void> {
check(buf, s);
while (true) {
const r = await buf.read(fub);
- if (r.nread == 0) {
+ if (r === Deno.EOF) {
break;
}
- s = s.slice(r.nread);
+ s = s.slice(r);
check(buf, s);
}
check(buf, "");
@@ -126,8 +126,7 @@ test(async function bufferReadEmptyAtEOF(): Promise<void> {
let buf = new Buffer();
const zeroLengthTmp = new Uint8Array(0);
let result = await buf.read(zeroLengthTmp);
- assertEquals(result.nread, 0);
- assertEquals(result.eof, false);
+ assertEquals(result, 0);
});
test(async function bufferLargeByteWrites(): Promise<void> {
@@ -217,7 +216,8 @@ test(async function bufferTestGrow(): Promise<void> {
for (let growLen of [0, 100, 1000, 10000, 100000]) {
const buf = new Buffer(xBytes.buffer as ArrayBuffer);
// If we read, this affects buf.off, which is good to test.
- const { nread } = await buf.read(tmp);
+ const result = await buf.read(tmp);
+ const nread = result === Deno.EOF ? 0 : result;
buf.grow(growLen);
const yBytes = repeat("y", growLen);
await buf.write(yBytes);
diff --git a/js/deno.ts b/js/deno.ts
index 0bc3c95c7..f20b6eff1 100644
--- a/js/deno.ts
+++ b/js/deno.ts
@@ -20,9 +20,9 @@ export {
OpenMode
} from "./files";
export {
+ EOF,
copy,
toAsyncIterator,
- ReadResult,
SeekMode,
Reader,
SyncReader,
diff --git a/js/deps/https/deno.land/std b/js/deps/https/deno.land/std
-Subproject d99c15448dc6615bea372cc64453de3428c6ba2
+Subproject 6663e698d08147ae0a736d1df52ffd857729d3d
diff --git a/js/fetch.ts b/js/fetch.ts
index 3659710c5..9853b2194 100644
--- a/js/fetch.ts
+++ b/js/fetch.ts
@@ -218,7 +218,7 @@ class Body implements domTypes.Body, domTypes.ReadableStream, io.ReadCloser {
return decoder.decode(ab);
}
- read(p: Uint8Array): Promise<io.ReadResult> {
+ read(p: Uint8Array): Promise<number | io.EOF> {
return read(this.rid, p);
}
diff --git a/js/files.ts b/js/files.ts
index 1479e4146..eb899d738 100644
--- a/js/files.ts
+++ b/js/files.ts
@@ -1,10 +1,10 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import {
+ EOF,
Reader,
Writer,
Seeker,
Closer,
- ReadResult,
SeekMode,
SyncReader,
SyncWriter,
@@ -71,47 +71,50 @@ function reqRead(
return [builder, msg.Any.Read, inner, p];
}
-function resRead(baseRes: null | msg.Base): ReadResult {
+function resRead(baseRes: null | msg.Base): number | EOF {
assert(baseRes != null);
assert(msg.Any.ReadRes === baseRes!.innerType());
const res = new msg.ReadRes();
assert(baseRes!.inner(res) != null);
- return { nread: res.nread(), eof: res.eof() };
+ if (res.eof()) {
+ return EOF;
+ }
+ return res.nread();
}
/** Read synchronously from a file ID into an array buffer.
*
- * Return `ReadResult` for the operation.
+ * Return `number | EOF` for the operation.
*
* const file = Deno.openSync("/foo/bar.txt");
* const buf = new Uint8Array(100);
- * const { nread, eof } = Deno.readSync(file.rid, buf);
+ * const nread = Deno.readSync(file.rid, buf);
* const text = new TextDecoder().decode(buf);
*
*/
-export function readSync(rid: number, p: Uint8Array): ReadResult {
+export function readSync(rid: number, p: Uint8Array): number | EOF {
return resRead(dispatch.sendSync(...reqRead(rid, p)));
}
/** Read from a file ID into an array buffer.
*
- * Resolves with the `ReadResult` for the operation.
+ * Resolves with the `number | EOF` for the operation.
*
* (async () => {
* const file = await Deno.open("/foo/bar.txt");
* const buf = new Uint8Array(100);
- * const { nread, eof } = await Deno.read(file.rid, buf);
+ * const nread = await Deno.read(file.rid, buf);
* const text = new TextDecoder().decode(buf);
* })();
*/
-export async function read(rid: number, p: Uint8Array): Promise<ReadResult> {
+export async function read(rid: number, p: Uint8Array): Promise<number | EOF> {
const nread = await sendAsyncMinimal(OP_READ, rid, p);
if (nread < 0) {
throw new Error("read error");
} else if (nread == 0) {
- return { nread, eof: true };
+ return EOF;
} else {
- return { nread, eof: false };
+ return nread;
}
}
@@ -227,11 +230,11 @@ export class File
return writeSync(this.rid, p);
}
- read(p: Uint8Array): Promise<ReadResult> {
+ read(p: Uint8Array): Promise<number | EOF> {
return read(this.rid, p);
}
- readSync(p: Uint8Array): ReadResult {
+ readSync(p: Uint8Array): number | EOF {
return readSync(this.rid, p);
}
diff --git a/js/files_test.ts b/js/files_test.ts
index 350c1eb41..babec1fc2 100644
--- a/js/files_test.ts
+++ b/js/files_test.ts
@@ -39,15 +39,16 @@ test(async function readerToAsyncIterator(): Promise<void> {
constructor(private readonly s: string) {}
- async read(p: Uint8Array): Promise<Deno.ReadResult> {
+ async read(p: Uint8Array): Promise<number | Deno.EOF> {
const n = Math.min(p.byteLength, this.buf.byteLength - this.offset);
p.set(this.buf.slice(this.offset, this.offset + n));
this.offset += n;
- return {
- nread: n,
- eof: this.offset === this.buf.byteLength
- };
+ if (n === 0) {
+ return Deno.EOF;
+ }
+
+ return n;
}
}
@@ -228,7 +229,7 @@ testPerm(
const buf = new Uint8Array(20);
await file.seek(0, Deno.SeekMode.SEEK_START);
const result = await file.read(buf);
- assertEquals(result.nread, 13);
+ assertEquals(result, 13);
file.close();
await Deno.remove(tempDir, { recursive: true });
diff --git a/js/io.ts b/js/io.ts
index 60b7e442c..aa1f08f36 100644
--- a/js/io.ts
+++ b/js/io.ts
@@ -3,11 +3,11 @@
// Documentation liberally lifted from them too.
// Thank you! We love Go!
-// The bytes read during an I/O call and a boolean indicating EOF.
-export interface ReadResult {
- nread: number;
- eof: boolean;
-}
+// TODO(kt3k): EOF should be `unique symbol` type.
+// That might require some changes of ts_library_builder.
+// See #2591 for more details.
+export const EOF: null = null;
+export type EOF = null;
// Seek whence values.
// https://golang.org/pkg/io/#pkg-constants
@@ -21,36 +21,27 @@ export enum SeekMode {
// https://golang.org/pkg/io/#Reader
export interface Reader {
/** Reads up to p.byteLength bytes into `p`. It resolves to the number
- * of bytes read (`0` <= `n` <= `p.byteLength`) and any error encountered.
+ * of bytes read (`0` < `n` <= `p.byteLength`) and rejects if any error encountered.
* Even if `read()` returns `n` < `p.byteLength`, it may use all of `p` as
* scratch space during the call. If some data is available but not
* `p.byteLength` bytes, `read()` conventionally returns what is available
* instead of waiting for more.
*
- * When `read()` encounters an error or end-of-file condition after
- * successfully reading `n` > `0` bytes, it returns the number of bytes read.
- * It may return the (non-nil) error from the same call or return the error
- * (and `n` == `0`) from a subsequent call. An instance of this general case
- * is that a `Reader` returning a non-zero number of bytes at the end of the
- * input stream may return either `err` == `EOF` or `err` == `null`. The next
- * `read()` should return `0`, `EOF`.
+ * When `read()` encounters end-of-file condition, it returns EOF symbol.
*
- * Callers should always process the `n` > `0` bytes returned before
- * considering the `EOF`. Doing so correctly handles I/O errors that happen
- * after reading some bytes and also both of the allowed `EOF` behaviors.
+ * When `read()` encounters an error, it rejects with an error.
*
- * Implementations of `read()` are discouraged from returning a zero byte
- * count with a `null` error, except when `p.byteLength` == `0`. Callers
- * should treat a return of `0` and `null` as indicating that nothing
- * happened; in particular it does not indicate `EOF`.
+ * Callers should always process the `n` > `0` bytes returned before
+ * considering the EOF. Doing so correctly handles I/O errors that happen
+ * after reading some bytes and also both of the allowed EOF behaviors.
*
* Implementations must not retain `p`.
*/
- read(p: Uint8Array): Promise<ReadResult>;
+ read(p: Uint8Array): Promise<number | EOF>;
}
export interface SyncReader {
- readSync(p: Uint8Array): ReadResult;
+ readSync(p: Uint8Array): number | EOF;
}
// Writer is the interface that wraps the basic write() method.
@@ -128,10 +119,11 @@ export async function copy(dst: Writer, src: Reader): Promise<number> {
let gotEOF = false;
while (gotEOF === false) {
const result = await src.read(b);
- if (result.eof) {
+ if (result === EOF) {
gotEOF = true;
+ } else {
+ n += await dst.write(b.subarray(0, result));
}
- n += await dst.write(b.subarray(0, result.nread));
}
return n;
}
@@ -146,7 +138,7 @@ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
const b = new Uint8Array(1024);
// Keep track if end-of-file has been reached, then
// signal that iterator is done during subsequent next()
- // call. This is required because `r` can return a `ReadResult`
+ // call. This is required because `r` can return a `number | EOF`
// with data read and EOF reached. But if iterator returns
// `done` then `value` is discarded.
//
@@ -164,10 +156,13 @@ export function toAsyncIterator(r: Reader): AsyncIterableIterator<Uint8Array> {
}
const result = await r.read(b);
- sawEof = result.eof;
+ if (result === EOF) {
+ sawEof = true;
+ return { value: new Uint8Array(), done: true };
+ }
return {
- value: b.subarray(0, result.nread),
+ value: b.subarray(0, result),
done: false
};
}
diff --git a/js/net.ts b/js/net.ts
index 7bf6dc098..f1470b86e 100644
--- a/js/net.ts
+++ b/js/net.ts
@@ -1,5 +1,5 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
-import { ReadResult, Reader, Writer, Closer } from "./io";
+import { EOF, Reader, Writer, Closer } from "./io";
import * as msg from "gen/cli/msg_generated";
import { assert, notImplemented } from "./util";
import * as dispatch from "./dispatch";
@@ -55,7 +55,7 @@ class ConnImpl implements Conn {
return write(this.rid, p);
}
- read(p: Uint8Array): Promise<ReadResult> {
+ read(p: Uint8Array): Promise<number | EOF> {
return read(this.rid, p);
}
diff --git a/js/net_test.ts b/js/net_test.ts
index 9f7e621bc..10652136c 100644
--- a/js/net_test.ts
+++ b/js/net_test.ts
@@ -53,20 +53,16 @@ testPerm({ net: true }, async function netDialListen(): Promise<void> {
const conn = await Deno.dial("tcp", "127.0.0.1:4500");
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
- assertEquals(3, readResult.nread);
+ assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
assert(conn.rid > 0);
- // TODO Currently ReadResult does not properly transmit EOF in the same call.
- // it requires a second call to get the EOF. Either ReadResult to be an
- // integer in which 0 signifies EOF or the handler should be modified so that
- // EOF is properly transmitted.
- assertEquals(false, readResult.eof);
+ assert(readResult !== Deno.EOF);
const readResult2 = await conn.read(buf);
- assertEquals(true, readResult2.eof);
+ assertEquals(Deno.EOF, readResult2);
listener.close();
conn.close();
@@ -85,20 +81,16 @@ testPerm({ net: true }, async function netListenAsyncIterator(): Promise<void> {
const conn = await Deno.dial("tcp", "127.0.0.1:4500");
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
- assertEquals(3, readResult.nread);
+ assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
assert(conn.rid > 0);
- // TODO Currently ReadResult does not properly transmit EOF in the same call.
- // it requires a second call to get the EOF. Either ReadResult to be an
- // integer in which 0 signifies EOF or the handler should be modified so that
- // EOF is properly transmitted.
- assertEquals(false, readResult.eof);
+ assert(readResult !== Deno.EOF);
const readResult2 = await conn.read(buf);
- assertEquals(true, readResult2.eof);
+ assertEquals(Deno.EOF, readResult2);
listener.close();
conn.close();
@@ -116,7 +108,7 @@ testPerm({ net: true }, async function netCloseReadSuccess() {
await conn.write(new Uint8Array([1, 2, 3]));
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
- assertEquals(3, readResult.nread);
+ assertEquals(3, readResult);
assertEquals(4, buf[0]);
assertEquals(5, buf[1]);
assertEquals(6, buf[2]);
@@ -128,8 +120,7 @@ testPerm({ net: true }, async function netCloseReadSuccess() {
closeReadDeferred.resolve();
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
- assertEquals(0, readResult.nread); // No error, read nothing
- assertEquals(true, readResult.eof); // with immediate EOF
+ assertEquals(Deno.EOF, readResult); // with immediate EOF
// Ensure closeRead does not impact write
await conn.write(new Uint8Array([4, 5, 6]));
await closeDeferred.promise;
@@ -181,7 +172,7 @@ testPerm({ net: true }, async function netCloseWriteSuccess() {
const buf = new Uint8Array(1024);
// Check read not impacted
const readResult = await conn.read(buf);
- assertEquals(3, readResult.nread);
+ assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
diff --git a/js/process_test.ts b/js/process_test.ts
index 6e5fe7947..874f59a81 100644
--- a/js/process_test.ts
+++ b/js/process_test.ts
@@ -156,13 +156,14 @@ testPerm({ run: true }, async function runStdoutPiped(): Promise<void> {
const data = new Uint8Array(10);
let r = await p.stdout.read(data);
- assertEquals(r.nread, 5);
- assertEquals(r.eof, false);
- const s = new TextDecoder().decode(data.subarray(0, r.nread));
+ if (r === Deno.EOF) {
+ throw new Error("p.stdout.read(...) should not be EOF");
+ }
+ assertEquals(r, 5);
+ const s = new TextDecoder().decode(data.subarray(0, r));
assertEquals(s, "hello");
r = await p.stdout.read(data);
- assertEquals(r.nread, 0);
- assertEquals(r.eof, true);
+ assertEquals(r, Deno.EOF);
p.stdout.close();
const status = await p.status();
@@ -182,13 +183,14 @@ testPerm({ run: true }, async function runStderrPiped(): Promise<void> {
const data = new Uint8Array(10);
let r = await p.stderr.read(data);
- assertEquals(r.nread, 5);
- assertEquals(r.eof, false);
- const s = new TextDecoder().decode(data.subarray(0, r.nread));
+ if (r === Deno.EOF) {
+ throw new Error("p.stderr.read should not return EOF here");
+ }
+ assertEquals(r, 5);
+ const s = new TextDecoder().decode(data.subarray(0, r));
assertEquals(s, "hello");
r = await p.stderr.read(data);
- assertEquals(r.nread, 0);
- assertEquals(r.eof, true);
+ assertEquals(r, Deno.EOF);
p.stderr.close();
const status = await p.status();
@@ -306,8 +308,7 @@ testPerm({ run: true }, async function runClose(): Promise<void> {
const data = new Uint8Array(10);
let r = await p.stderr.read(data);
- assertEquals(r.nread, 0);
- assertEquals(r.eof, true);
+ assertEquals(r, Deno.EOF);
});
test(function signalNumbers(): void {
diff --git a/js/xeval.ts b/js/xeval.ts
index f769a2ead..81e79f590 100644
--- a/js/xeval.ts
+++ b/js/xeval.ts
@@ -1,7 +1,7 @@
import { Buffer } from "./buffer";
import { stdin } from "./files";
import { TextEncoder, TextDecoder } from "./text_encoding";
-import { Reader } from "./io";
+import { Reader, EOF } from "./io";
export type XevalFunc = (v: string) => void;
@@ -35,12 +35,13 @@ async function* chunks(
// Record how far we have gone with delimiter matching.
let nextMatchIndex = 0;
while (true) {
- const rr = await reader.read(inspectArr);
- if (rr.nread < 0) {
+ let result = await reader.read(inspectArr);
+ let rr = result === EOF ? 0 : result;
+ if (rr < 0) {
// Silently fail.
break;
}
- const sliceRead = inspectArr.subarray(0, rr.nread);
+ const sliceRead = inspectArr.subarray(0, rr);
// Remember how far we have scanned through inspectArr.
let nextSliceStartIndex = 0;
for (let i = 0; i < sliceRead.length; i++) {
@@ -74,7 +75,7 @@ async function* chunks(
}
// Write all unprocessed chunk to buffer for future inspection.
await writeAll(inputBuffer, sliceRead.subarray(nextSliceStartIndex));
- if (rr.eof) {
+ if (result === EOF) {
// Flush the remainder unprocessed chunk.
const lastChunk = inputBuffer.toString();
yield lastChunk;