# HG changeset patch # User František Kučera # Date 1627206835 -7200 # Node ID 7128fabeede0f14390657ab2d1b01036a6602c8b # Parent 68a281aefa7610fb2cbae27c13a3d59638df5062 FreeformASN1ContentHandler: basic ASN.1 tree in a relation diff -r 68a281aefa76 -r 7128fabeede0 nbproject/configurations.xml --- a/nbproject/configurations.xml Sat Jul 24 17:35:27 2021 +0200 +++ b/nbproject/configurations.xml Sun Jul 25 11:53:55 2021 +0200 @@ -42,7 +42,12 @@ + + AbstractParser.cpp + ASN1Command.cpp + FreeformASN1ContentHandler.h + RelpipeASN1ContentHandler.h relpipe-in-asn1.cpp @@ -97,6 +102,14 @@ + + + + + + + + @@ -131,6 +144,10 @@ true + + + + diff -r 68a281aefa76 -r 7128fabeede0 src/ASN1Command.cpp --- a/src/ASN1Command.cpp Sat Jul 24 17:35:27 2021 +0200 +++ b/src/ASN1Command.cpp Sun Jul 25 11:53:55 2021 +0200 @@ -26,11 +26,17 @@ #include +#include "lib/ASN1ContentHandler.h" +#include "lib/BasicASN1Reader.h" +#include "lib/TransactionalBuffer.h" + #include "ASN1Command.h" +#include "RelpipeASN1ContentHandler.h" +#include "FreeformASN1ContentHandler.h" using namespace std; using namespace relpipe::writer; -//using namespace relpipe::in::asn1::lib; +using namespace relpipe::in::asn1::lib; namespace relpipe { namespace in { @@ -38,6 +44,32 @@ void ASN1Command::process(std::istream& input, std::shared_ptr writer, Configuration& configuration) { // TODO: parse ASN.1 and write relational data + BasicASN1Reader reader; + std::shared_ptr asn1handler; + + if (configuration.mode == Mode::Relpipe) asn1handler = std::make_shared(writer, configuration); + else if (configuration.mode == Mode::Freeform) asn1handler = std::make_shared(writer, configuration); + else throw RelpipeWriterException(L"Unsupported mode in ASN1Command: " + std::to_wstring((int) configuration.mode)); + + for (ParserOptionRecipe o : configuration.parserOptions) { + int n = 0; + n += reader.setOption(convertor.to_bytes(o.uri), convertor.to_bytes(o.value)); + n += asn1handler->setOption(convertor.to_bytes(o.uri), convertor.to_bytes(o.value)); + if (n == 0) throw RelpipeWriterException(L"Invalid parser option: „" + o.uri + L"“ with value: „" + o.value + L"“"); + } + + reader.addHandler(asn1handler); + + try { + // TODO: buffering? (reader itself also buffers) + for (uint8_t b = input.get(); input.good(); b = input.get()) reader.write(&b, 1); + } catch (const relpipe::in::asn1::lib::TransactionalBuffer::WriteBufferOverflowException& e) { + // TODO: avoid leaky abstraction and use different exception + throw relpipe::writer::RelpipeWriterException(L"Transactional buffer for ASN.1 input is too small"); + } + + reader.close(); + } diff -r 68a281aefa76 -r 7128fabeede0 src/CMakeLists.txt --- a/src/CMakeLists.txt Sat Jul 24 17:35:27 2021 +0200 +++ b/src/CMakeLists.txt Sun Jul 25 11:53:55 2021 +0200 @@ -29,6 +29,7 @@ # Executable output: add_executable( ${EXECUTABLE_FILE} + lib/AbstractParser.cpp ASN1Command.cpp relpipe-in-asn1.cpp ) diff -r 68a281aefa76 -r 7128fabeede0 src/FreeformASN1ContentHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/FreeformASN1ContentHandler.h Sun Jul 25 11:53:55 2021 +0200 @@ -0,0 +1,170 @@ +/** + * Relational pipes + * Copyright © 2021 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 "lib/ASN1ContentHandler.h" +#include "Configuration.h" + +namespace relpipe { +namespace in { +namespace asn1 { + +class FreeformASN1ContentHandler : public lib::ASN1ContentHandler { +private: + std::shared_ptr writer; + Configuration configuration; + std::vector position; + + class Record { + public: + const Header* header; + const std::vector& position; + relpipe::common::type::Integer level = 0; + relpipe::common::type::StringX event; + + Record(const Header* header, std::vector& position, relpipe::common::type::StringX event) : header(header), position(position), event(event) { + } + + virtual ~Record() { + } + }; + + void write(const Record& r) { + relpipe::common::type::Integer tag = r.header ? r.header->tag : -1; // TODO: null + possible integer overflow + relpipe::common::type::Integer id = r.position.back(); + relpipe::common::type::Integer parent = r.position[r.position.size() - 2]; + relpipe::common::type::Integer level = r.position.size() - 2; + + writer->writeAttribute(&id, typeid (id)); + writer->writeAttribute(&parent, typeid (parent)); + writer->writeAttribute(&level, typeid (level)); + writer->writeAttribute(&r.event, typeid (r.event)); + writer->writeAttribute(&tag, typeid (tag)); + } + +public: + + FreeformASN1ContentHandler(std::shared_ptr writer, Configuration configuration) : writer(writer), configuration(configuration) { + } + + bool setOption(const std::string& uri, const std::string& value) override { + return false; + } + + void writeStreamStart() override { + writer->startRelation(configuration.relation,{ + {L"id", relpipe::writer::TypeId::INTEGER}, + {L"parent", relpipe::writer::TypeId::INTEGER}, + {L"level", relpipe::writer::TypeId::INTEGER}, + {L"event", relpipe::writer::TypeId::STRING}, + //{L"pc", relpipe::writer::TypeId::STRING}, + //{L"tag_class", relpipe::writer::TypeId::STRING}, + {L"tag", relpipe::writer::TypeId::INTEGER}, + }, true); + + position.push_back(-1); // TODO: null + position.push_back(1); + Record r(nullptr, position, L"stream-start"); + write(r); + position.push_back(position.back()); + } + + void writeStreamEnd() override { + auto id = position.back() + 1; + position.pop_back(); + position.back() = id; + Record r(nullptr, position, L"stream-end"); + write(r); + } + + void writeCollectionStart(const Header& header) override { + position.back()++; + Record r(&header, position, L"collection-start"); + write(r); + position.push_back(position.back()); + } + + void writeCollectionEnd() override { + auto id = position.back() + 1; + position.pop_back(); + position.back() = id; + Record r(nullptr, position, L"collection-end"); + write(r); + } + + void writeBitString(const Header& header, std::vector value) override { + position.back()++; + Record r(&header, position, L"bit-string"); + write(r); + } + + void writeBoolean(const Header& header, bool value) override { + position.back()++; + Record r(&header, position, L"boolean"); + write(r); + } + + void writeDateTime(const Header& header, DateTime value) override { + position.back()++; + Record r(&header, position, L"date-time"); + write(r); + } + + void writeInteger(const Header& header, Integer value) override { + position.back()++; + Record r(&header, position, L"integer"); + write(r); + } + + void writeNull(const Header& header) override { + position.back()++; + Record r(&header, position, L"null"); + write(r); + } + + void writeOID(const Header& header, ObjectIdentifier value) override { + position.back()++; + Record r(&header, position, L"oid"); + write(r); + } + + void writeOctetString(const Header& header, std::string value) override { + position.back()++; + Record r(&header, position, L"octet-string"); + write(r); + } + + void writeTextString(const Header& header, std::string value) override { + position.back()++; + Record r(&header, position, L"text-string"); + write(r); + } + + void writeSpecific(const Header& header, std::string value) override { + position.back()++; + Record r(&header, position, L"specific"); + write(r); + } + + + +}; + +} +} +} \ No newline at end of file diff -r 68a281aefa76 -r 7128fabeede0 src/RelpipeASN1ContentHandler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/RelpipeASN1ContentHandler.h Sun Jul 25 11:53:55 2021 +0200 @@ -0,0 +1,85 @@ +/** + * Relational pipes + * Copyright © 2021 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 "lib/ASN1ContentHandler.h" +#include "Configuration.h" + +namespace relpipe { +namespace in { +namespace asn1 { + +class RelpipeASN1ContentHandler : public lib::ASN1ContentHandler { +private: + std::shared_ptr writer; + Configuration configuration; + +public: + + RelpipeASN1ContentHandler(std::shared_ptr writer, Configuration configuration) : writer(writer), configuration(configuration) { + } + + bool setOption(const std::string& uri, const std::string& value) override { + return false; + } + + void writeStreamStart() override { + } + + void writeStreamEnd() override { + } + + void writeCollectionStart(const Header& header) override { + } + + void writeCollectionEnd() override { + } + + void writeBitString(const Header& header, std::vector value) override { + } + + void writeBoolean(const Header& header, bool value) override { + } + + void writeDateTime(const Header& header, DateTime value) override { + } + + void writeInteger(const Header& header, Integer value) override { + } + + void writeNull(const Header& header) override { + } + + void writeOID(const Header& header, ObjectIdentifier value) override { + } + + void writeOctetString(const Header& header, std::string value) override { + } + + void writeTextString(const Header& header, std::string value) override { + } + + void writeSpecific(const Header& header, std::string value) override { + } + + +}; + +} +} +} \ No newline at end of file diff -r 68a281aefa76 -r 7128fabeede0 src/relpipe-in-asn1.cpp --- a/src/relpipe-in-asn1.cpp Sat Jul 24 17:35:27 2021 +0200 +++ b/src/relpipe-in-asn1.cpp Sun Jul 25 11:53:55 2021 +0200 @@ -52,10 +52,14 @@ std::shared_ptr writer(Factory::create(std::cout)); command.process(cin, writer, configuration); 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 (RelpipeCLIException& e) { + fwprintf(stderr, L"Caught CLI 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 = e.getExitCode(); } return resultCode;