summaryrefslogtreecommitdiff
path: root/src/string.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/string.cc')
-rw-r--r--src/string.cc31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/string.cc b/src/string.cc
index e4b5c0e2..d9689938 100644
--- a/src/string.cc
+++ b/src/string.cc
@@ -61,11 +61,21 @@ String escape(StringView str, StringView characters, char escape)
{
String res;
res.reserve(str.length());
- for (auto& c : str)
+ for (auto it = str.begin(), end = str.end(); it != end; )
{
- if (contains(characters, c))
- res += escape;
- res += c;
+ auto next = std::find_if(it, end, [&characters](char c) { return contains(characters, c); });
+ if (next != end)
+ {
+ res += StringView{it, next+1};
+ res.back() = escape;
+ res += *next;
+ it = next+1;
+ }
+ else
+ {
+ res += StringView{it, next};
+ break;
+ }
}
return res;
}
@@ -74,12 +84,17 @@ String unescape(StringView str, StringView characters, char escape)
{
String res;
res.reserve(str.length());
- for (auto& c : str)
+ for (auto it = str.begin(), end = str.end(); it != end; )
{
- if (contains(characters, c) and not res.empty() and res.back() == escape)
- res.back() = c;
+ auto next = std::find(it, end, escape);
+ if (next != end and next+1 != end and contains(characters, *(next+1)))
+ {
+ res += StringView{it, next+1};
+ res.back() = *(next+1);
+ }
else
- res += c;
+ res += StringView{it, next == end ? next : next + 1};
+ it = next == end ? next : next + 1;
}
return res;
}