Module
СсылкаBytes stores immutable octets. ByteBuffer is a mutable value with a fixed length. Indexing counts bytes and text conversion uses an explicit encoding.
Why
СсылкаBinary data needs exact byte values, explicit text encodings, and a mutable buffer for incremental work.
Availability
СсылкаImport std.bytes in language mode 5.21. The current compiler selects std/bytes.tpz for this language mode. Availability in other released editions and inclusion in each installed distribution are Pending.
Exported types
Ссылкаexport type Bytes = Bytes
export type Byte
Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.
Public API
СсылкаPending contracts
СсылкаRead collection sizes, keys, and values as properties
СсылкаRead collection sizes, keys, and values as properties
Bytes.length and ByteBuffer.length are read-only int properties that report the number of bytes.
JSONValue.length is an Option<int> property. Arrays and objects return Some(count) for their element or member count. Other JSON kinds return None().
JSONValue.keys and JSONValue.values are properties returning Option<Array<string>> and Option<Array<JSON. Objects return Some(keys) or Some(values). Other JSON kinds return None().
Read these properties without parentheses, as with Array.length, Map.length, Map.keys, Map.values, and Set.length. Calling a property value is rejected as a non-callable value.
Причина
The same collection observation should use the same syntax across core collections and library values. Keeping JSONValue results optional preserves its distinction between collections and scalar values.
Read the same properties on core collections
Ссылкаimport std.iolet array = [2, 3]let entries = map { "name": "Topaz" }let values = set { 2, 3 }io.writeLine("{array.length}:{entries.length}:{values.length}")io.writeLine(entries.keys[0])io.writeLine(entries.values[0])
2:1:2
name
Topaz
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
2:1:2nameTopaz
Read a byte sequence size
Ссылкаimport std.bytes { Bytes }import std.iolet bytes = Bytes.empty()let size: int = bytes.lengthio.writeLine("{size}")
0
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
0
Read a byte buffer size
Ссылкаimport std.bytes { ByteBuffer }import std.iolet buffer = ByteBuffer.allocate(3)let size: int = buffer.lengthio.writeLine("{size}")
3
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
3
Read JSON sizes and preserve optional results
Ссылкаimport std.jsonimport std.testimport std.iolet array = test.assertOk(json.parse("[1,2]"))let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))let scalar = test.assertOk(json.parse("42"))let arraySize: Option<int> = array.lengthlet objectSize: Option<int> = object.lengthlet scalarSize: Option<int> = scalar.lengthtest.assertEq(test.assertSome(arraySize), 2)test.assertEq(test.assertSome(objectSize), 1)test.assertNone(scalarSize)io.writeLine("JSON sizes read")
JSON sizes read
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
JSON sizes read
Read JSON object keys
Ссылкаimport std.jsonimport std.testimport std.iolet object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))let array = test.assertOk(json.parse("[]"))let scalar = test.assertOk(json.parse("42"))let names: Option<Array<string>> = object.keystest.assertEq(test.assertSome(names)[0], "name")test.assertNone(array.keys)test.assertNone(scalar.keys)io.writeLine("JSON keys read")
JSON keys read
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
JSON keys read
Read JSON object values
Ссылкаimport std.jsonimport std.testimport std.iolet object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))let array = test.assertOk(json.parse("[]"))let scalar = test.assertOk(json.parse("42"))let values = test.assertSome(object.values)test.assertEq(test.assertSome(values[0].asString()), "Topaz")test.assertNone(array.values)test.assertNone(scalar.values)io.writeLine("JSON values read")
JSON values read
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
JSON values read
Reject calling Bytes.length
Ссылкаimport std.bytes { Bytes }function inspect(value: Bytes) -> () {let result = value.length()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-property-not-callable at
main.tpz:3:22
Reject calling ByteBuffer.length
Ссылкаimport std.bytes { ByteBuffer }function inspect(value: ByteBuffer) -> () {let result = value.length()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-property-not-callable at
main.tpz:3:22
Reject calling JSONValue.length
Ссылкаimport std.json { JSONValue }function inspect(value: JSONValue) -> () {let result = value.length()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-property-not-callable at
main.tpz:3:22
Reject calling JSONValue.keys
Ссылкаimport std.json { JSONValue }function inspect(value: JSONValue) -> () {let result = value.keys()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-property-not-callable at
main.tpz:3:22
Reject calling JSONValue.values
Ссылкаimport std.json { JSONValue }function inspect(value: JSONValue) -> () {let result = value.values()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-property-not-callable at
main.tpz:3:22
Diagnostics
СсылкаTest collection emptiness with length
СсылкаTest collection emptiness with length
Test whether a Bytes, Map, or Set value is empty by comparing its length property with zero. The comparison is true exactly when the collection has no bytes, entries, or elements.
Bytes, Map, and Set do not expose an isEmpty member. Read the length property and use the ordinary equality operator.
Причина
A collection already exposes its count through length. Comparing that value with zero expresses emptiness for every collection without another query name or a type-specific method.
Test empty and nonempty maps with length
Ссылкаimport std.iolet empty: Map<string, int> = map {}let filled = map { "one": 1 }io.writeLine("{empty.length == 0}:{filled.length == 0}")
true:false
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
true:false
Test empty and nonempty sets with length
Ссылкаimport std.iolet empty: Set<int> = set {}let filled = set { 1 }io.writeLine("{empty.length == 0}:{filled.length == 0}")
true:false
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
true:false
Test empty and nonempty byte sequences with length
Ссылкаimport std.bytes { Bytes }import std.testimport std.iolet empty = Bytes.empty()let filled = test.assertOk(Bytes.fromArray([1]))io.writeLine("{empty.length == 0}:{filled.length == 0}")
true:false
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
true:false
Reject Bytes.isEmpty
Ссылкаimport std.bytes { Bytes }function inspect(value: Bytes) -> () {let result = value.isEmpty()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-removed-member at
main.tpz:3:22
Reject Map.isEmpty
Ссылкаfunction inspect(value: Map<string, int>) -> () {let result = value.isEmpty()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-removed-member at
main.tpz:2:22
Reject Set.isEmpty
Ссылкаfunction inspect(value: Set<int>) -> () {let result = value.isEmpty()return ()}
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения check. Ненулевой код завершения.
stdlib-removed-member at
main.tpz:2:22
Diagnostics
СсылкаConstruct and inspect immutable byte sequences
СсылкаConstruct and inspect immutable byte sequences
A Bytes value is an immutable ordered sequence of octets. Each octet is an int from 0 through 255.
Bytes.empty returns the empty sequence. Bytes.fromArray accepts an Array<int> and returns an independent snapshot in Ok.
Bytes.fromArray returns Err with a string identifying the first element outside 0 through 255. It does not wrap, clamp, or return a partial sequence.
Bytes.toArray returns a new Array<int> in byte order. Mutating that array or the original input array does not change an existing Bytes value.
Bytes.concat returns the receiver bytes followed by the argument bytes. Either input may be empty and both inputs retain their contents.
Bytes.get uses a zero-based byte index. It returns Some(byte) within the sequence and None() for every negative or past-end index.
Bytes.length is the number of bytes and is read as a property. Compare it with zero to test emptiness.
Receivers and supplied arguments evaluate once from left to right before the operation begins. These operations perform no I/O or text normalization.
A correctly typed lookup or concatenation has no data-dependent Result failure. Allocation exhaustion is an operational failure and is not a decoded data error.
Причина
Exact octets keep binary payloads independent of text encoding. Snapshot conversion prevents later array edits from silently changing a payload.
Preserve empty values and byte order
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet empty = test.assertOk(Bytes.fromArray([]))let value = test.assertOk(Bytes.fromArray([0, 128, 255]))io.writeLine(Bytes.empty().toHex())io.writeLine(empty.concat(value).toHex())io.writeLine(value.concat(test.assertOk(Bytes.fromArray([1]))).toHex())
0080ff
0080ff01
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
0080ff0080ff01
Reject out-of-range array elements
Ссылкаimport std.bytes { Bytes }import std.iofor values in ([[0, -1, 255], [0, 256, 255]]) {match (Bytes.fromArray(values)) {case Err(_) => io.writeLine("invalid byte")case Ok(_) => io.writeLine("accepted")}}
invalid byte
invalid byte
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid byteinvalid byte
Read optional bytes at both boundaries
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet value = test.assertOk(Bytes.fromArray([0, 128, 255]))for index in ([-1, 0, 2, 3]) {match (value.get(index)) {case Some(byte) => io.writeLine("{byte}")case None() => io.writeLine("absent")}}
absent
0
255
absent
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
absent0255absent
Keep array edits independent from bytes
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet mut input = [0, 255]let value = test.assertOk(Bytes.fromArray(input))let mut output = value.toArray()input[0] = 7output[1] = 8io.writeLine(value.toHex())io.writeLine("{input[0]},{output[1]}")
00ff
7,8
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
00ff7,8
Evaluate the receiver before its argument
Ссылкаimport std.bytes { Bytes }import std.iofunction receiver() -> Bytes {io.writeLine("receiver")return "a".encodeUtf8()}function argument() -> Bytes {io.writeLine("argument")return "b".encodeUtf8()}io.writeLine(receiver().concat(argument()).toHex())
receiver
argument
6162
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
receiverargument6162
Select explicit byte intervals
СсылкаSelect explicit byte intervals
Bytes.slice uses a start position and an exclusive end position measured in bytes.
Valid bounds satisfy 0 <= start <= end <= length. The result contains exactly the bytes from start through end minus one.
Equal endpoints produce empty Bytes, including endpoints at zero and at length. A full interval preserves every byte.
Negative bounds, inverted bounds, and endpoints beyond length produce TPZ4001 at runtime. Bounds are not clamped or interpreted from the end.
Slicing never changes the receiver. The receiver, start, and end expressions evaluate once in that order before the bounds are checked.
A byte interval may split a UTF-8 encoding. Bytes.slice preserves those selected octets and Bytes.decodeUtf8 reports invalid text when they form an incomplete sequence.
Причина
An explicit interval should identify exactly the requested payload. Rejecting an invalid interval makes a mistaken byte count visible before subsequent decoding.
Select empty and nonempty intervals
Ссылкаimport std.iolet value = "abcd".encodeUtf8()io.writeLine(value.slice(0, 0).toHex())io.writeLine(value.slice(1, 3).toHex())io.writeLine(value.slice(4, 4).toHex())io.writeLine(value.toHex())
6263
61626364
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
626361626364
Keep byte slicing separate from UTF-8 validation
Ссылкаimport std.iolet byte = "é".encodeUtf8().slice(0, 1)io.writeLine(byte.toHex())match (byte.decodeUtf8()) {case Err(_) => io.writeLine("invalid UTF-8")case Ok(_) => io.writeLine("accepted")}
c3
invalid UTF-8
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
c3invalid UTF-8
Reject a negative slice start
Ссылкаimport std.bytes { Bytes }let value = "abcd".encodeUtf8()value.slice(-1, 2)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
bytes-slice-bounds at
main.tpz:3:1
Reject an inverted byte interval
Ссылкаimport std.bytes { Bytes }let value = "abcd".encodeUtf8()value.slice(3, 2)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
bytes-slice-bounds at
main.tpz:3:1
Reject an endpoint beyond the sequence
Ссылкаimport std.bytes { Bytes }let value = "abcd".encodeUtf8()value.slice(0, 5)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
bytes-slice-bounds at
main.tpz:3:1
Diagnostics
СсылкаUse a canonical hexadecimal spelling
СсылкаUse a canonical hexadecimal spelling
Bytes.toHex emits two lowercase ASCII hexadecimal digits per byte with the high nibble first. Empty Bytes produces an empty string.
Bytes.fromHex accepts an even number of digits drawn from 0 through 9 and a through f. Empty text returns Ok with empty Bytes.
Uppercase letters, prefixes, separators, whitespace, non-ASCII characters, and an odd digit count return Err with a string describing invalid hex input.
Decoding returns the entire byte sequence in Ok or an error with no decoded prefix. It never mutates an input value.
Encoding then decoding recovers the bytes exactly. Decoding then encoding preserves every accepted input spelling.
The input expression evaluates once. These conversions perform no I/O and do not apply Unicode normalization.
Причина
One accepted hexadecimal spelling makes serialized byte text stable for comparison and reproduction. Data that uses another spelling can be normalized explicitly before decoding.
Decode byte pairs and emit lowercase text
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testio.writeLine(test.assertOk(Bytes.fromHex("")).toHex())io.writeLine(test.assertOk(Bytes.fromHex("000f80ff")).toHex())
000f80ff
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
000f80ff
Reject malformed hexadecimal strings
Ссылкаimport std.bytes { Bytes }import std.iofor text in (["0", "gg", "0x00", "00 11", "00"]) {match (Bytes.fromHex(text)) {case Err(_) => io.writeLine("invalid hex")case Ok(_) => io.writeLine("accepted")}}
invalid hex
invalid hex
invalid hex
invalid hex
invalid hex
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid hexinvalid hexinvalid hexinvalid hexinvalid hex
Reject uppercase hexadecimal input
Ссылкаimport std.bytes { Bytes }import std.iomatch (Bytes.fromHex("CAfe")) {case Err(_) => io.writeLine("uppercase rejected")case Ok(_) => io.writeLine("accepted")}
uppercase rejected
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
uppercase rejected
Encode and validate padded Base64
СсылкаEncode and validate padded Base64
Bytes.toBase64 uses the RFC 4648 standard alphabet with plus and slash. Its output has no whitespace or line wrapping.
A final group containing one byte ends with two equals signs. A final group containing two bytes ends with one equals sign.
Bytes.fromBase64 accepts complete groups of four characters. Padding appears at the end of the final group and all unused bits are zero.
Missing or misplaced padding, nonzero unused bits, whitespace, non-ASCII characters, minus signs, and underscores return Err with a string.
Empty bytes encode as empty text and empty text decodes to Ok with empty Bytes. Invalid text never returns a partial byte sequence.
The input is evaluated once and is unchanged. Encoding then decoding recovers the input bytes exactly without any external effects.
Причина
A precise alphabet and padding rule let independent implementations exchange the same bytes. Rejecting nonzero unused bits prevents several texts from representing one accepted encoding.
Use standard Base64 vectors
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor text in (["", "f", "fo", "foo"]) {io.writeLine(text.encodeUtf8().toBase64())}for text in (["", "Zg==", "Zm8=", "Zm9v"]) {io.writeLine(test.assertOk(Bytes.fromBase64(text)).toHex())}
Zg==
Zm8=
Zm9v
66
666f
666f6f
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
Zg==Zm8=Zm9v66666f666f6f
Reject padding and alphabet errors
Ссылкаimport std.bytes { Bytes }import std.iofor text in (["Zg", "Zh==", "Zg== ", "_w==", "Zg==Zg==", "=g=="]) {match (Bytes.fromBase64(text)) {case Err(_) => io.writeLine("invalid Base64")case Ok(_) => io.writeLine("accepted")}}
invalid Base64
invalid Base64
invalid Base64
invalid Base64
invalid Base64
invalid Base64
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid Base64invalid Base64invalid Base64invalid Base64invalid Base64invalid Base64
Decode UTF-8 without replacing data
СсылкаDecode UTF-8 without replacing data
Bytes.decodeUtf8 returns Ok with the exact Unicode scalar sequence encoded by valid UTF-8 bytes.
Empty Bytes returns Ok with an empty string. A leading UTF-8 encoding of U+FEFF remains in the returned string.
Overlong encodings, isolated continuation bytes, incomplete sequences, surrogate encodings, and values above U+10FFFF return Err with a string.
Decoding does not insert replacement characters, normalize scalars, alter newline sequences, or discard a byte order mark.
For a string, encodeUtf8 followed by decodeUtf8 returns the original string. Re-encoding any successfully decoded sequence recovers its original bytes.
The receiver evaluates once and remains unchanged. No text is exposed before the entire sequence has passed validation.
Причина
Lossless decoding keeps malformed input visible and preserves distinctions needed by file formats, checksums, and text layout.
Retain a byte order mark and combining sequence
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor hex in (["", "efbbbf", "65cc81", "0d0a", "f09f9880"]) {let decoded = test.assertOk(test.assertOk(Bytes.fromHex(hex)).decodeUtf8())io.writeLine(decoded.encodeUtf8().toHex())}
efbbbf
65cc81
0d0a
f09f9880
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
efbbbf65cc810d0af09f9880
Reject malformed UTF-8 categories
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor hex in (["80", "c080", "e282", "eda080", "f4908080"]) {match (test.assertOk(Bytes.fromHex(hex)).decodeUtf8()) {case Err(_) => io.writeLine("invalid UTF-8")case Ok(_) => io.writeLine("accepted")}}
invalid UTF-8
invalid UTF-8
invalid UTF-8
invalid UTF-8
invalid UTF-8
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid UTF-8invalid UTF-8invalid UTF-8invalid UTF-8invalid UTF-8
Allocate buffers and convert byte values
СсылкаAllocate buffers and convert byte values
ByteBuffer.allocate accepts a nonnegative int length and an int initial value from 0 through 255. The initial value defaults to zero.
The new buffer has exactly that many copies of the initial byte. Zero length is valid and still requires a valid initial byte.
A negative length produces TPZ4001 at runtime. An invalid initial byte or an allocation that cannot be satisfied produces TPZ5001 at runtime.
ByteBuffer.fromBytes converts an immutable Bytes value into a mutable ByteBuffer value containing the same bytes.
ByteBuffer.toBytes converts the current buffer contents into an immutable Bytes value.
ByteBuffer.length is a read-only byte count property. Buffer operations never change its length.
Assignment, argument passing, return, capture, and aggregate storage follow collection value semantics.
Supplied expressions evaluate once from left to right before allocation or conversion. These operations have no I/O effects.
Причина
A fixed length gives binary algorithms stable byte positions. Explicit conversion distinguishes mutable construction from immutable byte data.
Allocate zero-filled and initialized buffers
Ссылкаimport std.bytes { ByteBuffer }import std.ioio.writeLine(ByteBuffer.allocate(0).toBytes().toHex())io.writeLine(ByteBuffer.allocate(3).toBytes().toHex())io.writeLine(ByteBuffer.allocate(2, 255).toBytes().toHex())
000000
ffff
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
000000ffff
Keep the original buffer and converted bytes unchanged
Ссылкаimport std.bytes { ByteBuffer }import std.iolet source = "ab".encodeUtf8()let buffer = ByteBuffer.fromBytes(source)let independent = ByteBuffer.fromBytes(source)let before = buffer.toBytes()let mut alias = bufferalias.set(0, 99)io.writeLine(source.toHex())io.writeLine(before.toHex())io.writeLine(independent.toBytes().toHex())io.writeLine(buffer.toBytes().toHex())
6162
6162
6162
6162
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
6162616261626162
Reject a negative buffer length
Ссылкаimport std.bytes { ByteBuffer }ByteBuffer.allocate(-1)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-negative-bound at
main.tpz:2:1
Validate the initial byte of an empty buffer
Ссылкаimport std.bytes { ByteBuffer }import std.ioByteBuffer.allocate(0, -1)io.writeLine("after")
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-byte-value at
main.tpz:3:1
Validate the initial byte of an empty buffer
Ссылкаimport std.bytes { ByteBuffer }import std.ioByteBuffer.allocate(0, 256)io.writeLine("after")
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-byte-value at
main.tpz:3:1
Diagnostics
СсылкаValidate buffer regions before writing
СсылкаValidate buffer regions before writing
ByteBuffer.get and ByteBuffer.set use zero-based byte indices from zero through length minus one. Get returns an int byte.
ByteBuffer.set replaces one byte. ByteBuffer.fill replaces length bytes beginning at start. Both require values from 0 through 255.
ByteBuffer.copy receives the source buffer, sourceStart, targetStart, and length in that order. The receiver is the destination.
Fill and copy use byte intervals from each start to start plus length. Starts and lengths must be nonnegative. Every complete source and destination interval must fit its buffer without arithmetic overflow.
A zero length region at the end of a buffer is valid. A start beyond the end is invalid even when length is zero.
Copy observes the source interval before its first destination write. Copying within one buffer therefore supports overlap in either direction.
Set, fill, and copy return unit. They require a let mut root binding and update its destination value under collection value semantics.
The receiver and supplied arguments evaluate once from left to right. Every range and byte check finishes before the first write.
An invalid index or region produces TPZ4001 at runtime. An invalid byte value produces TPZ5001 at runtime, including a fill of zero bytes.
A rejected operation performs no buffer writes. Effects performed while evaluating its receiver or arguments remain visible.
When several preconditions fail, the selected failing precondition is unspecified. The operation still completes every argument evaluation before validation and performs no writes.
Причина
Checking complete regions prevents a malformed count from leaving half-written data. Reading the source interval before writing gives one result for every overlap direction.
Copy overlapping regions and preserve an earlier buffer value
Ссылкаimport std.bytes { Bytes, ByteBuffer }import std.ioimport std.testlet mut buffer = ByteBuffer.fromBytes(test.assertOk(Bytes.fromHex("000102030405")))let alias = bufferbuffer.copy(buffer, 0, 1, 5)io.writeLine(buffer.toBytes().toHex())buffer.fill(2, 2, 255)buffer.set(0, 128)io.writeLine(buffer.toBytes().toHex())buffer.copy(buffer, 1, 0, 5)buffer.fill(6, 0, 0)buffer.copy(buffer, 6, 6, 0)io.writeLine(buffer.toBytes().toHex())io.writeLine(alias.toBytes().toHex())io.writeLine("{alias.get(0)}")
000001020304
8000ffff0304
00ffff030404
000102030405
0
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
0000010203048000ffff030400ffff0304040001020304050
Keep an independent source buffer unchanged
Ссылкаimport std.bytes { ByteBuffer }import std.iolet source = ByteBuffer.fromBytes("abc".encodeUtf8())let mut target = ByteBuffer.allocate(4, 0)target.copy(source, 1, 1, 2)io.writeLine(target.toBytes().toHex())io.writeLine(source.toBytes().toHex())
00626300
616263
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
00626300616263
Reject a read at the exclusive end
Ссылкаimport std.bytes { ByteBuffer }let buffer = ByteBuffer.allocate(2)buffer.get(2)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-index-bounds at
main.tpz:3:1
Reject a negative write index
Ссылкаimport std.bytes { ByteBuffer }let mut buffer = ByteBuffer.allocate(2)buffer.set(-1, 0)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-negative-bound at
main.tpz:3:1
Reject a fill whose complete region does not fit
Ссылкаimport std.bytes { ByteBuffer }let mut buffer = ByteBuffer.allocate(2)buffer.fill(1, 2, 0)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-region-bounds at
main.tpz:3:1
Reject an empty copy beyond the buffer end
Ссылкаimport std.bytes { ByteBuffer }let mut buffer = ByteBuffer.allocate(2)buffer.copy(buffer, 3, 2, 0)
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-region-bounds at
main.tpz:3:1
Reject an invalid byte at a valid write index
Ссылкаimport std.bytes { ByteBuffer }import std.iolet mut buffer = ByteBuffer.allocate(1)buffer.set(0, -1)io.writeLine("after")
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-byte-value at
main.tpz:4:1
Validate the byte for a fill of zero bytes
Ссылкаimport std.bytes { ByteBuffer }import std.iolet mut buffer = ByteBuffer.allocate(1)buffer.fill(1, 0, 256)io.writeLine("after")
Нет стандартного вывода.Ожидаемый результат
Ожидаемый результат
Этап отклонения run. Ненулевой код завершения.
byte-buffer-byte-value at
main.tpz:4:1
Compute interoperable checksums and digests
СсылкаCompute interoperable checksums and digests
Bytes.crc32 returns the unsigned CRC-32/ISO-HDLC value as an int from 0 through 4294967295.
CRC-32 uses width 32, polynomial 0x04c11db7, reflected input and output, initial value 0xffffffff, and final XOR 0xffffffff.
Bytes.sha256 and Bytes.sha512 implement FIPS 180-4 and return 32 and 64 digest bytes respectively.
Bytes.hmacSha256 uses its receiver as the key and its argument as the message. It returns the 32-byte HMAC-SHA-256 value from RFC 2104.
HMAC hashes a key longer than the 64-byte SHA-256 block before zero-padding it. Empty keys and messages are valid.
Empty input is valid for every checksum and digest. CRC-32 of empty input is zero.
These operations process stored bytes without decoding or normalization. Inputs remain unchanged and correctly typed calls have no data-dependent failure.
The receiver and any message argument evaluate once in that order. No external state, random input, or I/O affects the result.
Use toHex or toBase64 on a digest when a text encoding is required. Those encodings are separate from the digest bytes.
Причина
Named standard algorithms must agree with independent implementations. Keeping digest bytes separate from their text representation makes the same digest usable in binary and text formats.
Match established checksum and hash vectors
Ссылкаimport std.bytes { Bytes }import std.ioio.writeLine("{Bytes.empty().crc32()}")let checksum = "123456789".encodeUtf8().crc32()io.writeLine("{checksum}")io.writeLine("abc".encodeUtf8().sha256().toHex())io.writeLine("abc".encodeUtf8().sha512().toHex())io.writeLine("key".encodeUtf8().hmacSha256("The quick brown fox jumps over the lazy dog".encodeUtf8()).toHex())
0
3421780262
ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
03421780262ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015adddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49ff7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
Distinguish raw DEFLATE from zlib framing
СсылкаDistinguish raw DEFLATE from zlib framing
Bytes.deflateCompress returns Ok with one complete raw RFC 1951 DEFLATE stream. It adds no zlib or gzip header or checksum.
Bytes.deflateFixedCompress returns Ok with one final fixed Huffman block. Empty input is valid and the final unused bits are zero.
Fixed Huffman compression accepts at most 268435456 input bytes. Larger inputs return Err with a string before producing output.
Bytes.zlibFixedCompress applies the same fixed Huffman compression and input bound, with an RFC 1950 zlib header and Adler-32 trailer.
The zlib stream declares a 32768-byte window and no preset dictionary. Its header bytes are 0x78 and 0x01.
Bytes.deflateDecompress accepts raw streams containing stored, fixed Huffman, and dynamic Huffman blocks. It reconstructs the original bytes in Ok.
The decoder consumes one complete stream. Malformed or truncated blocks, invalid back-references, and complete trailing bytes return Err with a string.
Final unused padding bits are not decoded as data. A zlib or gzip wrapper is not a raw DEFLATE stream.
Bytes.deflateDecompress reverses either raw compressor for every supported input. Bytes.zlibFixedCompress requires a zlib decoder because its wrapper is part of the result.
Each receiver evaluates once and remains unchanged. The operations perform no I/O and errors expose no partially decoded Bytes.
Compression does not promise a particular size reduction. Except for the fixed block and wrapper requirements, encoded byte choices may change while preserving the stream format.
Причина
Raw DEFLATE and zlib are different wire formats. The fixed Huffman operation additionally specifies block coding, so it serves a distinct format requirement rather than another name for a general compressor.
Recover bytes from a raw stream
Ссылкаimport std.ioimport std.testlet encoded = test.assertOk("hello".encodeUtf8().deflateCompress())io.writeLine(test.assertOk(encoded.deflateDecompress()).toHex())io.writeLine(test.assertOk("".encodeUtf8().deflateFixedCompress()).toHex())io.writeLine(test.assertOk("".encodeUtf8().zlibFixedCompress()).toHex())
68656c6c6f
0300
7801030000000001
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f03007801030000000001
Decode a valid fixed Huffman stream
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("cb48cdc9c90700"))match (encoded.deflateDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
68656c6c6f
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f
Decode short nonfinal stored blocks
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("000100feff41010100feff42"))match (encoded.deflateDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
4142
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
4142
Ignore stored block alignment bits
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("f90100feff41"))match (encoded.deflateDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
41
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
41
Reject truncated streams and trailing bytes
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor hex in (["", "010100feff", "010000ffff00", "070000"]) {match (test.assertOk(Bytes.fromHex(hex)).deflateDecompress()) {case Err(_) => io.writeLine("invalid DEFLATE")case Ok(_) => io.writeLine("accepted")}}
invalid DEFLATE
invalid DEFLATE
invalid DEFLATE
invalid DEFLATE
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid DEFLATEinvalid DEFLATEinvalid DEFLATEinvalid DEFLATE
Read and write complete gzip members
СсылкаRead and write complete gzip members
Bytes.gzipCompress returns Ok with one RFC 1952 gzip member containing the receiver bytes. Empty input is valid.
The compressor does not read a clock or derive a filename from its environment. The header timestamp is zero and optional name and comment fields are absent.
Bytes.gzipDecompress accepts one member with compression method DEFLATE, including valid timestamp, operating system, extra field, name, comment, and header CRC fields.
The decoder accepts stored, fixed Huffman, and dynamic Huffman DEFLATE blocks. It validates the member CRC-32 and uncompressed size modulo 4294967296.
Reserved header flags, malformed optional fields, invalid compressed data, checksum mismatches, and truncation return Err with a string.
A second member or other bytes after the member return Err. A Bytes value represents one complete compressed payload in this API.
Decoding a successfully compressed value recovers the original bytes. A decoder failure never exposes a prefix of the output.
The receiver evaluates once and remains unchanged. Compression and decompression perform no I/O and do not decode the payload as text.
Причина
Standard header and block handling allows gzip data to move between programs. Requiring one complete member prevents unconsumed suffixes from being silently discarded.
Recover empty and nonempty payloads
Ссылкаimport std.ioimport std.testfor text in (["", "hello"]) {let encoded = test.assertOk(text.encodeUtf8().gzipCompress())io.writeLine(test.assertOk(encoded.gzipDecompress()).toHex())}
68656c6c6f
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f
Accept ordinary gzip header metadata
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("1f8b0800010000000003010500faff68656c6c6f86a6103605000000"))match (encoded.gzipDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
68656c6c6f
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f
Accept compressed gzip blocks
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("1f8b08000000000000ffcb48cdc9c9070086a6103605000000"))match (encoded.gzipDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
68656c6c6f
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f
Reject a truncated member and an invalid checksum
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor hex in (["1f8b0800", "1f8b08000000000000ff010500faff68656c6c6f87a6103605000000"]) {match (test.assertOk(Bytes.fromHex(hex)).gzipDecompress()) {case Err(_) => io.writeLine("invalid gzip")case Ok(_) => io.writeLine("accepted")}}
invalid gzip
invalid gzip
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid gzipinvalid gzip
Use Zstandard frames and explicit effort levels
СсылкаUse Zstandard frames and explicit effort levels
Bytes.zstdCompress accepts an int level from 1 through 22. The default is 3 and other values return Err with a string.
The level is a compression effort hint. The API does not promise a size ratio, execution time, or different bytes for every pair of levels.
A successful call returns Ok with one RFC 8878 frame requiring no external dictionary. Empty input is valid.
Bytes.zstdDecompress accepts one standard frame containing raw, RLE, or compressed blocks, with valid frame parameters and an optional content checksum.
A frame requiring an unavailable dictionary, a malformed header or block, a size or checksum mismatch, and truncation return Err with a string.
Skippable frames, additional frames, and other trailing bytes return Err. The entire input must represent one data frame.
Decompression returns all uncompressed bytes in Ok or an error without a partial output. Compressing then decompressing preserves the input bytes.
The receiver and explicit level expression evaluate once in that order. The input remains unchanged and the operation performs no I/O.
Причина
A bounded level range keeps calls portable. A complete frame boundary and explicit dictionary failure make the returned bytes independent of hidden decoder state.
Use the default and both supported level boundaries
Ссылкаimport std.ioimport std.testlet source = "hello".encodeUtf8()io.writeLine(test.assertOk(test.assertOk(source.zstdCompress()).zstdDecompress()).toHex())for level in ([1, 22]) {io.writeLine(test.assertOk(test.assertOk(source.zstdCompress(level)).zstdDecompress()).toHex())}for level in ([0, 23]) {match (source.zstdCompress(level)) {case Err(_) => io.writeLine("invalid level")case Ok(_) => io.writeLine("accepted")}}
68656c6c6f
68656c6c6f
68656c6c6f
invalid level
invalid level
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6f68656c6c6f68656c6c6finvalid levelinvalid level
Decode a valid Zstandard RLE block
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("28b52ffd20052b000041"))match (encoded.zstdDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
4141414141
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
4141414141
Decode short nonfinal Zstandard raw blocks
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(Bytes.fromHex("28b52ffd20020800004109000042"))match (encoded.zstdDecompress()) {case Ok(bytes) => io.writeLine(bytes.toHex())case Err(_) => io.writeLine("rejected")}
4142
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
4142
Reject missing block data and trailing bytes
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testfor hex in (["", "28b52ffd20052900006869", "28b52ffd200001000000"]) {match (test.assertOk(Bytes.fromHex(hex)).zstdDecompress()) {case Err(_) => io.writeLine("invalid Zstandard")case Ok(_) => io.writeLine("accepted")}}
invalid Zstandard
invalid Zstandard
invalid Zstandard
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
invalid Zstandardinvalid Zstandardinvalid Zstandard
Protect data with systematic Reed-Solomon codewords
СсылкаProtect data with systematic Reed-Solomon codewords
Bytes.reedSolomon255223Protect accepts between 1 and 14614305 input bytes. Empty input and larger input return Err with a string.
Input bytes are partitioned into consecutive 223-byte data chunks. The final chunk is padded with zero bytes to 223 bytes.
Each output codeword contains its 223 data bytes followed by 32 parity bytes. Codewords are concatenated in input order.
The result contains 255 times the ceiling of input length divided by 223 bytes. At most 65535 codewords are produced.
Field arithmetic uses GF256 with primitive polynomial 0x11d and primitive element 2. Generator roots are the powers of that element from 0 through 31.
Treat the first data byte as the highest-degree coefficient. Parity is the 32-byte remainder after multiplying the data polynomial by x to the power 32.
The output contains no original length or additional framing. Callers must retain the input length to distinguish padding from original trailing zero bytes.
The operation generates parity bytes. It does not detect or correct corruption in existing codewords.
The receiver evaluates once and remains unchanged. Input bounds are checked before output allocation and failure exposes no codeword prefix.
Причина
A field definition and systematic layout make parity interoperable. Keeping the original length outside the codeword avoids silently guessing which trailing zero bytes belong to the payload.
Protect a zero byte with zero padding and parity
Ссылкаimport std.bytes { Bytes }import std.ioimport std.testlet encoded = test.assertOk(test.assertOk(Bytes.fromArray([0])).reedSolomon255223Protect())io.writeLine("{encoded.toArray().length}")io.writeLine(encoded.slice(0, 4).toHex())io.writeLine(encoded.slice(223, 255).toHex())
255
00000000
0000000000000000000000000000000000000000000000000000000000000000
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
255000000000000000000000000000000000000000000000000000000000000000000000000
Reject empty data before creating codewords
Ссылкаimport std.bytes { Bytes }import std.iomatch (Bytes.empty().reedSolomon255223Protect()) {case Err(_) => io.writeLine("empty data rejected")case Ok(_) => io.writeLine("accepted")}
empty data rejected
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
empty data rejected
Emit the specified parity for a nonzero payload
Ссылкаimport std.ioimport std.testlet encoded = test.assertOk("hello".encodeUtf8().reedSolomon255223Protect())io.writeLine(encoded.slice(0, 5).toHex())io.writeLine(encoded.slice(223, 255).toHex())
68656c6c6f
c7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd
Ожидаемый результат
Ожидаемый результат
Выполнение завершается. Код завершения 0.
68656c6c6fc7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd