diff -r ee70b17950bd -r 80e129ec3408 src/lib/UnescapingINIHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/UnescapingINIHandler.h Wed Nov 25 21:50:26 2020 +0100 @@ -0,0 +1,99 @@ +/** + * Relational pipes + * Copyright © 2020 František Kučera (Frantovo.cz, GlobalCode.info) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#pragma once + +#include + +#include "INIReader.h" + +using namespace std; +using namespace relpipe::writer; + +namespace relpipe { +namespace in { +namespace ini { +namespace lib { + +class UnescapingINIContentHandler : public INIContentHandler { +private: + INIContentHandler& output; + +protected: + const char ESC = '\\'; + bool lastEscaphingPhase; + + std::stringstream& put(std::stringstream& result, const char& ch, int& i) { + result.put(ch); + i++; + return result; + } + + virtual std::string unescape(const std::string& s) = 0; + +public: + + /** + * @param output here will be sent events with unescaped values + * @param lastEscaphingPhase instances of UnescapingINIContentHandler might be chained: + * unsupported escaping sequences are kept untouched to be processed in further phases; + * in the last phase, all remaining sequences (including \\) must be recognized and unescaped + * (otherwise the input is considered invalid and an exception is thrown) + */ + UnescapingINIContentHandler(INIContentHandler& output, bool lastEscaphingPhase) : output(output), lastEscaphingPhase(lastEscaphingPhase) { + } + + void startDocument() override { + output.startDocument(); + } + + void endDocument() override { + output.endDocument(); + } + + void startSection(const SectionStartEvent& event) override { + SectionStartEvent e = event; + e.name = unescape(e.name); + output.startSection(e); + } + + void endSection() override { + output.endSection(); + } + + void entry(const EntryEvent& event) override { + EntryEvent e = event; + e.key = unescape(e.key); + e.fullKey = unescape(e.fullKey); + e.subKey = unescape(e.subKey); + e.value = unescape(e.value); + output.entry(e); + } + + void comment(const CommentEvent& event) override { + output.comment(event); + } + + void whitespace(const WhitespaceEvent& event) override { + output.whitespace(event); + } + +}; + +} +} +} +}