BytesImmutable binary data — a contiguous run of raw octets. Text crosses the boundary explicitly: '…'.asBytes encodes, asString decodes (UTF-8). Build from integers with Bytes.of:, slice with from:to:, concatenate with +. An opaque blob (an image, a gzip stream) belongs here; a typed numeric column belongs in Array.
Encoding conveniences: any Bytes can render itself as base64 or hex text.
The in-memory half of the random-access protocol: with this (plus the native size it already has), Bytes answers the same two messages as RandomAccessFile — clamped at the end, the same contract — so the zip reader works over a file on disk and a downloaded buffer alike.
A zero-length Bytes.
Bytes.empty "* -> Bytes[0]
A zero-length Bytes — the same as Bytes.empty.
Bytes from a list of integers, each 0..=255; anything else raises a catchable error.
Bytes.of:#(72 105) "* -> Bytes[2] 48 69
Concatenation (a + b): a new Bytes of the receiver's bytes followed by the argument's. Bytes + Bytes only — there is no implicit text coercion.
(Bytes.of:#(1 2)) + (Bytes.of:#(3)) "* -> Bytes[3] 01 02 03
The bytes decoded as UTF-8 text; invalid UTF-8 raises a catchable ParseError saying how far the valid prefix ran. To decode anything, use asStringLossy.
(Bytes.of:#(72 105)).asString "* -> Hi
The bytes decoded as UTF-8 with every invalid sequence replaced by U+FFFD — never throws.
The byte — an Integer 0..=255 — at a zero-based index; out of range raises a catchable IndexError.
(Bytes.of:#(10 20 30)).at:1 "* -> 20
The number of bytes — an alias of size.
The CRC-32 (IEEE) checksum of these bytes, as a non-negative Integer — the per-entry integrity stamp of the zip format.
'hi'.asBytes.crc32 "* -> 3633523372
Decompress a raw deflate stream into a new Bytes; malformed input raises a catchable ParseError.
'hello'.asBytes.encodeDeflate.decodeDeflate.asString "* -> hello
Decompress a gzip stream into a new Bytes; malformed input raises a catchable ParseError. Large inputs run on the compute pool, so other tasks keep the scheduler while they grind.
'hello'.asBytes.encodeGz.decodeGz.asString "* -> hello
Decompress a zstandard stream into a new Bytes; malformed input raises a catchable ParseError. Decode only — there is no encodeZstd; gzip and deflate cover the encode side.
Call a block once per byte (an Integer 0..=255), first to last; answers the receiver.
Compress into ZLIB-WRAPPED deflate (a new Bytes) — the RFC-correct form of HTTP's Content-Encoding: deflate. For the raw RFC 1951 stream (what zip entries carry), use encodeDeflateRaw; decodeDeflate reads both back.
Compress into a RAW deflate stream (RFC 1951 — no zlib header or trailer): gzip's body format, and what zip entries carry. decodeDeflate reads it back.
Compress into a gzip stream (a new Bytes). Large inputs run on the compute pool, so other tasks keep the scheduler while they grind.
A new Bytes over the half-open range [from, to) — the end index is excluded — with both bounds clamped to the buffer, so out-of-range indexes never throw.
(Bytes.of:#(1 2 3 4 5)).from:1 to:4 "* -> Bytes[3] 02 03 04
These bytes XORed with key, cycled — WebSocket's frame masking. Its own inverse: masking twice with the same key answers the original. An empty key throws a ValueError.
('hi'.asBytes.maskWith:(Bytes.of:#( 7 ))).maskWith:(Bytes.of:#( 7 )) "* -> Bytes[2] 68 69
Up to count bytes from byte offset; short only at the end.
The inspect string: the byte count and a short hex preview.
(Bytes.of:#(1 2 3)).s "* -> Bytes[3] 01 02 03
The number of bytes.
(Bytes.of:#(1 2 3)).size "* -> 3
This Bytes encoded as a base64 String.
'hi'.asBytes.toBase64 "* -> aGk=
This Bytes encoded as a lowercase hex String, two digits per byte.
'hi'.asBytes.toHex "* -> 6869