From 678313b17677e012ba9a07aeca58af1aafbf4e8c Mon Sep 17 00:00:00 2001 From: Nayeem Rahman Date: Tue, 28 Apr 2020 17:40:43 +0100 Subject: [PATCH] BREAKING: Remove Deno.EOF, use null instead (#4953) --- cli/js/buffer.ts | 12 ++-- cli/js/deno.ts | 1 - cli/js/files.ts | 9 ++- cli/js/io.ts | 13 ++--- cli/js/lib.deno.ns.d.ts | 76 +++++++++++++------------- cli/js/net.ts | 4 +- cli/js/ops/io.ts | 9 ++- cli/js/tests/buffer_test.ts | 5 +- cli/js/tests/files_test.ts | 8 +-- cli/js/tests/io_test.ts | 2 +- cli/js/tests/net_test.ts | 16 +++--- cli/js/tests/process_test.ts | 14 ++--- cli/js/tests/tls_test.ts | 6 +- cli/js/web/fetch.ts | 2 +- cli/tests/raw_mode.ts | 2 +- std/archive/tar.ts | 4 +- std/encoding/README.md | 4 +- std/encoding/binary.ts | 20 +++---- std/encoding/csv.ts | 14 ++--- std/examples/chat/server_test.ts | 2 +- std/examples/gist.ts | 2 +- std/examples/tests/echo_server_test.ts | 4 +- std/http/file_server_test.ts | 6 +- std/http/io.ts | 40 +++++++------- std/http/io_test.ts | 64 +++++++++++++--------- std/http/mock.ts | 2 +- std/http/racing_server_test.ts | 2 +- std/http/server.ts | 8 +-- std/http/server_test.ts | 28 +++++----- std/io/bufio.ts | 54 +++++++++--------- std/io/bufio_test.ts | 59 +++++++++++--------- std/io/iotest.ts | 6 +- std/io/ioutil.ts | 22 ++++---- std/io/ioutil_test.ts | 2 +- std/io/readers.ts | 10 ++-- std/io/readers_test.ts | 4 +- std/mime/multipart.ts | 26 ++++----- std/mime/multipart_test.ts | 2 +- std/testing/asserts.ts | 5 -- std/textproto/mod.ts | 18 +++--- std/textproto/test.ts | 29 +++++----- std/ws/README.md | 2 +- std/ws/example_client.ts | 2 +- std/ws/mod.ts | 22 +++++--- std/ws/test.ts | 10 ++-- tools/deno_tcp.ts | 2 +- 46 files changed, 329 insertions(+), 325 deletions(-) diff --git a/cli/js/buffer.ts b/cli/js/buffer.ts index e2a7e3de97..fdacf70a9f 100644 --- a/cli/js/buffer.ts +++ b/cli/js/buffer.ts @@ -4,7 +4,7 @@ // Copyright 2009 The Go Authors. All rights reserved. BSD license. // https://github.com/golang/go/blob/master/LICENSE -import { Reader, Writer, EOF, ReaderSync, WriterSync } from "./io.ts"; +import { Reader, Writer, ReaderSync, WriterSync } from "./io.ts"; import { assert } from "./util.ts"; import { TextDecoder } from "./web/text_encoding.ts"; @@ -91,7 +91,7 @@ export class Buffer implements Reader, ReaderSync, Writer, WriterSync { this.#buf = new Uint8Array(this.#buf.buffer, 0, len); }; - readSync(p: Uint8Array): number | EOF { + readSync(p: Uint8Array): number | null { if (this.empty()) { // Buffer is empty, reset to recover space. this.reset(); @@ -99,14 +99,14 @@ export class Buffer implements Reader, ReaderSync, Writer, WriterSync { // this edge case is tested in 'bufferReadEmptyAtEOF' test return 0; } - return EOF; + return null; } const nread = copyBytes(p, this.#buf.subarray(this.#off)); this.#off += nread; return nread; } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { const rr = this.readSync(p); return Promise.resolve(rr); } @@ -169,7 +169,7 @@ export class Buffer implements Reader, ReaderSync, Writer, WriterSync { this.#reslice(i); const fub = new Uint8Array(this.#buf.buffer, i); const nread = await r.read(fub); - if (nread === EOF) { + if (nread === null) { return n; } this.#reslice(i + nread); @@ -188,7 +188,7 @@ export class Buffer implements Reader, ReaderSync, Writer, WriterSync { this.#reslice(i); const fub = new Uint8Array(this.#buf.buffer, i); const nread = r.readSync(fub); - if (nread === EOF) { + if (nread === null) { return n; } this.#reslice(i + nread); diff --git a/cli/js/deno.ts b/cli/js/deno.ts index 3e1a2b263b..0e8057b72c 100644 --- a/cli/js/deno.ts +++ b/cli/js/deno.ts @@ -40,7 +40,6 @@ export { read, readSync, write, writeSync } from "./ops/io.ts"; export { FsEvent, watchFs } from "./ops/fs_events.ts"; export { internalSymbol as internal } from "./internals.ts"; export { - EOF, copy, iter, iterSync, diff --git a/cli/js/files.ts b/cli/js/files.ts index 46d6c8a850..d6df8bad03 100644 --- a/cli/js/files.ts +++ b/cli/js/files.ts @@ -1,6 +1,5 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { - EOF, Reader, Writer, Seeker, @@ -76,11 +75,11 @@ export class File return writeSync(this.rid, p); } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { return read(this.rid, p); } - readSync(p: Uint8Array): number | EOF { + readSync(p: Uint8Array): number | null { return readSync(this.rid, p); } @@ -103,11 +102,11 @@ class Stdin implements Reader, ReaderSync, Closer { this.rid = 0; } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { return read(this.rid, p); } - readSync(p: Uint8Array): number | EOF { + readSync(p: Uint8Array): number | null { return readSync(this.rid, p); } diff --git a/cli/js/io.ts b/cli/js/io.ts index 0b77206821..72c90d047a 100644 --- a/cli/js/io.ts +++ b/cli/js/io.ts @@ -3,9 +3,6 @@ // Documentation liberally lifted from them too. // Thank you! We love Go! -export const EOF: unique symbol = Symbol("EOF"); -export type EOF = typeof EOF; - const DEFAULT_BUFFER_SIZE = 32 * 1024; // Seek whence values. @@ -19,11 +16,11 @@ export enum SeekMode { // Reader is the interface that wraps the basic read() method. // https://golang.org/pkg/io/#Reader export interface Reader { - read(p: Uint8Array): Promise; + read(p: Uint8Array): Promise; } export interface ReaderSync { - readSync(p: Uint8Array): number | EOF; + readSync(p: Uint8Array): number | null; } // Writer is the interface that wraps the basic write() method. @@ -65,7 +62,7 @@ export async function copy( let gotEOF = false; while (gotEOF === false) { const result = await src.read(b); - if (result === EOF) { + if (result === null) { gotEOF = true; } else { n += await dst.write(b.subarray(0, result)); @@ -84,7 +81,7 @@ export async function* iter( const b = new Uint8Array(bufSize); while (true) { const result = await r.read(b); - if (result === EOF) { + if (result === null) { break; } @@ -102,7 +99,7 @@ export function* iterSync( const b = new Uint8Array(bufSize); while (true) { const result = r.readSync(b); - if (result === EOF) { + if (result === null) { break; } diff --git a/cli/js/lib.deno.ns.d.ts b/cli/js/lib.deno.ns.d.ts index 4626f6214b..5defc5732a 100644 --- a/cli/js/lib.deno.ns.d.ts +++ b/cli/js/lib.deno.ns.d.ts @@ -361,10 +361,6 @@ declare namespace Deno { */ export function umask(mask?: number): number; - /** **UNSTABLE**: might be removed in favor of `null` (#3932). */ - export const EOF: unique symbol; - export type EOF = typeof EOF; - export enum SeekMode { Start = 0, Current = 1, @@ -379,20 +375,21 @@ declare namespace Deno { * available but not `p.byteLength` bytes, `read()` conventionally resolves * to what is available instead of waiting for more. * - * When `read()` encounters end-of-file condition, it resolves to - * `Deno.EOF` symbol. + * When `read()` encounters end-of-file condition, it resolves to EOF + * (`null`). * * When `read()` encounters an error, it rejects with an error. * * 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. + * considering the EOF (`null`). Doing so correctly handles I/O errors that + * happen after reading some bytes and also both of the allowed EOF + * behaviors. * * Implementations should not retain a reference to `p`. * * Use Deno.iter() to turn a Reader into an AsyncIterator. */ - read(p: Uint8Array): Promise; + read(p: Uint8Array): Promise; } export interface ReaderSync { @@ -403,20 +400,20 @@ declare namespace Deno { * but not `p.byteLength` bytes, `read()` conventionally returns what is * available instead of waiting for more. * - * When `readSync()` encounters end-of-file condition, it returns `Deno.EOF` - * symbol. + * When `readSync()` encounters end-of-file condition, it returns EOF + * (`null`). * * When `readSync()` encounters an error, it throws with an error. * * Callers should always process the `n` > `0` bytes returned before - * considering the `EOF`. Doing so correctly handles I/O errors that happen + * considering the EOF (`null`). Doing so correctly handles I/O errors that happen * after reading some bytes and also both of the allowed EOF behaviors. * * Implementations should not retain a reference to `p`. * * Use Deno.iterSync() to turn a ReaderSync into an Iterator. */ - readSync(p: Uint8Array): number | EOF; + readSync(p: Uint8Array): number | null; } export interface Writer { @@ -477,8 +474,8 @@ declare namespace Deno { seekSync(offset: number, whence: SeekMode): number; } - /** Copies from `src` to `dst` until either `EOF` is reached on `src` or an - * error occurs. It resolves to the number of bytes copied or rejects with + /** Copies from `src` to `dst` until either EOF (`null`) is read from `src` or + * an error occurs. It resolves to the number of bytes copied or rejects with * the first error encountered while copying. * * const source = await Deno.open("my_file.txt"); @@ -486,9 +483,6 @@ declare namespace Deno { * const bytesCopied1 = await Deno.copy(source, Deno.stdout); * const bytesCopied2 = await Deno.copy(source, buffer); * - * Because `copy()` is defined to read from `src` until `EOF`, it does not - * treat an `EOF` from `read()` as an error to be reported. - * * @param src The source to copy from * @param dst The destination to copy to * @param options Can be used to tune size of the buffer. Default size is 32kB @@ -611,8 +605,11 @@ declare namespace Deno { /** Synchronously read from a resource ID (`rid`) into an array buffer (`buffer`). * - * Returns either the number of bytes read during the operation or End Of File - * (`Symbol(EOF)`) if there was nothing to read. + * Returns either the number of bytes read during the operation or EOF + * (`null`) if there was nothing more to read. + * + * It is possible for a read to successfully return with `0` bytes. This does + * not indicate EOF. * * // if "/foo/bar.txt" contains the text "hello world": * const file = Deno.openSync("/foo/bar.txt"); @@ -621,12 +618,15 @@ declare namespace Deno { * const text = new TextDecoder().decode(buf); // "hello world" * Deno.close(file.rid); */ - export function readSync(rid: number, buffer: Uint8Array): number | EOF; + export function readSync(rid: number, buffer: Uint8Array): number | null; /** Read from a resource ID (`rid`) into an array buffer (`buffer`). * - * Resolves to either the number of bytes read during the operation or End Of - * File (`Symbol(EOF)`) if there was nothing to read. + * Resolves to either the number of bytes read during the operation or EOF + * (`null`) if there was nothing more to read. + * + * It is possible for a read to successfully return with `0` bytes. This does + * not indicate EOF. * * // if "/foo/bar.txt" contains the text "hello world": * const file = await Deno.open("/foo/bar.txt"); @@ -635,7 +635,7 @@ declare namespace Deno { * const text = new TextDecoder().decode(buf); // "hello world" * Deno.close(file.rid); */ - export function read(rid: number, buffer: Uint8Array): Promise; + export function read(rid: number, buffer: Uint8Array): Promise; /** Synchronously write to the resource ID (`rid`) the contents of the array * buffer (`data`). @@ -743,8 +743,8 @@ declare namespace Deno { constructor(rid: number); write(p: Uint8Array): Promise; writeSync(p: Uint8Array): number; - read(p: Uint8Array): Promise; - readSync(p: Uint8Array): number | EOF; + read(p: Uint8Array): Promise; + readSync(p: Uint8Array): number | null; seek(offset: number, whence: SeekMode): Promise; seekSync(offset: number, whence: SeekMode): number; close(): void; @@ -863,12 +863,12 @@ declare namespace Deno { reset(): void; /** Reads the next `p.length` bytes from the buffer or until the buffer is * drained. Returns the number of bytes read. If the buffer has no data to - * return, the return is `Deno.EOF`. */ - readSync(p: Uint8Array): number | EOF; + * return, the return is EOF (`null`). */ + readSync(p: Uint8Array): number | null; /** Reads the next `p.length` bytes from the buffer or until the buffer is * drained. Resolves to the number of bytes read. If the buffer has no - * data to return, resolves to `Deno.EOF`. */ - read(p: Uint8Array): Promise; + * data to return, resolves to EOF (`null`). */ + read(p: Uint8Array): Promise; writeSync(p: Uint8Array): number; write(p: Uint8Array): Promise; /** Grows the buffer's capacity, if necessary, to guarantee space for @@ -879,14 +879,14 @@ declare namespace Deno { * Based on Go Lang's * [Buffer.Grow](https://golang.org/pkg/bytes/#Buffer.Grow). */ grow(n: number): void; - /** Reads data from `r` until `Deno.EOF` and appends it to the buffer, + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, * growing the buffer as needed. It resolves to the number of bytes read. * If the buffer becomes too large, `.readFrom()` will reject with an error. * * Based on Go Lang's * [Buffer.ReadFrom](https://golang.org/pkg/bytes/#Buffer.ReadFrom). */ readFrom(r: Reader): Promise; - /** Reads data from `r` until `Deno.EOF` and appends it to the buffer, + /** Reads data from `r` until EOF (`null`) and appends it to the buffer, * growing the buffer as needed. It returns the number of bytes read. If the * buffer becomes too large, `.readFromSync()` will throw an error. * @@ -895,8 +895,8 @@ declare namespace Deno { readFromSync(r: ReaderSync): number; } - /** Read Reader `r` until end of file (`Deno.EOF`) and resolve to the content - * as `Uint8Array`. + /** Read Reader `r` until EOF (`null`) and resolve to the content as + * Uint8Array`. * * // Example from stdin * const stdinContent = await Deno.readAll(Deno.stdin); @@ -914,8 +914,8 @@ declare namespace Deno { */ export function readAll(r: Reader): Promise; - /** Synchronously reads Reader `r` until end of file (`Deno.EOF`) and returns - * the content as `Uint8Array`. + /** Synchronously reads Reader `r` until EOF (`null`) and returns the content + * as `Uint8Array`. * * // Example from stdin * const stdinContent = Deno.readAllSync(Deno.stdin); @@ -2183,13 +2183,13 @@ declare namespace Deno { readonly stderr?: Reader & Closer; /** Resolves to the current status of the process. */ status(): Promise; - /** Buffer the stdout and return it as `Uint8Array` after `Deno.EOF`. + /** Buffer the stdout until EOF and return it as `Uint8Array`. * * You must set stdout to `"piped"` when creating the process. * * This calls `close()` on stdout after its done. */ output(): Promise; - /** Buffer the stderr and return it as `Uint8Array` after `Deno.EOF`. + /** Buffer the stderr until EOF and return it as `Uint8Array`. * * You must set stderr to `"piped"` when creating the process. * diff --git a/cli/js/net.ts b/cli/js/net.ts index 6f6736ee22..3ca1219e6a 100644 --- a/cli/js/net.ts +++ b/cli/js/net.ts @@ -1,6 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { errors } from "./errors.ts"; -import { EOF, Reader, Writer, Closer } from "./io.ts"; +import { Reader, Writer, Closer } from "./io.ts"; import { read, write } from "./ops/io.ts"; import { close } from "./ops/resources.ts"; import * as netOps from "./ops/net.ts"; @@ -40,7 +40,7 @@ export class ConnImpl implements Conn { return write(this.rid, p); } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { return read(this.rid, p); } diff --git a/cli/js/ops/io.ts b/cli/js/ops/io.ts index 16b42bfbcb..b4ef837e01 100644 --- a/cli/js/ops/io.ts +++ b/cli/js/ops/io.ts @@ -1,7 +1,6 @@ // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. import { sendAsyncMinimal, sendSyncMinimal } from "./dispatch_minimal.ts"; -import { EOF } from "../io.ts"; // TODO(bartlomieju): remove this import and maybe lazy-initialize // OPS_CACHE that belongs only to this module import { OPS_CACHE } from "../runtime.ts"; @@ -10,7 +9,7 @@ import { OPS_CACHE } from "../runtime.ts"; let OP_READ = -1; let OP_WRITE = -1; -export function readSync(rid: number, buffer: Uint8Array): number | EOF { +export function readSync(rid: number, buffer: Uint8Array): number | null { if (buffer.length == 0) { return 0; } @@ -21,7 +20,7 @@ export function readSync(rid: number, buffer: Uint8Array): number | EOF { if (nread < 0) { throw new Error("read error"); } else if (nread == 0) { - return EOF; + return null; } else { return nread; } @@ -30,7 +29,7 @@ export function readSync(rid: number, buffer: Uint8Array): number | EOF { export async function read( rid: number, buffer: Uint8Array -): Promise { +): Promise { if (buffer.length == 0) { return 0; } @@ -41,7 +40,7 @@ export async function read( if (nread < 0) { throw new Error("read error"); } else if (nread == 0) { - return EOF; + return null; } else { return nread; } diff --git a/cli/js/tests/buffer_test.ts b/cli/js/tests/buffer_test.ts index 9cfb716697..e45bcb976a 100644 --- a/cli/js/tests/buffer_test.ts +++ b/cli/js/tests/buffer_test.ts @@ -65,7 +65,7 @@ async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise { check(buf, s); while (true) { const r = await buf.read(fub); - if (r === Deno.EOF) { + if (r === null) { break; } s = s.slice(r); @@ -231,8 +231,7 @@ unitTest(async function bufferTestGrow(): Promise { for (const 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 result = await buf.read(tmp); - const nread = result === Deno.EOF ? 0 : result; + const nread = (await buf.read(tmp)) ?? 0; buf.grow(growLen); const yBytes = repeat("y", growLen); await buf.write(yBytes); diff --git a/cli/js/tests/files_test.ts b/cli/js/tests/files_test.ts index 8952166db7..a035c70742 100644 --- a/cli/js/tests/files_test.ts +++ b/cli/js/tests/files_test.ts @@ -101,13 +101,13 @@ unitTest(async function readerIter(): Promise { this.#buf = new Uint8Array(encoder.encode(s)); } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset); p.set(this.#buf.slice(this.#offset, this.#offset + n)); this.#offset += n; if (n === 0) { - return Promise.resolve(Deno.EOF); + return Promise.resolve(null); } return Promise.resolve(n); @@ -136,13 +136,13 @@ unitTest(async function readerIterSync(): Promise { this.#buf = new Uint8Array(encoder.encode(s)); } - readSync(p: Uint8Array): number | Deno.EOF { + readSync(p: Uint8Array): number | null { const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset); p.set(this.#buf.slice(this.#offset, this.#offset + n)); this.#offset += n; if (n === 0) { - return Deno.EOF; + return null; } return n; diff --git a/cli/js/tests/io_test.ts b/cli/js/tests/io_test.ts index 5b6e860bea..d6d6e35d1c 100644 --- a/cli/js/tests/io_test.ts +++ b/cli/js/tests/io_test.ts @@ -19,7 +19,7 @@ function spyRead(obj: Deno.Buffer): Spy { const orig = obj.read.bind(obj); - obj.read = (p: Uint8Array): Promise => { + obj.read = (p: Uint8Array): Promise => { spy.calls++; return orig(p); }; diff --git a/cli/js/tests/net_test.ts b/cli/js/tests/net_test.ts index 8840730a8b..ef3cd833de 100644 --- a/cli/js/tests/net_test.ts +++ b/cli/js/tests/net_test.ts @@ -179,10 +179,10 @@ unitTest({ perms: { net: true } }, async function netTcpDialListen(): Promise< assertEquals(3, buf[2]); assert(conn.rid > 0); - assert(readResult !== Deno.EOF); + assert(readResult !== null); const readResult2 = await conn.read(buf); - assertEquals(Deno.EOF, readResult2); + assertEquals(readResult2, null); listener.close(); conn.close(); @@ -214,10 +214,10 @@ unitTest( assertEquals(3, buf[2]); assert(conn.rid > 0); - assert(readResult !== Deno.EOF); + assert(readResult !== null); const readResult2 = await conn.read(buf); - assertEquals(Deno.EOF, readResult2); + assertEquals(readResult2, null); listener.close(); conn.close(); @@ -358,10 +358,10 @@ unitTest( assertEquals(3, buf[2]); assert(conn.rid > 0); - assert(readResult !== Deno.EOF); + assert(readResult !== null); const readResult2 = await conn.read(buf); - assertEquals(Deno.EOF, readResult2); + assertEquals(readResult2, null); listener.close(); conn.close(); @@ -396,7 +396,7 @@ unitTest( closeReadDeferred.resolve(); const buf = new Uint8Array(1024); const readResult = await conn.read(buf); - assertEquals(Deno.EOF, readResult); // with immediate EOF + assertEquals(readResult, null); // with immediate EOF // Ensure closeRead does not impact write await conn.write(new Uint8Array([4, 5, 6])); await closeDeferred; @@ -523,7 +523,7 @@ unitTest( try { while (true) { const nread = await conn.read(p); - if (nread === Deno.EOF) { + if (nread === null) { break; } await conn.write(new Uint8Array([1, 2, 3])); diff --git a/cli/js/tests/process_test.ts b/cli/js/tests/process_test.ts index f0615193bb..b70ce83076 100644 --- a/cli/js/tests/process_test.ts +++ b/cli/js/tests/process_test.ts @@ -154,14 +154,14 @@ unitTest({ perms: { run: true } }, async function runStdoutPiped(): Promise< const data = new Uint8Array(10); let r = await p.stdout!.read(data); - if (r === Deno.EOF) { - throw new Error("p.stdout.read(...) should not be EOF"); + if (r === null) { + throw new Error("p.stdout.read(...) should not be null"); } assertEquals(r, 5); const s = new TextDecoder().decode(data.subarray(0, r)); assertEquals(s, "hello"); r = await p.stdout!.read(data); - assertEquals(r, Deno.EOF); + assertEquals(r, null); p.stdout!.close(); const status = await p.status(); @@ -183,14 +183,14 @@ unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise< const data = new Uint8Array(10); let r = await p.stderr!.read(data); - if (r === Deno.EOF) { - throw new Error("p.stderr.read should not return EOF here"); + if (r === null) { + throw new Error("p.stderr.read should not return null here"); } assertEquals(r, 5); const s = new TextDecoder().decode(data.subarray(0, r)); assertEquals(s, "hello"); r = await p.stderr!.read(data); - assertEquals(r, Deno.EOF); + assertEquals(r, null); p.stderr!.close(); const status = await p.status(); @@ -313,7 +313,7 @@ unitTest({ perms: { run: true } }, async function runClose(): Promise { const data = new Uint8Array(10); const r = await p.stderr!.read(data); - assertEquals(r, Deno.EOF); + assertEquals(r, null); p.stderr!.close(); }); diff --git a/cli/js/tests/tls_test.ts b/cli/js/tests/tls_test.ts index ce44beac0d..b971ccf5c6 100644 --- a/cli/js/tests/tls_test.ts +++ b/cli/js/tests/tls_test.ts @@ -191,7 +191,7 @@ unitTest( await w.flush(); const tpr = new TextProtoReader(r); const statusLine = await tpr.readLine(); - assert(statusLine !== Deno.EOF, `line must be read: ${String(statusLine)}`); + assert(statusLine !== null, `line must be read: ${String(statusLine)}`); const m = statusLine.match(/^(.+?) (.+?) (.+?)$/); assert(m !== null, "must be matched"); const [_, proto, status, ok] = m; @@ -199,7 +199,7 @@ unitTest( assertEquals(status, "200"); assertEquals(ok, "OK"); const headers = await tpr.readMIMEHeader(); - assert(headers !== Deno.EOF); + assert(headers !== null); const contentLength = parseInt(headers.get("content-length")!); const bodyBuf = new Uint8Array(contentLength); await r.readFull(bodyBuf); @@ -225,7 +225,7 @@ unitTest( let writer = new BufWriter(conn); let reader = new TextProtoReader(new BufReader(conn)); - let line: string | Deno.EOF = (await reader.readLine()) as string; + let line: string | null = (await reader.readLine()) as string; assert(line.startsWith("220")); await writer.write(encoder.encode(`EHLO ${hostname}\r\n`)); diff --git a/cli/js/web/fetch.ts b/cli/js/web/fetch.ts index 60dafa1500..cbedcabfdb 100644 --- a/cli/js/web/fetch.ts +++ b/cli/js/web/fetch.ts @@ -220,7 +220,7 @@ class Body return decoder.decode(ab); } - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { this.#bodyUsed = true; return read(this.#rid, p); } diff --git a/cli/tests/raw_mode.ts b/cli/tests/raw_mode.ts index 125601b2b5..87502e7d9f 100644 --- a/cli/tests/raw_mode.ts +++ b/cli/tests/raw_mode.ts @@ -6,7 +6,7 @@ Deno.stdout.writeSync(new TextEncoder().encode("S")); const buf = new Uint8Array(3); for (let i = 0; i < 3; i++) { const nread = await Deno.stdin.read(buf); - if (nread === Deno.EOF) { + if (nread === null) { break; } else { const data = new TextDecoder().decode(buf.subarray(0, nread)); diff --git a/std/archive/tar.ts b/std/archive/tar.ts index 28c4bbd9a9..225bcb7693 100644 --- a/std/archive/tar.ts +++ b/std/archive/tar.ts @@ -41,12 +41,12 @@ class FileReader implements Deno.Reader { constructor(private filePath: string) {} - public async read(p: Uint8Array): Promise { + public async read(p: Uint8Array): Promise { if (!this.file) { this.file = await Deno.open(this.filePath, { read: true }); } const res = await Deno.read(this.file.rid, p); - if (res === Deno.EOF) { + if (res === null) { Deno.close(this.file.rid); this.file = undefined; } diff --git a/std/encoding/README.md b/std/encoding/README.md index e6604c6050..7d9c891177 100644 --- a/std/encoding/README.md +++ b/std/encoding/README.md @@ -17,8 +17,8 @@ Available Functions: ```typescript sizeof(dataType: RawTypes): number getNBytes(r: Deno.Reader, n: number): Promise -varnum(b: Uint8Array, o: VarnumOptions = {}): number | Deno.EOF -varbig(b: Uint8Array, o: VarbigOptions = {}): bigint | Deno.EOF +varnum(b: Uint8Array, o: VarnumOptions = {}): number | null +varbig(b: Uint8Array, o: VarbigOptions = {}): bigint | null putVarnum(b: Uint8Array, x: number, o: VarnumOptions = {}): number putVarbig(b: Uint8Array, x: bigint, o: VarbigOptions = {}): number readVarnum(r: Deno.Reader, o: VarnumOptions = {}): Promise diff --git a/std/encoding/binary.ts b/std/encoding/binary.ts index cd338703b1..dd9c26243d 100644 --- a/std/encoding/binary.ts +++ b/std/encoding/binary.ts @@ -51,19 +51,16 @@ export async function getNBytes( ): Promise { const scratch = new Uint8Array(n); const nRead = await r.read(scratch); - if (nRead === Deno.EOF || nRead < n) throw new Deno.errors.UnexpectedEof(); + if (nRead === null || nRead < n) throw new Deno.errors.UnexpectedEof(); return scratch; } /** Decode a number from `b`, and return it as a `number`. Data-type defaults to `int32`. - * Returns `EOF` if `b` is too short for the data-type given in `o`. */ -export function varnum( - b: Uint8Array, - o: VarnumOptions = {} -): number | Deno.EOF { + * Returns `null` if `b` is too short for the data-type given in `o`. */ +export function varnum(b: Uint8Array, o: VarnumOptions = {}): number | null { o.dataType = o.dataType ?? "int32"; const littleEndian = (o.endian ?? "big") === "little" ? true : false; - if (b.length < sizeof(o.dataType)) return Deno.EOF; + if (b.length < sizeof(o.dataType)) return null; const view = new DataView(b.buffer); switch (o.dataType) { case "int8": @@ -86,14 +83,11 @@ export function varnum( } /** Decode an integer from `b`, and return it as a `bigint`. Data-type defaults to `int64`. - * Returns `EOF` if `b` is too short for the data-type given in `o`. */ -export function varbig( - b: Uint8Array, - o: VarbigOptions = {} -): bigint | Deno.EOF { + * Returns `null` if `b` is too short for the data-type given in `o`. */ +export function varbig(b: Uint8Array, o: VarbigOptions = {}): bigint | null { o.dataType = o.dataType ?? "int64"; const littleEndian = (o.endian ?? "big") === "little" ? true : false; - if (b.length < sizeof(o.dataType)) return Deno.EOF; + if (b.length < sizeof(o.dataType)) return null; const view = new DataView(b.buffer); switch (o.dataType) { case "int8": diff --git a/std/encoding/csv.ts b/std/encoding/csv.ts index 711e277722..ae86e25bbc 100644 --- a/std/encoding/csv.ts +++ b/std/encoding/csv.ts @@ -64,12 +64,12 @@ async function readRecord( Startline: number, reader: BufReader, opt: ReadOptions = { comma: ",", trimLeadingSpace: false } -): Promise { +): Promise { const tp = new TextProtoReader(reader); const lineIndex = Startline; let line = await readLine(tp); - if (line === Deno.EOF) return Deno.EOF; + if (line === null) return null; if (line.length === 0) { return []; } @@ -147,7 +147,7 @@ async function readRecord( // Hit end of line (copy all data so far). recordBuffer += line; const r = await readLine(tp); - if (r === Deno.EOF) { + if (r === null) { if (!opt.lazyQuotes) { quoteError = ERR_QUOTE; break parseField; @@ -182,13 +182,13 @@ async function readRecord( } async function isEOF(tp: TextProtoReader): Promise { - return (await tp.r.peek(0)) === Deno.EOF; + return (await tp.r.peek(0)) === null; } -async function readLine(tp: TextProtoReader): Promise { +async function readLine(tp: TextProtoReader): Promise { let line: string; const r = await tp.readLine(); - if (r === Deno.EOF) return Deno.EOF; + if (r === null) return null; line = r; // For backwards compatibility, drop trailing \r before EOF. @@ -226,7 +226,7 @@ export async function readMatrix( for (;;) { const r = await readRecord(lineIndex, reader, opt); - if (r === Deno.EOF) break; + if (r === null) break; lineResult = r; lineIndex++; // If fieldsPerRecord is 0, Read sets it to diff --git a/std/examples/chat/server_test.ts b/std/examples/chat/server_test.ts index 47e17314ba..74d4fefced 100644 --- a/std/examples/chat/server_test.ts +++ b/std/examples/chat/server_test.ts @@ -17,7 +17,7 @@ async function startServer(): Promise { assert(server.stdout != null); const r = new TextProtoReader(new BufReader(server.stdout)); const s = await r.readLine(); - assert(s !== Deno.EOF && s.includes("chat server starting")); + assert(s !== null && s.includes("chat server starting")); } catch (err) { server.stdout!.close(); server.close(); diff --git a/std/examples/gist.ts b/std/examples/gist.ts index a11a923835..c41b9b98ed 100755 --- a/std/examples/gist.ts +++ b/std/examples/gist.ts @@ -1,6 +1,6 @@ #!/usr/bin/env -S deno --allow-net --allow-env // Copyright 2018-2020 the Deno authors. All rights reserved. MIT license. -import { parse } from "https://deno.land/std/flags/mod.ts"; +import { parse } from "../flags/mod.ts"; function pathBase(p: string): string { const parts = p.split("/"); diff --git a/std/examples/tests/echo_server_test.ts b/std/examples/tests/echo_server_test.ts index fecc7d6a66..9c413d737d 100644 --- a/std/examples/tests/echo_server_test.ts +++ b/std/examples/tests/echo_server_test.ts @@ -16,7 +16,7 @@ Deno.test("[examples/echo_server]", async () => { const processReader = new BufReader(process.stdout!); const message = await processReader.readLine(); - assertNotEquals(message, Deno.EOF); + assertNotEquals(message, null); assertStrictEq( decoder.decode((message as ReadLineResult).line).trim(), "Listening on 0.0.0.0:8080" @@ -28,7 +28,7 @@ Deno.test("[examples/echo_server]", async () => { await conn.write(encoder.encode("Hello echo_server\n")); const result = await connReader.readLine(); - assertNotEquals(result, Deno.EOF); + assertNotEquals(result, null); const actualResponse = decoder .decode((result as ReadLineResult).line) diff --git a/std/http/file_server_test.ts b/std/http/file_server_test.ts index eff47c41bb..8be35621c3 100644 --- a/std/http/file_server_test.ts +++ b/std/http/file_server_test.ts @@ -25,7 +25,7 @@ async function startFileServer(): Promise { assert(fileServer.stdout != null); const r = new TextProtoReader(new BufReader(fileServer.stdout)); const s = await r.readLine(); - assert(s !== Deno.EOF && s.includes("server listening")); + assert(s !== null && s.includes("server listening")); } function killFileServer(): void { @@ -114,7 +114,7 @@ test("servePermissionDenied", async function (): Promise { assert(deniedServer.stderr != null); const errReader = new TextProtoReader(new BufReader(deniedServer.stderr)); const s = await reader.readLine(); - assert(s !== Deno.EOF && s.includes("server listening")); + assert(s !== null && s.includes("server listening")); try { const res = await fetch("http://localhost:4500/"); @@ -138,7 +138,7 @@ test("printHelp", async function (): Promise { assert(helpProcess.stdout != null); const r = new TextProtoReader(new BufReader(helpProcess.stdout)); const s = await r.readLine(); - assert(s !== Deno.EOF && s.includes("Deno File Server")); + assert(s !== null && s.includes("Deno File Server")); helpProcess.close(); helpProcess.stdout.close(); }); diff --git a/std/http/io.ts b/std/http/io.ts index d87a033064..fbce443426 100644 --- a/std/http/io.ts +++ b/std/http/io.ts @@ -7,8 +7,8 @@ import { STATUS_TEXT } from "./http_status.ts"; export function emptyReader(): Deno.Reader { return { - read(_: Uint8Array): Promise { - return Promise.resolve(Deno.EOF); + read(_: Uint8Array): Promise { + return Promise.resolve(null); }, }; } @@ -16,9 +16,9 @@ export function emptyReader(): Deno.Reader { export function bodyReader(contentLength: number, r: BufReader): Deno.Reader { let totalRead = 0; let finished = false; - async function read(buf: Uint8Array): Promise { - if (finished) return Deno.EOF; - let result: number | Deno.EOF; + async function read(buf: Uint8Array): Promise { + if (finished) return null; + let result: number | null; const remaining = contentLength - totalRead; if (remaining >= buf.byteLength) { result = await r.read(buf); @@ -26,7 +26,7 @@ export function bodyReader(contentLength: number, r: BufReader): Deno.Reader { const readBuf = buf.subarray(0, remaining); result = await r.read(readBuf); } - if (result !== Deno.EOF) { + if (result !== null) { totalRead += result; } finished = totalRead === contentLength; @@ -43,8 +43,8 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader { offset: number; data: Uint8Array; }> = []; - async function read(buf: Uint8Array): Promise { - if (finished) return Deno.EOF; + async function read(buf: Uint8Array): Promise { + if (finished) return null; const [chunk] = chunks; if (chunk) { const chunkRemaining = chunk.data.byteLength - chunk.offset; @@ -56,14 +56,14 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader { if (chunk.offset === chunk.data.byteLength) { chunks.shift(); // Consume \r\n; - if ((await tp.readLine()) === Deno.EOF) { + if ((await tp.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } } return readLength; } const line = await tp.readLine(); - if (line === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (line === null) throw new Deno.errors.UnexpectedEof(); // TODO: handle chunk extension const [chunkSizeString] = line.split(";"); const chunkSize = parseInt(chunkSizeString, 16); @@ -73,12 +73,12 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader { if (chunkSize > 0) { if (chunkSize > buf.byteLength) { let eof = await r.readFull(buf); - if (eof === Deno.EOF) { + if (eof === null) { throw new Deno.errors.UnexpectedEof(); } const restChunk = new Uint8Array(chunkSize - buf.byteLength); eof = await r.readFull(restChunk); - if (eof === Deno.EOF) { + if (eof === null) { throw new Deno.errors.UnexpectedEof(); } else { chunks.push({ @@ -90,11 +90,11 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader { } else { const bufToFill = buf.subarray(0, chunkSize); const eof = await r.readFull(bufToFill); - if (eof === Deno.EOF) { + if (eof === null) { throw new Deno.errors.UnexpectedEof(); } // Consume \r\n - if ((await tp.readLine()) === Deno.EOF) { + if ((await tp.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } return chunkSize; @@ -102,12 +102,12 @@ export function chunkedBodyReader(h: Headers, r: BufReader): Deno.Reader { } else { assert(chunkSize === 0); // Consume \r\n - if ((await r.readLine()) === Deno.EOF) { + if ((await r.readLine()) === null) { throw new Deno.errors.UnexpectedEof(); } await readTrailers(h, r); finished = true; - return Deno.EOF; + return null; } } return { read }; @@ -131,7 +131,7 @@ export async function readTrailers( if (!keys) return; const tp = new TextProtoReader(r); const result = await tp.readMIMEHeader(); - assert(result != Deno.EOF, "trailer must be set"); + assert(result !== null, "trailer must be set"); for (const [k, v] of result) { if (!keys.has(k)) { throw new Error("Undeclared trailer field"); @@ -332,12 +332,12 @@ export function parseHTTPVersion(vers: string): [number, number] { export async function readRequest( conn: Deno.Conn, bufr: BufReader -): Promise { +): Promise { const tp = new TextProtoReader(bufr); const firstLine = await tp.readLine(); // e.g. GET /index.html HTTP/1.0 - if (firstLine === Deno.EOF) return Deno.EOF; + if (firstLine === null) return null; const headers = await tp.readMIMEHeader(); - if (headers === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (headers === null) throw new Deno.errors.UnexpectedEof(); const req = new ServerRequest(); req.conn = conn; diff --git a/std/http/io_test.ts b/std/http/io_test.ts index 0fe70730b4..b9bb56f119 100644 --- a/std/http/io_test.ts +++ b/std/http/io_test.ts @@ -3,7 +3,6 @@ import { assertThrowsAsync, assertEquals, assert, - assertNotEOF, assertNotEquals, } from "../testing/asserts.ts"; import { @@ -43,11 +42,11 @@ test("chunkedBodyReader", async () => { ].join(""); const h = new Headers(); const r = chunkedBodyReader(h, new BufReader(new Buffer(encode(body)))); - let result: number | Deno.EOF; + let result: number | null; // Use small buffer as some chunks exceed buffer size const buf = new Uint8Array(5); const dest = new Buffer(); - while ((result = await r.read(buf)) !== Deno.EOF) { + while ((result = await r.read(buf)) !== null) { const len = Math.min(buf.byteLength, result); await dest.write(buf.subarray(0, len)); } @@ -223,25 +222,28 @@ test("writeUint8ArrayResponse", async function (): Promise { const decoder = new TextDecoder("utf-8"); const reader = new BufReader(buf); - let r: ReadLineResult; - r = assertNotEOF(await reader.readLine()); + let r: ReadLineResult | null = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), "HTTP/1.1 200 OK"); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), `content-length: ${shortText.length}`); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(r.line.byteLength, 0); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), shortText); assertEquals(r.more, false); const eof = await reader.readLine(); - assertEquals(eof, Deno.EOF); + assertEquals(eof, null); }); test("writeStringResponse", async function (): Promise { @@ -255,25 +257,28 @@ test("writeStringResponse", async function (): Promise { const decoder = new TextDecoder("utf-8"); const reader = new BufReader(buf); - let r: ReadLineResult; - r = assertNotEOF(await reader.readLine()); + let r: ReadLineResult | null = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), "HTTP/1.1 200 OK"); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), `content-length: ${body.length}`); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(r.line.byteLength, 0); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), body); assertEquals(r.more, false); const eof = await reader.readLine(); - assertEquals(eof, Deno.EOF); + assertEquals(eof, null); }); test("writeStringReaderResponse", async function (): Promise { @@ -288,28 +293,33 @@ test("writeStringReaderResponse", async function (): Promise { const decoder = new TextDecoder("utf-8"); const reader = new BufReader(buf); - let r: ReadLineResult; - r = assertNotEOF(await reader.readLine()); + let r: ReadLineResult | null = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), "HTTP/1.1 200 OK"); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), "transfer-encoding: chunked"); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(r.line.byteLength, 0); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), shortText.length.toString()); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), shortText); assertEquals(r.more, false); - r = assertNotEOF(await reader.readLine()); + r = await reader.readLine(); + assert(r !== null); assertEquals(decoder.decode(r.line), "0"); assertEquals(r.more, false); }); @@ -372,7 +382,7 @@ test("testReadRequestError", async function (): Promise { in: "GET / HTTP/1.1\r\nheader:foo\r\n", err: Deno.errors.UnexpectedEof, }, - { in: "", err: Deno.EOF }, + { in: "", eof: true }, { in: "HEAD / HTTP/1.1\r\nContent-Length:4\r\n\r\n", err: "http: method cannot contain a Content-Length", @@ -427,14 +437,14 @@ test("testReadRequestError", async function (): Promise { for (const test of testCases) { const reader = new BufReader(new StringReader(test.in)); let err; - let req: ServerRequest | Deno.EOF | undefined; + let req: ServerRequest | null = null; try { req = await readRequest(mockConn(), reader); } catch (e) { err = e; } - if (test.err === Deno.EOF) { - assertEquals(req, Deno.EOF); + if (test.eof) { + assertEquals(req, null); } else if (typeof test.err === "string") { assertEquals(err.message, test.err); } else if (test.err) { @@ -443,7 +453,7 @@ test("testReadRequestError", async function (): Promise { assert(req instanceof ServerRequest); assert(test.headers); assertEquals(err, undefined); - assertNotEquals(req, Deno.EOF); + assertNotEquals(req, null); for (const h of test.headers) { assertEquals(req.headers.get(h.key), h.value); } diff --git a/std/http/mock.ts b/std/http/mock.ts index 64bd3fcb99..f373b42147 100644 --- a/std/http/mock.ts +++ b/std/http/mock.ts @@ -14,7 +14,7 @@ export function mockConn(base: Partial = {}): Deno.Conn { rid: -1, closeRead: (): void => {}, closeWrite: (): void => {}, - read: (): Promise => { + read: (): Promise => { return Promise.resolve(0); }, write: (): Promise => { diff --git a/std/http/racing_server_test.ts b/std/http/racing_server_test.ts index d80072e7d8..90961f7f83 100644 --- a/std/http/racing_server_test.ts +++ b/std/http/racing_server_test.ts @@ -13,7 +13,7 @@ async function startServer(): Promise { assert(server.stdout != null); const r = new TextProtoReader(new BufReader(server.stdout)); const s = await r.readLine(); - assert(s !== Deno.EOF && s.includes("Racing server listening...")); + assert(s !== null && s.includes("Racing server listening...")); } function killServer(): void { server.close(); diff --git a/std/http/server.ts b/std/http/server.ts index bc48d46289..9c678ad3d8 100644 --- a/std/http/server.ts +++ b/std/http/server.ts @@ -60,7 +60,7 @@ export class ServerRequest { * let totRead = 0; * while (true) { * const nread = await req.body.read(bufSlice); - * if (nread === Deno.EOF) break; + * if (nread === null) break; * totRead += nread; * if (totRead >= req.contentLength) break; * bufSlice = bufSlice.subarray(nread); @@ -117,7 +117,7 @@ export class ServerRequest { // Consume unread body const body = this.body; const buf = new Uint8Array(1024); - while ((await body.read(buf)) !== Deno.EOF) {} + while ((await body.read(buf)) !== null) {} this.finalized = true; } } @@ -151,7 +151,7 @@ export class Server implements AsyncIterable { const writer = new BufWriter(conn); while (!this.closing) { - let request: ServerRequest | Deno.EOF; + let request: ServerRequest | null; try { request = await readRequest(conn, reader); } catch (error) { @@ -167,7 +167,7 @@ export class Server implements AsyncIterable { } break; } - if (request == Deno.EOF) { + if (request === null) { break; } diff --git a/std/http/server_test.ts b/std/http/server_test.ts index 939e796009..4e7b4b69e5 100644 --- a/std/http/server_test.ts +++ b/std/http/server_test.ts @@ -10,7 +10,6 @@ import { assert, assertEquals, assertMatch, - assertNotEOF, assertStrContains, assertThrowsAsync, } from "../testing/asserts.ts"; @@ -108,7 +107,7 @@ interface TotalReader extends Deno.Reader { } function totalReader(r: Deno.Reader): TotalReader { let _total = 0; - async function read(p: Uint8Array): Promise { + async function read(p: Uint8Array): Promise { const result = await r.read(p); if (typeof result === "number") { _total += result; @@ -252,13 +251,13 @@ test("requestBodyReaderWithContentLength", async function (): Promise { let offset = 0; while (offset < shortText.length) { const nread = await req.body.read(readBuf); - assertNotEOF(nread); + assert(nread !== null); const s = decode(readBuf.subarray(0, nread as number)); assertEquals(shortText.substr(offset, nread as number), s); offset += nread as number; } const nread = await req.body.read(readBuf); - assertEquals(nread, Deno.EOF); + assertEquals(nread, null); } // Larger than given buf @@ -273,13 +272,13 @@ test("requestBodyReaderWithContentLength", async function (): Promise { let offset = 0; while (offset < longText.length) { const nread = await req.body.read(readBuf); - assertNotEOF(nread); + assert(nread !== null); const s = decode(readBuf.subarray(0, nread as number)); assertEquals(longText.substr(offset, nread as number), s); offset += nread as number; } const nread = await req.body.read(readBuf); - assertEquals(nread, Deno.EOF); + assertEquals(nread, null); } }); @@ -307,13 +306,13 @@ test("requestBodyReaderWithTransferEncoding", async function (): Promise { let offset = 0; while (offset < shortText.length) { const nread = await req.body.read(readBuf); - assertNotEOF(nread); + assert(nread !== null); const s = decode(readBuf.subarray(0, nread as number)); assertEquals(shortText.substr(offset, nread as number), s); offset += nread as number; } const nread = await req.body.read(readBuf); - assertEquals(nread, Deno.EOF); + assertEquals(nread, null); } // Larger than internal buf @@ -340,13 +339,13 @@ test("requestBodyReaderWithTransferEncoding", async function (): Promise { let offset = 0; while (offset < longText.length) { const nread = await req.body.read(readBuf); - assertNotEOF(nread); + assert(nread !== null); const s = decode(readBuf.subarray(0, nread as number)); assertEquals(longText.substr(offset, nread as number), s); offset += nread as number; } const nread = await req.body.read(readBuf); - assertEquals(nread, Deno.EOF); + assertEquals(nread, null); } }); @@ -372,7 +371,7 @@ test({ try { const r = new TextProtoReader(new BufReader(p.stdout!)); const s = await r.readLine(); - assert(s !== Deno.EOF && s.includes("server listening")); + assert(s !== null && s.includes("server listening")); await delay(100); // Reqeusts to the server and immediately closes the connection const conn = await Deno.connect({ port: 4502 }); @@ -419,7 +418,7 @@ test({ const r = new TextProtoReader(new BufReader(p.stdout!)); const s = await r.readLine(); assert( - s !== Deno.EOF && s.includes("server listening"), + s !== null && s.includes("server listening"), "server must be started" ); // Requests to the server and immediately closes the connection @@ -433,7 +432,8 @@ test({ new TextEncoder().encode("GET / HTTP/1.0\r\n\r\n") ); const res = new Uint8Array(100); - const nread = assertNotEOF(await conn.read(res)); + const nread = await conn.read(res); + assert(nread !== null); conn.close(); const resStr = new TextDecoder().decode(res.subarray(0, nread)); assert(resStr.includes("Hello HTTPS")); @@ -476,7 +476,7 @@ test({ ); const res = new Uint8Array(100); const nread = await conn.read(res); - assert(nread !== Deno.EOF); + assert(nread !== null); const resStr = new TextDecoder().decode(res.subarray(0, nread)); assertStrContains(resStr, "/hello"); server.close(); diff --git a/std/io/bufio.ts b/std/io/bufio.ts index cd08fbefac..9a22c7f3ee 100644 --- a/std/io/bufio.ts +++ b/std/io/bufio.ts @@ -83,7 +83,7 @@ export class BufReader implements Reader { // Read new data: try a limited number of times. for (let i = MAX_CONSECUTIVE_EMPTY_READS; i > 0; i--) { const rr = await this.rd.read(this.buf.subarray(this.w)); - if (rr === Deno.EOF) { + if (rr === null) { this.eof = true; return; } @@ -120,8 +120,8 @@ export class BufReader implements Reader { * hence n may be less than len(p). * To read exactly len(p) bytes, use io.ReadFull(b, p). */ - async read(p: Uint8Array): Promise { - let rr: number | Deno.EOF = p.byteLength; + async read(p: Uint8Array): Promise { + let rr: number | null = p.byteLength; if (p.byteLength === 0) return rr; if (this.r === this.w) { @@ -129,7 +129,7 @@ export class BufReader implements Reader { // Large read, empty buffer. // Read directly into p to avoid copy. const rr = await this.rd.read(p); - const nread = rr === Deno.EOF ? 0 : rr; + const nread = rr ?? 0; assert(nread >= 0, "negative read"); // if (rr.nread > 0) { // this.lastByte = p[rr.nread - 1]; @@ -143,7 +143,7 @@ export class BufReader implements Reader { this.r = 0; this.w = 0; rr = await this.rd.read(this.buf); - if (rr === 0 || rr === Deno.EOF) return rr; + if (rr === 0 || rr === null) return rr; assert(rr >= 0, "negative read"); this.w += rr; } @@ -161,7 +161,7 @@ export class BufReader implements Reader { * If successful, `p` is returned. * * If the end of the underlying stream has been reached, and there are no more - * bytes available in the buffer, `readFull()` returns `EOF` instead. + * bytes available in the buffer, `readFull()` returns `null` instead. * * An error is thrown if some bytes could be read, but not enough to fill `p` * entirely before the underlying stream reported an error or EOF. Any error @@ -170,14 +170,14 @@ export class BufReader implements Reader { * * Ported from https://golang.org/pkg/io/#ReadFull */ - async readFull(p: Uint8Array): Promise { + async readFull(p: Uint8Array): Promise { let bytesRead = 0; while (bytesRead < p.length) { try { const rr = await this.read(p.subarray(bytesRead)); - if (rr === Deno.EOF) { + if (rr === null) { if (bytesRead === 0) { - return Deno.EOF; + return null; } else { throw new PartialReadError(); } @@ -191,10 +191,10 @@ export class BufReader implements Reader { return p; } - /** Returns the next byte [0, 255] or `EOF`. */ - async readByte(): Promise { + /** Returns the next byte [0, 255] or `null`. */ + async readByte(): Promise { while (this.r === this.w) { - if (this.eof) return Deno.EOF; + if (this.eof) return null; await this._fill(); // buffer is empty. } const c = this.buf[this.r]; @@ -207,17 +207,17 @@ export class BufReader implements Reader { * returning a string containing the data up to and including the delimiter. * If ReadString encounters an error before finding a delimiter, * it returns the data read before the error and the error itself - * (often io.EOF). + * (often `null`). * ReadString returns err != nil if and only if the returned data does not end * in delim. * For simple uses, a Scanner may be more convenient. */ - async readString(delim: string): Promise { + async readString(delim: string): Promise { if (delim.length !== 1) { throw new Error("Delimiter should be a single character"); } const buffer = await this.readSlice(delim.charCodeAt(0)); - if (buffer == Deno.EOF) return Deno.EOF; + if (buffer === null) return null; return new TextDecoder().decode(buffer); } @@ -237,14 +237,14 @@ export class BufReader implements Reader { * When the end of the underlying stream is reached, the final bytes in the * stream are returned. No indication or error is given if the input ends * without a final line end. When there are no more trailing bytes to read, - * `readLine()` returns the `EOF` symbol. + * `readLine()` returns `null`. * * Calling `unreadByte()` after `readLine()` will always unread the last byte * read (possibly a character belonging to the line end) even if that byte is * not part of the line returned by `readLine()`. */ - async readLine(): Promise { - let line: Uint8Array | Deno.EOF; + async readLine(): Promise { + let line: Uint8Array | null; try { line = await this.readSlice(LF); @@ -277,8 +277,8 @@ export class BufReader implements Reader { return { line: partial, more: !this.eof }; } - if (line === Deno.EOF) { - return Deno.EOF; + if (line === null) { + return null; } if (line.byteLength === 0) { @@ -306,12 +306,12 @@ export class BufReader implements Reader { * If `readSlice()` encounters the end of the underlying stream and there are * any bytes left in the buffer, the rest of the buffer is returned. In other * words, EOF is always treated as a delimiter. Once the buffer is empty, - * it returns `EOF`. + * it returns `null`. * * Because the data returned from `readSlice()` will be overwritten by the * next I/O operation, most clients should use `readString()` instead. */ - async readSlice(delim: number): Promise { + async readSlice(delim: number): Promise { let s = 0; // search start index let slice: Uint8Array | undefined; @@ -328,7 +328,7 @@ export class BufReader implements Reader { // EOF? if (this.eof) { if (this.r === this.w) { - return Deno.EOF; + return null; } slice = this.buf.subarray(this.r, this.w); this.r = this.w; @@ -367,13 +367,13 @@ export class BufReader implements Reader { * * When the end of the underlying stream is reached, but there are unread * bytes left in the buffer, those bytes are returned. If there are no bytes - * left in the buffer, it returns `EOF`. + * left in the buffer, it returns `null`. * * If an error is encountered before `n` bytes are available, `peek()` throws * an error with the `partial` property set to a slice of the buffer that * contains the bytes that were available before the error occurred. */ - async peek(n: number): Promise { + async peek(n: number): Promise { if (n < 0) { throw Error("negative count"); } @@ -390,7 +390,7 @@ export class BufReader implements Reader { } if (avail === 0 && this.eof) { - return Deno.EOF; + return null; } else if (avail < n && this.eof) { return this.buf.subarray(this.r, this.r + avail); } else if (avail < n) { @@ -656,7 +656,7 @@ export async function* readDelim( let matchIndex = 0; while (true) { const result = await reader.read(inspectArr); - if (result === Deno.EOF) { + if (result === null) { // Yield last chunk. yield inputBuffer.bytes(); return; diff --git a/std/io/bufio_test.ts b/std/io/bufio_test.ts index 7e737e60f4..a4f03338d1 100644 --- a/std/io/bufio_test.ts +++ b/std/io/bufio_test.ts @@ -5,12 +5,7 @@ const { Buffer } = Deno; type Reader = Deno.Reader; -import { - assert, - assertEquals, - fail, - assertNotEOF, -} from "../testing/asserts.ts"; +import { assert, assertEquals, fail } from "../testing/asserts.ts"; import { BufReader, BufWriter, @@ -30,7 +25,7 @@ async function readBytes(buf: BufReader): Promise { let nb = 0; while (true) { const c = await buf.readByte(); - if (c === Deno.EOF) { + if (c === null) { break; // EOF } b[nb] = c; @@ -69,7 +64,7 @@ async function reads(buf: BufReader, m: number): Promise { let nb = 0; while (true) { const result = await buf.read(b.subarray(nb, nb + m)); - if (result === Deno.EOF) { + if (result === null) { break; } nb += result; @@ -152,7 +147,8 @@ Deno.test("bufioBufferFull", async function (): Promise { assertEquals(decoder.decode(err.partial), "And now, hello, "); } - const line = assertNotEOF(await buf.readSlice(charCode("!"))); + const line = await buf.readSlice(charCode("!")); + assert(line !== null); const actual = decoder.decode(line); assertEquals(actual, "world!"); }); @@ -161,14 +157,16 @@ Deno.test("bufioReadString", async function (): Promise { const string = "And now, hello world!"; const buf = new BufReader(stringsReader(string), MIN_READ_BUFFER_SIZE); - const line = assertNotEOF(await buf.readString(",")); + const line = await buf.readString(","); + assert(line !== null); assertEquals(line, "And now,"); assertEquals(line.length, 8); - const line2 = assertNotEOF(await buf.readString(",")); + const line2 = await buf.readString(","); + assert(line2 !== null); assertEquals(line2, " hello world!"); - assertEquals(await buf.readString(","), Deno.EOF); + assertEquals(await buf.readString(","), null); try { await buf.readString("deno"); @@ -192,7 +190,7 @@ const testOutput = encoder.encode("0123456789abcdefghijklmnopqrstuvwxy"); class TestReader implements Reader { constructor(private data: Uint8Array, private stride: number) {} - read(buf: Uint8Array): Promise { + read(buf: Uint8Array): Promise { let nread = this.stride; if (nread > this.data.byteLength) { nread = this.data.byteLength; @@ -201,7 +199,7 @@ class TestReader implements Reader { nread = buf.byteLength; } if (nread === 0) { - return Promise.resolve(Deno.EOF); + return Promise.resolve(null); } copyBytes(buf as Uint8Array, this.data); this.data = this.data.subarray(nread); @@ -216,7 +214,7 @@ async function testReadLine(input: Uint8Array): Promise { const l = new BufReader(reader, input.byteLength + 1); while (true) { const r = await l.readLine(); - if (r === Deno.EOF) { + if (r === null) { break; } const { line, more } = r; @@ -253,10 +251,12 @@ Deno.test("bufioPeek", async function (): Promise { MIN_READ_BUFFER_SIZE ); - let actual = assertNotEOF(await buf.peek(1)); + let actual = await buf.peek(1); + assert(actual !== null); assertEquals(decoder.decode(actual), "a"); - actual = assertNotEOF(await buf.peek(4)); + actual = await buf.peek(4); + assert(actual !== null); assertEquals(decoder.decode(actual), "abcd"); try { @@ -271,33 +271,39 @@ Deno.test("bufioPeek", async function (): Promise { await buf.read(p.subarray(0, 3)); assertEquals(decoder.decode(p.subarray(0, 3)), "abc"); - actual = assertNotEOF(await buf.peek(1)); + actual = await buf.peek(1); + assert(actual !== null); assertEquals(decoder.decode(actual), "d"); - actual = assertNotEOF(await buf.peek(1)); + actual = await buf.peek(1); + assert(actual !== null); assertEquals(decoder.decode(actual), "d"); - actual = assertNotEOF(await buf.peek(1)); + actual = await buf.peek(1); + assert(actual !== null); assertEquals(decoder.decode(actual), "d"); - actual = assertNotEOF(await buf.peek(2)); + actual = await buf.peek(2); + assert(actual !== null); assertEquals(decoder.decode(actual), "de"); const res = await buf.read(p.subarray(0, 3)); assertEquals(decoder.decode(p.subarray(0, 3)), "def"); - assert(res !== Deno.EOF); + assert(res !== null); - actual = assertNotEOF(await buf.peek(4)); + actual = await buf.peek(4); + assert(actual !== null); assertEquals(decoder.decode(actual), "ghij"); await buf.read(p); assertEquals(decoder.decode(p), "ghijklmnop"); - actual = assertNotEOF(await buf.peek(0)); + actual = await buf.peek(0); + assert(actual !== null); assertEquals(decoder.decode(actual), ""); const r = await buf.peek(1); - assert(r === Deno.EOF); + assert(r === null); /* TODO Test for issue 3022, not exposing a reader's error on a successful Peek. buf = NewReaderSize(dataAndEOFReader("abcd"), 32) @@ -396,7 +402,8 @@ Deno.test("bufReaderReadFull", async function (): Promise { const bufr = new BufReader(data, 3); { const buf = new Uint8Array(6); - const r = assertNotEOF(await bufr.readFull(buf)); + const r = await bufr.readFull(buf); + assert(r !== null); assertEquals(r, buf); assertEquals(dec.decode(buf), "Hello "); } diff --git a/std/io/iotest.ts b/std/io/iotest.ts index e2cf315aa8..a309fb5e12 100644 --- a/std/io/iotest.ts +++ b/std/io/iotest.ts @@ -10,7 +10,7 @@ type Reader = Deno.Reader; export class OneByteReader implements Reader { constructor(readonly r: Reader) {} - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { if (p.byteLength === 0) { return Promise.resolve(0); } @@ -27,7 +27,7 @@ export class OneByteReader implements Reader { export class HalfReader implements Reader { constructor(readonly r: Reader) {} - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { if (!(p instanceof Uint8Array)) { throw Error("expected Uint8Array"); } @@ -43,7 +43,7 @@ export class TimeoutReader implements Reader { count = 0; constructor(readonly r: Reader) {} - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { this.count++; if (this.count === 2) { throw new Deno.errors.TimedOut(); diff --git a/std/io/ioutil.ts b/std/io/ioutil.ts index 8c30ae5666..7b67617081 100644 --- a/std/io/ioutil.ts +++ b/std/io/ioutil.ts @@ -21,13 +21,13 @@ export async function copyN( buf = new Uint8Array(size - bytesRead); } const result = await r.read(buf); - const nread = result === Deno.EOF ? 0 : result; + const nread = result ?? 0; bytesRead += nread; if (nread > 0) { const n = await dest.write(buf.slice(0, nread)); assert(n === nread, "could not write"); } - if (result === Deno.EOF) { + if (result === null) { break; } } @@ -35,31 +35,31 @@ export async function copyN( } /** Read big endian 16bit short from BufReader */ -export async function readShort(buf: BufReader): Promise { +export async function readShort(buf: BufReader): Promise { const high = await buf.readByte(); - if (high === Deno.EOF) return Deno.EOF; + if (high === null) return null; const low = await buf.readByte(); - if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (low === null) throw new Deno.errors.UnexpectedEof(); return (high << 8) | low; } /** Read big endian 32bit integer from BufReader */ -export async function readInt(buf: BufReader): Promise { +export async function readInt(buf: BufReader): Promise { const high = await readShort(buf); - if (high === Deno.EOF) return Deno.EOF; + if (high === null) return null; const low = await readShort(buf); - if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (low === null) throw new Deno.errors.UnexpectedEof(); return (high << 16) | low; } const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER); /** Read big endian 64bit long from BufReader */ -export async function readLong(buf: BufReader): Promise { +export async function readLong(buf: BufReader): Promise { const high = await readInt(buf); - if (high === Deno.EOF) return Deno.EOF; + if (high === null) return null; const low = await readInt(buf); - if (low === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (low === null) throw new Deno.errors.UnexpectedEof(); const big = (BigInt(high) << 32n) | BigInt(low); // We probably should provide a similar API that returns BigInt values. if (big > MAX_SAFE_INTEGER) { diff --git a/std/io/ioutil_test.ts b/std/io/ioutil_test.ts index 5e4d3e3d21..4d7d0f4ca0 100644 --- a/std/io/ioutil_test.ts +++ b/std/io/ioutil_test.ts @@ -17,7 +17,7 @@ class BinaryReader implements Reader { constructor(private bytes: Uint8Array = new Uint8Array(0)) {} - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { p.set(this.bytes.subarray(this.index, p.byteLength)); this.index += p.byteLength; return Promise.resolve(p.byteLength); diff --git a/std/io/readers.ts b/std/io/readers.ts index 8a567d7d12..10069986ce 100644 --- a/std/io/readers.ts +++ b/std/io/readers.ts @@ -9,12 +9,12 @@ export class StringReader implements Reader { constructor(private readonly s: string) {} - read(p: Uint8Array): Promise { + read(p: Uint8Array): Promise { const n = Math.min(p.byteLength, this.buf.byteLength - this.offs); p.set(this.buf.slice(this.offs, this.offs + n)); this.offs += n; if (n === 0) { - return Promise.resolve(Deno.EOF); + return Promise.resolve(null); } return Promise.resolve(n); } @@ -29,11 +29,11 @@ export class MultiReader implements Reader { this.readers = readers; } - async read(p: Uint8Array): Promise { + async read(p: Uint8Array): Promise { const r = this.readers[this.currentIndex]; - if (!r) return Deno.EOF; + if (!r) return null; const result = await r.read(p); - if (result === Deno.EOF) { + if (result === null) { this.currentIndex++; return 0; } diff --git a/std/io/readers_test.ts b/std/io/readers_test.ts index c942855814..b0810f9e06 100644 --- a/std/io/readers_test.ts +++ b/std/io/readers_test.ts @@ -10,7 +10,7 @@ test("ioStringReader", async function (): Promise { const res0 = await r.read(new Uint8Array(6)); assertEquals(res0, 6); const res1 = await r.read(new Uint8Array(6)); - assertEquals(res1, Deno.EOF); + assertEquals(res1, null); }); test("ioStringReader", async function (): Promise { @@ -23,7 +23,7 @@ test("ioStringReader", async function (): Promise { assertEquals(res2, 3); assertEquals(decode(buf), "def"); const res3 = await r.read(buf); - assertEquals(res3, Deno.EOF); + assertEquals(res3, null); assertEquals(decode(buf), "def"); }); diff --git a/std/mime/multipart.ts b/std/mime/multipart.ts index 027854dae6..48e32c65d8 100644 --- a/std/mime/multipart.ts +++ b/std/mime/multipart.ts @@ -105,7 +105,7 @@ export function scanUntilBoundary( newLineDashBoundary: Uint8Array, total: number, eof: boolean -): number | Deno.EOF { +): number | null { if (total === 0) { // At beginning of body, allow dashBoundary. if (hasPrefix(buf, dashBoundary)) { @@ -115,7 +115,7 @@ export function scanUntilBoundary( case 0: return 0; case 1: - return Deno.EOF; + return null; } } if (hasPrefix(dashBoundary, buf)) { @@ -132,7 +132,7 @@ export function scanUntilBoundary( case 0: return i; case 1: - return i > 0 ? i : Deno.EOF; + return i > 0 ? i : null; } } if (hasPrefix(newLineDashBoundary, buf)) { @@ -151,12 +151,12 @@ export function scanUntilBoundary( } class PartReader implements Reader, Closer { - n: number | Deno.EOF = 0; + n: number | null = 0; total = 0; constructor(private mr: MultipartReader, public readonly headers: Headers) {} - async read(p: Uint8Array): Promise { + async read(p: Uint8Array): Promise { const br = this.mr.bufReader; // Read into buffer until we identify some data to return, @@ -165,7 +165,7 @@ class PartReader implements Reader, Closer { while (this.n === 0) { peekLength = max(peekLength, br.buffered()); const peekBuf = await br.peek(peekLength); - if (peekBuf === Deno.EOF) { + if (peekBuf === null) { throw new Deno.errors.UnexpectedEof(); } const eof = peekBuf.length < peekLength; @@ -183,8 +183,8 @@ class PartReader implements Reader, Closer { } } - if (this.n === Deno.EOF) { - return Deno.EOF; + if (this.n === null) { + return null; } const nread = min(p.length, this.n); @@ -288,7 +288,7 @@ export class MultipartReader { const buf = new Buffer(new Uint8Array(maxValueBytes)); for (;;) { const p = await this.nextPart(); - if (p === Deno.EOF) { + if (p === null) { break; } if (p.formName === "") { @@ -354,7 +354,7 @@ export class MultipartReader { private currentPart: PartReader | undefined; private partsRead = 0; - private async nextPart(): Promise { + private async nextPart(): Promise { if (this.currentPart) { this.currentPart.close(); } @@ -364,14 +364,14 @@ export class MultipartReader { let expectNewPart = false; for (;;) { const line = await this.bufReader.readSlice("\n".charCodeAt(0)); - if (line === Deno.EOF) { + if (line === null) { throw new Deno.errors.UnexpectedEof(); } if (this.isBoundaryDelimiterLine(line)) { this.partsRead++; const r = new TextProtoReader(this.bufReader); const headers = await r.readMIMEHeader(); - if (headers === Deno.EOF) { + if (headers === null) { throw new Deno.errors.UnexpectedEof(); } const np = new PartReader(this, headers); @@ -379,7 +379,7 @@ export class MultipartReader { return np; } if (this.isFinalBoundary(line)) { - return Deno.EOF; + return null; } if (expectNewPart) { throw new Error(`expecting a new Part; got line ${line}`); diff --git a/std/mime/multipart_test.ts b/std/mime/multipart_test.ts index 57c64bba0e..f8973cc8c9 100644 --- a/std/mime/multipart_test.ts +++ b/std/mime/multipart_test.ts @@ -31,7 +31,7 @@ test("multipartScanUntilBoundary1", function (): void { 0, true ); - assertEquals(n, Deno.EOF); + assertEquals(n, null); }); test("multipartScanUntilBoundary2", function (): void { diff --git a/std/testing/asserts.ts b/std/testing/asserts.ts index 21d699e5ce..6dd3af226e 100644 --- a/std/testing/asserts.ts +++ b/std/testing/asserts.ts @@ -379,8 +379,3 @@ export function unimplemented(msg?: string): never { export function unreachable(): never { throw new AssertionError("unreachable"); } - -export function assertNotEOF(val: T | Deno.EOF): T { - assertNotEquals(val, Deno.EOF); - return val as T; -} diff --git a/std/textproto/mod.ts b/std/textproto/mod.ts index 218ec9d442..ca14c05469 100644 --- a/std/textproto/mod.ts +++ b/std/textproto/mod.ts @@ -22,9 +22,9 @@ export class TextProtoReader { /** readLine() reads a single line from the TextProtoReader, * eliding the final \n or \r\n from the returned string. */ - async readLine(): Promise { + async readLine(): Promise { const s = await this.readLineSlice(); - if (s === Deno.EOF) return Deno.EOF; + if (s === null) return null; return str(s); } @@ -48,20 +48,20 @@ export class TextProtoReader { * "Long-Key": {"Even Longer Value"}, * } */ - async readMIMEHeader(): Promise { + async readMIMEHeader(): Promise { const m = new Headers(); let line: Uint8Array | undefined; // The first line cannot start with a leading space. let buf = await this.r.peek(1); - if (buf === Deno.EOF) { - return Deno.EOF; + if (buf === null) { + return null; } else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) { line = (await this.readLineSlice()) as Uint8Array; } buf = await this.r.peek(1); - if (buf === Deno.EOF) { + if (buf === null) { throw new Deno.errors.UnexpectedEof(); } else if (buf[0] == charCode(" ") || buf[0] == charCode("\t")) { throw new Deno.errors.InvalidData( @@ -71,7 +71,7 @@ export class TextProtoReader { while (true) { const kv = await this.readLineSlice(); // readContinuedLineSlice - if (kv === Deno.EOF) throw new Deno.errors.UnexpectedEof(); + if (kv === null) throw new Deno.errors.UnexpectedEof(); if (kv.byteLength === 0) return m; // Key ends at first colon @@ -112,12 +112,12 @@ export class TextProtoReader { } } - async readLineSlice(): Promise { + async readLineSlice(): Promise { // this.closeDot(); let line: Uint8Array | undefined; while (true) { const r = await this.r.readLine(); - if (r === Deno.EOF) return Deno.EOF; + if (r === null) return null; const { line: l, more } = r; // Avoid the copy if the first call produced a full line. diff --git a/std/textproto/test.ts b/std/textproto/test.ts index b9947ab33a..3b71bc08ca 100644 --- a/std/textproto/test.ts +++ b/std/textproto/test.ts @@ -6,12 +6,7 @@ import { BufReader } from "../io/bufio.ts"; import { TextProtoReader } from "./mod.ts"; import { stringsReader } from "../io/util.ts"; -import { - assert, - assertEquals, - assertThrows, - assertNotEOF, -} from "../testing/asserts.ts"; +import { assert, assertEquals, assertThrows } from "../testing/asserts.ts"; const { test } = Deno; function reader(s: string): TextProtoReader { @@ -31,7 +26,7 @@ test({ test("[textproto] ReadEmpty", async () => { const r = reader(""); const m = await r.readMIMEHeader(); - assertEquals(m, Deno.EOF); + assertEquals(m, null); }); test("[textproto] Reader", async () => { @@ -43,7 +38,7 @@ test("[textproto] Reader", async () => { assertEquals(s, "line2"); s = await r.readLine(); - assert(s === Deno.EOF); + assert(s === null); }); test({ @@ -53,7 +48,8 @@ test({ "my-key: Value 1 \r\nLong-key: Even Longer Value\r\nmy-Key: " + "Value 2\r\n\n"; const r = reader(input); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("My-Key"), "Value 1, Value 2"); assertEquals(m.get("Long-key"), "Even Longer Value"); }, @@ -64,7 +60,8 @@ test({ async fn(): Promise { const input = "Foo: bar\n\n"; const r = reader(input); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("Foo"), "bar"); }, }); @@ -74,7 +71,8 @@ test({ async fn(): Promise { const input = ": bar\ntest-1: 1\n\n"; const r = reader(input); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("Test-1"), "1"); }, }); @@ -89,7 +87,8 @@ test({ } const sdata = data.join(""); const r = reader(`Cookie: ${sdata}\r\n\r\n`); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("Cookie"), sdata); }, }); @@ -106,7 +105,8 @@ test({ "Audio Mode : None\r\n" + "Privilege : 127\r\n\r\n"; const r = reader(input); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("Foo"), "bar"); assertEquals(m.get("Content-Language"), "en"); // Make sure we drop headers with trailing whitespace @@ -174,7 +174,8 @@ test({ "------WebKitFormBoundaryimeZ2Le9LjohiUiG--\r\n\n", ]; const r = reader(input.join("")); - const m = assertNotEOF(await r.readMIMEHeader()); + const m = await r.readMIMEHeader(); + assert(m !== null); assertEquals(m.get("Accept"), "*/*"); assertEquals(m.get("Content-Disposition"), 'form-data; name="test"'); }, diff --git a/std/ws/README.md b/std/ws/README.md index 2379d9f96e..5dcb9ce904 100644 --- a/std/ws/README.md +++ b/std/ws/README.md @@ -102,7 +102,7 @@ const tpr = new TextProtoReader(new BufReader(Deno.stdin)); while (true) { await Deno.stdout.write(encode("> ")); const line = await tpr.readLine(); - if (line === Deno.EOF) { + if (line === null) { break; } if (line === "close") { diff --git a/std/ws/example_client.ts b/std/ws/example_client.ts index 3b1c6a33ac..d680c6fefd 100644 --- a/std/ws/example_client.ts +++ b/std/ws/example_client.ts @@ -31,7 +31,7 @@ const tpr = new TextProtoReader(new BufReader(Deno.stdin)); while (true) { await Deno.stdout.write(encode("> ")); const line = await tpr.readLine(); - if (line === Deno.EOF) { + if (line === null) { break; } if (line === "close") { diff --git a/std/ws/mod.ts b/std/ws/mod.ts index 9632fbbfb0..7e444f274b 100644 --- a/std/ws/mod.ts +++ b/std/ws/mod.ts @@ -8,7 +8,7 @@ import { Sha1 } from "../util/sha1.ts"; import { writeResponse } from "../http/io.ts"; import { TextProtoReader } from "../textproto/mod.ts"; import { Deferred, deferred } from "../util/async.ts"; -import { assertNotEOF } from "../testing/asserts.ts"; +import { assert } from "../testing/asserts.ts"; import { concat } from "../bytes/mod.ts"; import Conn = Deno.Conn; import Writer = Deno.Writer; @@ -149,7 +149,8 @@ export async function writeFrame( * @throws `Error` Frame is invalid */ export async function readFrame(buf: BufReader): Promise { - let b = assertNotEOF(await buf.readByte()); + let b = await buf.readByte(); + assert(b !== null); let isLastFrame = false; switch (b >>> 4) { case 0b1000: @@ -163,25 +164,28 @@ export async function readFrame(buf: BufReader): Promise { } const opcode = b & 0x0f; // has_mask & payload - b = assertNotEOF(await buf.readByte()); + b = await buf.readByte(); + assert(b !== null); const hasMask = b >>> 7; let payloadLength = b & 0b01111111; if (payloadLength === 126) { - const l = assertNotEOF(await readShort(buf)); + const l = await readShort(buf); + assert(l !== null); payloadLength = l; } else if (payloadLength === 127) { - const l = assertNotEOF(await readLong(buf)); + const l = await readLong(buf); + assert(l !== null); payloadLength = Number(l); } // mask let mask: Uint8Array | undefined; if (hasMask) { mask = new Uint8Array(4); - assertNotEOF(await buf.readFull(mask)); + assert((await buf.readFull(mask)) !== null); } // payload const payload = new Uint8Array(payloadLength); - assertNotEOF(await buf.readFull(payload)); + assert((await buf.readFull(payload)) !== null); return { isLastFrame, opcode, @@ -479,7 +483,7 @@ export async function handshake( const tpReader = new TextProtoReader(bufReader); const statusLine = await tpReader.readLine(); - if (statusLine === Deno.EOF) { + if (statusLine === null) { throw new Deno.errors.UnexpectedEof(); } const m = statusLine.match(/^(?\S+) (?\S+) /); @@ -497,7 +501,7 @@ export async function handshake( } const responseHeaders = await tpReader.readMIMEHeader(); - if (responseHeaders === Deno.EOF) { + if (responseHeaders === null) { throw new Deno.errors.UnexpectedEof(); } diff --git a/std/ws/test.ts b/std/ws/test.ts index 20ba2ba61e..0d4541f62c 100644 --- a/std/ws/test.ts +++ b/std/ws/test.ts @@ -278,7 +278,7 @@ function dummyConn(r: Reader, w: Writer): Conn { rid: -1, closeRead: (): void => {}, closeWrite: (): void => {}, - read: (x): Promise => r.read(x), + read: (x): Promise => r.read(x), write: (x): Promise => w.write(x), close: (): void => {}, localAddr: { transport: "tcp", hostname: "0.0.0.0", port: 0 }, @@ -335,8 +335,8 @@ test("[ws] createSecKeyHasCorrectLength", () => { test("[ws] WebSocket should throw `Deno.errors.ConnectionReset` when peer closed connection without close frame", async () => { const buf = new Buffer(); const eofReader: Deno.Reader = { - read(_: Uint8Array): Promise { - return Promise.resolve(Deno.EOF); + read(_: Uint8Array): Promise { + return Promise.resolve(null); }, }; const conn = dummyConn(eofReader, buf); @@ -353,8 +353,8 @@ test("[ws] WebSocket should throw `Deno.errors.ConnectionReset` when peer closed test("[ws] WebSocket shouldn't throw `Deno.errors.UnexpectedEof` on recive()", async () => { const buf = new Buffer(); const eofReader: Deno.Reader = { - read(_: Uint8Array): Promise { - return Promise.resolve(Deno.EOF); + read(_: Uint8Array): Promise { + return Promise.resolve(null); }, }; const conn = dummyConn(eofReader, buf); diff --git a/tools/deno_tcp.ts b/tools/deno_tcp.ts index 068c48a04f..06907db907 100644 --- a/tools/deno_tcp.ts +++ b/tools/deno_tcp.ts @@ -13,7 +13,7 @@ async function handle(conn: Deno.Conn): Promise { try { while (true) { const r = await conn.read(buffer); - if (r === Deno.EOF) { + if (r === null) { break; } await conn.write(response);