mirror of
https://github.com/status-im/nim-stew.git
synced 2025-01-23 10:29:44 +00:00
Add byteutils.hexToByteArrayStrict (#120)
This commit is contained in:
parent
b3ea2c6b46
commit
9fe9cb7002
@ -31,14 +31,14 @@ proc readHexChar*(c: char): byte
|
||||
else:
|
||||
raise newException(ValueError, $c & " is not a hexadecimal character")
|
||||
|
||||
template skip0xPrefix(hexStr: string): int =
|
||||
template skip0xPrefix(hexStr: openArray[char]): int =
|
||||
## Returns the index of the first meaningful char in `hexStr` by skipping
|
||||
## "0x" prefix
|
||||
if hexStr.len > 1 and hexStr[0] == '0' and hexStr[1] in {'x', 'X'}: 2
|
||||
else: 0
|
||||
|
||||
func hexToByteArray*(hexStr: string, output: var openArray[byte], fromIdx, toIdx: int)
|
||||
{.raises: [ValueError, Defect].} =
|
||||
func hexToByteArrayImpl(hexStr: openArray[char], output: var openArray[byte], fromIdx, toIdx: int): int
|
||||
{.raises: [ValueError, Defect].} =
|
||||
## Read a hex string and store it in a byte array `output`. No "endianness" reordering is done.
|
||||
## Allows specifying the byte range to process into the array
|
||||
var sIdx = skip0xPrefix(hexStr)
|
||||
@ -53,21 +53,58 @@ func hexToByteArray*(hexStr: string, output: var openArray[byte], fromIdx, toIdx
|
||||
output[bIdx] = hexStr[sIdx].readHexChar shl 4 or hexStr[sIdx + 1].readHexChar
|
||||
inc(sIdx, 2)
|
||||
|
||||
sIdx
|
||||
|
||||
func hexToByteArray*(hexStr: string, output: var openArray[byte], fromIdx, toIdx: int)
|
||||
{.raises: [ValueError, Defect].} =
|
||||
## Read a hex string and store it in a byte array `output`. No "endianness" reordering is done.
|
||||
## Allows specifying the byte range to process into the array.
|
||||
## The hex input may be longer than strictly necessary.
|
||||
discard hexToByteArrayImpl(hexStr, output, fromIdx, toIdx)
|
||||
|
||||
func hexToByteArray*(hexStr: string, output: var openArray[byte])
|
||||
{.raises: [ValueError, Defect], inline.} =
|
||||
## Read a hex string and store it in a byte array `output`. No "endianness" reordering is done.
|
||||
## The hex input may be longer than strictly necessary.
|
||||
hexToByteArray(hexStr, output, 0, output.high)
|
||||
|
||||
func hexToByteArray*[N: static[int]](hexStr: string): array[N, byte]
|
||||
{.raises: [ValueError, Defect], noinit, inline.}=
|
||||
## Read an hex string and store it in a byte array. No "endianness" reordering is done.
|
||||
## The hex input may be longer than strictly necessary.
|
||||
hexToByteArray(hexStr, result)
|
||||
|
||||
func hexToByteArray*(hexStr: string, N: static int): array[N, byte]
|
||||
{.raises: [ValueError, Defect], noinit, inline.}=
|
||||
## Read an hex string and store it in a byte array. No "endianness" reordering is done.
|
||||
## The hex input may be longer than strictly necessary.
|
||||
hexToByteArray(hexStr, result)
|
||||
|
||||
func hexToByteArrayStrict*(hexStr: openArray[char], output: var openArray[byte], fromIdx, toIdx: int)
|
||||
{.raises: [ValueError, Defect].} =
|
||||
## Read a hex string and store it in a byte array `output`. No "endianness" reordering is done.
|
||||
## Allows specifying the byte range to process into the array. The entire input must be consumed.
|
||||
if hexToByteArrayImpl(hexStr, output, fromIdx, toIdx) != hexStr.len:
|
||||
raise (ref ValueError)(msg: "hex string too long")
|
||||
|
||||
func hexToByteArrayStrict*(hexStr: openArray[char], output: var openArray[byte])
|
||||
{.raises: [ValueError, Defect], inline.} =
|
||||
## Read a hex string and store it in a byte array `output`. No "endianness" reordering is done.
|
||||
## The entire input must be consumed.
|
||||
hexToByteArrayStrict(hexStr, output, 0, output.high)
|
||||
|
||||
func hexToByteArrayStrict*[N: static[int]](hexStr: openArray[char]): array[N, byte]
|
||||
{.raises: [ValueError, Defect], noinit, inline.}=
|
||||
## Read an hex string and store it in a byte array. No "endianness" reordering is done.
|
||||
## The entire input must be consumed.
|
||||
hexToByteArrayStrict(hexStr, result)
|
||||
|
||||
func hexToByteArrayStrict*(hexStr: openArray[char], N: static int): array[N, byte]
|
||||
{.raises: [ValueError, Defect], noinit, inline.}=
|
||||
## Read an hex string and store it in a byte array. No "endianness" reordering is done.
|
||||
## The entire input must be consumed.
|
||||
hexToByteArrayStrict(hexStr, result)
|
||||
|
||||
func fromHex*[N](A: type array[N, byte], hexStr: string): A
|
||||
{.raises: [ValueError, Defect], noinit, inline.}=
|
||||
## Read an hex string and store it in a byte array. No "endianness" reordering is done.
|
||||
|
@ -28,6 +28,32 @@ suite "Byte utils":
|
||||
hexToByteArray(s, a)
|
||||
check a == [255.byte, 255, 255, 255]
|
||||
|
||||
test "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
|
||||
|
||||
test "hexToByteArray: Return array":
|
||||
let
|
||||
s = "0x12345678"
|
||||
@ -115,6 +141,7 @@ suite "Byte utils":
|
||||
string.fromBytes([]) == ""
|
||||
@[byte(ord('a'))] == static("a".toBytes())
|
||||
"a" == static(string.fromBytes([byte(ord('a'))]))
|
||||
|
||||
test "slices":
|
||||
var a: array[4, byte]
|
||||
a[0..<2] = [2'u8, 3]
|
||||
|
Loading…
x
Reference in New Issue
Block a user