# HG changeset patch # User František Kučera # Date 1547162972 -3600 # Node ID 3ab78bf63467b887f4c7d224614fd1f7dcc6d922 # Parent 9aed8c2ea97d841a1a9b5f87be95a8142c2bf172 read XML from istream using Xerces (just parse/validate, no processing yet) diff -r 9aed8c2ea97d -r 3ab78bf63467 nbproject/configurations.xml --- a/nbproject/configurations.xml Thu Jan 10 20:05:13 2019 +0100 +++ b/nbproject/configurations.xml Fri Jan 11 00:29:32 2019 +0100 @@ -42,6 +42,7 @@ + StreamInputSource.h relpipe-in-xml.cpp @@ -91,6 +92,8 @@ true + + @@ -130,6 +133,8 @@ true + + diff -r 9aed8c2ea97d -r 3ab78bf63467 src/StreamInputSource.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/StreamInputSource.h Fri Jan 11 00:29:32 2019 +0100 @@ -0,0 +1,72 @@ +/** + * Relational pipes + * Copyright © 2018 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, either version 3 of the License, or + * (at your option) any later version. + * + * 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 + +namespace relpipe { +namespace in { +namespace xml { + +class StreamInputSource : public xercesc::InputSource { +private: + std::istream& input; + + class StreamBinInputStream : public xercesc::BinInputStream { + private: + std::istream& input; + public: + + StreamBinInputStream(std::istream& input) : BinInputStream(), input(input) { + } + + XMLFilePos curPos() const override { + return input.tellg(); + } + + const XMLCh* getContentType() const override { + return nullptr; + } + + XMLSize_t readBytes(XMLByte * const toFill, const XMLSize_t maxToRead) override { + input.read((char*) toFill, maxToRead); + return input.gcount(); + } + }; + +public: + + StreamInputSource(std::istream& input, xercesc::MemoryManager * const manager = xercesc::XMLPlatformUtils::fgMemoryManager) : InputSource(manager), input(input) { + } + + virtual ~StreamInputSource() { + } + + xercesc::BinInputStream* makeStream() const override { + // TODO: avoid multiple calls, input can be used only once + return new StreamBinInputStream(input); + } +}; + +} +} +} \ No newline at end of file diff -r 9aed8c2ea97d -r 3ab78bf63467 src/XMLCommand.h --- a/src/XMLCommand.h Thu Jan 10 20:05:13 2019 +0100 +++ b/src/XMLCommand.h Fri Jan 11 00:29:32 2019 +0100 @@ -30,6 +30,8 @@ #include +#include "StreamInputSource.h" + namespace relpipe { namespace in { namespace xml { @@ -40,7 +42,23 @@ void process(std::istream& input, std::ostream& output) { using namespace relpipe::writer; using namespace xercesc; - std::shared_ptr writer(Factory::create(output)); + unique_ptr writer(Factory::create(output)); + XMLPlatformUtils::Initialize(); + + + unique_ptr parser(XMLReaderFactory::createXMLReader()); + parser->setFeature(XMLUni::fgSAX2CoreValidation, true); + parser->setFeature(XMLUni::fgSAX2CoreNameSpaces, true); + + // TODO: custom handler that reads + DefaultHandler defaultHandler; + parser->setContentHandler(&defaultHandler); + parser->setErrorHandler(&defaultHandler); + + StreamInputSource inputSource(input); + + parser->parse(inputSource); + // TODO: remove demo // Various data types passed as strings @@ -53,7 +71,7 @@ writer->writeAttribute(L"a"); writer->writeAttribute(L"1"); writer->writeAttribute(L"true"); - + } }; diff -r 9aed8c2ea97d -r 3ab78bf63467 src/relpipe-in-xml.cpp --- a/src/relpipe-in-xml.cpp Thu Jan 10 20:05:13 2019 +0100 +++ b/src/relpipe-in-xml.cpp Fri Jan 11 00:29:32 2019 +0100 @@ -46,10 +46,16 @@ XMLCommand command; command.process(cin, cout); resultCode = CLI::EXIT_CODE_SUCCESS; - } catch (RelpipeWriterException e) { + } catch (RelpipeWriterException& e) { fwprintf(stderr, L"Caught Writer exception: %ls\n", e.getMessge().c_str()); fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); resultCode = CLI::EXIT_CODE_DATA_ERROR; + } catch (const xercesc::XMLException& e) { + // TODO: print message + // char* message = xercesc::XMLString::transcode(e.getMessage()); + fwprintf(stderr, L"Caught xercesc::XMLException\n"); + fwprintf(stderr, L"Debug: Input stream: eof=%ls, lastRead=%d\n", (cin.eof() ? L"true" : L"false"), cin.gcount()); + resultCode = CLI::EXIT_CODE_UNEXPECTED_ERROR; } return resultCode;