src: Faster percent encode/deocde

This commit is contained in:
Tatsuhiro Tsujikawa 2016-01-26 15:23:42 +09:00
parent 98253b1d0d
commit 6d8fe72174
2 changed files with 26 additions and 17 deletions

View File

@ -131,20 +131,24 @@ bool in_attr_char(char c) {
}
std::string percent_encode_token(const std::string &target) {
auto len = target.size();
std::string dest;
for (size_t i = 0; i < len; ++i) {
unsigned char c = target[i];
dest.resize(target.size() * 3);
auto p = std::begin(dest);
for (auto first = std::begin(target); first != std::end(target); ++first) {
uint8_t c = *first;
if (c != '%' && in_token(c)) {
dest += c;
} else {
dest += '%';
dest += UPPER_XDIGITS[c >> 4];
dest += UPPER_XDIGITS[(c & 0x0f)];
*p++ = c;
continue;
}
*p++ = '%';
*p++ = UPPER_XDIGITS[c >> 4];
*p++ = UPPER_XDIGITS[(c & 0x0f)];
}
dest.resize(p - std::begin(dest));
return dest;
}

View File

@ -98,19 +98,24 @@ std::string percent_encode_path(const std::string &s);
template <typename InputIt>
std::string percent_decode(InputIt first, InputIt last) {
std::string result;
result.resize(last - first);
auto p = std::begin(result);
for (; first != last; ++first) {
if (*first == '%') {
if (first + 1 != last && first + 2 != last &&
is_hex_digit(*(first + 1)) && is_hex_digit(*(first + 2))) {
result += (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
if (*first != '%') {
*p++ = *first;
continue;
}
if (first + 1 != last && first + 2 != last && is_hex_digit(*(first + 1)) &&
is_hex_digit(*(first + 2))) {
*p++ = (hex_to_uint(*(first + 1)) << 4) + hex_to_uint(*(first + 2));
first += 2;
continue;
}
result += *first;
continue;
}
result += *first;
*p++ = *first;
}
result.resize(p - std::begin(result));
return result;
}