OptionalhiThe high halves; see lo.
OptionalloOptionallongsDestination taking each element as a Long — no bigint is
materialised at all, which is most of why this is a quarter cheaper than the
per-element path for a 64-bit array (see ArrayTarget). A real
Array, cut to length at the array's end, exactly like values.
High half of the largest element the schema allows.
Low half of the largest element the schema allows.
High half of the smallest element the schema allows.
Low half of the smallest element the schema allows.
OptionaltypedExact-width destination: one typed array whose element width IS the schema's
declared width — a Uint16Array for a u16 array, an Int8Array for an
i8 one. Must hold at least count elements.
The bound is still compared, and that is not negotiable. A typed array
masks on store (a[0] = 70000 in a Uint16Array is 4464), and
MESSAGE_SPEC §7.1 makes an element outside the declared width INVALID —
neither masked to the width nor kept. So this destination buys the storage,
never the verdict: the fill loop compares exactly as values does and
refuses the same elements.
What it does buy is the store (unboxed, and no element-kind transition the
way a number[] takes when a value leaves the small-integer range), the
memory (2 bytes for a u16, against a tagged slot), and the encoder's
side, where the width is then statically known.
The bound must fit the array's own width: a destination narrower than the interval could not represent every legal element, and is refused with SofabErrorCode.Argument rather than silently masking.
OptionalvaluesNumber-first destination: each element as the value its per-element
callback would have received — a number when it fits exactly (≤ 2^53-1,
every u8..u32 and small 64-bit values) and a bigint beyond that. The
right destination for u8..u32 / i8..i32 arrays, where no bigint is
ever built.
A real Array — grown as it fills and cut to length when the array ends, so
it need not be pre-sized and never carries a previous array's tail. A typed
array here is refused with SofabErrorCode.Argument: it would take the
writes and silently drop everything past its own length.
An integer array's destination and the element bound to enforce while filling it — for an
ArrayKind.UnsignedorArrayKind.Signedarray.Exactly one destination must be set (
values,longs, orloandhi); any other combination is a caller mistake and is refused with SofabErrorCode.Argument before a single element is written.The bound is four halves, and it is never optional. The interval is the schema's —
0..65535for au16,-2^63..2^63-1for ani64— so its violation isINVALID, a statement about the message (§6.2.1 keeps a receiver cap off a field the schema already bounds; a receiver cap on the element count is compared by the visitor inarrayBegin, as before, and this hand-off happens after it).Halves rather than a
numberpair because anumbercannot express the 64-bit domain:u64's bound is2^64-1andNumber.MAX_SAFE_INTEGERis2^53-1, so anumberbound both rejects valid messages at the top of the range and makes the comparison a mixedbigint/numberone, which measured +35% onarray<u64>— worse than the per-element path it replaces. Two unsigned 32-bit comparisons are exact and cost nothing.For a signed array the halves are the two's-complement ones (an
i16minimum of-32768isminLo = 0xffff8000,minHi = 0xffffffff). Long.fromBigInt is the ready-made way to compute them from the schema's bound once.The codec compares the bound; it never owns one (§6.2.1). There is no default and no "unbounded" spelling, because an integer element always has a declared width: the widest
u64interval is0 .. 0xffffffff_ffffffffand is stated as such.