/// @module std::core::encoding
/// Encoding Utilities
///
/// URL encoding/decoding and other text encoding helpers.
/// For base64 and hex encoding, use the crypto module:
/// crypto.base64_encode(), crypto.base64_decode()
/// crypto.hex_encode(), crypto.hex_decode()
/// URL-encode a string (percent encoding).
///
/// Encodes all characters except unreserved ones (A-Z, a-z, 0-9, -, _, ., ~).
/// Spaces are encoded as %20 (not +).
///
/// @param s - string to encode
/// @returns URL-encoded string
pub fn url_encode(s: string) {
var result = "";
for i in range(0, s.len()) {
let ch = s[i];
if is_url_unreserved(ch) {
result = result + ch;
} else if ch == " " {
result = result + "%20";
} else {
// For ASCII printable chars, encode as %HH
result = result + "%" + char_to_hex(ch);
}
}
result
}
/// URL-decode a percent-encoded string.
///
/// @param s - URL-encoded string
/// @returns decoded string
pub fn url_decode(s: string) {
var result = "";
var i = 0;
let n = s.len();
while i < n {
let ch = s[i];
if ch == "%" && i + 2 < n {
let hex_str = s[i + 1] + s[i + 2];
let decoded = hex_to_char(hex_str);
result = result + decoded;
i = i + 3;
} else if ch == "+" {
result = result + " ";
i = i + 1;
} else {
result = result + ch;
i = i + 1;
}
}
result
}
// ===== Helpers =====
function is_url_unreserved(ch) {
let c = __intrinsic_char_code(ch);
(c >= 65 && c <= 90) ||
(c >= 97 && c <= 122) ||
(c >= 48 && c <= 57) ||
ch == "-" || ch == "_" || ch == "." || ch == "~"
}
function char_to_hex(ch) {
let hex_chars = "0123456789ABCDEF";
// Use char code to get hex representation
let code = __intrinsic_char_code(ch);
let hi = code / 16;
let lo = code % 16;
hex_chars[floor(hi)] + hex_chars[floor(lo)]
}
function hex_to_char(hex_str) {
let hi = hex_digit_value(hex_str[0]);
let lo = hex_digit_value(hex_str[1]);
__intrinsic_from_char_code(hi * 16 + lo)
}
function hex_digit_value(ch) {
let c = __intrinsic_char_code(ch);
if c >= 48 && c <= 57 {
c - 48
} else if c >= 65 && c <= 70 {
c - 65 + 10
} else if c >= 97 && c <= 102 {
c - 97 + 10
} else {
0
}
}