mirror of https://github.com/aria2/aria2
util::htmlEscape: Optimize a bit
The cause of slowness of the first implementation is the memory allocation overhead and appending character by character. In this implementation, the output buffer is reserved the same size of input. This is reasonable because most likely no replacement happens in practice. And the unmodified region is copied using iterator range to speed up a bit.pull/122/head
parent
3b0ad59ee5
commit
acd2af82d0
47
src/util.cc
47
src/util.cc
|
@ -1542,32 +1542,31 @@ getNumericNameInfo(const struct sockaddr* sockaddr, socklen_t len)
|
|||
|
||||
std::string htmlEscape(const std::string& src)
|
||||
{
|
||||
std::string rv(src);
|
||||
std::string::size_type pos = 0;
|
||||
while ((pos = rv.find_first_of("<>&\"'", pos)) != std::string::npos) {
|
||||
auto ch = rv[pos];
|
||||
if (ch == '<') {
|
||||
rv.replace(pos, 1, "<");
|
||||
pos += 4;
|
||||
}
|
||||
else if (ch == '>') {
|
||||
rv.replace(pos, 1, ">");
|
||||
pos += 4;
|
||||
}
|
||||
else if (ch == '&') {
|
||||
rv.replace(pos, 1, "&");
|
||||
pos += 5;
|
||||
}
|
||||
else if (ch == '"') {
|
||||
rv.replace(pos, 1, """);
|
||||
pos += 6;
|
||||
}
|
||||
else { // '\''
|
||||
rv.replace(pos, 1, "'");
|
||||
pos += 5;
|
||||
std::string dest;
|
||||
dest.reserve(src.size());
|
||||
auto j = std::begin(src);
|
||||
for(auto i = std::begin(src); i != std::end(src); ++i) {
|
||||
char ch = *i;
|
||||
const char *repl;
|
||||
if(ch == '<') {
|
||||
repl = "<";
|
||||
} else if(ch == '>') {
|
||||
repl = ">";
|
||||
} else if(ch == '&') {
|
||||
repl = "&";
|
||||
} else if(ch == '\'') {
|
||||
repl = "'";
|
||||
} else if(ch == '"') {
|
||||
repl = """;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
dest.append(j, i);
|
||||
j = i + 1;
|
||||
dest += repl;
|
||||
}
|
||||
return rv;
|
||||
dest.append(j, std::end(src));
|
||||
return dest;
|
||||
}
|
||||
|
||||
std::pair<size_t, std::string>
|
||||
|
|
Loading…
Reference in New Issue