# byteutils # Copyright (c) 2018-2022 Status Research & Development GmbH # Licensed and distributed under either of # * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # at your option. This file may not be copied, modified, or distributed except according to those terms. {.used.} import unittest2, ../stew/byteutils proc compilationTest {.exportc: "compilationTest".} = var bytes = @[1.byte, 2, 3, 4] writeFile("test", bytes) suite "Byte utils": const simpleBArray = [0x12.byte, 0x34, 0x56, 0x78] dualTest "hexToByteArray: Inplace partial string": let s = "0x1234567890" var a: array[5, byte] hexToByteArray(s, a, 1, 3) check a == [0.byte, 0x34, 0x56, 0x78, 0] dualTest "hexToByteArray: Inplace full string": let s = "0xffffffff" var a: array[4, byte] hexToByteArray(s, a) check a == [255.byte, 255, 255, 255] dualTest "hexToByteArrayStrict": let short0 = "" short1 = "0x" short2 = "0x00" short3 = "0xffffff" short4 = "0xfffffff" correct = "0xffffffff" long1 = "0xfffffffff" long2 = "0xffffffffff" var a: array[4, byte] hexToByteArrayStrict(correct, a) check a == [255.byte, 255, 255, 255] template reject(val: string) = expect ValueError: hexToByteArrayStrict(val, a) reject short0 reject short1 reject short2 reject short3 reject short4 reject long1 reject long2 dualTest "hexToByteArray: Return array": let s = "0x12345678" a = hexToByteArray[4](s) check a == simpleBArray expect(ValueError): discard hexToByteArray[1]("") expect(ValueError): discard hexToByteArray[1]("1") dualTest "hexToByteArray: missing bytes": var buffer: array[1, byte] expect(ValueError): hexToByteArray("0x", buffer) expect(ValueError): hexToByteArray("", buffer) expect(ValueError): hexToByteArray("0", buffer) dualTest "valid hex with empty array": var buffer: seq[byte] hexToByteArray("0x123", openArray[byte](buffer)) check(buffer == seq[byte](@[])) dualTest "valid hex with empty array of size": var buffer: seq[byte] = newSeq[byte](4) hexToByteArray("00000123", openArray[byte](buffer)) check(buffer == @[0.byte, 0.byte, 1.byte, 35.byte]) check buffer.toHex == "00000123" dualTest "empty output array is ok": var output: array[0, byte] hexToByteArray("", output) hexToByteArray("0x", output) hexToByteArray("0x32", output) dualTest "array.fromHex": let s = "0x12345678" a2 = array[2, byte].fromHex(s) a4 = array[4, byte].fromHex(s) check: a2.toHex == "1234" a4.toHex == "12345678" expect(ValueError): echo array[5, byte].fromHex(s) dualTest "toHex": check simpleBArray.toHex == "12345678" check hexToSeqByte("12345678") == simpleBArray check hexToSeqByte("00") == [byte 0] check hexToSeqByte("0x") == [] expect(ValueError): discard hexToSeqByte("1234567") expect(ValueError): discard hexToSeqByte("X") expect(ValueError): discard hexToSeqByte("0") check simpleBArray.to0xHex == "0x12345678" test "Array concatenation": check simpleBArray & simpleBArray == [0x12.byte, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78] dualTest "hexToPaddedByteArray": block: let a = hexToPaddedByteArray[4]("0x123") check a.toHex == "00000123" block: let a = hexToPaddedByteArray[4]("0x1234") check a.toHex == "00001234" block: let a = hexToPaddedByteArray[4]("0x1234567") check a.toHex == "01234567" block: let a = hexToPaddedByteArray[4]("0x12345678") check a.toHex == "12345678" block: let a = hexToPaddedByteArray[32]("0x68656c6c6f20776f726c64") check a.toHex == "00000000000000000000000000000000000000000068656c6c6f20776f726c64" block: expect ValueError: discard hexToPaddedByteArray[2]("0x12345") dualTest "lessThan": let a = [0'u8, 1, 2] b = [2'u8, 1, 0] c = [0'u8, 1, 2, 3] d = [0'u8, 1, 3, 3] check: not (a < a) a < b not (b < a) c < b not (b < c) a < c not (c < a) c < d not (d < c) proc copyView(v: openArray[char]): seq[byte] = v.toBytes() dualTest "strings": check: "a".toBytes() == @[byte(ord('a'))] copyView("a") == @[byte(ord('a'))] string.fromBytes([byte(ord('a'))]) == "a" "".toBytes().len() == 0 string.fromBytes([]) == "" @[byte(ord('a'))] == static("a".toBytes()) "a" == static(string.fromBytes([byte(ord('a'))])) test "strings cast": check: cast[ptr UncheckedArray[byte]](cstring(string.fromBytes([byte(ord('a'))])))[1] == byte(0) test "slices": var a: array[4, byte] a[0..<2] = [2'u8, 3] check: a[1] == 3 a.toOpenArray(0, 3)[0..<2] = [4'u8, 5] check: a[1] == 5