Added: encodeURIComponent, decodeURIComponent

feature/pre-code-move
Nimetu 5 years ago
parent 58cc988fbc
commit d2ccc09b7d

@ -307,6 +307,10 @@ template <class T> T trimQuotes (const T &str)
return str.substr(1, size - 2);
}
// encode/decode uri component using %AB hex encoding
std::string encodeURIComponent(const std::string &in);
std::string decodeURIComponent(const std::string &in);
//////////////////////////////////////////////////////////////////////////
// **** DEPRECATED *****: PLEASE DON'T USE THESE METHODS BUT FUNCTIONS ABOVE toLower() and toUpper()
//////////////////////////////////////////////////////////////////////////

@ -784,6 +784,94 @@ bool fromHexa(const char hexa, uint8 &b)
return false;
}
static std::vector<char> makeCharLookupTable(const std::string &chars)
{
std::vector<char> out(256, -1);
for(uint i = 0; i< chars.size(); i++)
out[chars[i]] = i;
return out;
}
std::string encodeURIComponent(const std::string &in)
{
static const char hexLookup[] = "0123456789ABCDEF";
static const std::vector<char> notEscaped(makeCharLookupTable(
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789"
"-_.!~*'()"
));
if (in.empty())
return std::string();
std::string out;
size_t inSize = in.size();
size_t outSize = in.size();
// resize to worst case for smaller strings,
// give some replacements for free for larger strings
if (in.size() < 100)
out.reserve(in.size() * 3);
else
out.reserve(in.size() + 200);
for(size_t i = 0; i < inSize; i++)
{
char ch = in[i];
if (notEscaped[(uint8)ch] == -1)
{
out += '%';
out += hexLookup[(ch>>4)& 0x0F];
out += hexLookup[ch & 0x0F];
outSize += 2;
}
else
{
out += ch;
}
}
// resize back to correct size
out.resize(outSize);
return out;
}
std::string decodeURIComponent(const std::string &in)
{
if (in.find("%") == std::string::npos)
return in;
std::string out;
out.resize(in.size());
size_t outIndex = 0, inSize = in.size();
for(size_t i = 0; i < inSize; i++, outIndex++)
{
if (in[i] == '%' && (i+2 < inSize))
{
uint8 a;
uint8 b;
if (fromHexa(in[i+1], a) && fromHexa(in[i+2], b))
{
out[outIndex] = (a << 4) | b;
i += 2;
} else {
// not hex chars
out[outIndex] = in[i];
}
}
else
{
out[outIndex] = in[i];
}
}
out.resize(outIndex);
return out;
}
std::string formatThousands(const std::string& s)
{
sint i, k;

@ -26,6 +26,8 @@ struct CUTMiscCommon : public Test::Suite
{
TEST_ADD(CUTMiscCommon::bytesToHumanReadableUnits);
TEST_ADD(CUTMiscCommon::humanReadableToBytes);
TEST_ADD(CUTMiscCommon::encodeURIComponent);
TEST_ADD(CUTMiscCommon::decodeURIComponent);
// Add a line here when adding a new test METHOD
}
@ -166,6 +168,27 @@ struct CUTMiscCommon : public Test::Suite
bytes = NLMISC::humanReadableToBytes("-1 B");
TEST_ASSERT(bytes == 0);
}
void encodeURIComponent()
{
TEST_ASSERT("%00" == NLMISC::encodeURIComponent(std::string("\x00", 1)));
TEST_ASSERT("%0A" == NLMISC::encodeURIComponent(std::string("\x0A", 1)));
TEST_ASSERT("%A0" == NLMISC::encodeURIComponent(std::string("\xA0", 1)));
TEST_ASSERT("a%20b" == NLMISC::encodeURIComponent("a b"));
TEST_ASSERT("a%2Bb" == NLMISC::encodeURIComponent("a+b"));
}
void decodeURIComponent()
{
TEST_ASSERT(std::string("\x00", 1) == NLMISC::decodeURIComponent(std::string("\x00", 1)));
TEST_ASSERT(std::string("\x0A", 1) == NLMISC::decodeURIComponent(std::string("\x0A", 1)));
TEST_ASSERT(std::string("\xA0", 1) == NLMISC::decodeURIComponent(std::string("\xA0", 1)));
TEST_ASSERT("a b" == NLMISC::decodeURIComponent("a%20b"));
TEST_ASSERT("a+b" == NLMISC::decodeURIComponent("a%2Bb"));
TEST_ASSERT("a%A" == NLMISC::decodeURIComponent("a%A"));
TEST_ASSERT("a%AX" == NLMISC::decodeURIComponent("a%AX"));
}
};
#endif

Loading…
Cancel
Save