mirror of
https://github.com/denoland/std.git
synced 2024-11-21 20:50:22 +00:00
docs(io): document std/io
(#5656)
Co-authored-by: Asher Gomez <ashersaupingomez@gmail.com>
This commit is contained in:
parent
8e32dac73f
commit
d93b33aff8
@ -50,6 +50,7 @@ const ENTRY_POINTS = [
|
||||
"../http/mod.ts",
|
||||
"../ini/mod.ts",
|
||||
"../internal/mod.ts",
|
||||
"../io/mod.ts",
|
||||
"../json/mod.ts",
|
||||
"../jsonc/mod.ts",
|
||||
"../media_types/mod.ts",
|
||||
|
306
io/buf_reader.ts
306
io/buf_reader.ts
@ -11,10 +11,49 @@ const CR = "\r".charCodeAt(0);
|
||||
const LF = "\n".charCodeAt(0);
|
||||
|
||||
/**
|
||||
* Thrown when a write operation is attempted on a full buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter, BufferFullError, Writer } from "@std/io";
|
||||
* import { assert, assertEquals } from "@std/assert";
|
||||
*
|
||||
* const writer: Writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* throw new BufferFullError(p);
|
||||
* }
|
||||
* };
|
||||
* const bufWriter = new BufWriter(writer);
|
||||
* try {
|
||||
* await bufWriter.write(new Uint8Array([1, 2, 3]));
|
||||
* } catch (err) {
|
||||
* assert(err instanceof BufferFullError);
|
||||
* assertEquals(err.partial, new Uint8Array([3]));
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class BufferFullError extends Error {
|
||||
/**
|
||||
* The partially read bytes
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufferFullError } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const err = new BufferFullError(new Uint8Array(2));
|
||||
* assertEquals(err.partial, new Uint8Array(2));
|
||||
* ```
|
||||
*/
|
||||
partial: Uint8Array;
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
* @param partial The bytes partially read
|
||||
*/
|
||||
constructor(partial: Uint8Array) {
|
||||
super("Buffer full");
|
||||
this.name = this.constructor.name;
|
||||
@ -23,11 +62,41 @@ export class BufferFullError extends Error {
|
||||
}
|
||||
|
||||
/**
|
||||
* Thrown when a read from a stream fails to read the
|
||||
* requested number of bytes.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { PartialReadError } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const err = new PartialReadError(new Uint8Array(2));
|
||||
* assertEquals(err.name, "PartialReadError");
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class PartialReadError extends Error {
|
||||
/**
|
||||
* The partially read bytes
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { PartialReadError } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const err = new PartialReadError(new Uint8Array(2));
|
||||
* assertEquals(err.partial, new Uint8Array(2));
|
||||
* ```
|
||||
*/
|
||||
partial: Uint8Array;
|
||||
|
||||
/**
|
||||
* Construct a {@linkcode PartialReadError}.
|
||||
*
|
||||
* @param partial The bytes partially read
|
||||
*/
|
||||
constructor(partial: Uint8Array) {
|
||||
super("Encountered UnexpectedEof, data only partially read");
|
||||
this.name = this.constructor.name;
|
||||
@ -36,16 +105,34 @@ export class PartialReadError extends Error {
|
||||
}
|
||||
|
||||
/**
|
||||
* Result type returned by of BufReader.readLine().
|
||||
* Result type returned by of {@linkcode BufReader.readLine}.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export interface ReadLineResult {
|
||||
/** The line read */
|
||||
line: Uint8Array;
|
||||
/** `true if the end of the line has not been reached, `false` otherwise. */
|
||||
more: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements buffering for a {@linkcode Reader} object.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const encoder = new TextEncoder();
|
||||
* const decoder = new TextDecoder();
|
||||
*
|
||||
* const reader = new BufReader(new Deno.Buffer(encoder.encode("hello world")));
|
||||
* const buf = new Uint8Array(11);
|
||||
* await reader.read(buf);
|
||||
* assertEquals(decoder.decode(buf), "hello world");
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class BufReader implements Reader {
|
||||
@ -55,11 +142,33 @@ export class BufReader implements Reader {
|
||||
#w = 0; // buf write position.
|
||||
#eof = false;
|
||||
|
||||
/** return new BufReader unless r is BufReader */
|
||||
/**
|
||||
* Returns a new {@linkcode BufReader} if `r` is not already one.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assert } from "@std/assert/assert";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = BufReader.create(reader);
|
||||
* assert(bufReader instanceof BufReader);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from.
|
||||
* @param size The size of the buffer.
|
||||
* @returns A new {@linkcode BufReader} if `r` is not already one.
|
||||
*/
|
||||
static create(r: Reader, size: number = DEFAULT_BUF_SIZE): BufReader {
|
||||
return r instanceof BufReader ? r : new BufReader(r, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new {@linkcode BufReader} for the given reader and buffer size.
|
||||
*
|
||||
* @param rd The reader to read from.
|
||||
* @param size The size of the buffer.
|
||||
*/
|
||||
constructor(rd: Reader, size: number = DEFAULT_BUF_SIZE) {
|
||||
if (size < MIN_BUF_SIZE) {
|
||||
size = MIN_BUF_SIZE;
|
||||
@ -67,11 +176,42 @@ export class BufReader implements Reader {
|
||||
this.#reset(new Uint8Array(size), rd);
|
||||
}
|
||||
|
||||
/** Returns the size of the underlying buffer in bytes. */
|
||||
/**
|
||||
* Returns the size of the underlying buffer in bytes.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
*
|
||||
* assertEquals(bufReader.size(), 4096);
|
||||
* ```
|
||||
*
|
||||
* @returns The size of the underlying buffer in bytes.
|
||||
*/
|
||||
size(): number {
|
||||
return this.#buf.byteLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that can be read from the current buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* await bufReader.read(new Uint8Array(5));
|
||||
* assertEquals(bufReader.buffered(), 6);
|
||||
* ```
|
||||
*
|
||||
* @returns Number of bytes that can be read from the buffer
|
||||
*/
|
||||
buffered(): number {
|
||||
return this.#w - this.#r;
|
||||
}
|
||||
@ -107,8 +247,23 @@ export class BufReader implements Reader {
|
||||
);
|
||||
};
|
||||
|
||||
/** Discards any buffered data, resets all state, and switches
|
||||
* the buffered reader to read from r.
|
||||
/**
|
||||
* Discards any buffered data, resets all state, and switches
|
||||
* the buffered reader to read from `r`.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* await bufReader.read(new Uint8Array(5));
|
||||
* bufReader.reset(reader);
|
||||
* assertEquals(bufReader.buffered(), 6);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from.
|
||||
*/
|
||||
reset(r: Reader) {
|
||||
this.#reset(this.#buf, r);
|
||||
@ -122,11 +277,27 @@ export class BufReader implements Reader {
|
||||
// this.lastCharSize = -1;
|
||||
};
|
||||
|
||||
/** reads data into p.
|
||||
* It returns the number of bytes read into p.
|
||||
* The bytes are taken from at most one Read on the underlying Reader,
|
||||
* hence n may be less than len(p).
|
||||
* To read exactly len(p) bytes, use io.ReadFull(b, p).
|
||||
/**
|
||||
* Reads data into `p`.
|
||||
*
|
||||
* The bytes are taken from at most one `read()` on the underlying `Reader`,
|
||||
* hence n may be less than `len(p)`.
|
||||
* To read exactly `len(p)` bytes, use `io.ReadFull(b, p)`.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const buf = new Uint8Array(5);
|
||||
* await bufReader.read(buf);
|
||||
* assertEquals(new TextDecoder().decode(buf), "hello");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The number of bytes read into `p`.
|
||||
*/
|
||||
async read(p: Uint8Array): Promise<number | null> {
|
||||
let rr: number | null = p.byteLength;
|
||||
@ -161,7 +332,8 @@ export class BufReader implements Reader {
|
||||
return copied;
|
||||
}
|
||||
|
||||
/** reads exactly `p.length` bytes into `p`.
|
||||
/**
|
||||
* Reads exactly `p.length` bytes into `p`.
|
||||
*
|
||||
* If successful, `p` is returned.
|
||||
*
|
||||
@ -174,6 +346,22 @@ export class BufReader implements Reader {
|
||||
* buffer that has been successfully filled with data.
|
||||
*
|
||||
* Ported from https://golang.org/pkg/io/#ReadFull
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const buf = new Uint8Array(5);
|
||||
* await bufReader.readFull(buf);
|
||||
* assertEquals(new TextDecoder().decode(buf), "hello");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The buffer `p` if the read is successful, `null` if the end of the
|
||||
* underlying stream has been reached, and there are no more bytes available in the buffer.
|
||||
*/
|
||||
async readFull(p: Uint8Array): Promise<Uint8Array | null> {
|
||||
let bytesRead = 0;
|
||||
@ -191,7 +379,22 @@ export class BufReader implements Reader {
|
||||
return p;
|
||||
}
|
||||
|
||||
/** Returns the next byte [0, 255] or `null`. */
|
||||
/**
|
||||
* Returns the next byte ([0, 255]) or `null`.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const byte = await bufReader.readByte();
|
||||
* assertEquals(byte, 104);
|
||||
* ```
|
||||
*
|
||||
* @returns The next byte ([0, 255]) or `null`.
|
||||
*/
|
||||
async readByte(): Promise<number | null> {
|
||||
while (this.#r === this.#w) {
|
||||
if (this.#eof) return null;
|
||||
@ -203,14 +406,31 @@ export class BufReader implements Reader {
|
||||
return c;
|
||||
}
|
||||
|
||||
/** readString() reads until the first occurrence of delim in the input,
|
||||
/**
|
||||
* Reads until the first occurrence of delim in the input,
|
||||
* 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 `null`).
|
||||
* ReadString returns err !== null if and only if the returned data does not end
|
||||
* in delim.
|
||||
* For simple uses, a Scanner may be more convenient.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const str = await bufReader.readString(" ");
|
||||
* assertEquals(str, "hello ");
|
||||
*
|
||||
* const str2 = await bufReader.readString(" ");
|
||||
* assertEquals(str2, "world");
|
||||
* ```
|
||||
*
|
||||
* @param delim The delimiter to read until.
|
||||
* @returns The string containing the data up to and including the delimiter.
|
||||
*/
|
||||
async readString(delim: string): Promise<string | null> {
|
||||
if (delim.length !== 1) {
|
||||
@ -221,8 +441,9 @@ export class BufReader implements Reader {
|
||||
return new TextDecoder().decode(buffer);
|
||||
}
|
||||
|
||||
/** `readLine()` is a low-level line-reading primitive. Most callers should
|
||||
* use `readString('\n')` instead or use a Scanner.
|
||||
/**
|
||||
* A low-level line-reading primitive. Most callers should use
|
||||
* `readString('\n')` instead.
|
||||
*
|
||||
* `readLine()` tries to return a single line, not including the end-of-line
|
||||
* bytes. If the line was too long for the buffer then `more` is set and the
|
||||
@ -231,7 +452,7 @@ export class BufReader implements Reader {
|
||||
* of the line. The returned buffer is only valid until the next call to
|
||||
* `readLine()`.
|
||||
*
|
||||
* The text returned from ReadLine does not include the line end ("\r\n" or
|
||||
* The text returned from this method does not include the line end ("\r\n" or
|
||||
* "\n").
|
||||
*
|
||||
* When the end of the underlying stream is reached, the final bytes in the
|
||||
@ -239,9 +460,20 @@ export class BufReader implements Reader {
|
||||
* without a final line end. When there are no more trailing bytes to read,
|
||||
* `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()`.
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello\nworld"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const line1 = await bufReader.readLine();
|
||||
* assertEquals(new TextDecoder().decode(line1!.line), "hello");
|
||||
* const line2 = await bufReader.readLine();
|
||||
* assertEquals(new TextDecoder().decode(line2!.line), "world");
|
||||
* ```
|
||||
*
|
||||
* @returns The line read.
|
||||
*/
|
||||
async readLine(): Promise<ReadLineResult | null> {
|
||||
let line: Uint8Array | null = null;
|
||||
@ -295,7 +527,8 @@ export class BufReader implements Reader {
|
||||
return { line, more: false };
|
||||
}
|
||||
|
||||
/** `readSlice()` reads until the first occurrence of `delim` in the input,
|
||||
/**
|
||||
* Reads until the first occurrence of `delim` in the input,
|
||||
* returning a slice pointing at the bytes in the buffer. The bytes stop
|
||||
* being valid at the next read.
|
||||
*
|
||||
@ -310,6 +543,20 @@ export class BufReader implements Reader {
|
||||
*
|
||||
* Because the data returned from `readSlice()` will be overwritten by the
|
||||
* next I/O operation, most clients should use `readString()` instead.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const slice = await bufReader.readSlice(0x20);
|
||||
* assertEquals(new TextDecoder().decode(slice!), "hello ");
|
||||
* ```
|
||||
*
|
||||
* @param delim The delimiter to read until.
|
||||
* @returns A slice pointing at the bytes in the buffer.
|
||||
*/
|
||||
async readSlice(delim: number): Promise<Uint8Array | null> {
|
||||
let s = 0; // search start index
|
||||
@ -361,7 +608,8 @@ export class BufReader implements Reader {
|
||||
return slice;
|
||||
}
|
||||
|
||||
/** `peek()` returns the next `n` bytes without advancing the reader. The
|
||||
/**
|
||||
* Returns the next `n` bytes without advancing the reader. The
|
||||
* bytes stop being valid at the next read call.
|
||||
*
|
||||
* When the end of the underlying stream is reached, but there are unread
|
||||
@ -371,6 +619,20 @@ export class BufReader implements Reader {
|
||||
* 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.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader, Buffer } from "@std/io";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const reader = new Buffer(new TextEncoder().encode("hello world"));
|
||||
* const bufReader = new BufReader(reader);
|
||||
* const peeked = await bufReader.peek(5);
|
||||
* assertEquals(new TextDecoder().decode(peeked!), "hello");
|
||||
* ```
|
||||
*
|
||||
* @param n The number of bytes to peek.
|
||||
* @returns The next `n` bytes without advancing the reader.
|
||||
*/
|
||||
async peek(n: number): Promise<Uint8Array | null> {
|
||||
if (n < 0) {
|
||||
|
397
io/buf_writer.ts
397
io/buf_writer.ts
@ -6,57 +6,261 @@ import type { Writer, WriterSync } from "./types.ts";
|
||||
|
||||
const DEFAULT_BUF_SIZE = 4096;
|
||||
|
||||
abstract class AbstractBufBase {
|
||||
/**
|
||||
* AbstractBufBase is a base class which other classes can embed to
|
||||
* implement the {@inkcode Reader} and {@linkcode Writer} interfaces.
|
||||
* It provides basic implementations of those interfaces based on a buffer
|
||||
* array.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { Reader } from "@std/io/types";
|
||||
*
|
||||
* class MyBufReader extends AbstractBufBase {
|
||||
* constructor(buf: Uint8Array) {
|
||||
* super(buf);
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
export abstract class AbstractBufBase {
|
||||
/**
|
||||
* The buffer
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.buf, buf);
|
||||
* ```
|
||||
*/
|
||||
buf: Uint8Array;
|
||||
/**
|
||||
* The used buffer bytes
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.usedBufferBytes, 0);
|
||||
* ```
|
||||
*/
|
||||
usedBufferBytes = 0;
|
||||
/**
|
||||
* The error
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.err, null);
|
||||
* ```
|
||||
*/
|
||||
err: Error | null = null;
|
||||
|
||||
/**
|
||||
* Construct a {@linkcode AbstractBufBase} instance
|
||||
*
|
||||
* @param buf The buffer to use.
|
||||
*/
|
||||
constructor(buf: Uint8Array) {
|
||||
this.buf = buf;
|
||||
}
|
||||
|
||||
/** Size returns the size of the underlying buffer in bytes. */
|
||||
/**
|
||||
* Size returns the size of the underlying buffer in bytes.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.size(), 1024);
|
||||
* ```
|
||||
*
|
||||
* @return the size of the buffer in bytes.
|
||||
*/
|
||||
size(): number {
|
||||
return this.buf.byteLength;
|
||||
}
|
||||
|
||||
/** Returns how many bytes are unused in the buffer. */
|
||||
/**
|
||||
* Returns how many bytes are unused in the buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.available(), 1024);
|
||||
* ```
|
||||
*
|
||||
* @return the number of bytes that are unused in the buffer.
|
||||
*/
|
||||
available(): number {
|
||||
return this.buf.byteLength - this.usedBufferBytes;
|
||||
}
|
||||
|
||||
/** buffered returns the number of bytes that have been written into the
|
||||
/**
|
||||
* buffered returns the number of bytes that have been written into the
|
||||
* current buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { AbstractBufBase } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* class MyBuffer extends AbstractBufBase {}
|
||||
*
|
||||
* const buf = new Uint8Array(1024);
|
||||
* const mb = new MyBuffer(buf);
|
||||
*
|
||||
* assertEquals(mb.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @return the number of bytes that have been written into the current buffer.
|
||||
*/
|
||||
buffered(): number {
|
||||
return this.usedBufferBytes;
|
||||
}
|
||||
}
|
||||
|
||||
/** BufWriter implements buffering for an deno.Writer object.
|
||||
/**
|
||||
* `BufWriter` implements buffering for an {@linkcode Writer} object.
|
||||
* If an error occurs writing to a Writer, no more data will be
|
||||
* accepted and all subsequent writes, and flush(), will return the error.
|
||||
* After all data has been written, the client should call the
|
||||
* flush() method to guarantee all data has been forwarded to
|
||||
* the underlying deno.Writer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* return Promise.resolve(p.length);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriter(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* await bufWriter.write(data);
|
||||
* await bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class BufWriter extends AbstractBufBase implements Writer {
|
||||
#writer: Writer;
|
||||
|
||||
/** return new BufWriter unless writer is BufWriter */
|
||||
/**
|
||||
* return new BufWriter unless writer is BufWriter
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter } from "@std/io/buf-writer";
|
||||
* import { Writer } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: Writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* return Promise.resolve(p.length);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = BufWriter.create(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* await bufWriter.write(data);
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 1024);
|
||||
* ```
|
||||
*
|
||||
* @param writer The writer to wrap.
|
||||
* @param size The size of the buffer.
|
||||
*
|
||||
* @return a new {@linkcode BufWriter} instance.
|
||||
*/
|
||||
static create(writer: Writer, size: number = DEFAULT_BUF_SIZE): BufWriter {
|
||||
return writer instanceof BufWriter ? writer : new BufWriter(writer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@linkcode BufWriter}
|
||||
*
|
||||
* @param writer The writer to wrap.
|
||||
* @param size The size of the buffer.
|
||||
*/
|
||||
constructor(writer: Writer, size: number = DEFAULT_BUF_SIZE) {
|
||||
super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size));
|
||||
this.#writer = writer;
|
||||
}
|
||||
|
||||
/** Discards any unflushed buffered data, clears any error, and
|
||||
/**
|
||||
* Discards any unflushed buffered data, clears any error, and
|
||||
* resets buffer to write its output to w.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter } from "@std/io/buf-writer";
|
||||
* import { Writer } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: Writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* return Promise.resolve(p.length);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriter(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* await bufWriter.write(data);
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 1024);
|
||||
*
|
||||
* bufWriter.reset(writer);
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @param w The writer to write to.
|
||||
*/
|
||||
reset(w: Writer) {
|
||||
this.err = null;
|
||||
@ -64,7 +268,30 @@ export class BufWriter extends AbstractBufBase implements Writer {
|
||||
this.#writer = w;
|
||||
}
|
||||
|
||||
/** Flush writes any buffered data to the underlying io.Writer. */
|
||||
/**
|
||||
* Flush writes any buffered data to the underlying io.Writer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter } from "@std/io/buf-writer";
|
||||
* import { Writer } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: Writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* return Promise.resolve(p.length);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriter(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* await bufWriter.write(data);
|
||||
* await bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*/
|
||||
async flush() {
|
||||
if (this.err !== null) throw this.err;
|
||||
if (this.usedBufferBytes === 0) return;
|
||||
@ -86,10 +313,32 @@ export class BufWriter extends AbstractBufBase implements Writer {
|
||||
this.usedBufferBytes = 0;
|
||||
}
|
||||
|
||||
/** Writes the contents of `data` into the buffer. If the contents won't fully
|
||||
/**
|
||||
* Writes the contents of `data` into the buffer. If the contents won't fully
|
||||
* fit into the buffer, those bytes that are copied into the buffer will be flushed
|
||||
* to the writer and the remaining bytes are then copied into the now empty buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriter } from "@std/io/buf-writer";
|
||||
* import { Writer } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: Writer = {
|
||||
* write(p: Uint8Array): Promise<number> {
|
||||
* return Promise.resolve(p.length);
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriter(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* await bufWriter.write(data);
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 1024);
|
||||
* ```
|
||||
*
|
||||
* @param data The data to write to the buffer.
|
||||
* @return the number of bytes written to the buffer.
|
||||
*/
|
||||
async write(data: Uint8Array): Promise<number> {
|
||||
@ -126,19 +375,66 @@ export class BufWriter extends AbstractBufBase implements Writer {
|
||||
}
|
||||
}
|
||||
|
||||
/** BufWriterSync implements buffering for a deno.WriterSync object.
|
||||
/**
|
||||
* BufWriterSync implements buffering for a deno.WriterSync object.
|
||||
* If an error occurs writing to a WriterSync, no more data will be
|
||||
* accepted and all subsequent writes, and flush(), will return the error.
|
||||
* After all data has been written, the client should call the
|
||||
* flush() method to guarantee all data has been forwarded to
|
||||
* the underlying deno.WriterSync.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriterSync } from "@std/io/buf-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer = {
|
||||
* writeSync(p: Uint8Array): number {
|
||||
* return p.length;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriterSync(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* bufWriter.writeSync(data);
|
||||
* bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class BufWriterSync extends AbstractBufBase implements WriterSync {
|
||||
#writer: WriterSync;
|
||||
|
||||
/** return new BufWriterSync unless writer is BufWriterSync */
|
||||
/**
|
||||
* return new BufWriterSync unless writer is BufWriterSync
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriterSync } from "@std/io/buf-writer";
|
||||
* import { WriterSync } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: WriterSync = {
|
||||
* writeSync(p: Uint8Array): number {
|
||||
* return p.length;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = BufWriterSync.create(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
* bufWriter.writeSync(data);
|
||||
* bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @param writer The writer to wrap.
|
||||
* @param size The size of the buffer.
|
||||
* @returns a new {@linkcode BufWriterSync} instance.
|
||||
*/
|
||||
static create(
|
||||
writer: WriterSync,
|
||||
size: number = DEFAULT_BUF_SIZE,
|
||||
@ -148,13 +444,43 @@ export class BufWriterSync extends AbstractBufBase implements WriterSync {
|
||||
: new BufWriterSync(writer, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new {@linkcode BufWriterSync}
|
||||
*
|
||||
* @param writer The writer to wrap.
|
||||
* @param size The size of the buffer.
|
||||
*/
|
||||
constructor(writer: WriterSync, size: number = DEFAULT_BUF_SIZE) {
|
||||
super(new Uint8Array(size <= 0 ? DEFAULT_BUF_SIZE : size));
|
||||
this.#writer = writer;
|
||||
}
|
||||
|
||||
/** Discards any unflushed buffered data, clears any error, and
|
||||
/**
|
||||
* Discards any unflushed buffered data, clears any error, and
|
||||
* resets buffer to write its output to w.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriterSync } from "@std/io/buf-writer";
|
||||
* import { WriterSync } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: WriterSync = {
|
||||
* writeSync(p: Uint8Array): number {
|
||||
* return p.length;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriterSync(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* bufWriter.writeSync(data);
|
||||
* bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @param w The writer to write to.
|
||||
*/
|
||||
reset(w: WriterSync) {
|
||||
this.err = null;
|
||||
@ -162,7 +488,30 @@ export class BufWriterSync extends AbstractBufBase implements WriterSync {
|
||||
this.#writer = w;
|
||||
}
|
||||
|
||||
/** Flush writes any buffered data to the underlying io.WriterSync. */
|
||||
/**
|
||||
* Flush writes any buffered data to the underlying io.WriterSync.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriterSync } from "@std/io/buf-writer";
|
||||
* import { WriterSync } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: WriterSync = {
|
||||
* writeSync(p: Uint8Array): number {
|
||||
* return p.length;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriterSync(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* bufWriter.writeSync(data);
|
||||
* bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*/
|
||||
flush() {
|
||||
if (this.err !== null) throw this.err;
|
||||
if (this.usedBufferBytes === 0) return;
|
||||
@ -189,6 +538,28 @@ export class BufWriterSync extends AbstractBufBase implements WriterSync {
|
||||
* buffer is the flushed to the writer and the remaining bytes are copied into
|
||||
* the now empty buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufWriterSync } from "@std/io/buf-writer";
|
||||
* import { WriterSync } from "@std/io/types";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const writer: WriterSync = {
|
||||
* writeSync(p: Uint8Array): number {
|
||||
* return p.length;
|
||||
* }
|
||||
* };
|
||||
*
|
||||
* const bufWriter = new BufWriterSync(writer);
|
||||
* const data = new Uint8Array(1024);
|
||||
*
|
||||
* bufWriter.writeSync(data);
|
||||
* bufWriter.flush();
|
||||
*
|
||||
* assertEquals(bufWriter.buffered(), 0);
|
||||
* ```
|
||||
*
|
||||
* @param data The data to write to the buffer.
|
||||
* @return the number of bytes written to the buffer.
|
||||
*/
|
||||
writeSync(data: Uint8Array): number {
|
||||
|
277
io/buffer.ts
277
io/buffer.ts
@ -11,7 +11,8 @@ import type { Reader, ReaderSync, Writer, WriterSync } from "./types.ts";
|
||||
const MIN_READ = 32 * 1024;
|
||||
const MAX_SIZE = 2 ** 32 - 2;
|
||||
|
||||
/** A variable-sized buffer of bytes with `read()` and `write()` methods.
|
||||
/**
|
||||
* A variable-sized buffer of bytes with `read()` and `write()` methods.
|
||||
*
|
||||
* 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 as
|
||||
@ -25,49 +26,145 @@ const MAX_SIZE = 2 ** 32 - 2;
|
||||
* ArrayBuffer.
|
||||
*
|
||||
* Based on {@link https://golang.org/pkg/bytes/#Buffer | Go Buffer}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, "));
|
||||
* await buf.write(new TextEncoder().encode("world!"));
|
||||
*
|
||||
* const data = new Uint8Array(13);
|
||||
* await buf.read(data);
|
||||
*
|
||||
* assertEquals(new TextDecoder().decode(data), "Hello, world!");
|
||||
* ```
|
||||
*/
|
||||
|
||||
export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
#buf: Uint8Array; // contents are the bytes buf[off : len(buf)]
|
||||
#off = 0; // read at buf[off], write at buf[buf.byteLength]
|
||||
|
||||
/**
|
||||
* Constructs a new instance with the specified {@linkcode ArrayBuffer} as its
|
||||
* initial contents.
|
||||
*
|
||||
* @param ab The ArrayBuffer to use as the initial contents of the buffer.
|
||||
*/
|
||||
constructor(ab?: ArrayBufferLike | ArrayLike<number>) {
|
||||
this.#buf = ab === undefined ? new Uint8Array(0) : new Uint8Array(ab);
|
||||
}
|
||||
|
||||
/** Returns a slice holding the unread portion of the buffer.
|
||||
/**
|
||||
* Returns a slice holding the unread portion of the buffer.
|
||||
*
|
||||
* The slice is valid for use only until the next buffer modification (that
|
||||
* is, only until the next call to a method like `read()`, `write()`,
|
||||
* `reset()`, or `truncate()`). If `options.copy` is false the slice aliases the buffer content at
|
||||
* least until the next buffer modification, so immediate changes to the
|
||||
* slice will affect the result of future reads.
|
||||
* @param [options={ copy: true }]
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
*
|
||||
* const slice = buf.bytes();
|
||||
* assertEquals(new TextDecoder().decode(slice), "Hello, world!");
|
||||
* ```
|
||||
*
|
||||
* @param options The options for the slice.
|
||||
* @returns A slice holding the unread portion of the buffer.
|
||||
*/
|
||||
bytes(options = { copy: true }): Uint8Array {
|
||||
if (options.copy === false) return this.#buf.subarray(this.#off);
|
||||
return this.#buf.slice(this.#off);
|
||||
}
|
||||
|
||||
/** Returns whether the unread portion of the buffer is empty. */
|
||||
/**
|
||||
* Returns whether the unread portion of the buffer is empty.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* assertEquals(buf.empty(), true);
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
* assertEquals(buf.empty(), false);
|
||||
* ```
|
||||
*
|
||||
* @returns `true` if the unread portion of the buffer is empty, `false`
|
||||
* otherwise.
|
||||
*/
|
||||
empty(): boolean {
|
||||
return this.#buf.byteLength <= this.#off;
|
||||
}
|
||||
|
||||
/** A read only number of bytes of the unread portion of the buffer. */
|
||||
/**
|
||||
* A read only number of bytes of the unread portion of the buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
*
|
||||
* assertEquals(buf.length, 13);
|
||||
* ```
|
||||
*
|
||||
* @returns The number of bytes of the unread portion of the buffer.
|
||||
*/
|
||||
get length(): number {
|
||||
return this.#buf.byteLength - this.#off;
|
||||
}
|
||||
|
||||
/** The read only capacity of the buffer's underlying byte slice, that is,
|
||||
* the total space allocated for the buffer's data. */
|
||||
/**
|
||||
* The read only capacity of the buffer's underlying byte slice, that is,
|
||||
* the total space allocated for the buffer's data.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* assertEquals(buf.capacity, 0);
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
* assertEquals(buf.capacity, 13);
|
||||
* ```
|
||||
*
|
||||
* @returns The capacity of the buffer.
|
||||
*/
|
||||
get capacity(): number {
|
||||
return this.#buf.buffer.byteLength;
|
||||
}
|
||||
|
||||
/** Discards all but the first `n` unread bytes from the buffer but
|
||||
/**
|
||||
* Discards all but the first `n` unread bytes from the buffer but
|
||||
* continues to use the same allocated storage. It throws if `n` is
|
||||
* negative or greater than the length of the buffer. */
|
||||
* negative or greater than the length of the buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
* buf.truncate(6);
|
||||
* assertEquals(buf.length, 6);
|
||||
* ```
|
||||
*
|
||||
* @param n The number of bytes to keep.
|
||||
*/
|
||||
truncate(n: number) {
|
||||
if (n === 0) {
|
||||
this.reset();
|
||||
@ -79,6 +176,20 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
this.#reslice(this.#off + n);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets the contents
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
* buf.reset();
|
||||
* assertEquals(buf.length, 0);
|
||||
* ```
|
||||
*/
|
||||
reset() {
|
||||
this.#reslice(0);
|
||||
this.#off = 0;
|
||||
@ -100,9 +211,29 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
this.#buf = new Uint8Array(this.#buf.buffer, 0, len);
|
||||
}
|
||||
|
||||
/** Reads the next `p.length` bytes from the buffer or until the buffer is
|
||||
/**
|
||||
* 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 EOF (`null`). */
|
||||
* return, the return is EOF (`null`).
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
*
|
||||
* const data = new Uint8Array(5);
|
||||
* const res = await buf.read(data);
|
||||
*
|
||||
* assertEquals(res, 5);
|
||||
* assertEquals(new TextDecoder().decode(data), "Hello");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
readSync(p: Uint8Array): number | null {
|
||||
if (this.empty()) {
|
||||
// Buffer is empty, reset to recover space.
|
||||
@ -118,25 +249,85 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
return nread;
|
||||
}
|
||||
|
||||
/** Reads the next `p.length` bytes from the buffer or until the buffer is
|
||||
/**
|
||||
* 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 EOF (`null`).
|
||||
*
|
||||
* NOTE: This methods reads bytes synchronously; it's provided for
|
||||
* compatibility with `Reader` interfaces.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* await buf.write(new TextEncoder().encode("Hello, world!"));
|
||||
*
|
||||
* const data = new Uint8Array(5);
|
||||
* const res = await buf.read(data);
|
||||
*
|
||||
* assertEquals(res, 5);
|
||||
* assertEquals(new TextDecoder().decode(data), "Hello");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
read(p: Uint8Array): Promise<number | null> {
|
||||
const rr = this.readSync(p);
|
||||
return Promise.resolve(rr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the given data to the buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* const data = new TextEncoder().encode("Hello, world!");
|
||||
* buf.writeSync(data);
|
||||
*
|
||||
* const slice = buf.bytes();
|
||||
* assertEquals(new TextDecoder().decode(slice), "Hello, world!");
|
||||
* ```
|
||||
*
|
||||
* @param p The data to write to the buffer.
|
||||
* @returns The number of bytes written.
|
||||
*/
|
||||
writeSync(p: Uint8Array): number {
|
||||
const m = this.#grow(p.byteLength);
|
||||
return copy(p, this.#buf, m);
|
||||
}
|
||||
|
||||
/** NOTE: This methods writes bytes synchronously; it's provided for
|
||||
* compatibility with `Writer` interface. */
|
||||
/**
|
||||
* Writes the given data to the buffer. Resolves to the number of bytes
|
||||
* written.
|
||||
*
|
||||
* > [!NOTE]
|
||||
* > This methods writes bytes synchronously; it's provided for compatibility
|
||||
* > with the {@linkcode Writer} interface.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* const data = new TextEncoder().encode("Hello, world!");
|
||||
* await buf.write(data);
|
||||
*
|
||||
* const slice = buf.bytes();
|
||||
* assertEquals(new TextDecoder().decode(slice), "Hello, world!");
|
||||
* ```
|
||||
*
|
||||
* @param p The data to write to the buffer.
|
||||
* @returns The number of bytes written.
|
||||
*/
|
||||
write(p: Uint8Array): Promise<number> {
|
||||
const n = this.writeSync(p);
|
||||
return Promise.resolve(n);
|
||||
@ -180,7 +371,20 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
* throw. If the buffer can't grow it will throw an error.
|
||||
*
|
||||
* Based on Go Lang's
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.Grow | Buffer.Grow}. */
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.Grow | Buffer.Grow}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* buf.grow(10);
|
||||
* assertEquals(buf.capacity, 10);
|
||||
* ```
|
||||
*
|
||||
* @param n The number of bytes to grow the buffer by.
|
||||
*/
|
||||
grow(n: number) {
|
||||
if (n < 0) {
|
||||
throw Error("Buffer.grow: negative count");
|
||||
@ -189,12 +393,30 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
this.#reslice(m);
|
||||
}
|
||||
|
||||
/** Reads data from `r` until EOF (`null`) 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
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.ReadFrom | Buffer.ReadFrom}. */
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.ReadFrom | Buffer.ReadFrom}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* const r = new StringReader("Hello, world!");
|
||||
* const n = await buf.readFrom(r);
|
||||
*
|
||||
* assertEquals(n, 13);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
async readFrom(r: Reader): Promise<number> {
|
||||
let n = 0;
|
||||
const tmp = new Uint8Array(MIN_READ);
|
||||
@ -224,7 +446,24 @@ export class Buffer implements Writer, WriterSync, Reader, ReaderSync {
|
||||
* buffer becomes too large, `.readFromSync()` will throw an error.
|
||||
*
|
||||
* Based on Go Lang's
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.ReadFrom | Buffer.ReadFrom}. */
|
||||
* {@link https://golang.org/pkg/bytes/#Buffer.ReadFrom | Buffer.ReadFrom}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { Buffer } from "@std/io/buffer";
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new Buffer();
|
||||
* const r = new StringReader("Hello, world!");
|
||||
* const n = buf.readFromSync(r);
|
||||
*
|
||||
* assertEquals(n, 13);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
readFromSync(r: ReaderSync): number {
|
||||
let n = 0;
|
||||
const tmp = new Uint8Array(MIN_READ);
|
||||
|
@ -10,8 +10,8 @@ import type { Reader, Writer } from "./types.ts";
|
||||
* an error occurs. It resolves to the number of bytes copied or rejects with
|
||||
* the first error encountered while copying.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { copy } from "@std/io/copy";
|
||||
*
|
||||
* const source = await Deno.open("my_file.txt");
|
||||
|
13
io/copy_n.ts
13
io/copy_n.ts
@ -7,9 +7,22 @@ const DEFAULT_BUFFER_SIZE = 32 * 1024;
|
||||
|
||||
/**
|
||||
* Copy N size at the most. If read size is lesser than N, then returns nread
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { copyN } from "@std/io/copy-n";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const source = await Deno.open("README.md");
|
||||
*
|
||||
* const res = await copyN(source, Deno.stdout, 10);
|
||||
* assertEquals(res, 10);
|
||||
* ```
|
||||
*
|
||||
* @param r Reader
|
||||
* @param dest Writer
|
||||
* @param size Read size
|
||||
* @returns Number of bytes copied
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -9,24 +9,21 @@ export type { Reader, ReaderSync };
|
||||
/**
|
||||
* Turns a {@linkcode Reader} into an async iterator.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { iterateReader } from "@std/io/iterate-reader";
|
||||
*
|
||||
* using file = await Deno.open("/etc/passwd");
|
||||
* using file = await Deno.open("README.md");
|
||||
* for await (const chunk of iterateReader(file)) {
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Second argument can be used to tune size of a buffer.
|
||||
* Default size of the buffer is 32kB.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage with buffer size
|
||||
* ```ts no-assert
|
||||
* import { iterateReader } from "@std/io/iterate-reader";
|
||||
*
|
||||
* using file = await Deno.open("/etc/passwd");
|
||||
* using file = await Deno.open("README.md");
|
||||
* const iter = iterateReader(file, {
|
||||
* bufSize: 1024 * 1024
|
||||
* });
|
||||
@ -34,6 +31,11 @@ export type { Reader, ReaderSync };
|
||||
* console.log(chunk);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param options The options
|
||||
* @param options.bufSize The size of the buffer to use
|
||||
* @returns The async iterator of Uint8Array chunks
|
||||
*/
|
||||
export async function* iterateReader(
|
||||
reader: Reader,
|
||||
@ -56,27 +58,31 @@ export async function* iterateReader(
|
||||
/**
|
||||
* Turns a {@linkcode ReaderSync} into an iterator.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { iterateReaderSync } from "@std/io/iterate-reader";
|
||||
* import { assert } from "@std/assert/assert"
|
||||
*
|
||||
* using file = Deno.openSync("/etc/passwd");
|
||||
* using file = Deno.openSync("README.md");
|
||||
* for (const chunk of iterateReaderSync(file)) {
|
||||
* console.log(chunk);
|
||||
* assert(chunk instanceof Uint8Array);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* Second argument can be used to tune size of a buffer.
|
||||
* Default size of the buffer is 32kB.
|
||||
*
|
||||
* @example Usage with buffer size
|
||||
* ```ts
|
||||
* import { iterateReaderSync } from "@std/io/iterate-reader";
|
||||
|
||||
* using file = await Deno.open("/etc/passwd");
|
||||
* import { assert } from "@std/assert/assert"
|
||||
*
|
||||
* using file = await Deno.open("README.md");
|
||||
* const iter = iterateReaderSync(file, {
|
||||
* bufSize: 1024 * 1024
|
||||
* });
|
||||
* for (const chunk of iter) {
|
||||
* console.log(chunk);
|
||||
* assert(chunk instanceof Uint8Array);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
@ -84,6 +90,10 @@ export async function* iterateReader(
|
||||
* a view on that buffer on each iteration. It is therefore caller's
|
||||
* responsibility to copy contents of the buffer if needed; otherwise the
|
||||
* next iteration will overwrite contents of previously returned chunk.
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param options The options
|
||||
* @returns The iterator of Uint8Array chunks
|
||||
*/
|
||||
export function* iterateReaderSync(
|
||||
reader: ReaderSync,
|
||||
|
@ -1,26 +1,97 @@
|
||||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
||||
// This module is browser compatible.
|
||||
|
||||
/**
|
||||
* A `LimitedReader` reads from `reader` but limits the amount of data returned to just `limit` bytes.
|
||||
* Each call to `read` updates `limit` to reflect the new amount remaining.
|
||||
* `read` returns `null` when `limit` <= `0` or
|
||||
* when the underlying `reader` returns `null`.
|
||||
*/
|
||||
import type { Reader } from "./types.ts";
|
||||
|
||||
/**
|
||||
* Reads from `reader` but limits the amount of data returned to just `limit` bytes.
|
||||
* Each call to `read` updates `limit` to reflect the new amount remaining.
|
||||
* `read` returns `null` when `limit` <= `0` or
|
||||
* when the underlying `reader` returns `null`.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { LimitedReader } from "@std/io/limited-reader";
|
||||
* import { readAll } from "@std/io/read-all";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r = new StringReader("hello world");
|
||||
* const lr = new LimitedReader(r, 5);
|
||||
* const res = await readAll(lr);
|
||||
*
|
||||
* assertEquals(new TextDecoder().decode(res), "hello");
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class LimitedReader implements Reader {
|
||||
/**
|
||||
* The reader to read from
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { LimitedReader } from "@std/io/limited-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r = new StringReader("hello world");
|
||||
* const lr = new LimitedReader(r, 5);
|
||||
*
|
||||
* assertEquals(lr.reader, r);
|
||||
* ```
|
||||
*/
|
||||
reader: Reader;
|
||||
/**
|
||||
* The number of bytes to limit the reader to
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { LimitedReader } from "@std/io/limited-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r = new StringReader("hello world");
|
||||
* const lr = new LimitedReader(r, 5);
|
||||
*
|
||||
* assertEquals(lr.limit, 5);
|
||||
* ```
|
||||
*/
|
||||
limit: number;
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
* @param reader The reader to read from.
|
||||
* @param limit The number of bytes to limit the reader to.
|
||||
*/
|
||||
constructor(reader: Reader, limit: number) {
|
||||
this.reader = reader;
|
||||
this.limit = limit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the reader.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { LimitedReader } from "@std/io/limited-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r = new StringReader("hello world");
|
||||
* const lr = new LimitedReader(r, 5);
|
||||
*
|
||||
* const data = new Uint8Array(5);
|
||||
* const res = await lr.read(data);
|
||||
*
|
||||
* assertEquals(res, 5);
|
||||
* assertEquals(new TextDecoder().decode(data), "hello");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
async read(p: Uint8Array): Promise<number | null> {
|
||||
if (this.limit <= 0) {
|
||||
return null;
|
||||
|
@ -6,6 +6,13 @@
|
||||
* `Reader` and `Writer` interfaces are deprecated in Deno, and so many of these
|
||||
* utilities are also deprecated. Consider using web streams instead.
|
||||
*
|
||||
* ```ts no-assert
|
||||
* import { toReadableStream, toWritableStream } from "@std/io";
|
||||
*
|
||||
* await toReadableStream(Deno.stdin)
|
||||
* .pipeTo(toWritableStream(Deno.stdout));
|
||||
* ```
|
||||
*
|
||||
* @module
|
||||
*/
|
||||
|
||||
|
@ -4,7 +4,23 @@
|
||||
import type { Reader } from "./types.ts";
|
||||
|
||||
/**
|
||||
* Reader utility for combining multiple readers
|
||||
* Reader utility for combining multiple readers.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { MultiReader } from "@std/io/multi-reader";
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { readAll } from "@std/io/read-all";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r1 = new StringReader("hello");
|
||||
* const r2 = new StringReader("world");
|
||||
* const mr = new MultiReader([r1, r2]);
|
||||
*
|
||||
* const res = await readAll(mr);
|
||||
*
|
||||
* assertEquals(new TextDecoder().decode(res), "helloworld");
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
@ -12,10 +28,46 @@ export class MultiReader implements Reader {
|
||||
readonly #readers: Reader[];
|
||||
#currentIndex = 0;
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
* @param readers The readers to combine.
|
||||
*/
|
||||
constructor(readers: Reader[]) {
|
||||
this.#readers = [...readers];
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads data from the readers.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { MultiReader } from "@std/io/multi-reader";
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { readAll } from "@std/io/read-all";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const r1 = new StringReader("hello");
|
||||
* const r2 = new StringReader("world");
|
||||
* const mr = new MultiReader([r1, r2]);
|
||||
*
|
||||
* const data = new Uint8Array(5);
|
||||
* const res = await mr.read(data);
|
||||
*
|
||||
* assertEquals(res, 5);
|
||||
* assertEquals(new TextDecoder().decode(data), "hello");
|
||||
*
|
||||
* const res2 = await mr.read(data);
|
||||
* assertEquals(res2, 0);
|
||||
*
|
||||
* const res3 = await mr.read(data);
|
||||
* assertEquals(res3, 5);
|
||||
* assertEquals(new TextDecoder().decode(data), "world");
|
||||
* ```
|
||||
*
|
||||
* @param p The buffer to read data into.
|
||||
* @returns The number of bytes read.
|
||||
*/
|
||||
async read(p: Uint8Array): Promise<number | null> {
|
||||
const r = this.#readers[this.#currentIndex];
|
||||
if (!r) return null;
|
||||
|
@ -9,8 +9,8 @@ import type { Reader, ReaderSync } from "./types.ts";
|
||||
* Read {@linkcode Reader} `r` until EOF (`null`) and resolve to the content as
|
||||
* {@linkcode Uint8Array}.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { readAll } from "@std/io/read-all";
|
||||
*
|
||||
* // Example from stdin
|
||||
@ -20,6 +20,9 @@ import type { Reader, ReaderSync } from "./types.ts";
|
||||
* using file = await Deno.open("my_file.txt", {read: true});
|
||||
* const myFileContent = await readAll(file);
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @returns The content as Uint8Array
|
||||
*/
|
||||
export async function readAll(reader: Reader): Promise<Uint8Array> {
|
||||
const chunks: Uint8Array[] = [];
|
||||
@ -41,8 +44,8 @@ export async function readAll(reader: Reader): Promise<Uint8Array> {
|
||||
* Synchronously reads {@linkcode ReaderSync} `r` until EOF (`null`) and returns
|
||||
* the content as {@linkcode Uint8Array}.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { readAllSync } from "@std/io/read-all";
|
||||
*
|
||||
* // Example from stdin
|
||||
@ -52,6 +55,9 @@ export async function readAll(reader: Reader): Promise<Uint8Array> {
|
||||
* using file = Deno.openSync("my_file.txt", {read: true});
|
||||
* const myFileContent = readAllSync(file);
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @returns The content as Uint8Array
|
||||
*/
|
||||
export function readAllSync(reader: ReaderSync): Uint8Array {
|
||||
const chunks: Uint8Array[] = [];
|
||||
|
@ -26,7 +26,23 @@ function createLPS(pat: Uint8Array): Uint8Array {
|
||||
}
|
||||
|
||||
/**
|
||||
* Read delimited bytes from a Reader.
|
||||
* Read delimited bytes from a {@linkcode Reader} through an
|
||||
* {@linkcode AsyncIterableIterator} of {@linkcode Uint8Array}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { readDelim } from "@std/io/read-delim";
|
||||
* import { assert } from "@std/assert/assert"
|
||||
*
|
||||
* const fileReader = await Deno.open("README.md");
|
||||
* for await (const chunk of readDelim(fileReader, new TextEncoder().encode("\n"))) {
|
||||
* assert(chunk instanceof Uint8Array);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param delim The delimiter to read until
|
||||
* @returns The {@linkcode AsyncIterableIterator} of {@linkcode Uint8Array}s.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -4,8 +4,21 @@ import type { BufReader } from "./buf_reader.ts";
|
||||
import { readShort } from "./read_short.ts";
|
||||
|
||||
/**
|
||||
* Read big endian 32bit integer from BufReader
|
||||
* @param buf
|
||||
* Read big endian 32bit integer from a {@linkcode BufReader}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader } from "@std/io/buf-reader";
|
||||
* import { readInt } from "@std/io/read-int";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new BufReader(new Deno.Buffer(new Uint8Array([0x12, 0x34, 0x56, 0x78])));
|
||||
* const int = await readInt(buf);
|
||||
* assertEquals(int, 0x12345678);
|
||||
* ```
|
||||
*
|
||||
* @param buf The buffer reader to read from
|
||||
* @returns The 32bit integer
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -6,21 +6,24 @@ import { BufReader } from "./buf_reader.ts";
|
||||
import { concat } from "@std/bytes/concat";
|
||||
|
||||
/**
|
||||
* Read strings line-by-line from a Reader.
|
||||
* Read strings line-by-line from a {@linkcode Reader}.
|
||||
*
|
||||
* @example
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { readLines } from "@std/io/read-lines";
|
||||
* import * as path from "@std/path";
|
||||
* import { assert } from "@std/assert/assert"
|
||||
*
|
||||
* const filename = path.join(Deno.cwd(), "std/io/README.md");
|
||||
* let fileReader = await Deno.open(filename);
|
||||
* let fileReader = await Deno.open("README.md");
|
||||
*
|
||||
* for await (let line of readLines(fileReader)) {
|
||||
* console.log(line);
|
||||
* assert(typeof line === "string");
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param decoderOpts The options
|
||||
* @returns The async iterator of strings
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export async function* readLines(
|
||||
|
@ -6,8 +6,23 @@ import { readInt } from "./read_int.ts";
|
||||
const MAX_SAFE_INTEGER = BigInt(Number.MAX_SAFE_INTEGER);
|
||||
|
||||
/**
|
||||
* Read big endian 64bit long from BufReader
|
||||
* @param buf
|
||||
* Read big endian 64bit long from a {@linkcode BufReader}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader } from "@std/io/buf-reader";
|
||||
* import { readLong } from "@std/io/read-long";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new BufReader(new Deno.Buffer(new Uint8Array([0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a])));
|
||||
* const long = await readLong(buf);
|
||||
* assertEquals(long, 0x123456789a);
|
||||
* ```
|
||||
*
|
||||
* @param buf The BufReader to read from
|
||||
* @returns The 64bit long
|
||||
* @throws {Deno.errors.UnexpectedEof} If the reader returns unexpected EOF
|
||||
* @throws {RangeError} If the long value is too big to be represented as a JavaScript number
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -6,6 +6,8 @@ import type { Reader, ReaderSync } from "./types.ts";
|
||||
const DEFAULT_BUFFER_SIZE = 32 * 1024;
|
||||
|
||||
/**
|
||||
* The range of bytes to read from a file or other resource that is readable.
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export interface ByteRange {
|
||||
@ -21,7 +23,8 @@ export interface ByteRange {
|
||||
* seekable. The range start and end are inclusive of the bytes within that
|
||||
* range.
|
||||
*
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { assertEquals } from "@std/assert";
|
||||
* import { readRange } from "@std/io/read-range";
|
||||
*
|
||||
@ -31,6 +34,10 @@ export interface ByteRange {
|
||||
* assertEquals(bytes.length, 10);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from
|
||||
* @param range The range of bytes to read
|
||||
* @returns The bytes read
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export async function readRange(
|
||||
@ -67,7 +74,8 @@ export async function readRange(
|
||||
* readable and seekable. The range start and end are inclusive of the bytes
|
||||
* within that range.
|
||||
*
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-eval
|
||||
* import { assertEquals } from "@std/assert";
|
||||
* import { readRangeSync } from "@std/io/read-range";
|
||||
*
|
||||
@ -77,6 +85,10 @@ export async function readRange(
|
||||
* assertEquals(bytes.length, 10);
|
||||
* ```
|
||||
*
|
||||
* @param r The reader to read from
|
||||
* @param range The range of bytes to read
|
||||
* @returns The bytes read
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export function readRangeSync(
|
||||
|
@ -3,8 +3,21 @@
|
||||
import type { BufReader } from "./buf_reader.ts";
|
||||
|
||||
/**
|
||||
* Read big endian 16bit short from BufReader
|
||||
* @param buf
|
||||
* Read big endian 16bit short from a {@linkcode BufReader}.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { BufReader } from "@std/io/buf-reader";
|
||||
* import { readShort } from "@std/io/read-short";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const buf = new BufReader(new Deno.Buffer(new Uint8Array([0x12, 0x34])));
|
||||
* const short = await readShort(buf);
|
||||
* assertEquals(short, 0x1234);
|
||||
* ```
|
||||
*
|
||||
* @param buf The reader to read from
|
||||
* @returns The 16bit short
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -5,21 +5,25 @@ import type { Reader } from "./types.ts";
|
||||
import { readDelim } from "./read_delim.ts";
|
||||
|
||||
/**
|
||||
* Read Reader chunk by chunk, splitting based on delimiter.
|
||||
* Read {@linkcode Reader} chunk by chunk, splitting based on delimiter.
|
||||
*
|
||||
* @example
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { readStringDelim } from "@std/io/read-string-delim";
|
||||
* import * as path from "@std/path";
|
||||
* import { assert } from "@std/assert/assert"
|
||||
*
|
||||
* const filename = path.join(Deno.cwd(), "std/io/README.md");
|
||||
* let fileReader = await Deno.open(filename);
|
||||
* let fileReader = await Deno.open("README.md");
|
||||
*
|
||||
* for await (let line of readStringDelim(fileReader, "\n")) {
|
||||
* console.log(line);
|
||||
* assert(typeof line === "string");
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param delim The delimiter to split the reader by
|
||||
* @param decoderOpts The options
|
||||
* @returns The async iterator of strings
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export async function* readStringDelim(
|
||||
|
@ -8,17 +8,19 @@ import type { Reader } from "./types.ts";
|
||||
/**
|
||||
* Create a {@linkcode Reader} from a {@linkcode ReadableStreamDefaultReader}.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { copy } from "@std/io/copy";
|
||||
* import { readerFromStreamReader } from "@std/io/reader-from-stream-reader";
|
||||
*
|
||||
* const res = await fetch("https://deno.land");
|
||||
* using file = await Deno.open("./deno.land.html", { create: true, write: true });
|
||||
*
|
||||
* const reader = readerFromStreamReader(res.body!.getReader());
|
||||
* await copy(reader, file);
|
||||
* await copy(reader, Deno.stdout);
|
||||
* ```
|
||||
*
|
||||
* @param streamReader The stream reader to read from
|
||||
* @returns The reader
|
||||
*/
|
||||
export function readerFromStreamReader(
|
||||
streamReader: ReadableStreamDefaultReader<Uint8Array>,
|
||||
|
@ -2,9 +2,20 @@
|
||||
// This module is browser compatible.
|
||||
|
||||
/**
|
||||
* Slice number into 64bit big endian byte array
|
||||
* Slice number into 64bit big endian byte array.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { sliceLongToBytes } from "@std/io/slice-long-to-bytes";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const dest = sliceLongToBytes(0x123456789a);
|
||||
* assertEquals(dest, [0, 0, 0, 0x12, 0x34, 0x56, 0x78, 0x9a]);
|
||||
* ```
|
||||
*
|
||||
* @param d The number to be sliced
|
||||
* @param dest The sliced array
|
||||
* @param dest The array to store the sliced bytes
|
||||
* @returns The sliced bytes
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
|
@ -6,35 +6,29 @@ import { Buffer } from "./buffer.ts";
|
||||
/**
|
||||
* Reader utility for strings.
|
||||
*
|
||||
* @example
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringReader } from "@std/io/string-reader";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const data = new Uint8Array(6);
|
||||
* const r = new StringReader("abcdef");
|
||||
* const res0 = await r.read(data);
|
||||
* const res1 = await r.read(new Uint8Array(6));
|
||||
*
|
||||
* // Number of bytes read
|
||||
* console.log(res0); // 6
|
||||
* console.log(res1); // null, no byte left to read. EOL
|
||||
*
|
||||
* // text
|
||||
*
|
||||
* console.log(new TextDecoder().decode(data)); // abcdef
|
||||
* ```
|
||||
*
|
||||
* **Output:**
|
||||
*
|
||||
* ```text
|
||||
* 6
|
||||
* null
|
||||
* abcdef
|
||||
* assertEquals(res0, 6);
|
||||
* assertEquals(res1, null);
|
||||
* assertEquals(new TextDecoder().decode(data), "abcdef");
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
*/
|
||||
export class StringReader extends Buffer {
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
* @param s The string to read.
|
||||
*/
|
||||
constructor(s: string) {
|
||||
super(new TextEncoder().encode(s).buffer);
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ const decoder = new TextDecoder();
|
||||
/**
|
||||
* Writer utility for buffering string chunks.
|
||||
*
|
||||
* @example
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import {
|
||||
* copyN,
|
||||
@ -16,23 +16,16 @@ const decoder = new TextDecoder();
|
||||
* StringWriter,
|
||||
* } from "@std/io";
|
||||
* import { copy } from "@std/io/copy";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const w = new StringWriter("base");
|
||||
* const r = new StringReader("0123456789");
|
||||
* await copyN(r, w, 4); // copy 4 bytes
|
||||
*
|
||||
* // Number of bytes read
|
||||
* console.log(w.toString()); //base0123
|
||||
* assertEquals(w.toString(), "base0123");
|
||||
*
|
||||
* await copy(r, w); // copy all
|
||||
* console.log(w.toString()); // base0123456789
|
||||
* ```
|
||||
*
|
||||
* **Output:**
|
||||
*
|
||||
* ```text
|
||||
* base0123
|
||||
* base0123456789
|
||||
* assertEquals(w.toString(), "base0123456789");
|
||||
* ```
|
||||
*
|
||||
* @deprecated This will be removed in 1.0.0. Use the {@link https://developer.mozilla.org/en-US/docs/Web/API/Streams_API | Web Streams API} instead.
|
||||
@ -43,6 +36,11 @@ export class StringWriter implements Writer, WriterSync {
|
||||
#cache: string | undefined;
|
||||
#base: string;
|
||||
|
||||
/**
|
||||
* Construct a new instance.
|
||||
*
|
||||
* @param base The base string to write to the buffer.
|
||||
*/
|
||||
constructor(base = "") {
|
||||
const c = new TextEncoder().encode(base);
|
||||
this.#chunks.push(c);
|
||||
@ -50,10 +48,42 @@ export class StringWriter implements Writer, WriterSync {
|
||||
this.#base = base;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the bytes to the buffer asynchronously.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringWriter } from "@std/io/string-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const w = new StringWriter("base");
|
||||
* await w.write(new TextEncoder().encode("0123"));
|
||||
* assertEquals(w.toString(), "base0123");
|
||||
* ```
|
||||
*
|
||||
* @param p The bytes to write to the buffer.
|
||||
* @returns The number of bytes written to the buffer in total.
|
||||
*/
|
||||
write(p: Uint8Array): Promise<number> {
|
||||
return Promise.resolve(this.writeSync(p));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the bytes to the buffer synchronously.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringWriter } from "@std/io/string-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const w = new StringWriter("base");
|
||||
* w.writeSync(new TextEncoder().encode("0123"));
|
||||
* assertEquals(w.toString(), "base0123");
|
||||
* ```
|
||||
*
|
||||
* @param p The bytes to write to the buffer.
|
||||
* @returns The number of bytes written to the buffer in total.
|
||||
*/
|
||||
writeSync(p: Uint8Array): number {
|
||||
this.#chunks.push(new Uint8Array(p));
|
||||
this.#byteLength += p.byteLength;
|
||||
@ -61,6 +91,21 @@ export class StringWriter implements Writer, WriterSync {
|
||||
return p.byteLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string written to the buffer.
|
||||
*
|
||||
* @example Usage
|
||||
* ```ts
|
||||
* import { StringWriter } from "@std/io/string-writer";
|
||||
* import { assertEquals } from "@std/assert/equals";
|
||||
*
|
||||
* const w = new StringWriter("base");
|
||||
* await w.write(new TextEncoder().encode("0123"));
|
||||
* assertEquals(w.toString(), "base0123");
|
||||
* ```
|
||||
*
|
||||
* @returns the string written to the buffer.
|
||||
*/
|
||||
toString(): string {
|
||||
if (this.#cache) {
|
||||
return this.#cache;
|
||||
|
@ -14,11 +14,14 @@ export interface ToReadableStreamOptions {
|
||||
*/
|
||||
autoClose?: boolean;
|
||||
|
||||
/** The size of chunks to allocate to read, the default is ~16KiB, which is
|
||||
* the maximum size that Deno operations can currently support. */
|
||||
/**
|
||||
* The size of chunks to allocate to read.
|
||||
*
|
||||
* @default {16640}
|
||||
*/
|
||||
chunkSize?: number;
|
||||
|
||||
/** The queuing strategy to create the `ReadableStream` with. */
|
||||
/** The queuing strategy to create the {@linkcode ReadableStream} with. */
|
||||
strategy?: QueuingStrategy<Uint8Array>;
|
||||
}
|
||||
|
||||
@ -30,13 +33,17 @@ export interface ToReadableStreamOptions {
|
||||
* will be read. When `null` is returned from the reader, the stream will be
|
||||
* closed along with the reader (if it is also a `Closer`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { toReadableStream } from "@std/io/to-readable-stream";
|
||||
*
|
||||
* const file = await Deno.open("./file.txt", { read: true });
|
||||
* const file = await Deno.open("./README.md", { read: true });
|
||||
* const fileStream = toReadableStream(file);
|
||||
* ```
|
||||
*
|
||||
* @param reader The reader to read from
|
||||
* @param options The options
|
||||
* @returns The readable stream
|
||||
*/
|
||||
export function toReadableStream(
|
||||
reader: Reader | (Reader & Closer),
|
||||
|
@ -19,15 +19,18 @@ export interface toWritableStreamOptions {
|
||||
/**
|
||||
* Create a {@linkcode WritableStream} from a {@linkcode Writer}.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Usage
|
||||
* ```ts no-assert
|
||||
* import { toWritableStream } from "@std/io/to-writable-stream";
|
||||
*
|
||||
* const file = await Deno.open("./file.txt", { create: true, write: true });
|
||||
* await ReadableStream.from("Hello World")
|
||||
* await ReadableStream.from(["Hello World"])
|
||||
* .pipeThrough(new TextEncoderStream())
|
||||
* .pipeTo(toWritableStream(file));
|
||||
* .pipeTo(toWritableStream(Deno.stdout));
|
||||
* ```
|
||||
*
|
||||
* @param writer The writer to write to
|
||||
* @param options The options
|
||||
* @returns The writable stream
|
||||
*/
|
||||
export function toWritableStream(
|
||||
writer: Writer,
|
||||
|
@ -6,19 +6,25 @@ import type { Writer, WriterSync } from "./types.ts";
|
||||
/**
|
||||
* Write all the content of the array buffer (`arr`) to the writer (`w`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example Writing to stdout
|
||||
* ```ts no-assert
|
||||
* import { writeAll } from "@std/io/write-all";
|
||||
|
||||
* // Example writing to stdout
|
||||
* let contentBytes = new TextEncoder().encode("Hello World");
|
||||
* await writeAll(Deno.stdout, contentBytes);
|
||||
*
|
||||
* // Example writing to file
|
||||
* contentBytes = new TextEncoder().encode("Hello World");
|
||||
* using file = await Deno.open('test.file', {write: true});
|
||||
* const contentBytes = new TextEncoder().encode("Hello World");
|
||||
* await writeAll(Deno.stdout, contentBytes);
|
||||
* ```
|
||||
*
|
||||
* @example Writing to file
|
||||
* ```ts no-eval no-assert
|
||||
* import { writeAll } from "@std/io/write-all";
|
||||
*
|
||||
* const contentBytes = new TextEncoder().encode("Hello World");
|
||||
* using file = await Deno.open('test.file', { write: true });
|
||||
* await writeAll(file, contentBytes);
|
||||
* ```
|
||||
*
|
||||
* @param writer The writer to write to
|
||||
* @param data The data to write
|
||||
*/
|
||||
export async function writeAll(writer: Writer, data: Uint8Array) {
|
||||
let nwritten = 0;
|
||||
@ -31,19 +37,25 @@ export async function writeAll(writer: Writer, data: Uint8Array) {
|
||||
* Synchronously write all the content of the array buffer (`arr`) to the
|
||||
* writer (`w`).
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* @example "riting to stdout
|
||||
* ```ts no-assert
|
||||
* import { writeAllSync } from "@std/io/write-all";
|
||||
*
|
||||
* // Example writing to stdout
|
||||
* let contentBytes = new TextEncoder().encode("Hello World");
|
||||
* const contentBytes = new TextEncoder().encode("Hello World");
|
||||
* writeAllSync(Deno.stdout, contentBytes);
|
||||
* ```
|
||||
*
|
||||
* // Example writing to file
|
||||
* contentBytes = new TextEncoder().encode("Hello World");
|
||||
* using file = Deno.openSync('test.file', {write: true});
|
||||
* @example Writing to file
|
||||
* ```ts no-eval no-assert
|
||||
* import { writeAllSync } from "@std/io/write-all";
|
||||
*
|
||||
* const contentBytes = new TextEncoder().encode("Hello World");
|
||||
* using file = Deno.openSync("test.file", { write: true });
|
||||
* writeAllSync(file, contentBytes);
|
||||
* ```
|
||||
*
|
||||
* @param writer The writer to write to
|
||||
* @param data The data to write
|
||||
*/
|
||||
export function writeAllSync(writer: WriterSync, data: Uint8Array) {
|
||||
let nwritten = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user