aboutsummaryrefslogtreecommitdiff
path: root/src/inspstring.cpp
diff options
context:
space:
mode:
authorGravatar Sadie Powell2021-05-10 22:54:16 +0100
committerGravatar Sadie Powell2021-05-10 22:54:16 +0100
commit7b92cf28664da516cfe5ec1390a672e358c15424 (patch)
tree23a12a678c95909f44a1251e5b2392def09bb46b /src/inspstring.cpp
parentRefactor the hex encoding function. (diff)
Extract percent encoding logic from spanningtree to inspstring.
Diffstat (limited to 'src/inspstring.cpp')
-rw-r--r--src/inspstring.cpp60
1 files changed, 60 insertions, 0 deletions
diff --git a/src/inspstring.cpp b/src/inspstring.cpp
index bb3eab2bb..e65e3918f 100644
--- a/src/inspstring.cpp
+++ b/src/inspstring.cpp
@@ -26,6 +26,66 @@
#include "inspircd.h"
+std::string Percent::Encode(const void* data, size_t length, const char* table, char padding)
+{
+ if (!table)
+ table = Percent::TABLE;
+
+ // Preallocate the output buffer to avoid constant reallocations.
+ std::string buffer;
+ buffer.reserve(length * 3);
+
+ const unsigned char* udata = reinterpret_cast<const unsigned char*>(data);
+ for (size_t idx = 0; idx < length; ++idx)
+ {
+ unsigned char chr = udata[idx];
+ if (strchr(table, chr))
+ {
+ // The character is on the safe list; push it as is.
+ buffer.push_back(chr);
+ }
+ else
+ {
+ // The character is not on the safe list; percent encode it.
+ buffer.push_back('%');
+ buffer.push_back(Hex::TABLE_UPPER[chr >> 4]);
+ buffer.push_back(Hex::TABLE_UPPER[chr & 15]);
+ }
+ }
+
+ return buffer;
+}
+
+std::string Percent::Decode(const void* data, size_t length)
+{
+ // Preallocate the output buffer to avoid constant reallocations.
+ std::string buffer;
+ buffer.reserve(length * 3);
+
+ const char* cdata = reinterpret_cast<const char*>(data);
+ for (size_t idx = 0; idx < length; ++idx)
+ {
+ if (cdata[idx] == '%')
+ {
+ // Percent encoding encodes two octets into 1-2 characters.
+ const char octet1 = ++idx < length ? toupper(cdata[idx]) : 0;
+ const char octet2 = ++idx < length ? toupper(cdata[idx]) : 0;
+
+ const char* table1 = strchr(Hex::TABLE_UPPER, octet1);
+ const char* table2 = strchr(Hex::TABLE_UPPER, octet2);
+
+ char pair = ((table1 ? table1 - Hex::TABLE_UPPER : 0) << 4) + (table2 ? table2 - Hex::TABLE_UPPER : 0);
+ buffer.push_back(pair);
+ }
+ else
+ {
+ buffer.push_back(cdata[idx]);
+ }
+ }
+
+ return buffer;
+}
+
std::string Hex::Encode(const void* data, size_t length, const char* table, char separator)
{
if (!table)