From 6d8fe721740a844eb176ee9b5eaf254e24032126 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Tue, 26 Jan 2016 15:23:42 +0900 Subject: [PATCH] src: Faster percent encode/deocde --- src/util.cc | 20 ++++++++++++-------- src/util.h | 23 ++++++++++++++--------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/util.cc b/src/util.cc index a2d649ef..32669dea 100644 --- a/src/util.cc +++ b/src/util.cc @@ -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; } diff --git a/src/util.h b/src/util.h index fd88f318..e460599b 100644 --- a/src/util.h +++ b/src/util.h @@ -98,19 +98,24 @@ std::string percent_encode_path(const std::string &s); template 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)); - first += 2; - continue; - } - result += *first; + if (*first != '%') { + *p++ = *first; continue; } - result += *first; + + 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; + } + + *p++ = *first; } + result.resize(p - std::begin(result)); return result; }