hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 86425c7d0d5337c4187b2e7e5de8c813a9e31cbd
parent 2ab02483e5356939d332ee44933787f6bc3e7cc2
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 24 Mar 2021 11:33:39 -0400

encoding::hex: add decode

Diffstat:
Mencoding/hex/hex.ha | 31+++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+), 0 deletions(-)

diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha @@ -1,8 +1,12 @@ +use bytes; use io; use strconv; use strings; use strio; +// Error returned when attempting to decode an invalid hex string. +export type invalid = void!; + // Encodes a byte slice to hex and writes it to a string. The caller must free // this string. export fn encode(b: []u8) str = { @@ -23,3 +27,30 @@ export fn encode(b: []u8) str = { defer free(s); assert(s == "cafebabedeadf00d"); }; + +// Decodes a string of hexadecimal bytes into a byte slice. The caller must free +// the return value. +export fn decode(s: str) ([]u8 | invalid) = { + if (len(s) % 2 != 0) { + return invalid; + }; + let buf: []u8 = alloc([], len(s) / 2); + let s = strings::to_utf8(s); + for (let i = 0z; i < len(s) / 2; i += 1) { + let oct = strings::from_utf8_unsafe(s[i * 2..i * 2 + 2]); + let u = match (strconv::stou8b(oct, 16)) { + (strconv::invalid | strconv::overflow) => return invalid, + u: u8 => u, + }; + append(buf, u); + }; + return buf; +}; + +@test fn decode() void = { + let s = decode("cafebabedeadf00d") as []u8; + defer free(s); + assert(bytes::equal(s, [0xCA, 0xFE, 0xBA, 0xBE, 0xDE, 0xAD, 0xF0, 0x0D])); + + decode("this is not hex") as invalid; +};