diff -r 000000000000 -r 1bb084f84eb9 src/INIDispatchHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/INIDispatchHandler.h Wed Dec 09 17:55:03 2020 +0100 @@ -0,0 +1,105 @@ +/** + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "Configuration.h" +#include "INIWriter.h" +#include "INIStandardHandler.h" +#include "INILiteralHandler.h" + +namespace relpipe { +namespace out { +namespace ini { + +class INIDispatchHandler : public relpipe::reader::handlers::RelationalReaderStringHandler { +private: + std::ostream& output; + INIWriter writer; + Configuration& configuration; + std::shared_ptr currentHandler; + + relpipe::reader::handlers::RelationalReaderStringHandler* createHandlerAuto(const relpipe::common::type::StringX& name, std::vector attributes) { + bool hasKey = false; + bool hasValue = false; + + for (auto a : attributes) { + if (a.getAttributeName() == L"key") hasKey = true; + else if (a.getAttributeName() == L"value") hasValue = true; + } + + if (hasKey && hasValue) return new INIStandardHandler(writer); + else return new INILiteralHandler(writer); + } + + relpipe::reader::handlers::RelationalReaderStringHandler* createHandler(const relpipe::common::type::StringX& name, std::vector attributes) { + for (auto rc : configuration.relationConfigurations) { + if (std::regex_match(name, std::wregex(rc.relation))) { + if (rc.style == Style::Standard) return new INIStandardHandler(writer); + else if (rc.style == Style::Literal) return new INILiteralHandler(writer); + else if (rc.style == Style::LiteralWithSectionAttribute) return new INILiteralHandler(writer, L"section"); + else if (rc.style == Style::Dropped) return nullptr; + else if (rc.style == Style::Automatic) return createHandlerAuto(name, attributes); + else throw std::invalid_argument("Unsupported style: " + std::to_string((int) rc.style)); + } + } + + if (configuration.relationConfigurations.size()) return nullptr; + else return createHandlerAuto(name, attributes); + } + +public: + + INIDispatchHandler(std::ostream& output, Configuration& configuration) : output(output), writer(output), configuration(configuration) { + for (auto o : configuration.writerOptions) writer.setOption(o.uri, o.value); + } + + void startRelation(relpipe::common::type::StringX name, std::vector attributes) override { + if (currentHandler) currentHandler->endOfPipe(); + currentHandler.reset(createHandler(name, attributes)); + if (currentHandler) currentHandler->startRelation(name, attributes); + } + + void attribute(const relpipe::common::type::StringX& value) override { + if (currentHandler) currentHandler->attribute(value); + } + + void endOfPipe() { + if (currentHandler) currentHandler->endOfPipe(); + currentHandler.reset(); + output.flush(); + } + +}; + +} +} +}