--- /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 <http://www.gnu.org/licenses/>.
+ */
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <sstream>
+#include <locale>
+#include <codecvt>
+#include <regex>
+#include <stdexcept>
+
+#include <relpipe/common/type/typedefs.h>
+#include <relpipe/reader/TypeId.h>
+#include <relpipe/reader/handlers/RelationalReaderStringHandler.h>
+#include <relpipe/reader/handlers/AttributeMetadata.h>
+
+#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<relpipe::reader::handlers::RelationalReaderStringHandler> currentHandler;
+
+ relpipe::reader::handlers::RelationalReaderStringHandler* createHandlerAuto(const relpipe::common::type::StringX& name, std::vector<relpipe::reader::handlers::AttributeMetadata> 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<relpipe::reader::handlers::AttributeMetadata> 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<relpipe::reader::handlers::AttributeMetadata> 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();
+ }
+
+};
+
+}
+}
+}