From 2c2544aec13536304438be045bfdd22452741466 Mon Sep 17 00:00:00 2001 From: Jacek Sieka Date: Tue, 14 Nov 2023 11:53:47 +0100 Subject: [PATCH] byteutils: `openArray[char]` version of `toBytes` (#210) and compile-time tests --- stew/byteutils.nim | 14 +++++++------- tests/test_byteutils.nim | 38 +++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/stew/byteutils.nim b/stew/byteutils.nim index 45af334..bdd013c 100644 --- a/stew/byteutils.nim +++ b/stew/byteutils.nim @@ -237,17 +237,17 @@ func to0xHex*[N: static[int]](ba: array[N, byte]): string {.inline.} = ## No "endianness" reordering is done. toHexAux(ba, true) +func toBytes*(s: openArray[char]): seq[byte] = + ## Convert a char array to the corresponding byte sequence - since strings in + ## nim essentially are byte sequences without any particular encoding, this + ## simply copies the bytes without a null terminator + @(s.toOpenArrayByte(0, s.high)) + func toBytes*(s: string): seq[byte] = ## Convert a string to the corresponding byte sequence - since strings in ## nim essentially are byte sequences without any particular encoding, this ## simply copies the bytes without a null terminator - when nimvm: - var r = newSeq[byte](s.len) - for i, c in s: - r[i] = cast[byte](c) - r - else: - @(s.toOpenArrayByte(0, s.high)) + @(s.toOpenArrayByte(0, s.high)) func fromBytes*(T: type string, v: openArray[byte]): string = if v.len > 0: diff --git a/tests/test_byteutils.nim b/tests/test_byteutils.nim index c8ec8e0..6fa8a35 100644 --- a/tests/test_byteutils.nim +++ b/tests/test_byteutils.nim @@ -16,21 +16,21 @@ proc compilationTest {.exportc: "compilationTest".} = writeFile("test", bytes) suite "Byte utils": - let simpleBArray = [0x12.byte, 0x34, 0x56, 0x78] + const simpleBArray = [0x12.byte, 0x34, 0x56, 0x78] - test "hexToByteArray: Inplace partial string": + 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] - test "hexToByteArray: Inplace full string": + dualTest "hexToByteArray: Inplace full string": let s = "0xffffffff" var a: array[4, byte] hexToByteArray(s, a) check a == [255.byte, 255, 255, 255] - test "hexToByteArrayStrict": + dualTest "hexToByteArrayStrict": let short0 = "" short1 = "0x" @@ -56,7 +56,7 @@ suite "Byte utils": reject long1 reject long2 - test "hexToByteArray: Return array": + dualTest "hexToByteArray: Return array": let s = "0x12345678" a = hexToByteArray[4](s) @@ -65,7 +65,7 @@ suite "Byte utils": expect(ValueError): discard hexToByteArray[1]("") expect(ValueError): discard hexToByteArray[1]("1") - test "hexToByteArray: missing bytes": + dualTest "hexToByteArray: missing bytes": var buffer: array[1, byte] expect(ValueError): hexToByteArray("0x", buffer) @@ -74,25 +74,25 @@ suite "Byte utils": expect(ValueError): hexToByteArray("0", buffer) - test "valid hex with empty array": + dualTest "valid hex with empty array": var buffer: seq[byte] hexToByteArray("0x123", openArray[byte](buffer)) check(buffer == seq[byte](@[])) - test "valid hex with empty array of size": + 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" - test "empty output array is ok": + dualTest "empty output array is ok": var output: array[0, byte] hexToByteArray("", output) hexToByteArray("0x", output) hexToByteArray("0x32", output) - test "array.fromHex": + dualTest "array.fromHex": let s = "0x12345678" a2 = array[2, byte].fromHex(s) @@ -104,7 +104,7 @@ suite "Byte utils": expect(ValueError): echo array[5, byte].fromHex(s) - test "toHex": + dualTest "toHex": check simpleBArray.toHex == "12345678" check hexToSeqByte("12345678") == simpleBArray check hexToSeqByte("00") == [byte 0] @@ -118,7 +118,7 @@ suite "Byte utils": check simpleBArray & simpleBArray == [0x12.byte, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78] - test "hexToPaddedByteArray": + dualTest "hexToPaddedByteArray": block: let a = hexToPaddedByteArray[4]("0x123") check a.toHex == "00000123" @@ -138,7 +138,7 @@ suite "Byte utils": expect ValueError: discard hexToPaddedByteArray[2]("0x12345") - test "lessThan": + dualTest "lessThan": let a = [0'u8, 1, 2] b = [2'u8, 1, 0] @@ -160,17 +160,25 @@ suite "Byte utils": c < d not (d < c) - test "strings": + 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" - cast[ptr UncheckedArray[byte]](cstring(string.fromBytes([byte(ord('a'))])))[1] == byte(0) "".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]