Перейти к содержимому
Топаз6.0 · До релиза
Загрузка →

Поиск в документации

Спецификация 6.0

Выберите результат стрелками и нажмите Enter, чтобы открыть его.

Введите имя API, номер диагностики, правило или тему проекта.

    Библиотека

    std.bytes

    Construct byte sequences and use byte buffers, encodings, hashes, and compression.

    API этого модуля

    33 API

    ИмяМодуль
    ByteBuffer.allocate →std.bytes →
    ByteBuffer.copy →std.bytes →
    ByteBuffer.fill →std.bytes →
    ByteBuffer.fromBytes →std.bytes →
    ByteBuffer.get →std.bytes →
    ByteBuffer.length →std.bytes →
    ByteBuffer.set →std.bytes →
    ByteBuffer.toBytes →std.bytes →
    Bytes.concat →std.bytes →
    Bytes.crc32 →std.bytes →
    Bytes.decodeUtf8 →std.bytes →
    Bytes.deflateCompress →std.bytes →
    Bytes.deflateDecompress →std.bytes →
    Bytes.deflateFixedCompress →std.bytes →
    Bytes.empty →std.bytes →
    Bytes.fromArray →std.bytes →
    Bytes.fromBase64 →std.bytes →
    Bytes.fromHex →std.bytes →
    Bytes.get →std.bytes →
    Bytes.gzipCompress →std.bytes →
    Bytes.gzipDecompress →std.bytes →
    Bytes.hmacSha256 →std.bytes →
    Bytes.length →std.bytes →
    Bytes.reedSolomon255223Protect →std.bytes →
    Bytes.sha256 →std.bytes →
    Bytes.sha512 →std.bytes →
    Bytes.slice →std.bytes →
    Bytes.toArray →std.bytes →
    Bytes.toBase64 →std.bytes →
    Bytes.toHex →std.bytes →
    Bytes.zlibFixedCompress →std.bytes →
    Bytes.zstdCompress →std.bytes →
    Bytes.zstdDecompress →std.bytes →

    Module

    Ссылка

    Bytes stores immutable octets. ByteBuffer is a mutable value with a fixed length. Indexing counts bytes and text conversion uses an explicit encoding.

    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 ByteBuffer = ByteBuffer

    Type members keep the compiler-owned type name shown in their declarations. Importing a module does not create a new type identity.

    Public API

    Ссылка

    ByteBuffer.allocate →

    ByteBuffer.copy →

    ByteBuffer.fill →

    ByteBuffer.fromBytes →

    ByteBuffer.get →

    ByteBuffer.length →

    ByteBuffer.set →

    ByteBuffer.toBytes →

    Bytes.concat →

    Bytes.crc32 →

    Bytes.decodeUtf8 →

    Bytes.deflateCompress →

    Bytes.deflateDecompress →

    Bytes.deflateFixedCompress →

    Bytes.empty →

    Bytes.fromArray →

    Bytes.fromBase64 →

    Bytes.fromHex →

    Bytes.get →

    Bytes.gzipCompress →

    Bytes.gzipDecompress →

    Bytes.hmacSha256 →

    Bytes.length →

    Bytes.reedSolomon255223Protect →

    Bytes.sha256 →

    Bytes.sha512 →

    Bytes.slice →

    Bytes.toArray →

    Bytes.toBase64 →

    Bytes.toHex →

    Bytes.zlibFixedCompress →

    Bytes.zstdCompress →

    Bytes.zstdDecompress →

    Pending contracts

    Ссылка

    Read collection sizes, keys, and values as properties

    Ссылка
    Правилоtopaz.stdlib.contract.collection-properties.rule

    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<JSONValue>>. 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

    Ссылка
    main.tpzRead the same properties on core collectionsОткрыть песочницу →
    1. import std.io
    2. let array = [2, 3]
    3. let entries = map { "name": "Topaz" }
    4. let values = set { 2, 3 }
    5. io.writeLine("{array.length}:{entries.length}:{values.length}")
    6. io.writeLine(entries.keys[0])
    7. io.writeLine(entries.values[0])
    Ожидаемый выводКод завершения 0
    2:1:2
    name
    Topaz
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 2:1:2
    2. name
    3. Topaz

    Read a byte sequence size

    Ссылка
    main.tpzRead a byte sequence sizeОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. let bytes = Bytes.empty()
    4. let size: int = bytes.length
    5. io.writeLine("{size}")
    Ожидаемый выводКод завершения 0
    0
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 0

    Read a byte buffer size

    Ссылка
    main.tpzRead a byte buffer sizeОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let buffer = ByteBuffer.allocate(3)
    4. let size: int = buffer.length
    5. io.writeLine("{size}")
    Ожидаемый выводКод завершения 0
    3
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 3

    Read JSON sizes and preserve optional results

    Ссылка
    main.tpzRead JSON sizes and preserve optional resultsОткрыть песочницу →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let array = test.assertOk(json.parse("[1,2]"))
    5. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let arraySize: Option<int> = array.length
    8. let objectSize: Option<int> = object.length
    9. let scalarSize: Option<int> = scalar.length
    10. test.assertEq(test.assertSome(arraySize), 2)
    11. test.assertEq(test.assertSome(objectSize), 1)
    12. test.assertNone(scalarSize)
    13. io.writeLine("JSON sizes read")
    Ожидаемый выводКод завершения 0
    JSON sizes read
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. JSON sizes read

    Read JSON object keys

    Ссылка
    main.tpzRead JSON object keysОткрыть песочницу →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    5. let array = test.assertOk(json.parse("[]"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let names: Option<Array<string>> = object.keys
    8. test.assertEq(test.assertSome(names)[0], "name")
    9. test.assertNone(array.keys)
    10. test.assertNone(scalar.keys)
    11. io.writeLine("JSON keys read")
    Ожидаемый выводКод завершения 0
    JSON keys read
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. JSON keys read

    Read JSON object values

    Ссылка
    main.tpzRead JSON object valuesОткрыть песочницу →
    1. import std.json
    2. import std.test
    3. import std.io
    4. let object = test.assertOk(json.parse("\{\"name\":\"Topaz\"\}"))
    5. let array = test.assertOk(json.parse("[]"))
    6. let scalar = test.assertOk(json.parse("42"))
    7. let values = test.assertSome(object.values)
    8. test.assertEq(test.assertSome(values[0].asString()), "Topaz")
    9. test.assertNone(array.values)
    10. test.assertNone(scalar.values)
    11. io.writeLine("JSON values read")
    Ожидаемый выводКод завершения 0
    JSON values read
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. JSON values read

    Reject calling Bytes.length

    Ссылка
    main.tpzReject calling Bytes.lengthОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. function inspect(value: Bytes) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling ByteBuffer.length

    Ссылка
    main.tpzReject calling ByteBuffer.lengthОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. function inspect(value: ByteBuffer) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.length

    Ссылка
    main.tpzReject calling JSONValue.lengthОткрыть песочницу →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.length()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.keys

    Ссылка
    main.tpzReject calling JSONValue.keysОткрыть песочницу →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.keys()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Reject calling JSONValue.values

    Ссылка
    main.tpzReject calling JSONValue.valuesОткрыть песочницу →
    1. import std.json { JSONValue }
    2. function inspect(value: JSONValue) -> () {
    3. let result = value.values()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    • TPZ5005 →

      stdlib-property-not-callable at main.tpz:3:22

    Diagnostics

    Ссылка

    Value is not callable →

    Test collection emptiness with length

    Ссылка
    Правилоtopaz.stdlib.contract.collection-emptiness.rule

    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

    Ссылка
    main.tpzTest empty and nonempty maps with lengthОткрыть песочницу →
    1. import std.io
    2. let empty: Map<string, int> = map {}
    3. let filled = map { "one": 1 }
    4. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    Ожидаемый выводКод завершения 0
    true:false
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. true:false

    Test empty and nonempty sets with length

    Ссылка
    main.tpzTest empty and nonempty sets with lengthОткрыть песочницу →
    1. import std.io
    2. let empty: Set<int> = set {}
    3. let filled = set { 1 }
    4. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    Ожидаемый выводКод завершения 0
    true:false
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. true:false

    Test empty and nonempty byte sequences with length

    Ссылка
    main.tpzTest empty and nonempty byte sequences with lengthОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.test
    3. import std.io
    4. let empty = Bytes.empty()
    5. let filled = test.assertOk(Bytes.fromArray([1]))
    6. io.writeLine("{empty.length == 0}:{filled.length == 0}")
    Ожидаемый выводКод завершения 0
    true:false
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. true:false

    Reject Bytes.isEmpty

    Ссылка
    main.tpzReject Bytes.isEmptyОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. function inspect(value: Bytes) -> () {
    3. let result = value.isEmpty()
    4. return ()
    5. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    Reject Map.isEmpty

    Ссылка
    main.tpzReject Map.isEmptyОткрыть песочницу →
    1. function inspect(value: Map<string, int>) -> () {
    2. let result = value.isEmpty()
    3. return ()
    4. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    Reject Set.isEmpty

    Ссылка
    main.tpzReject Set.isEmptyОткрыть песочницу →
    1. function inspect(value: Set<int>) -> () {
    2. let result = value.isEmpty()
    3. return ()
    4. }
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz check main.tpz --format json · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения check. Ненулевой код завершения.

    Diagnostics

    Ссылка

    Unknown member or field →

    Construct and inspect immutable byte sequences

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-values.rule

    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

    Ссылка
    main.tpzPreserve empty values and byte orderОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let empty = test.assertOk(Bytes.fromArray([]))
    5. let value = test.assertOk(Bytes.fromArray([0, 128, 255]))
    6. io.writeLine(Bytes.empty().toHex())
    7. io.writeLine(empty.concat(value).toHex())
    8. io.writeLine(value.concat(test.assertOk(Bytes.fromArray([1]))).toHex())
    Ожидаемый выводКод завершения 0
    
    0080ff
    0080ff01
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 0080ff
    2. 0080ff01

    Reject out-of-range array elements

    Ссылка
    main.tpzReject out-of-range array elementsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for values in ([[0, -1, 255], [0, 256, 255]]) {
    4. match (Bytes.fromArray(values)) {
    5. case Err(_) => io.writeLine("invalid byte")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    Ожидаемый выводКод завершения 0
    invalid byte
    invalid byte
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid byte
    2. invalid byte

    Read optional bytes at both boundaries

    Ссылка
    main.tpzRead optional bytes at both boundariesОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let value = test.assertOk(Bytes.fromArray([0, 128, 255]))
    5. for index in ([-1, 0, 2, 3]) {
    6. match (value.get(index)) {
    7. case Some(byte) => io.writeLine("{byte}")
    8. case None() => io.writeLine("absent")
    9. }
    10. }
    Ожидаемый выводКод завершения 0
    absent
    0
    255
    absent
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. absent
    2. 0
    3. 255
    4. absent

    Keep array edits independent from bytes

    Ссылка
    main.tpzKeep array edits independent from bytesОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let mut input = [0, 255]
    5. let value = test.assertOk(Bytes.fromArray(input))
    6. let mut output = value.toArray()
    7. input[0] = 7
    8. output[1] = 8
    9. io.writeLine(value.toHex())
    10. io.writeLine("{input[0]},{output[1]}")
    Ожидаемый выводКод завершения 0
    00ff
    7,8
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 00ff
    2. 7,8

    Evaluate the receiver before its argument

    Ссылка
    main.tpzEvaluate the receiver before its argumentОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. function receiver() -> Bytes {
    4. io.writeLine("receiver")
    5. return "a".encodeUtf8()
    6. }
    7. function argument() -> Bytes {
    8. io.writeLine("argument")
    9. return "b".encodeUtf8()
    10. }
    11. io.writeLine(receiver().concat(argument()).toHex())
    Ожидаемый выводКод завершения 0
    receiver
    argument
    6162
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. receiver
    2. argument
    3. 6162

    Select explicit byte intervals

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-slice.rule

    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

    Ссылка
    main.tpzSelect empty and nonempty intervalsОткрыть песочницу →
    1. import std.io
    2. let value = "abcd".encodeUtf8()
    3. io.writeLine(value.slice(0, 0).toHex())
    4. io.writeLine(value.slice(1, 3).toHex())
    5. io.writeLine(value.slice(4, 4).toHex())
    6. io.writeLine(value.toHex())
    Ожидаемый выводКод завершения 0
    
    6263
    
    61626364
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 6263
    2. 61626364

    Keep byte slicing separate from UTF-8 validation

    Ссылка
    main.tpzKeep byte slicing separate from UTF-8 validationОткрыть песочницу →
    1. import std.io
    2. let byte = "é".encodeUtf8().slice(0, 1)
    3. io.writeLine(byte.toHex())
    4. match (byte.decodeUtf8()) {
    5. case Err(_) => io.writeLine("invalid UTF-8")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    Ожидаемый выводКод завершения 0
    c3
    invalid UTF-8
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. c3
    2. invalid UTF-8

    Reject a negative slice start

    Ссылка
    main.tpzReject a negative slice startОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(-1, 2)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject an inverted byte interval

    Ссылка
    main.tpzReject an inverted byte intervalОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(3, 2)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject an endpoint beyond the sequence

    Ссылка
    main.tpzReject an endpoint beyond the sequenceОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. let value = "abcd".encodeUtf8()
    3. value.slice(0, 5)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Diagnostics

    Ссылка

    Index out of bounds →

    Use a canonical hexadecimal spelling

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-hex.rule

    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

    Ссылка
    main.tpzDecode byte pairs and emit lowercase textОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. io.writeLine(test.assertOk(Bytes.fromHex("")).toHex())
    5. io.writeLine(test.assertOk(Bytes.fromHex("000f80ff")).toHex())
    Ожидаемый выводКод завершения 0
    
    000f80ff
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 000f80ff

    Reject malformed hexadecimal strings

    Ссылка
    main.tpzReject malformed hexadecimal stringsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for text in (["0", "gg", "0x00", "00 11", "00"]) {
    4. match (Bytes.fromHex(text)) {
    5. case Err(_) => io.writeLine("invalid hex")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    Ожидаемый выводКод завершения 0
    invalid hex
    invalid hex
    invalid hex
    invalid hex
    invalid hex
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid hex
    2. invalid hex
    3. invalid hex
    4. invalid hex
    5. invalid hex

    Reject uppercase hexadecimal input

    Ссылка
    main.tpzReject uppercase hexadecimal inputОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. match (Bytes.fromHex("CAfe")) {
    4. case Err(_) => io.writeLine("uppercase rejected")
    5. case Ok(_) => io.writeLine("accepted")
    6. }
    Ожидаемый выводКод завершения 0
    uppercase rejected
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. uppercase rejected

    Encode and validate padded Base64

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-base64.rule

    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

    Ссылка
    main.tpzUse standard Base64 vectorsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for text in (["", "f", "fo", "foo"]) {
    5. io.writeLine(text.encodeUtf8().toBase64())
    6. }
    7. for text in (["", "Zg==", "Zm8=", "Zm9v"]) {
    8. io.writeLine(test.assertOk(Bytes.fromBase64(text)).toHex())
    9. }
    Ожидаемый выводКод завершения 0
    
    Zg==
    Zm8=
    Zm9v
    
    66
    666f
    666f6f
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. Zg==
    2. Zm8=
    3. Zm9v
    4. 66
    5. 666f
    6. 666f6f

    Reject padding and alphabet errors

    Ссылка
    main.tpzReject padding and alphabet errorsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. for text in (["Zg", "Zh==", "Zg== ", "_w==", "Zg==Zg==", "=g=="]) {
    4. match (Bytes.fromBase64(text)) {
    5. case Err(_) => io.writeLine("invalid Base64")
    6. case Ok(_) => io.writeLine("accepted")
    7. }
    8. }
    Ожидаемый выводКод завершения 0
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    invalid Base64
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid Base64
    2. invalid Base64
    3. invalid Base64
    4. invalid Base64
    5. invalid Base64
    6. invalid Base64

    Decode UTF-8 without replacing data

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-utf8.rule

    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

    Ссылка
    main.tpzRetain a byte order mark and combining sequenceОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "efbbbf", "65cc81", "0d0a", "f09f9880"]) {
    5. let decoded = test.assertOk(test.assertOk(Bytes.fromHex(hex)).decodeUtf8())
    6. io.writeLine(decoded.encodeUtf8().toHex())
    7. }
    Ожидаемый выводКод завершения 0
    
    efbbbf
    65cc81
    0d0a
    f09f9880
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. efbbbf
    2. 65cc81
    3. 0d0a
    4. f09f9880

    Reject malformed UTF-8 categories

    Ссылка
    main.tpzReject malformed UTF-8 categoriesОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["80", "c080", "e282", "eda080", "f4908080"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).decodeUtf8()) {
    6. case Err(_) => io.writeLine("invalid UTF-8")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    Ожидаемый выводКод завершения 0
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    invalid UTF-8
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid UTF-8
    2. invalid UTF-8
    3. invalid UTF-8
    4. invalid UTF-8
    5. invalid UTF-8

    Allocate buffers and convert byte values

    Ссылка
    Правилоtopaz.stdlib.contract.byte-buffer-storage.rule

    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

    Ссылка
    main.tpzAllocate zero-filled and initialized buffersОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. io.writeLine(ByteBuffer.allocate(0).toBytes().toHex())
    4. io.writeLine(ByteBuffer.allocate(3).toBytes().toHex())
    5. io.writeLine(ByteBuffer.allocate(2, 255).toBytes().toHex())
    Ожидаемый выводКод завершения 0
    
    000000
    ffff
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 000000
    2. ffff

    Keep the original buffer and converted bytes unchanged

    Ссылка
    main.tpzKeep the original buffer and converted bytes unchangedОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let source = "ab".encodeUtf8()
    4. let buffer = ByteBuffer.fromBytes(source)
    5. let independent = ByteBuffer.fromBytes(source)
    6. let before = buffer.toBytes()
    7. let mut alias = buffer
    8. alias.set(0, 99)
    9. io.writeLine(source.toHex())
    10. io.writeLine(before.toHex())
    11. io.writeLine(independent.toBytes().toHex())
    12. io.writeLine(buffer.toBytes().toHex())
    Ожидаемый выводКод завершения 0
    6162
    6162
    6162
    6162
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 6162
    2. 6162
    3. 6162
    4. 6162

    Reject a negative buffer length

    Ссылка
    main.tpzReject a negative buffer lengthОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. ByteBuffer.allocate(-1)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Validate the initial byte of an empty buffer

    Ссылка
    main.tpzValidate the initial byte of an empty bufferОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. ByteBuffer.allocate(0, -1)
    4. io.writeLine("after")
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Validate the initial byte of an empty buffer

    Ссылка
    main.tpzValidate the initial byte of an empty bufferОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. ByteBuffer.allocate(0, 256)
    4. io.writeLine("after")
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Diagnostics

    Ссылка

    Runtime value guard →

    Validate buffer regions before writing

    Ссылка
    Правилоtopaz.stdlib.contract.byte-buffer-mutation.rule

    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

    Ссылка
    main.tpzCopy overlapping regions and preserve an earlier buffer valueОткрыть песочницу →
    1. import std.bytes { Bytes, ByteBuffer }
    2. import std.io
    3. import std.test
    4. let mut buffer = ByteBuffer.fromBytes(test.assertOk(Bytes.fromHex("000102030405")))
    5. let alias = buffer
    6. buffer.copy(buffer, 0, 1, 5)
    7. io.writeLine(buffer.toBytes().toHex())
    8. buffer.fill(2, 2, 255)
    9. buffer.set(0, 128)
    10. io.writeLine(buffer.toBytes().toHex())
    11. buffer.copy(buffer, 1, 0, 5)
    12. buffer.fill(6, 0, 0)
    13. buffer.copy(buffer, 6, 6, 0)
    14. io.writeLine(buffer.toBytes().toHex())
    15. io.writeLine(alias.toBytes().toHex())
    16. io.writeLine("{alias.get(0)}")
    Ожидаемый выводКод завершения 0
    000001020304
    8000ffff0304
    00ffff030404
    000102030405
    0
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 000001020304
    2. 8000ffff0304
    3. 00ffff030404
    4. 000102030405
    5. 0

    Keep an independent source buffer unchanged

    Ссылка
    main.tpzKeep an independent source buffer unchangedОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let source = ByteBuffer.fromBytes("abc".encodeUtf8())
    4. let mut target = ByteBuffer.allocate(4, 0)
    5. target.copy(source, 1, 1, 2)
    6. io.writeLine(target.toBytes().toHex())
    7. io.writeLine(source.toBytes().toHex())
    Ожидаемый выводКод завершения 0
    00626300
    616263
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 00626300
    2. 616263

    Reject a read at the exclusive end

    Ссылка
    main.tpzReject a read at the exclusive endОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. let buffer = ByteBuffer.allocate(2)
    3. buffer.get(2)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject a negative write index

    Ссылка
    main.tpzReject a negative write indexОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.set(-1, 0)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject a fill whose complete region does not fit

    Ссылка
    main.tpzReject a fill whose complete region does not fitОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.fill(1, 2, 0)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject an empty copy beyond the buffer end

    Ссылка
    main.tpzReject an empty copy beyond the buffer endОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. let mut buffer = ByteBuffer.allocate(2)
    3. buffer.copy(buffer, 3, 2, 0)
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Reject an invalid byte at a valid write index

    Ссылка
    main.tpzReject an invalid byte at a valid write indexОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let mut buffer = ByteBuffer.allocate(1)
    4. buffer.set(0, -1)
    5. io.writeLine("after")
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Validate the byte for a fill of zero bytes

    Ссылка
    main.tpzValidate the byte for a fill of zero bytesОткрыть песочницу →
    1. import std.bytes { ByteBuffer }
    2. import std.io
    3. let mut buffer = ByteBuffer.allocate(1)
    4. buffer.fill(1, 0, 256)
    5. io.writeLine("after")
    Ожидаемый выводНенулевой код завершения
    Нет стандартного вывода.
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Этап отклонения run. Ненулевой код завершения.

    Compute interoperable checksums and digests

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-digests.rule

    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

    Ссылка
    main.tpzMatch established checksum and hash vectorsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. io.writeLine("{Bytes.empty().crc32()}")
    4. let checksum = "123456789".encodeUtf8().crc32()
    5. io.writeLine("{checksum}")
    6. io.writeLine("abc".encodeUtf8().sha256().toHex())
    7. io.writeLine("abc".encodeUtf8().sha512().toHex())
    8. io.writeLine("key".encodeUtf8().hmacSha256("The quick brown fox jumps over the lazy dog".encodeUtf8()).toHex())
    Ожидаемый выводКод завершения 0
    0
    3421780262
    ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
    ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
    f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 0
    2. 3421780262
    3. ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
    4. ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
    5. f7bc83f430538424b13298e6aa6fb143ef4d59a14946175997479dbc2d1a3cd8

    Distinguish raw DEFLATE from zlib framing

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-deflate.rule

    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

    Ссылка
    main.tpzRecover bytes from a raw streamОткрыть песочницу →
    1. import std.io
    2. import std.test
    3. let encoded = test.assertOk("hello".encodeUtf8().deflateCompress())
    4. io.writeLine(test.assertOk(encoded.deflateDecompress()).toHex())
    5. io.writeLine(test.assertOk("".encodeUtf8().deflateFixedCompress()).toHex())
    6. io.writeLine(test.assertOk("".encodeUtf8().zlibFixedCompress()).toHex())
    Ожидаемый выводКод завершения 0
    68656c6c6f
    0300
    7801030000000001
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f
    2. 0300
    3. 7801030000000001

    Decode a valid fixed Huffman stream

    Ссылка
    main.tpzDecode a valid fixed Huffman streamОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("cb48cdc9c90700"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    68656c6c6f
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f

    Decode short nonfinal stored blocks

    Ссылка
    main.tpzDecode short nonfinal stored blocksОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("000100feff41010100feff42"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    4142
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 4142

    Ignore stored block alignment bits

    Ссылка
    main.tpzIgnore stored block alignment bitsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("f90100feff41"))
    5. match (encoded.deflateDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    41
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 41

    Reject truncated streams and trailing bytes

    Ссылка
    main.tpzReject truncated streams and trailing bytesОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "010100feff", "010000ffff00", "070000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).deflateDecompress()) {
    6. case Err(_) => io.writeLine("invalid DEFLATE")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    Ожидаемый выводКод завершения 0
    invalid DEFLATE
    invalid DEFLATE
    invalid DEFLATE
    invalid DEFLATE
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid DEFLATE
    2. invalid DEFLATE
    3. invalid DEFLATE
    4. invalid DEFLATE

    Read and write complete gzip members

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-gzip.rule

    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

    Ссылка
    main.tpzRecover empty and nonempty payloadsОткрыть песочницу →
    1. import std.io
    2. import std.test
    3. for text in (["", "hello"]) {
    4. let encoded = test.assertOk(text.encodeUtf8().gzipCompress())
    5. io.writeLine(test.assertOk(encoded.gzipDecompress()).toHex())
    6. }
    Ожидаемый выводКод завершения 0
    
    68656c6c6f
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f

    Accept ordinary gzip header metadata

    Ссылка
    main.tpzAccept ordinary gzip header metadataОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("1f8b0800010000000003010500faff68656c6c6f86a6103605000000"))
    5. match (encoded.gzipDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    68656c6c6f
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f

    Accept compressed gzip blocks

    Ссылка
    main.tpzAccept compressed gzip blocksОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("1f8b08000000000000ffcb48cdc9c9070086a6103605000000"))
    5. match (encoded.gzipDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    68656c6c6f
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f

    Reject a truncated member and an invalid checksum

    Ссылка
    main.tpzReject a truncated member and an invalid checksumОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["1f8b0800", "1f8b08000000000000ff010500faff68656c6c6f87a6103605000000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).gzipDecompress()) {
    6. case Err(_) => io.writeLine("invalid gzip")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    Ожидаемый выводКод завершения 0
    invalid gzip
    invalid gzip
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid gzip
    2. invalid gzip

    Use Zstandard frames and explicit effort levels

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-zstd.rule

    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

    Ссылка
    main.tpzUse the default and both supported level boundariesОткрыть песочницу →
    1. import std.io
    2. import std.test
    3. let source = "hello".encodeUtf8()
    4. io.writeLine(test.assertOk(test.assertOk(source.zstdCompress()).zstdDecompress()).toHex())
    5. for level in ([1, 22]) {
    6. io.writeLine(test.assertOk(test.assertOk(source.zstdCompress(level)).zstdDecompress()).toHex())
    7. }
    8. for level in ([0, 23]) {
    9. match (source.zstdCompress(level)) {
    10. case Err(_) => io.writeLine("invalid level")
    11. case Ok(_) => io.writeLine("accepted")
    12. }
    13. }
    Ожидаемый выводКод завершения 0
    68656c6c6f
    68656c6c6f
    68656c6c6f
    invalid level
    invalid level
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f
    2. 68656c6c6f
    3. 68656c6c6f
    4. invalid level
    5. invalid level

    Decode a valid Zstandard RLE block

    Ссылка
    main.tpzDecode a valid Zstandard RLE blockОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("28b52ffd20052b000041"))
    5. match (encoded.zstdDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    4141414141
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 4141414141

    Decode short nonfinal Zstandard raw blocks

    Ссылка
    main.tpzDecode short nonfinal Zstandard raw blocksОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(Bytes.fromHex("28b52ffd20020800004109000042"))
    5. match (encoded.zstdDecompress()) {
    6. case Ok(bytes) => io.writeLine(bytes.toHex())
    7. case Err(_) => io.writeLine("rejected")
    8. }
    Ожидаемый выводКод завершения 0
    4142
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 4142

    Reject missing block data and trailing bytes

    Ссылка
    main.tpzReject missing block data and trailing bytesОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. for hex in (["", "28b52ffd20052900006869", "28b52ffd200001000000"]) {
    5. match (test.assertOk(Bytes.fromHex(hex)).zstdDecompress()) {
    6. case Err(_) => io.writeLine("invalid Zstandard")
    7. case Ok(_) => io.writeLine("accepted")
    8. }
    9. }
    Ожидаемый выводКод завершения 0
    invalid Zstandard
    invalid Zstandard
    invalid Zstandard
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. invalid Zstandard
    2. invalid Zstandard
    3. invalid Zstandard

    Protect data with systematic Reed-Solomon codewords

    Ссылка
    Правилоtopaz.stdlib.contract.bytes-reed-solomon.rule

    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

    Ссылка
    main.tpzProtect a zero byte with zero padding and parityОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. import std.test
    4. let encoded = test.assertOk(test.assertOk(Bytes.fromArray([0])).reedSolomon255223Protect())
    5. io.writeLine("{encoded.toArray().length}")
    6. io.writeLine(encoded.slice(0, 4).toHex())
    7. io.writeLine(encoded.slice(223, 255).toHex())
    Ожидаемый выводКод завершения 0
    255
    00000000
    0000000000000000000000000000000000000000000000000000000000000000
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 255
    2. 00000000
    3. 0000000000000000000000000000000000000000000000000000000000000000

    Reject empty data before creating codewords

    Ссылка
    main.tpzReject empty data before creating codewordsОткрыть песочницу →
    1. import std.bytes { Bytes }
    2. import std.io
    3. match (Bytes.empty().reedSolomon255223Protect()) {
    4. case Err(_) => io.writeLine("empty data rejected")
    5. case Ok(_) => io.writeLine("accepted")
    6. }
    Ожидаемый выводКод завершения 0
    empty data rejected
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. empty data rejected

    Emit the specified parity for a nonzero payload

    Ссылка
    main.tpzEmit the specified parity for a nonzero payloadОткрыть песочницу →
    1. import std.io
    2. import std.test
    3. let encoded = test.assertOk("hello".encodeUtf8().reedSolomon255223Protect())
    4. io.writeLine(encoded.slice(0, 5).toHex())
    5. io.writeLine(encoded.slice(223, 255).toHex())
    Ожидаемый выводКод завершения 0
    68656c6c6f
    c7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd
    
    $ topaz run main.tpz · Целевой продукт 5.21.3
    Ожидаемый результат

    Ожидаемый результат

    Выполнение завершается. Код завершения 0.

    Ожидаемый стандартный вывод
    1. 68656c6c6f
    2. c7a146d71a5245bf94210961b0acac5f4358ac66cf234be24bcea41117eeb5fd

    Меню

    Загрузка →