mirror of
https://github.com/odin-lang/Odin.git
synced 2026-04-29 01:33:56 +00:00
add encoding/hex and use it to expand the percent decoding chars
This commit is contained in:
74
core/encoding/hex/hex.odin
Normal file
74
core/encoding/hex/hex.odin
Normal file
@@ -0,0 +1,74 @@
|
||||
package hex
|
||||
|
||||
import "core:strings"
|
||||
|
||||
encode :: proc(src: []byte, allocator := context.allocator) -> []byte #no_bounds_check {
|
||||
dst := make([]byte, len(src) * 2, allocator)
|
||||
for i := 0; i < len(src); i += 1 {
|
||||
v := src[i]
|
||||
dst[i] = HEXTABLE[v>>4]
|
||||
dst[i+1] = HEXTABLE[v&0x0f]
|
||||
i += 2
|
||||
}
|
||||
|
||||
return dst
|
||||
}
|
||||
|
||||
|
||||
decode :: proc(src: []byte, allocator := context.allocator) -> (dst: []byte, ok: bool) #no_bounds_check {
|
||||
if len(src) % 2 == 1 {
|
||||
return
|
||||
}
|
||||
|
||||
dst = make([]byte, len(src) / 2, allocator)
|
||||
for i, j := 0, 1; j < len(src); j += 2 {
|
||||
p := src[j-1]
|
||||
q := src[j]
|
||||
|
||||
a := hex_digit(p) or_return
|
||||
b := hex_digit(q) or_return
|
||||
|
||||
dst[i] = (a << 4) | b
|
||||
i += 1
|
||||
}
|
||||
|
||||
return dst, true
|
||||
}
|
||||
|
||||
// Decodes the given sequence into one byte.
|
||||
// Should be called with one rune worth of the source, eg: 0x23 -> '#'.
|
||||
decode_sequence :: proc(str: string) -> (byte, bool) {
|
||||
no_prefix_str := strings.trim_prefix(str, "0x")
|
||||
val: byte
|
||||
for i := 0; i < len(no_prefix_str); i += 1 {
|
||||
index := (len(no_prefix_str) - 1) - i // reverse the loop.
|
||||
|
||||
hd, ok := hex_digit(no_prefix_str[i])
|
||||
if !ok {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
val += u8(hd) << uint(4 * index)
|
||||
}
|
||||
|
||||
return val, true
|
||||
}
|
||||
|
||||
@(private)
|
||||
HEXTABLE := [16]byte {
|
||||
'0', '1', '2', '3',
|
||||
'4', '5', '6', '7',
|
||||
'8', '9', 'a', 'b',
|
||||
'c', 'd', 'e', 'f',
|
||||
}
|
||||
|
||||
@(private)
|
||||
hex_digit :: proc(char: byte) -> (u8, bool) {
|
||||
switch char {
|
||||
case '0' ..= '9': return char - '0', true
|
||||
case 'a' ..= 'f': return char - 'a' + 10, true
|
||||
case 'A' ..= 'F': return char - 'A' + 10, true
|
||||
case: return 0, false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user