to_expression_string: fix backslash-escapes in strings
This commit is contained in:
parent
f19b8e8eff
commit
2d88fec458
1 changed files with 44 additions and 3 deletions
|
@ -710,14 +710,55 @@ struct to_unicode_impl
|
||||||
|
|
||||||
struct to_expression_string_impl
|
struct to_expression_string_impl
|
||||||
{
|
{
|
||||||
|
struct EscapingByteSink : U_NAMESPACE_QUALIFIER ByteSink
|
||||||
|
{
|
||||||
|
std::string dest_;
|
||||||
|
char quote_;
|
||||||
|
|
||||||
|
explicit EscapingByteSink(char quote)
|
||||||
|
: quote_(quote)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual void Append(const char* data, int32_t n)
|
||||||
|
{
|
||||||
|
// reserve enough room to hold the appended chunk and quotes;
|
||||||
|
// if another chunk follows, or any character needs escaping,
|
||||||
|
// the string will grow naturally
|
||||||
|
if (dest_.empty())
|
||||||
|
{
|
||||||
|
dest_.reserve(2 + static_cast<std::size_t>(n));
|
||||||
|
dest_.append(1, quote_);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dest_.reserve(dest_.size() + n + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto end = data + n; data < end; ++data)
|
||||||
|
{
|
||||||
|
if (*data == '\\' || *data == quote_)
|
||||||
|
dest_.append(1, '\\');
|
||||||
|
dest_.append(1, *data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Flush()
|
||||||
|
{
|
||||||
|
if (dest_.empty())
|
||||||
|
dest_.append(2, quote_);
|
||||||
|
else
|
||||||
|
dest_.append(1, quote_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
explicit to_expression_string_impl(char quote = '\'')
|
explicit to_expression_string_impl(char quote = '\'')
|
||||||
: quote_(quote) {}
|
: quote_(quote) {}
|
||||||
|
|
||||||
std::string operator() (value_unicode_string const& val) const
|
std::string operator() (value_unicode_string const& val) const
|
||||||
{
|
{
|
||||||
std::string utf8;
|
EscapingByteSink sink(quote_);
|
||||||
to_utf8(val,utf8);
|
val.toUTF8(sink);
|
||||||
return quote_ + utf8 + quote_;
|
return sink.dest_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string operator() (value_integer val) const
|
std::string operator() (value_integer val) const
|
||||||
|
|
Loading…
Add table
Reference in a new issue