src/RelpipeASN1ContentHandler.h
branchv_0
changeset 5 f913370404eb
parent 4 368ba99bb98f
child 6 523c9c39c996
equal deleted inserted replaced
4:368ba99bb98f 5:f913370404eb
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
    16  */
    16  */
    17 #pragma once
    17 #pragma once
    18 
    18 
    19 #include <relpipe/writer/RelationalWriter.h>
    19 #include <relpipe/writer/RelationalWriter.h>
       
    20 #include <relpipe/writer/RelpipeWriterException.h>
    20 #include "lib/ASN1ContentHandler.h"
    21 #include "lib/ASN1ContentHandler.h"
    21 #include "Configuration.h"
    22 #include "Configuration.h"
    22 
    23 
    23 namespace relpipe {
    24 namespace relpipe {
    24 namespace in {
    25 namespace in {
    27 class RelpipeASN1ContentHandler : public lib::ASN1ContentHandler {
    28 class RelpipeASN1ContentHandler : public lib::ASN1ContentHandler {
    28 private:
    29 private:
    29 	wstring_convert < codecvt_utf8<wchar_t>> convertor; // ASN.1 parser works with UTF-8
    30 	wstring_convert < codecvt_utf8<wchar_t>> convertor; // ASN.1 parser works with UTF-8
    30 	std::shared_ptr<relpipe::writer::RelationalWriter> writer;
    31 	std::shared_ptr<relpipe::writer::RelationalWriter> writer;
    31 	Configuration configuration;
    32 	Configuration configuration;
       
    33 
       
    34 	relpipe::common::type::StringX currentRelationName;
       
    35 	std::vector<relpipe::writer::AttributeMetadata> currentAttributes;
       
    36 
       
    37 	enum class State {
       
    38 		Start,
       
    39 		Relation,
       
    40 		RelationName,
       
    41 		Header,
       
    42 		HeaderItem,
       
    43 		AttributeName,
       
    44 		AttributeType,
       
    45 		Records,
       
    46 		Record,
       
    47 		Attribute,
       
    48 	};
       
    49 
       
    50 	State state = State::Start;
       
    51 
       
    52 	void assertTag(const Header& header, uint64_t expectedTag, TagClass expectedClass = TagClass::Universal) {
       
    53 		if (header.tagClass != expectedClass || header.tag != expectedTag) throw relpipe::writer::RelpipeWriterException(L"Unexpected tag."); // TODO: add actual vs. expected values
       
    54 	}
    32 
    55 
    33 public:
    56 public:
    34 
    57 
    35 	RelpipeASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) {
    58 	RelpipeASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) {
    36 	}
    59 	}
    44 
    67 
    45 	void writeStreamEnd() override {
    68 	void writeStreamEnd() override {
    46 	}
    69 	}
    47 
    70 
    48 	void writeCollectionStart(const Header& header) override {
    71 	void writeCollectionStart(const Header& header) override {
       
    72 		assertTag(header, lib::UniversalType::Sequence);
       
    73 		if (state == State::Start) state = State::Relation;
       
    74 		else if (state == State::Relation) state = State::RelationName;
       
    75 		else if (state == State::Header) state = State::HeaderItem;
       
    76 		else if (state == State::HeaderItem) state = State::AttributeName;
       
    77 		else if (state == State::Records) state = State::Record;
       
    78 		else std::wcerr << L"writeCollectionStart(): state=" << (int) state << std::endl; // TODO: remove
    49 	}
    79 	}
    50 
    80 
    51 	void writeCollectionEnd() override {
    81 	void writeCollectionEnd() override {
       
    82 		if (state == State::Header) state = State::Records;
       
    83 		else if (state == State::AttributeType) state = State::HeaderItem;
       
    84 		else if (state == State::HeaderItem) state = State::Records;
       
    85 		else if (state == State::Records) state = State::Relation;
       
    86 		else if (state == State::Record) state = State::Record;
       
    87 		else std::wcerr << L"writeCollectionEnd(): state=" << (int) state << std::endl; // TODO: remove
       
    88 		
       
    89 		if (state == State::Records) {
       
    90 			writer->startRelation(currentRelationName, currentAttributes, true);
       
    91 			currentRelationName = L"";
       
    92 			currentAttributes.clear();
       
    93 		}
    52 	}
    94 	}
    53 
    95 
    54 	void writeBitString(const Header& header, std::vector<bool> value) override {
    96 	void writeBitString(const Header& header, std::vector<bool> value) override {
    55 	}
    97 	}
    56 
    98 
    57 	void writeBoolean(const Header& header, bool value) override {
    99 	void writeBoolean(const Header& header, bool value) override {
       
   100 		if (state == State::Record) writer->writeAttribute(&value, typeid (value));
    58 	}
   101 	}
    59 
   102 
    60 	void writeDateTime(const Header& header, DateTime value) override {
   103 	void writeDateTime(const Header& header, DateTime value) override {
    61 	}
   104 	}
    62 
   105 
    63 	void writeInteger(const Header& header, Integer value) override {
   106 	void writeInteger(const Header& header, Integer value) override {
       
   107 		relpipe::common::type::Integer integer = value.toInt64();
       
   108 		if (state == State::Record) writer->writeAttribute(&integer, typeid (integer));
    64 	}
   109 	}
    65 
   110 
    66 	void writeNull(const Header& header) override {
   111 	void writeNull(const Header& header) override {
    67 	}
   112 	}
    68 
   113 
    71 
   116 
    72 	void writeOctetString(const Header& header, std::string value) override {
   117 	void writeOctetString(const Header& header, std::string value) override {
    73 	}
   118 	}
    74 
   119 
    75 	void writeTextString(const Header& header, std::string value) override {
   120 	void writeTextString(const Header& header, std::string value) override {
       
   121 		assertTag(header, lib::UniversalType::UTF8String);
       
   122 		relpipe::common::type::StringX str = convertor.from_bytes(value);
       
   123 
       
   124 		if (state == State::RelationName) {
       
   125 			currentRelationName = convertor.from_bytes(value);
       
   126 			state = State::Header;
       
   127 		} else if (state == State::AttributeName) {
       
   128 			currentAttributes.push_back({str, relpipe::writer::TypeId::STRING});
       
   129 			state = State::AttributeType;
       
   130 		} else if (state == State::AttributeType) {
       
   131 			currentAttributes.back().typeId = writer->toTypeId(str);
       
   132 		} else if (state == State::Record) {
       
   133 			writer->writeAttribute(&str, typeid (str));
       
   134 		} else std::wcerr << L"writeTextString(): state=" << (int) state << std::endl; // TODO: remove
    76 	}
   135 	}
    77 
   136 
    78 	void writeSpecific(const Header& header, std::string value) override {
   137 	void writeSpecific(const Header& header, std::string value) override {
    79 	}
   138 	}
    80 
   139