php-dextrin

Decoder
in package

FinalYes

`.dxnb` decoder -- the mirror image of {@see Encoder}. Envelope (`magic` `version` `cbor_item`) checked once at the top; everything below that is a single recursive {@see self::decodeItem()}, keyed on CBOR major type first, then on tag -- matching `dxn/DXN.md` §2.2's table row order.

readHead()'s argument is always a numeric string, never a native int -- CBOR major 0's argument can reach 2^64-1, which exceeds PHP_INT_MAX, the same boundary Writer's own doc explains.

One case needs care that the JS port didn't: @ordered's payload is an untagged CBOR map (major 5), and the plain, untagged major -5 case decodes through MapBuilder (this port's own PHP-array-key coercion for map) -- which ordered-map must NOT go through, since its pairs can hold any key type. decodeTag() special-cases T_ORDERED to read raw pairs directly, exactly mirroring how Text\Parser::parseOrderedTag() avoids the same trap.

Table of Contents

Properties

$buf  : string
$pos  : int
$registry  : Registry|null
$sharedItems  : array<int, mixed>
$stringrefStack  : array<int, array<int, string>>

Methods

decode()  : mixed
The one `.dxnb` document `$bytes` holds. Its shared-item and stringref state is its own: each document is read by a decoder of its own, so a schema check that reads a document inside a document (`encodes:`) leaves the outer one's state as it was.
decodeSequence()  : array<int, mixed>
`$bytes` read as `.dxnb` documents back to back, each with its own envelope -- a CBOR sequence of documents, as a schema's `encodes-seq:` reads one (DXNS.md §2); no bytes at all are no documents.
__construct()  : mixed
atTag()  : bool
Whether the next item is a tag of `$number`, without consuming it.
buildBignum()  : int|DXNInteger
buildBits()  : DXNBits|DXNBytes
T_BITS, `[bytes, count]` (DXN.md §2.3): the count must match the bytes; a whole number of them is bytes.
buildChar()  : DXNChar
buildCustom()  : mixed
buildDate()  : DXNDate
buildDatetime()  : DXNDateTime
buildDecimal()  : DXNDecimal
buildDuration()  : DXNDuration
`$scale` turns the seventh field into nanoseconds: 1 for tag 220, 1000 for 0.2's microseconds (tag 212).
buildFromList()  : mixed
buildIp()  : DXNIp
RFC 9164: an address is its raw bytes; a prefix is its length and the bytes with trailing zero bytes left off, put back here.
buildObjectId()  : DXNObjectId
buildRational()  : DXNRational
buildRegex()  : DXNRegex
The bare pattern for a regex without flags (DXN.md §2.2), or `[pattern, flags]`.
buildStruct()  : mixed
buildTagged()  : mixed
buildTime()  : DXNTime
buildUuid()  : DXNUuid
decodeByMajor()  : mixed
decodeItem()  : mixed
decodeMajor7()  : mixed
decodeMapPairsRaw()  : array<int, array{0: mixed, 1: mixed}>
decodeNItems()  : array<int, mixed>
decodeOrderedPairs()  : array<int, array{0: mixed, 1: mixed}>
decodeShareable()  : mixed
decodeSharedRef()  : mixed
decodeStringref()  : string
decodeStringrefNamespace()  : mixed
decodeStruct()  : mixed
A struct's payload, `[type-name, field..., extras?]`, read item by item so its last item may be its extra fields: a tag-215 map (DXN.md §2.3), legal nowhere else -- anywhere else it is an unrecognized tag. Read in order, so the extras keep the order they were written in.
decodeTag()  : mixed
decodeText()  : string
deepClone()  : mixed
Structural deep clone of a decoded value, used only to resolve a tag-29 shared-value reference into an independent copy. Every `DXN*` class here is `readonly`, so mutation-based aliasing is already structurally impossible -- this still rebuilds compound shapes (the ones with DXN-value-typed fields to recurse into) for full spec compliance and consistency with the JS port's own (mutable-object) behavior; scalar-only-field classes have nothing to alias and are returned as-is.
document()  : array{0: mixed, 1: int}
The document at `$at` in `$bytes`, and the offset just past it.
expectString()  : mixed
integerAsString()  : numeric-string
orderedMap()  : DXNOrderedMap
An ordered map, every key one DXN.md §1.6 allows.
pair()  : array{0: int, 1: int}
A datetime payload, `[epoch, offset-minutes]`, the epoch times `$scale`.
readByte()  : int
readHead()  : array{0: int, 1: numeric-string}
registerStringref()  : void
requireInteger()  : int|DXNInteger
requireSmallInt()  : int
scaled()  : int
An integer payload times `$scale`: 0.2's microseconds as nanoseconds.
smallIndexOrNull()  : int|null
take()  : string
unpackFloat()  : float
unpackUint()  : int

Properties

$sharedItems

private array<int, mixed> $sharedItems = []

indexed by tag-28 registration order.

$stringrefStack

private array<int, array<int, string>> $stringrefStack = []

innermost scope last.

Methods

decode()

The one `.dxnb` document `$bytes` holds. Its shared-item and stringref state is its own: each document is read by a decoder of its own, so a schema check that reads a document inside a document (`encodes:`) leaves the outer one's state as it was.

public static decode(string $bytes[, Registry|null $registry = null ]) : mixed
Parameters
$bytes : string
$registry : Registry|null = null

decodeSequence()

`$bytes` read as `.dxnb` documents back to back, each with its own envelope -- a CBOR sequence of documents, as a schema's `encodes-seq:` reads one (DXNS.md §2); no bytes at all are no documents.

public static decodeSequence(string $bytes[, Registry|null $registry = null ]) : array<int, mixed>
Parameters
$bytes : string
$registry : Registry|null = null
Return values
array<int, mixed>

__construct()

private __construct(string $buf, int $pos, Registry|null $registry) : mixed
Parameters
$buf : string
$pos : int
$registry : Registry|null

atTag()

Whether the next item is a tag of `$number`, without consuming it.

private atTag(int $number) : bool
Parameters
$number : int
Tags
phpstan-impure
Return values
bool

buildBignum()

private buildBignum(mixed $value, int $tag, bool $negative) : int|DXNInteger
Parameters
$value : mixed
$tag : int
$negative : bool
Return values
int|DXNInteger

buildBits()

T_BITS, `[bytes, count]` (DXN.md §2.3): the count must match the bytes; a whole number of them is bytes.

private buildBits(mixed $value) : DXNBits|DXNBytes
Parameters
$value : mixed
Return values
DXNBits|DXNBytes

buildCustom()

private buildCustom(mixed $value) : mixed
Parameters
$value : mixed

buildDatetime()

private buildDatetime(array{0: int, 1: int} $parts, int $tag) : DXNDateTime
Parameters
$parts : array{0: int, 1: int}
$tag : int
Return values
DXNDateTime

buildDuration()

`$scale` turns the seventh field into nanoseconds: 1 for tag 220, 1000 for 0.2's microseconds (tag 212).

private buildDuration(mixed $value, int $tag, int $scale) : DXNDuration
Parameters
$value : mixed
$tag : int
$scale : int
Return values
DXNDuration

buildFromList()

private buildFromList(mixed $value, int $tag, string $name, callable(array<int, mixed>): mixed $build) : mixed
Parameters
$value : mixed
$tag : int
$name : string
$build : callable(array<int, mixed>): mixed

buildIp()

RFC 9164: an address is its raw bytes; a prefix is its length and the bytes with trailing zero bytes left off, put back here.

private buildIp(mixed $value, int $tag, int $size) : DXNIp
Parameters
$value : mixed
$tag : int
$size : int
Return values
DXNIp

buildRegex()

The bare pattern for a regex without flags (DXN.md §2.2), or `[pattern, flags]`.

private buildRegex(mixed $value) : DXNRegex
Parameters
$value : mixed
Return values
DXNRegex

buildStruct()

private buildStruct(array<int, mixed> $items, array<int, array{0: mixed, 1: mixed}> $extra) : mixed
Parameters
$items : array<int, mixed>

the type name, then the fields.

$extra : array<int, array{0: mixed, 1: mixed}>

buildTagged()

private buildTagged(int $tag, mixed $value) : mixed
Parameters
$tag : int
$value : mixed

decodeByMajor()

private decodeByMajor(int $major, numeric-string $arg) : mixed
Parameters
$major : int
$arg : numeric-string

decodeItem()

private decodeItem() : mixed

decodeMajor7()

private decodeMajor7(int $info) : mixed
Parameters
$info : int

decodeMapPairsRaw()

private decodeMapPairsRaw(int $pairCount) : array<int, array{0: mixed, 1: mixed}>
Parameters
$pairCount : int
Return values
array<int, array{0: mixed, 1: mixed}>

decodeNItems()

private decodeNItems(int $count) : array<int, mixed>
Parameters
$count : int
Tags
phpstan-impure
Return values
array<int, mixed>

decodeOrderedPairs()

private decodeOrderedPairs() : array<int, array{0: mixed, 1: mixed}>
Return values
array<int, array{0: mixed, 1: mixed}>

decodeShareable()

private decodeShareable() : mixed

decodeSharedRef()

private decodeSharedRef() : mixed

decodeStringref()

private decodeStringref() : string
Return values
string

decodeStringrefNamespace()

private decodeStringrefNamespace() : mixed

decodeStruct()

A struct's payload, `[type-name, field..., extras?]`, read item by item so its last item may be its extra fields: a tag-215 map (DXN.md §2.3), legal nowhere else -- anywhere else it is an unrecognized tag. Read in order, so the extras keep the order they were written in.

private decodeStruct() : mixed

decodeTag()

private decodeTag(int $tagNumber) : mixed
Parameters
$tagNumber : int

decodeText()

private decodeText(int $len) : string
Parameters
$len : int
Return values
string

deepClone()

Structural deep clone of a decoded value, used only to resolve a tag-29 shared-value reference into an independent copy. Every `DXN*` class here is `readonly`, so mutation-based aliasing is already structurally impossible -- this still rebuilds compound shapes (the ones with DXN-value-typed fields to recurse into) for full spec compliance and consistency with the JS port's own (mutable-object) behavior; scalar-only-field classes have nothing to alias and are returned as-is.

private static deepClone(mixed $value) : mixed
Parameters
$value : mixed

document()

The document at `$at` in `$bytes`, and the offset just past it.

private static document(string $bytes, int $at, Registry|null $registry) : array{0: mixed, 1: int}
Parameters
$bytes : string
$at : int
$registry : Registry|null
Return values
array{0: mixed, 1: int}

expectString()

private expectString(mixed $value, int $tag, string $name, callable(string): mixed $build) : mixed
Parameters
$value : mixed
$tag : int
$name : string
$build : callable(string): mixed

integerAsString()

private integerAsString(int|DXNInteger $value) : numeric-string
Parameters
$value : int|DXNInteger
Return values
numeric-string

orderedMap()

An ordered map, every key one DXN.md §1.6 allows.

private static orderedMap(array<int, array{0: mixed, 1: mixed}> $pairs) : DXNOrderedMap
Parameters
$pairs : array<int, array{0: mixed, 1: mixed}>
Return values
DXNOrderedMap

pair()

A datetime payload, `[epoch, offset-minutes]`, the epoch times `$scale`.

private pair(mixed $value, int $tag, int $scale) : array{0: int, 1: int}
Parameters
$value : mixed
$tag : int
$scale : int
Return values
array{0: int, 1: int}

readByte()

private readByte() : int
Return values
int

readHead()

private readHead() : array{0: int, 1: numeric-string}
Tags
phpstan-impure
Return values
array{0: int, 1: numeric-string}

registerStringref()

private registerStringref(string $text) : void
Parameters
$text : string

requireInteger()

private requireInteger(mixed $value, int $tag, string $name) : int|DXNInteger
Parameters
$value : mixed
$tag : int
$name : string
Return values
int|DXNInteger

requireSmallInt()

private requireSmallInt(mixed $value, int $tag, string $name) : int
Parameters
$value : mixed
$tag : int
$name : string
Return values
int

scaled()

An integer payload times `$scale`: 0.2's microseconds as nanoseconds.

private scaled(mixed $value, int $tag, string $name, int $scale) : int
Parameters
$value : mixed
$tag : int
$name : string
$scale : int
Return values
int

smallIndexOrNull()

private smallIndexOrNull(mixed $value) : int|null
Parameters
$value : mixed
Return values
int|null

take()

private take(int $len) : string
Parameters
$len : int
Return values
string

unpackFloat()

private static unpackFloat(string $bytes, string $format) : float
Parameters
$bytes : string
$format : string
Return values
float

unpackUint()

private static unpackUint(string $bytes, string $format) : int
Parameters
$bytes : string
$format : string
Return values
int
On this page

Search results