From fd04142b2accb08ab3c79bfd5c5bffd25b3f5784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Fri, 17 Apr 2020 22:19:51 +0200 Subject: Storage: newline support in records --- src/storage.cpp | 47 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/storage.cpp b/src/storage.cpp index 6a0669c..16662df 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -642,21 +642,31 @@ optional> RecordT::decode(const S & st, auto items = make_shared>(); while (begin != end) { - const auto newline = std::find(begin, end, '\n'); - if (newline == end) + const auto colon = std::find(begin, end, ':'); + if (colon == end) throw runtime_error("invalid record"); + const string name(begin, colon); - const auto colon = std::find(begin, newline, ':'); - if (colon == newline) + const auto space = std::find(colon + 1, end, ' '); + if (space == end) throw runtime_error("invalid record"); + const string type(colon + 1, space); - const auto space = std::find(colon, newline, ' '); - if (space == newline) - throw runtime_error("invalid record"); - - const auto name = string(begin, colon); - const auto type = string(colon + 1, space); - const auto value = string(space + 1, newline); + begin = space + 1; + string value; + for (bool cont = true; cont; ) { + auto newline = std::find(begin, end, '\n'); + if (newline == end) + throw runtime_error("invalid record"); + + if (newline + 1 != end && *(newline + 1) == '\t') + newline++; + else + cont = false; + + value.append(begin, newline); + begin = newline + 1; + } if (type == "i") items->emplace_back(name, std::stoi(value)); @@ -680,8 +690,6 @@ optional> RecordT::decode(const S & st, } else items->emplace_back(name, typename Item::UnknownType { type, value }); - - begin = newline + 1; } return RecordT(items); @@ -765,8 +773,17 @@ vector RecordT::encodeInner() const copy(type.begin(), type.end(), inserter); inserter = ' '; - copy(value.begin(), value.end(), inserter); - inserter = '\n'; + + auto i = value.begin(); + while (true) { + auto j = std::find(i, value.end(), '\n'); + copy(i, j, inserter); + inserter = '\n'; + if (j == value.end()) + break; + inserter = '\t'; + i = j + 1; + } } return res; } -- cgit v1.2.3