Skip to content
BSD
Esc
navigateopen⌘Jpreview
On this page

Reader

Read primitive values, control the cursor, and inspect decoding failures.

BsdReader

BsdReader owns the input buffer and mutable decoding state. BSD constructs one for every schema.decode(input) call. Direct access is primarily useful inside custom(), modifiers, and .pipe() callbacks.

State

The reader state is mutable. Every schema decoder is responsible for advancing the internal cursor position and appending/popping path entries. This mutability in on purpose, and ensures we do not create new objects unnecessarily.

Member Contract
buffer Source Uint8Array; never copied
view DataView scoped to the source range
byteOffset Current absolute cursor
schemaOffset Starting offset of the active schema
remaining limit - byteOffset
limit Exclusive active-frame boundary
path Active struct keys and array indexes

Primitive reads

The reader exposes a few methods for reading bytes from its input buffer, based on the internal cursor position. This improves ergonomics when writing custom decoders (see custom()) and modifiers.

The reader internals are exposed on purpose, in case you need a scape hatch to implement a schema that is too complex to be expressed through the standard API.

All methods accept the argument advance, which controls whether the internal cursor advances after reading the value.

Method Result Advances cursor by
uint(bits, advance?) number 1–4 bytes
int(bits, advance?) number 1–4 bytes
biguint(bits, advance?) bigint 8 bytes
bigint(bits, advance?) bigint 8 bytes
float(bits, advance?) number 4 or 8 bytes
bool(advance?) boolean 1 byte
bytes(byteLength, advance?) Uint8Array byteLength
const TaggedValue = custom((reader) => {
    const tag = reader.uint(8, false);

    return tag === 1
        ? { tag: reader.uint(8), value: reader.uint(16) }
        : { tag: reader.uint(8), value: reader.uint(32) };
});

BsdIssue

BSD validation and contextual decoding failures throw BsdIssue, an Error subclass containing binary context.

Member Contract
message Failure description
schemaOffset Starting offset of the failing schema
byteOffset Cursor position when the issue was created
path Struct keys and array indexes leading to the schema
import { array, BsdIssue, u8 } from "@marceloclp/bsd";

try {
    array(3, u8().lte(10)).decode(Uint8Array.of(1, 99, 3));
} catch (error) {
    if (error instanceof BsdIssue) {
        console.log(error.message); // expected 99 to be less than or equal to 10
        console.log(error.schemaOffset); // 1
        console.log(error.byteOffset); // 2
        console.log(error.path); // [1]
    }
}

Use reader.fail(message) to construct a contextual issue in custom logic. It returns the error; throw it explicitly.

const Version = u8().check((value, reader) => {
    if (value !== 2) throw reader.fail(`unsupported version: ${value}`);
});

Was this page helpful?