// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // Interfaces 100% copied from Go. // Documentation liberally lifted from them too. // Thank you! We love Go! <3 import { core, primordials } from "ext:core/mod.js"; const { op_stdin_set_raw, op_is_terminal, } = core.ensureFastOps(true); const { Uint8Array, ArrayPrototypePush, TypedArrayPrototypeSubarray, TypedArrayPrototypeSet, TypedArrayPrototypeGetByteLength, } = primordials; import { readableStreamForRid, writableStreamForRid, } from "ext:deno_web/06_streams.js"; const DEFAULT_BUFFER_SIZE = 32 * 1024; // Seek whence values. // https://golang.org/pkg/io/#pkg-constants const SeekMode = { 0: "Start", 1: "Current", 2: "End", Start: 0, Current: 1, End: 2, }; async function copy( src, dst, options, ) { let n = 0; const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; const b = new Uint8Array(bufSize); let gotEOF = false; while (gotEOF === false) { const result = await src.read(b); if (result === null) { gotEOF = true; } else { let nwritten = 0; while (nwritten < result) { nwritten += await dst.write( TypedArrayPrototypeSubarray(b, nwritten, result), ); } n += nwritten; } } return n; } async function* iter( r, options, ) { const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; const b = new Uint8Array(bufSize); while (true) { const result = await r.read(b); if (result === null) { break; } yield TypedArrayPrototypeSubarray(b, 0, result); } } function* iterSync( r, options, ) { const bufSize = options?.bufSize ?? DEFAULT_BUFFER_SIZE; const b = new Uint8Array(bufSize); while (true) { const result = r.readSync(b); if (result === null) { break; } yield TypedArrayPrototypeSubarray(b, 0, result); } } function readSync(rid, buffer) { if (buffer.length === 0) return 0; const nread = core.readSync(rid, buffer); return nread === 0 ? null : nread; } async function read(rid, buffer) { if (buffer.length === 0) return 0; const nread = await core.read(rid, buffer); return nread === 0 ? null : nread; } function writeSync(rid, data) { return core.writeSync(rid, data); } function write(rid, data) { return core.write(rid, data); } const READ_PER_ITER = 64 * 1024; // 64kb 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") { ArrayPrototypePush(buffers, TypedArrayPrototypeSubarray(buf, 0, read)); } else { break; } } return concatBuffers(buffers); } function readAllSync(r) { const buffers = []; while (true) { const buf = new Uint8Array(READ_PER_ITER); const read = r.readSync(buf); if (typeof read == "number") { ArrayPrototypePush(buffers, TypedArrayPrototypeSubarray(buf, 0, read)); } else { break; } } return concatBuffers(buffers); } function concatBuffers(buffers) { let totalLen = 0; for (let i = 0; i < buffers.length; ++i) { totalLen += TypedArrayPrototypeGetByteLength(buffers[i]); } const contents = new Uint8Array(totalLen); let n = 0; for (let i = 0; i < buffers.length; ++i) { const buf = buffers[i]; TypedArrayPrototypeSet(contents, buf, n); n += TypedArrayPrototypeGetByteLength(buf); } return contents; } class Stdin { #readable; constructor() { } get rid() { return 0; } read(p) { return read(this.rid, p); } readSync(p) { return readSync(this.rid, p); } close() { core.tryClose(this.rid); } get readable() { if (this.#readable === undefined) { this.#readable = readableStreamForRid(this.rid); } return this.#readable; } setRaw(mode, options = {}) { const cbreak = !!(options.cbreak ?? false); op_stdin_set_raw(mode, cbreak); } isTerminal() { return op_is_terminal(this.rid); } } class Stdout { #writable; constructor() { } get rid() { return 1; } write(p) { return write(this.rid, p); } writeSync(p) { return writeSync(this.rid, p); } close() { core.close(this.rid); } get writable() { if (this.#writable === undefined) { this.#writable = writableStreamForRid(this.rid); } return this.#writable; } isTerminal() { return op_is_terminal(this.rid); } } class Stderr { #writable; constructor() { } get rid() { return 2; } write(p) { return write(this.rid, p); } writeSync(p) { return writeSync(this.rid, p); } close() { core.close(this.rid); } get writable() { if (this.#writable === undefined) { this.#writable = writableStreamForRid(this.rid); } return this.#writable; } isTerminal() { return op_is_terminal(this.rid); } } const stdin = new Stdin(); const stdout = new Stdout(); const stderr = new Stderr(); export { copy, iter, iterSync, read, readAll, readAllSync, readSync, SeekMode, stderr, stdin, stdout, write, writeSync, };