byteutils: `openArray[char]` version of `toBytes` (#210)

and compile-time tests
This commit is contained in:
Jacek Sieka 2023-11-14 11:53:47 +01:00 committed by GitHub
parent 49ab3c1d59
commit 2c2544aec1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 22 deletions

View File

@ -237,16 +237,16 @@ func to0xHex*[N: static[int]](ba: array[N, byte]): string {.inline.} =
## No "endianness" reordering is done. ## No "endianness" reordering is done.
toHexAux(ba, true) 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] = func toBytes*(s: string): seq[byte] =
## Convert a string to the corresponding byte sequence - since strings in ## Convert a string to the corresponding byte sequence - since strings in
## nim essentially are byte sequences without any particular encoding, this ## nim essentially are byte sequences without any particular encoding, this
## simply copies the bytes without a null terminator ## 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 = func fromBytes*(T: type string, v: openArray[byte]): string =

View File

@ -16,21 +16,21 @@ proc compilationTest {.exportc: "compilationTest".} =
writeFile("test", bytes) writeFile("test", bytes)
suite "Byte utils": 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" let s = "0x1234567890"
var a: array[5, byte] var a: array[5, byte]
hexToByteArray(s, a, 1, 3) hexToByteArray(s, a, 1, 3)
check a == [0.byte, 0x34, 0x56, 0x78, 0] check a == [0.byte, 0x34, 0x56, 0x78, 0]
test "hexToByteArray: Inplace full string": dualTest "hexToByteArray: Inplace full string":
let s = "0xffffffff" let s = "0xffffffff"
var a: array[4, byte] var a: array[4, byte]
hexToByteArray(s, a) hexToByteArray(s, a)
check a == [255.byte, 255, 255, 255] check a == [255.byte, 255, 255, 255]
test "hexToByteArrayStrict": dualTest "hexToByteArrayStrict":
let let
short0 = "" short0 = ""
short1 = "0x" short1 = "0x"
@ -56,7 +56,7 @@ suite "Byte utils":
reject long1 reject long1
reject long2 reject long2
test "hexToByteArray: Return array": dualTest "hexToByteArray: Return array":
let let
s = "0x12345678" s = "0x12345678"
a = hexToByteArray[4](s) a = hexToByteArray[4](s)
@ -65,7 +65,7 @@ suite "Byte utils":
expect(ValueError): discard hexToByteArray[1]("") expect(ValueError): discard hexToByteArray[1]("")
expect(ValueError): discard hexToByteArray[1]("1") expect(ValueError): discard hexToByteArray[1]("1")
test "hexToByteArray: missing bytes": dualTest "hexToByteArray: missing bytes":
var buffer: array[1, byte] var buffer: array[1, byte]
expect(ValueError): expect(ValueError):
hexToByteArray("0x", buffer) hexToByteArray("0x", buffer)
@ -74,25 +74,25 @@ suite "Byte utils":
expect(ValueError): expect(ValueError):
hexToByteArray("0", buffer) hexToByteArray("0", buffer)
test "valid hex with empty array": dualTest "valid hex with empty array":
var buffer: seq[byte] var buffer: seq[byte]
hexToByteArray("0x123", openArray[byte](buffer)) hexToByteArray("0x123", openArray[byte](buffer))
check(buffer == seq[byte](@[])) 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) var buffer: seq[byte] = newSeq[byte](4)
hexToByteArray("00000123", openArray[byte](buffer)) hexToByteArray("00000123", openArray[byte](buffer))
check(buffer == @[0.byte, 0.byte, 1.byte, 35.byte]) check(buffer == @[0.byte, 0.byte, 1.byte, 35.byte])
check buffer.toHex == "00000123" check buffer.toHex == "00000123"
test "empty output array is ok": dualTest "empty output array is ok":
var output: array[0, byte] var output: array[0, byte]
hexToByteArray("", output) hexToByteArray("", output)
hexToByteArray("0x", output) hexToByteArray("0x", output)
hexToByteArray("0x32", output) hexToByteArray("0x32", output)
test "array.fromHex": dualTest "array.fromHex":
let let
s = "0x12345678" s = "0x12345678"
a2 = array[2, byte].fromHex(s) a2 = array[2, byte].fromHex(s)
@ -104,7 +104,7 @@ suite "Byte utils":
expect(ValueError): echo array[5, byte].fromHex(s) expect(ValueError): echo array[5, byte].fromHex(s)
test "toHex": dualTest "toHex":
check simpleBArray.toHex == "12345678" check simpleBArray.toHex == "12345678"
check hexToSeqByte("12345678") == simpleBArray check hexToSeqByte("12345678") == simpleBArray
check hexToSeqByte("00") == [byte 0] check hexToSeqByte("00") == [byte 0]
@ -118,7 +118,7 @@ suite "Byte utils":
check simpleBArray & simpleBArray == check simpleBArray & simpleBArray ==
[0x12.byte, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78] [0x12.byte, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78]
test "hexToPaddedByteArray": dualTest "hexToPaddedByteArray":
block: block:
let a = hexToPaddedByteArray[4]("0x123") let a = hexToPaddedByteArray[4]("0x123")
check a.toHex == "00000123" check a.toHex == "00000123"
@ -138,7 +138,7 @@ suite "Byte utils":
expect ValueError: expect ValueError:
discard hexToPaddedByteArray[2]("0x12345") discard hexToPaddedByteArray[2]("0x12345")
test "lessThan": dualTest "lessThan":
let let
a = [0'u8, 1, 2] a = [0'u8, 1, 2]
b = [2'u8, 1, 0] b = [2'u8, 1, 0]
@ -160,17 +160,25 @@ suite "Byte utils":
c < d c < d
not (d < c) not (d < c)
test "strings": proc copyView(v: openArray[char]): seq[byte] =
v.toBytes()
dualTest "strings":
check: check:
"a".toBytes() == @[byte(ord('a'))] "a".toBytes() == @[byte(ord('a'))]
copyView("a") == @[byte(ord('a'))]
string.fromBytes([byte(ord('a'))]) == "a" string.fromBytes([byte(ord('a'))]) == "a"
cast[ptr UncheckedArray[byte]](cstring(string.fromBytes([byte(ord('a'))])))[1] == byte(0)
"".toBytes().len() == 0 "".toBytes().len() == 0
string.fromBytes([]) == "" string.fromBytes([]) == ""
@[byte(ord('a'))] == static("a".toBytes()) @[byte(ord('a'))] == static("a".toBytes())
"a" == static(string.fromBytes([byte(ord('a'))])) "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": test "slices":
var a: array[4, byte] var a: array[4, byte]
a[0..<2] = [2'u8, 3] a[0..<2] = [2'u8, 3]