decode_helpers.nim 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. proc handleHexChar*(c: char, x: var int): bool {.inline.} =
  2. ## Converts `%xx` hexadecimal to the ordinal number and adds the result to `x`.
  3. ## Returns `true` if `c` is hexadecimal.
  4. ##
  5. ## When `c` is hexadecimal, the proc is equal to `x = x shl 4 + hex2Int(c)`.
  6. runnableExamples:
  7. var x = 0
  8. assert handleHexChar('a', x)
  9. assert x == 10
  10. assert handleHexChar('B', x)
  11. assert x == 171 # 10 shl 4 + 11
  12. assert not handleHexChar('?', x)
  13. assert x == 171 # unchanged
  14. result = true
  15. case c
  16. of '0'..'9': x = (x shl 4) or (ord(c) - ord('0'))
  17. of 'a'..'f': x = (x shl 4) or (ord(c) - ord('a') + 10)
  18. of 'A'..'F': x = (x shl 4) or (ord(c) - ord('A') + 10)
  19. else:
  20. result = false
  21. proc handleHexChar*(c: char): int {.inline.} =
  22. case c
  23. of '0'..'9': result = (ord(c) - ord('0'))
  24. of 'a'..'f': result = (ord(c) - ord('a') + 10)
  25. of 'A'..'F': result = (ord(c) - ord('A') + 10)
  26. else: discard
  27. proc decodePercent*(s: openArray[char], i: var int): char =
  28. ## Converts `%xx` hexadecimal to the character with ordinal number `xx`.
  29. ##
  30. ## If `xx` is not a valid hexadecimal value, it is left intact: only the
  31. ## leading `%` is returned as-is, and `xx` characters will be processed in the
  32. ## next step (e.g. in `uri.decodeUrl`) as regular characters.
  33. result = '%'
  34. if i+2 < s.len:
  35. var x = 0
  36. if handleHexChar(s[i+1], x) and handleHexChar(s[i+2], x):
  37. result = chr(x)
  38. inc(i, 2)