diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2018-01-27 16:04:57 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2018-01-27 16:04:57 +0100 |
commit | 85411fab71952f234be0eb19934d7ff447cef339 (patch) | |
tree | 8312ba0df3a6a7b0fa6bc1501115a5d510d12311 /lib | |
parent | 78fb3ffeb1bf807f1632491d2e479c8669adc6a2 (diff) | |
parent | 1a565d7b2087f603a450527ab81e9d5a5f4ad831 (diff) | |
download | Nim-85411fab71952f234be0eb19934d7ff447cef339.tar.gz |
Merge branch 'devel' of github.com:nim-lang/Nim into devel
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pure/strutils.nim | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/pure/strutils.nim b/lib/pure/strutils.nim index dbb4db781..2ad006001 100644 --- a/lib/pure/strutils.nim +++ b/lib/pure/strutils.nim @@ -944,6 +944,19 @@ proc toHex*[T](x: T): string = ## Shortcut for ``toHex(x, T.sizeOf * 2)`` toHex(BiggestInt(x), T.sizeOf * 2) +proc toHex*(s: string): string {.noSideEffect, rtl.} = + ## Converts a bytes string to its hexadecimal representation. + ## + ## The output is twice the input long. No prefix like + ## ``0x`` is generated. + const HexChars = "0123456789ABCDEF" + result = newString(s.len * 2) + for pos, c in s: + var n = ord(c) + result[pos * 2 + 1] = HexChars[n and 0xF] + n = n shr 4 + result[pos * 2] = HexChars[n] + proc intToStr*(x: int, minchars: Positive = 1): string {.noSideEffect, rtl, extern: "nsuIntToStr".} = ## Converts `x` to its decimal representation. @@ -1026,6 +1039,43 @@ proc parseHexInt*(s: string): int {.noSideEffect, procvar, of '\0': break else: raise newException(ValueError, "invalid integer: " & s) +proc generateHexCharToValueMap(): string = + ## Generate a string to map a hex digit to uint value + result = "" + for inp in 0..255: + let ch = chr(inp) + let o = + case ch: + of '0'..'9': inp - ord('0') + of 'a'..'f': inp - ord('a') + 10 + of 'A'..'F': inp - ord('A') + 10 + else: 17 # indicates an invalid hex char + result.add chr(o) + +const hexCharToValueMap = generateHexCharToValueMap() + +proc parseHexStr*(s: string): string {.noSideEffect, procvar, + rtl, extern: "nsuParseHexStr".} = + ## Convert hex-encoded string to byte string, e.g.: + ## + ## .. code-block:: nim + ## hexToStr("00ff") == "\0\255" + ## + ## Raises ``ValueError`` for an invalid hex values. The comparison is + ## case-insensitive. + if s.len mod 2 != 0: + raise newException(ValueError, "Incorrect hex string len") + result = newString(s.len div 2) + var buf = 0 + for pos, c in s: + let val = hexCharToValueMap[ord(c)].ord + if val == 17: + raise newException(ValueError, "Invalid hex char " & repr(c)) + if pos mod 2 == 0: + buf = val + else: + result[pos div 2] = chr(val + buf shl 4) + proc parseBool*(s: string): bool = ## Parses a value into a `bool`. ## |