Initial Commit
This commit is contained in:
91
packages/foundation/flow/cbor/src/decoder/decoder.md
Normal file
91
packages/foundation/flow/cbor/src/decoder/decoder.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# `decoder`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs --> - half-float — Decodes 2 big-endian bytes representin…
|
||||
- [half-float](./half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
|
||||
- [well-formed](./well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
|
||||
- half-float — Decodes 2 big-endian bytes representin…
|
||||
|
||||
- [half-float](./half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
|
||||
- [well-formed](./well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
|
||||
|
||||
- half-float — Decodes 2 big-endian bytes representin…
|
||||
|
||||
- [half-float](./half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
|
||||
- [well-formed](./well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
|
||||
|
||||
- half-float — Decodes 2 big-endian bytes representin…
|
||||
|
||||
- [half-float](./half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
|
||||
- [well-formed](./well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
|
||||
- [half-float](./half-float.md) — Decodes 2 big-endian bytes representing IEEE 754 binary16 to a JavaScript `number`. The decoder is always available — n…
|
||||
- [well-formed](./well-formed.md) — `isWellFormed(bytes)` returns `true` iff `bytes` represent a single well-formed CBOR item per RFC 8949 §5.1. The functi…
|
||||
|
||||
## Purpose
|
||||
|
||||
The CBOR decoder materialises an RFC 8949 byte sequence into a JavaScript
|
||||
value. It defaults to strict mode — every §5.1 well-formedness rule is
|
||||
enforced, including rejection of trailing bytes after the top-level item,
|
||||
truncation, malformed UTF-8, unmatched break stops, and reserved minor-type
|
||||
encodings. Lax mode applies §5.2 only and is provided for interop with
|
||||
producers that emit looser CBOR.
|
||||
|
||||
## Features
|
||||
|
||||
- All seven major types decode end-to-end, including indefinite-length
|
||||
byte/text strings and indefinite-length arrays/maps.
|
||||
- Half-float (binary16) decode — always available; never gated by an option.
|
||||
- BigInt fallback: `u64` values exceeding `Number.MAX_SAFE_INTEGER` decode to
|
||||
`bigint`. Negative `u64` values likewise.
|
||||
- Pluggable tag handling: callers pass a `Map<number, TagHandler>` and the
|
||||
decoder substitutes handler output for the inner value. Unknown tags
|
||||
return as `Tagged` per RFC 8949 §3.4.
|
||||
- Bounded recursion + bounded item count — `maxDepth` (default 64) and
|
||||
`maxItems` (default 1_000_000) caps prevent stack and memory blowups on
|
||||
adversarial inputs.
|
||||
- `decodeOne` returns the consumed byte count, enabling streaming and
|
||||
sequence decoders to advance their cursors precisely.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { decode } from "@suaveplan/cbor/decoder";
|
||||
|
||||
const value = decode(bytes); // strict mode by default
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import { decode } from "@suaveplan/cbor/decoder";
|
||||
import { defaultTagHandlers } from "@suaveplan/cbor/tags";
|
||||
|
||||
// Decode with the IANA built-in tag handlers (Date, URL, RegExp, ...)
|
||||
const tags = defaultTagHandlers().snapshot();
|
||||
const value = decode(bytes, { mode: "strict" }, tags);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
- `decode(bytes: Uint8Array, options?: DecoderOptions, tags?: ReadonlyMap<number, TagHandler>): DecodedValue`
|
||||
- `decodeOne(bytes, options?, tags?): { value: DecodedValue; consumed: number }`
|
||||
- `DecoderOptions`:
|
||||
- `mode?: "strict" | "lax"` — default `"strict"`.
|
||||
- `tagHandling?: "registered" | "raw"` — default `"registered"`. `"raw"`
|
||||
yields `Tagged` instances even when a handler exists.
|
||||
- `maxDepth?: number`, `maxItems?: number`, `allowTrailingBytes?: boolean`.
|
||||
|
||||
Throws `CborError` with codes `MALFORMED`, `UNEXPECTED_TYPE`,
|
||||
`NESTED_TOO_DEEP`, `LENGTH_OVERFLOW`, `INDEFINITE_NOT_ALLOWED`.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The decoder is single-pass and zero-copy where possible — `subarray` views
|
||||
into the input buffer back returned `Uint8Array` byte strings. Indefinite
|
||||
text/byte strings are reassembled chunk by chunk; nested indefinite chunks
|
||||
are explicitly rejected per §3.2. UTF-8 decoding uses a fatal-mode
|
||||
`TextDecoder` so invalid sequences raise `MALFORMED` rather than silently
|
||||
substituting U+FFFD. The `decodeOne` exit point exposes the cursor position so
|
||||
upstream sequence + streaming decoders can advance the input without
|
||||
re-tokenising.
|
||||
Reference in New Issue
Block a user