From da60e2afcbd4b28e3b8ba69b5e38d4ff173ddbe1 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Tue, 6 Apr 2021 00:05:36 +0200 Subject: [PATCH] chore: deprecate Deno.Buffer and read/write utils (#9793) This commit marks the `Deno.Buffer` / `Deno.readAll` / `Deno.readAllSync` / `Deno.writeAll` / `Deno.writeAllSync` utils as deprecated, and schedules them for removal in Deno 2.0. These utilities are implemented in pure JS, so should not be part of the Deno namespace. These utilities are now available in std/io/buffer and std/io/util: https://github.com/denoland/deno_std/pull/808. This additionallty removes all internal dependance on Deno.Buffer. --- cli/dts/lib.deno.ns.d.ts | 29 +++++++++++++---- cli/tests/unit/fetch_test.ts | 6 ++-- cli/tests/unit/io_test.ts | 13 ++++---- runtime/js/12_io.js | 62 ++++++++++++++++++++++++++++++++++++ runtime/js/40_process.js | 2 +- runtime/js/40_read_file.js | 2 +- runtime/js/40_write_file.js | 13 ++++++-- 7 files changed, 106 insertions(+), 21 deletions(-) diff --git a/cli/dts/lib.deno.ns.d.ts b/cli/dts/lib.deno.ns.d.ts index cbbf44c849..1592ee5b21 100644 --- a/cli/dts/lib.deno.ns.d.ts +++ b/cli/dts/lib.deno.ns.d.ts @@ -405,9 +405,9 @@ declare namespace Deno { * * ```ts * const source = await Deno.open("my_file.txt"); - * const buffer = new Deno.Buffer() * const bytesCopied1 = await Deno.copy(source, Deno.stdout); - * const bytesCopied2 = await Deno.copy(source, buffer); + * const destination = await Deno.create("my_file_2.txt"); + * const bytesCopied2 = await Deno.copy(source, destination); * ``` * * @param src The source to copy from @@ -837,7 +837,10 @@ declare namespace Deno { */ export function isatty(rid: number): boolean; - /** A variable-sized buffer of bytes with `read()` and `write()` methods. + /** + * @deprecated Use Buffer from https://deno.land/std/io/buffer.ts instead. Deno.Buffer will be removed in Deno 2.0. + * + * A variable-sized buffer of bytes with `read()` and `write()` methods. * * Deno.Buffer is almost always used with some I/O like files and sockets. It * allows one to buffer up a download from a socket. Buffer grows and shrinks @@ -917,7 +920,10 @@ declare namespace Deno { readFromSync(r: ReaderSync): number; } - /** Read Reader `r` until EOF (`null`) and resolve to the content as + /** + * @deprecated Use readAll from https://deno.land/std/io/util.ts instead. Deno.readAll will be removed in Deno 2.0. + * + * Read Reader `r` until EOF (`null`) and resolve to the content as * Uint8Array`. * * ```ts @@ -938,7 +944,10 @@ declare namespace Deno { */ export function readAll(r: Reader): Promise; - /** Synchronously reads Reader `r` until EOF (`null`) and returns the content + /** + * @deprecated Use readAllSync from https://deno.land/std/io/util.ts instead. Deno.readAllSync will be removed in Deno 2.0. + * + * Synchronously reads Reader `r` until EOF (`null`) and returns the content * as `Uint8Array`. * * ```ts @@ -959,7 +968,10 @@ declare namespace Deno { */ export function readAllSync(r: ReaderSync): Uint8Array; - /** Write all the content of the array buffer (`arr`) to the writer (`w`). + /** + * @deprecated Use writeAll from https://deno.land/std/io/util.ts instead. Deno.readAll will be removed in Deno 2.0. + * + * Write all the content of the array buffer (`arr`) to the writer (`w`). * * ```ts * // Example writing to stdout @@ -981,7 +993,10 @@ declare namespace Deno { */ export function writeAll(w: Writer, arr: Uint8Array): Promise; - /** Synchronously write all the content of the array buffer (`arr`) to the + /** + * @deprecated Use writeAllSync from https://deno.land/std/io/util.ts instead. Deno.writeAllSync will be removed in Deno 2.0. + * + * Synchronously write all the content of the array buffer (`arr`) to the * writer (`w`). * * ```ts diff --git a/cli/tests/unit/fetch_test.ts b/cli/tests/unit/fetch_test.ts index fa013f0c5b..6ece3c8351 100644 --- a/cli/tests/unit/fetch_test.ts +++ b/cli/tests/unit/fetch_test.ts @@ -2,12 +2,12 @@ import { assert, assertEquals, - assertThrows, assertThrowsAsync, fail, unimplemented, unitTest, } from "./test_util.ts"; +import { Buffer } from "../../../test_util/std/io/buffer.ts"; unitTest({ perms: { net: true } }, async function fetchProtocolError(): Promise< void @@ -613,13 +613,13 @@ unitTest({ perms: { net: true } }, async function fetchUserAgent(): Promise< // at Object.assertEquals (file:///C:/deno/js/testing/util.ts:29:11) // at fetchPostBodyString (file -function bufferServer(addr: string): Deno.Buffer { +function bufferServer(addr: string): Buffer { const [hostname, port] = addr.split(":"); const listener = Deno.listen({ hostname, port: Number(port), }) as Deno.Listener; - const buf = new Deno.Buffer(); + const buf = new Buffer(); listener.accept().then(async (conn: Deno.Conn) => { const p1 = buf.readFrom(conn); const p2 = conn.write( diff --git a/cli/tests/unit/io_test.ts b/cli/tests/unit/io_test.ts index ba9641fdcc..c5c111e859 100644 --- a/cli/tests/unit/io_test.ts +++ b/cli/tests/unit/io_test.ts @@ -1,5 +1,6 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. import { assertEquals, unitTest } from "./test_util.ts"; +import { Buffer } from "../../../test_util/std/io/buffer.ts"; const DEFAULT_BUF_SIZE = 32 * 1024; @@ -12,7 +13,7 @@ function repeat(c: string, bytes: number): Uint8Array { return ui8; } -function spyRead(obj: Deno.Buffer): Spy { +function spyRead(obj: Buffer): Spy { const spy: Spy = { calls: 0, }; @@ -29,8 +30,8 @@ function spyRead(obj: Deno.Buffer): Spy { unitTest(async function copyWithDefaultBufferSize() { const xBytes = repeat("b", DEFAULT_BUF_SIZE); - const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer); - const write = new Deno.Buffer(); + const reader = new Buffer(xBytes.buffer as ArrayBuffer); + const write = new Buffer(); const readSpy = spyRead(reader); @@ -44,8 +45,8 @@ unitTest(async function copyWithDefaultBufferSize() { unitTest(async function copyWithCustomBufferSize() { const bufSize = 1024; const xBytes = repeat("b", DEFAULT_BUF_SIZE); - const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer); - const write = new Deno.Buffer(); + const reader = new Buffer(xBytes.buffer as ArrayBuffer); + const write = new Buffer(); const readSpy = spyRead(reader); @@ -61,7 +62,7 @@ unitTest({ perms: { write: true } }, async function copyBufferToFile() { // bigger than max File possible buffer 16kb const bufSize = 32 * 1024; const xBytes = repeat("b", bufSize); - const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer); + const reader = new Buffer(xBytes.buffer as ArrayBuffer); const write = await Deno.open(filePath, { write: true, create: true }); const n = await Deno.copy(reader, write, { bufSize }); diff --git a/runtime/js/12_io.js b/runtime/js/12_io.js index fe815c7ed0..aa153e9fd6 100644 --- a/runtime/js/12_io.js +++ b/runtime/js/12_io.js @@ -123,6 +123,66 @@ return result; } + const READ_PER_ITER = 32 * 1024; + + async function readAll(r) { + const buffers = []; + + while (true) { + const buf = new Uint8Array(READ_PER_ITER); + const read = await r.read(buf); + if (typeof read == "number") { + buffers.push(new Uint8Array(buf.buffer, 0, read)); + } else { + break; + } + } + + let totalLen = 0; + for (const buf of buffers) { + totalLen += buf.byteLength; + } + + const contents = new Uint8Array(totalLen); + + let n = 0; + for (const buf of buffers) { + contents.set(buf, n); + n += buf.byteLength; + } + + return contents; + } + + function readAllSync(r) { + const buffers = []; + + while (true) { + const buf = new Uint8Array(READ_PER_ITER); + const read = r.readSync(buf); + if (typeof read == "number") { + buffers.push(new Uint8Array(buf.buffer, 0, read)); + } else { + break; + } + } + + let totalLen = 0; + for (const buf of buffers) { + totalLen += buf.byteLength; + } + + const contents = new Uint8Array(totalLen); + + let n = 0; + for (const buf of buffers) { + contents.set(buf, n); + n += buf.byteLength; + } + + return contents; + } + window.__bootstrap.io = { iterSync, iter, @@ -132,5 +192,7 @@ readSync, write, writeSync, + readAll, + readAllSync, }; })(this); diff --git a/runtime/js/40_process.js b/runtime/js/40_process.js index cd8015e94c..a93818b95a 100644 --- a/runtime/js/40_process.js +++ b/runtime/js/40_process.js @@ -4,7 +4,7 @@ ((window) => { const core = window.Deno.core; const { File } = window.__bootstrap.files; - const { readAll } = window.__bootstrap.buffer; + const { readAll } = window.__bootstrap.io; const { assert, pathFromURL } = window.__bootstrap.util; function opKill(pid, signo) { diff --git a/runtime/js/40_read_file.js b/runtime/js/40_read_file.js index 63b05b8773..0ca8f56e90 100644 --- a/runtime/js/40_read_file.js +++ b/runtime/js/40_read_file.js @@ -3,7 +3,7 @@ ((window) => { const { open, openSync } = window.__bootstrap.files; - const { readAll, readAllSync } = window.__bootstrap.buffer; + const { readAll, readAllSync } = window.__bootstrap.io; function readFileSync(path) { const file = openSync(path); diff --git a/runtime/js/40_write_file.js b/runtime/js/40_write_file.js index 5964dec5f6..4662849a58 100644 --- a/runtime/js/40_write_file.js +++ b/runtime/js/40_write_file.js @@ -3,7 +3,6 @@ ((window) => { const { stat, statSync, chmod, chmodSync } = window.__bootstrap.fs; const { open, openSync } = window.__bootstrap.files; - const { writeAll, writeAllSync } = window.__bootstrap.buffer; const { build } = window.__bootstrap.build; function writeFileSync( @@ -32,7 +31,11 @@ chmodSync(path, options.mode); } - writeAllSync(file, data); + let nwritten = 0; + while (nwritten < data.length) { + nwritten += file.writeSync(data.subarray(nwritten)); + } + file.close(); } @@ -62,7 +65,11 @@ await chmod(path, options.mode); } - await writeAll(file, data); + let nwritten = 0; + while (nwritten < data.length) { + nwritten += await file.write(data.subarray(nwritten)); + } + file.close(); }