2019-07-02 03:32:09 +00:00

96 lines
2.8 KiB
Plaintext
Executable File

module std+, uri {
private import rt::c;
private var
rfc3986_table(256) char = 0,
html5_table(256) char = 0;
func urlencode_init() {
forvar i int = 0; i < 256; i++ {
if isalnum(i) or i == '~' or i == '-' or i == '.' or i == '_' {
rfc3986_table[i] = i;
else
rfc3986_table[i] = '\0';
}
if isalnum(i) or i == '*' or i == '-' or i == '.' or i == '_' {
html5_table[i] = i;
else
if i == ' ' {
html5_table[i] = '+';
else
html5_table[i] = '\0';
}
}
}
}
private func urlencode(table. char, str. char, upper bool = false) .char {
static lower_charset() char = "0123456789abcdef";
static upper_charset() char = "0123456789ABCDEF";
var charset. char;
if upper {
charset = &upper_charset;
else
charset = &lower_charset;
}
var len size_t = strlen(str);
var enc. char = (func = malloc((len * 3) + 1));
forvar i size_t = 0; i < len; i++ {
var b byte = str[i];
var c char = table[b];
if c {
.enc++ = c;
else
.enc++ = '%';
.enc++ = charset[b >> 4];
.enc++ = charset[b & 15];
}
}
.enc = '\0';
}
inline urlencode_rfc3986(str. char, upper bool = false) .char {
return urlencode(&rfc3986_table, str, upper);
}
inline urlencode_html5(str. char, upper bool = false) .char {
return urlencode(&html5_table, str, upper);
}
func urldecode(str. char) .char {
var len size_t = strlen(str);
var dec. char = (func = malloc(len + 1));
forvar i size_t = 0; i < len; i++ {
var c char = str[i];
if c == '%' {
if i + 2 < len {
lambda from_hex(c char) char [
if islower(c) {
return c - 'a' + 10;
elseif isupper(c);
return c - 'A' + 10;
elseif isdigit(c);
return c - '0';
}
return 0;
];
.dec++ =
from_hex(str[i + 1]) << 4 |
from_hex(str[i + 2]);
i += 2;
else
break;
}
elseif c == '+';
.dec++ = ' ';
else
.dec++ = c;
}
}
.dec = '\0';
}
}