diff options
| author | hcpp <[email protected]> | 2023-11-08 12:09:41 +0300 |
|---|---|---|
| committer | hcpp <[email protected]> | 2023-11-08 12:56:14 +0300 |
| commit | a361f5b98b98b44ea510d274f6769164640dd5e1 (patch) | |
| tree | c47c80962c6e2e7b06798238752fd3da0191a3f6 /library/cpp/string_utils/tskv_format/escape.cpp | |
| parent | 9478806fde1f4d40bd5a45e7cbe77237dab613e9 (diff) | |
metrics have been added
Diffstat (limited to 'library/cpp/string_utils/tskv_format/escape.cpp')
| -rw-r--r-- | library/cpp/string_utils/tskv_format/escape.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/library/cpp/string_utils/tskv_format/escape.cpp b/library/cpp/string_utils/tskv_format/escape.cpp new file mode 100644 index 00000000000..3dc78bec8c0 --- /dev/null +++ b/library/cpp/string_utils/tskv_format/escape.cpp @@ -0,0 +1,112 @@ +#include <util/generic/yexception.h> +#include "escape.h" + +namespace NTskvFormat { + namespace { + const TStringBuf ESCAPE_CHARS("\t\n\r\\\0=\"", 7); + + TString& EscapeImpl(const char* src, size_t len, TString& dst) { + TStringBuf srcStr(src, len); + size_t noEscapeStart = 0; + + while (noEscapeStart < len) { + size_t noEscapeEnd = srcStr.find_first_of(ESCAPE_CHARS, noEscapeStart); + + if (noEscapeEnd == TStringBuf::npos) { + dst.append(src + noEscapeStart, len - noEscapeStart); + break; + } + + dst.append(src + noEscapeStart, noEscapeEnd - noEscapeStart); + + switch (src[noEscapeEnd]) { + case '\t': + dst.append(TStringBuf("\\t")); + break; + case '\n': + dst.append(TStringBuf("\\n")); + break; + case '\r': + dst.append(TStringBuf("\\r")); + break; + case '\0': + dst.append(TStringBuf("\\0")); + break; + case '\\': + dst.append(TStringBuf("\\\\")); + break; + case '=': + dst.append(TStringBuf("\\=")); + break; + case '"': + dst.append(TStringBuf("\\\"")); + break; + } + + noEscapeStart = noEscapeEnd + 1; + } + + return dst; + } + + TString& UnescapeImpl(const char* src, const size_t len, TString& dst) { + TStringBuf srcStr(src, len); + size_t noEscapeStart = 0; + + while (noEscapeStart < len) { + size_t noEscapeEnd = srcStr.find('\\', noEscapeStart); + + if (noEscapeEnd == TStringBuf::npos) { + dst.append(src + noEscapeStart, len - noEscapeStart); + break; + } + + dst.append(src + noEscapeStart, noEscapeEnd - noEscapeStart); + + if (noEscapeEnd + 1 >= len) { + throw yexception() << "expected (t|n|r|0|\\|=|\"|) after \\. Got end of line."; + } + + switch (src[noEscapeEnd + 1]) { + case 't': + dst.append('\t'); + break; + case 'n': + dst.append('\n'); + break; + case 'r': + dst.append('\r'); + break; + case '0': + dst.append('\0'); + break; + case '\\': + dst.append('\\'); + break; + case '=': + dst.append('='); + break; + case '"': + dst.append('"'); + break; + default: + throw yexception() << "unexpected symbol '" << src[noEscapeEnd + 1] << "' after \\"; + } + + noEscapeStart = noEscapeEnd + 2; + } + + return dst; + } + + } + + TString& Escape(const TStringBuf& src, TString& dst) { + return EscapeImpl(src.data(), src.size(), dst); + } + + TString& Unescape(const TStringBuf& src, TString& dst) { + return UnescapeImpl(src.data(), src.size(), dst); + } + +} |
