thalassa/cms/urlenc.cpp

92 lines
2.1 KiB
C++
Raw Normal View History

2026-03-19 01:23:52 +00:00
#include "urlenc.hpp"
static int hexdig(int v)
{
v &= 0x0f;
return v <= 9 ? v + '0' : v + 'A' - 10;
}
static const char *percent_enc_char(int c)
{
static char res[4] = "%..";
res[1] = hexdig(c >> 4);
res[2] = hexdig(c);
return res;
}
static int hexdigvalue(int c)
{
if(c >= '0' && c <= '9')
return c - '0';
if(c >= 'a' && c <= 'f')
return c - 'a' + 10;
if(c >= 'A' && c <= 'F')
return c - 'A' + 10;
return -1;
}
ScriptVariable url_encode(const ScriptVariable &plain_sv)
{
ScriptVariable res;
const char *plain = plain_sv.c_str();
for(; *plain; plain++) {
if(*plain == ' ') {
res += '+';
} else
if((*plain >= 'A' && *plain <= 'Z') ||
(*plain >= 'a' && *plain <= 'z') ||
(*plain >= '0' && *plain <= '9') ||
*plain == '-' || *plain == '_' || *plain == '~' || *plain == '.')
{
res += *plain;
} else {
res += percent_enc_char(*plain);
}
}
return res;
}
static const char *decoded_byte(const char *enc)
{
static char buf[4] = "\0\0\0";
int dig1 = hexdigvalue(*enc);
int dig2 = hexdigvalue(enc[1]);
if(dig1 == -1 || dig2 == -1) {
buf[0] = '%';
buf[1] = *enc;
buf[2] = enc[1]; // NB: buf[3] never changes
} else {
buf[0] = (dig2 & 0x0f) | ((dig1 << 4) & 0xf0);
buf[1] = 0;
}
return buf;
}
ScriptVariable url_decode(const ScriptVariable &encoded_sv)
{
ScriptVariable res;
const char *encoded = encoded_sv.c_str();
while(*encoded) {
if(*encoded == '+') {
res += ' ';
encoded++;
} else
if(*encoded == '%') {
if(encoded[1] && encoded[2]) {
res += decoded_byte(encoded+1);
encoded += 3;
} else {
// unexpected end of line; leave %_ as is
res += encoded;
break;
}
} else {
res += *encoded;
encoded++;
}
}
return res;
}