diff --git a/dbms/include/DB/IO/ReadHelpers.h b/dbms/include/DB/IO/ReadHelpers.h index 14a2153f090..54c697c83a2 100644 --- a/dbms/include/DB/IO/ReadHelpers.h +++ b/dbms/include/DB/IO/ReadHelpers.h @@ -217,6 +217,8 @@ void readEscapedString(String & s, ReadBuffer & buf); void readQuotedString(String & s, ReadBuffer & buf); +void readDoubleQuotedString(String & s, ReadBuffer & buf); + /// в формате YYYY-MM-DD inline void readDateText(Yandex::DayNum_t & date, ReadBuffer & buf) diff --git a/dbms/include/DB/IO/WriteHelpers.h b/dbms/include/DB/IO/WriteHelpers.h index 0732361ba71..f9064b60bda 100644 --- a/dbms/include/DB/IO/WriteHelpers.h +++ b/dbms/include/DB/IO/WriteHelpers.h @@ -93,6 +93,9 @@ inline void writeQuotedString(const String & s, WriteBuffer & buf) writeChar('\'', buf); } +/// Совместимо с JSON. +void writeDoubleQuotedString(const String & s, WriteBuffer & buf); + /// в формате YYYY-MM-DD inline void writeDateText(Yandex::DayNum_t date, WriteBuffer & buf) diff --git a/dbms/src/IO/ReadHelpers.cpp b/dbms/src/IO/ReadHelpers.cpp index dcdf7e267cd..2cd41da171b 100644 --- a/dbms/src/IO/ReadHelpers.cpp +++ b/dbms/src/IO/ReadHelpers.cpp @@ -58,12 +58,14 @@ void readEscapedString(String & s, ReadBuffer & buf) } } -void readQuotedString(String & s, ReadBuffer & buf) + +template +static void readAnyQuotedString(String & s, ReadBuffer & buf) { s = ""; - if (buf.eof() || *buf.position() != '\'') - throw Exception("Cannot parse quoted string: expected opening single quote", + if (buf.eof() || *buf.position() != quote) + throw Exception("Cannot parse quoted string: expected opening quote", ErrorCodes::CANNOT_PARSE_QUOTED_STRING); ++buf.position(); @@ -71,13 +73,13 @@ void readQuotedString(String & s, ReadBuffer & buf) { size_t bytes = 0; for (; buf.position() + bytes != buf.buffer().end(); ++bytes) - if (buf.position()[bytes] == '\\' || buf.position()[bytes] == '\'') + if (buf.position()[bytes] == '\\' || buf.position()[bytes] == quote) break; s.append(buf.position(), bytes); buf.position() += bytes; - if (*buf.position() == '\'') + if (*buf.position() == quote) { ++buf.position(); return; @@ -93,8 +95,19 @@ void readQuotedString(String & s, ReadBuffer & buf) } } - throw Exception("Cannot parse quoted string: expected closing single quote", + throw Exception("Cannot parse quoted string: expected closing quote", ErrorCodes::CANNOT_PARSE_QUOTED_STRING); } + +void readQuotedString(String & s, ReadBuffer & buf) +{ + readAnyQuotedString<'\''>(s, buf); +} + +void readDoubleQuotedString(String & s, ReadBuffer & buf) +{ + readAnyQuotedString<'"'>(s, buf); +} + } diff --git a/dbms/src/IO/WriteHelpers.cpp b/dbms/src/IO/WriteHelpers.cpp index 01573dfff05..1b0a79a2bc6 100644 --- a/dbms/src/IO/WriteHelpers.cpp +++ b/dbms/src/IO/WriteHelpers.cpp @@ -37,6 +37,48 @@ void writeEscapedString(const String & s, WriteBuffer & buf) writeChar('\\', buf); writeChar('\'', buf); break; + case '\\': + writeChar('\\', buf); + writeChar('\\', buf); + break; + default: + writeChar(*it, buf); + } + } +} + + +void writeDoubleQuotedString(const String & s, WriteBuffer & buf) +{ + writeChar('"', buf); + for (String::const_iterator it = s.begin(); it != s.end(); ++it) + { + switch (*it) + { + case '\b': + writeChar('\\', buf); + writeChar('b', buf); + break; + case '\f': + writeChar('\\', buf); + writeChar('f', buf); + break; + case '\n': + writeChar('\\', buf); + writeChar('n', buf); + break; + case '\r': + writeChar('\\', buf); + writeChar('r', buf); + break; + case '\t': + writeChar('\\', buf); + writeChar('t', buf); + break; + case '\0': + writeChar('\\', buf); + writeChar('0', buf); + break; case '"': writeChar('\\', buf); writeChar('"', buf); @@ -49,6 +91,7 @@ void writeEscapedString(const String & s, WriteBuffer & buf) writeChar(*it, buf); } } + writeChar('"', buf); } }