Buffer
import { Buffer } from "jsr:@ende/streams";class
class BufferA variable-sized buffer of bytes with readable and writable getters that
allows you to work with Web Streams API.
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 necessary.
Buffer is NOT the same thing as Node's Buffer. Node's Buffer was created in 2009 before JavaScript had the concept of ArrayBuffers. It's simply a non-standard ArrayBuffer.
ArrayBuffer is a fixed memory allocation. Buffer is implemented on top of ArrayBuffer.
Based on Go Buffer.
Example: Buffer input bytes and convert it to a string
import { Buffer } from "@ende/streams/buffer";
import { toText } from "@ende/streams/to-text";
import { assert } from "@ende/assert";
import { assertEquals } from "@ende/assert";
// Create a new buffer
const buf = new Buffer();
assertEquals(buf.capacity, 0);
assertEquals(buf.length, 0);
// Dummy input stream
const inputStream = ReadableStream.from([
"hello, ",
"world",
"!",
]);
// Pipe the input stream to the buffer
await inputStream.pipeThrough(new TextEncoderStream()).pipeTo(buf.writable);
assert(buf.capacity > 0);
assert(buf.length > 0);
// Convert the buffered bytes to a string
const result = await toText(buf.readable);
assertEquals(result, "hello, world!");
assert(buf.empty());
Constructors
constructor
new Buffer(ab?: ArrayBufferLike | ArrayLike<number>)Constructs a new instance.
ab?: ArrayBufferLike | ArrayLike<number>An optional buffer to use as the initial buffer.
Methods
readable
get readable(): ReadableStream<Uint8Array>Getter returning the instance's ReadableStream.
Returns
A ReadableStream of the buffer.
Example: Read the content out of the buffer to stdout
import { Buffer } from "@ende/streams/buffer";
const buf = new Buffer();
await buf.readable.pipeTo(Ende.stdout.writable);
writable
get writable(): WritableStream<Uint8Array>Getter returning the instance's WritableStream.
Returns
A WritableStream of the buffer.
Example: Write the data from stdin to the buffer
import { Buffer } from "@ende/streams/buffer";
const buf = new Buffer();
await Ende.stdin.readable.pipeTo(buf.writable);
bytes
bytes(options: BufferBytesOptions = [UNSUPPORTED]): Uint8ArrayReturns 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 that mutates or consumes the
buffer, like reading data out via readable, 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. If options is not provided,
options.copy defaults to true.
options: BufferBytesOptions = [UNSUPPORTED]Options for the bytes method.
Returns
A copy or a slice of the buffer.
Example: Copy the buffer
import { assertEquals } from "@ende/assert";
import { assertNotEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([0, 1, 2]);
const buf = new Buffer(array.buffer);
const copied = buf.bytes();
assertEquals(copied.length, array.length);
// Modify an element in the original array
array[1] = 99;
assertEquals(copied[0], array[0]);
// The copied buffer is not affected by the modification
assertNotEquals(copied[1], array[1]);
assertEquals(copied[2], array[2]);
Example: Get a slice to the buffer
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([0, 1, 2]);
const buf = new Buffer(array.buffer);
const slice = buf.bytes({ copy: false });
assertEquals(slice.length, array.length);
// Modify an element in the original array
array[1] = 99;
assertEquals(slice[0], array[0]);
// The slice _is_ affected by the modification
assertEquals(slice[1], array[1]);
assertEquals(slice[2], array[2]);
empty
empty(): booleanReturns whether the unread portion of the buffer is empty.
Returns
Whether the buffer is empty.
Example: Empty buffer
import { assert } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const buf = new Buffer();
assert(buf.empty());
Example: Non-empty buffer
import { assert } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([42]);
const buf = new Buffer(array.buffer);
assert(!buf.empty());
Example: Non-empty, but the content was already read
import { assert } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([42]);
const buf = new Buffer(array.buffer);
assert(!buf.empty());
// Read the content out of the buffer
await buf.readable.pipeTo(Ende.stdout.writable);
// The buffer is now empty
assert(buf.empty());
length
get length(): numberA read only number of bytes of the unread portion of the buffer.
Returns
The number of bytes in the unread portion of the buffer.
Example: Basic usage
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([0, 1, 2]);
const buf = new Buffer(array.buffer);
assertEquals(buf.length, 3);
Example: Length becomes 0 after the content is read
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([42]);
const buf = new Buffer(array.buffer);
assertEquals(buf.length, 1);
// Read the content out of the buffer
await buf.readable.pipeTo(Ende.stdout.writable);
// The length is now 0
assertEquals(buf.length, 0);
capacity
get capacity(): numberThe read only capacity of the buffer's underlying byte slice, that is, the total space allocated for the buffer's data.
Returns
The number of allocated bytes for the buffer.
Example: Basic usage
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const arrayBuffer = new ArrayBuffer(256);
const buf = new Buffer(arrayBuffer);
assertEquals(buf.capacity, 256);
truncate
truncate(n: number): voidDiscards 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.
n: numberThe number of bytes to keep.
Example: Basic usage
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([0, 1, 2]);
const buf = new Buffer(array.buffer);
assertEquals(buf.bytes(), array);
// Discard all but the first 2 bytes
buf.truncate(2);
assertEquals(buf.bytes(), array.slice(0, 2));
reset
reset(): voidResets to an empty buffer.
Example: Basic usage
import { assert } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const array = new Uint8Array([0, 1, 2]);
const buf = new Buffer(array.buffer);
assert(!buf.empty());
// Reset
buf.reset();
assert(buf.empty());
grow
grow(n: number): voidGrows the buffer's capacity, if necessary, to guarantee space for
another n bytes. After .grow(n), at least n bytes can be written to
the buffer without another allocation. If n is negative, .grow() will
throw. If the buffer can't grow it will throw an error.
n: numberThe number of bytes to grow the buffer by.
Based on Go Lang's Buffer.Grow.
Example: Basic usage
import { assert } from "@ende/assert";
import { assertEquals } from "@ende/assert";
import { Buffer } from "@ende/streams/buffer";
const buf = new Buffer();
assertEquals(buf.capacity, 0);
buf.grow(200);
assert(buf.capacity >= 200);