Add generic parseHex from parseutils
This commit is contained in:
parent
1a9ee7397d
commit
5e03d90ad3
|
@ -0,0 +1,55 @@
|
|||
# From: https://github.com/nim-lang/Nim/pull/11067/
|
||||
proc parseHex*[T: SomeInteger](s: string, number: var T, start = 0, maxLen = 0): int
|
||||
{.inline, noSideEffect.} =
|
||||
## Parses a hexadecimal number and stores its value in ``number``.
|
||||
##
|
||||
## Returns the number of the parsed characters or 0 in case of an error.
|
||||
## If error, the value of ``number`` is not changed.
|
||||
##
|
||||
## If ``maxLen == 0``, the parsing continues until the first non-hex character
|
||||
## or to the end of the string. Otherwise, no more than ``maxLen`` characters
|
||||
## are parsed starting from the ``start`` position.
|
||||
##
|
||||
## It does not check for overflow. If the value represented by the string is
|
||||
## too big to fit into ``number``, only the value of last fitting characters
|
||||
## will be stored in ``number`` without producing an error.
|
||||
runnableExamples:
|
||||
var num: int
|
||||
doAssert parseHex("4E_69_ED", num) == 8
|
||||
doAssert num == 5138925
|
||||
doAssert parseHex("X", num) == 0
|
||||
doAssert parseHex("#ABC", num) == 4
|
||||
var num8: int8
|
||||
doAssert parseHex("0x_4E_69_ED", num8) == 11
|
||||
doAssert num8 == 0xED'i8
|
||||
doAssert parseHex("0x_4E_69_ED", num8, 3, 2) == 2
|
||||
doAssert num8 == 0x4E'i8
|
||||
var num8u: uint8
|
||||
doAssert parseHex("0x_4E_69_ED", num8u) == 11
|
||||
doAssert num8u == 237
|
||||
var num64: int64
|
||||
doAssert parseHex("4E69ED4E69ED", num64) == 12
|
||||
doAssert num64 == 86216859871725
|
||||
var i = start
|
||||
var output = T(0)
|
||||
var foundDigit = false
|
||||
let last = min(s.len, if maxLen == 0: s.len else: i + maxLen)
|
||||
if i + 1 < last and s[i] == '0' and (s[i+1] in {'x', 'X'}): inc(i, 2)
|
||||
elif i < last and s[i] == '#': inc(i)
|
||||
while i < last:
|
||||
case s[i]
|
||||
of '_': discard
|
||||
of '0'..'9':
|
||||
output = output shl 4 or T(ord(s[i]) - ord('0'))
|
||||
foundDigit = true
|
||||
of 'a'..'f':
|
||||
output = output shl 4 or T(ord(s[i]) - ord('a') + 10)
|
||||
foundDigit = true
|
||||
of 'A'..'F':
|
||||
output = output shl 4 or T(ord(s[i]) - ord('A') + 10)
|
||||
foundDigit = true
|
||||
else: break
|
||||
inc(i)
|
||||
if foundDigit:
|
||||
number = output
|
||||
result = i - start
|
Loading…
Reference in New Issue