RelpipeASN1ContentHandler: parse one or more relations v_0 tip
authorFrantišek Kučera <franta-hg@frantovo.cz>
Mon, 26 Jul 2021 23:41:18 +0200
branchv_0
changeset 6 523c9c39c996
parent 5 f913370404eb
RelpipeASN1ContentHandler: parse one or more relations
src/RelpipeASN1ContentHandler.h
--- a/src/RelpipeASN1ContentHandler.h	Mon Jul 26 21:25:48 2021 +0200
+++ b/src/RelpipeASN1ContentHandler.h	Mon Jul 26 23:41:18 2021 +0200
@@ -44,7 +44,7 @@
 		AttributeType,
 		Records,
 		Record,
-		Attribute,
+		End,
 	};
 
 	State state = State::Start;
@@ -53,6 +53,28 @@
 		if (header.tagClass != expectedClass || header.tag != expectedTag) throw relpipe::writer::RelpipeWriterException(L"Unexpected tag."); // TODO: add actual vs. expected values
 	}
 
+	State startRelation() {
+		writer->startRelation(currentRelationName, currentAttributes, true);
+		currentRelationName = L"";
+		currentAttributes.clear();
+		return State::Records;
+	}
+
+	State setRelationName(std::string value) {
+		currentRelationName = convertor.from_bytes(value);
+		return State::Header;
+	}
+
+	State setAttributeName(relpipe::common::type::StringX value) {
+		currentAttributes.push_back({value, relpipe::writer::TypeId::STRING});
+		return State::AttributeType;
+	}
+
+	State setAttributeType(relpipe::common::type::StringX value) {
+		currentAttributes.back().typeId = writer->toTypeId(value);
+		return State::AttributeType;
+	}
+
 public:
 
 	RelpipeASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) {
@@ -75,66 +97,62 @@
 		else if (state == State::Header) state = State::HeaderItem;
 		else if (state == State::HeaderItem) state = State::AttributeName;
 		else if (state == State::Records) state = State::Record;
-		else std::wcerr << L"writeCollectionStart(): state=" << (int) state << std::endl; // TODO: remove
+		else throw std::logic_error("Illegal state in writeCollectionStart(): " + std::to_string((int) state));
 	}
 
 	void writeCollectionEnd() override {
-		if (state == State::Header) state = State::Records;
-		else if (state == State::AttributeType) state = State::HeaderItem;
-		else if (state == State::HeaderItem) state = State::Records;
+		if (state == State::AttributeType) state = State::HeaderItem;
+		else if (state == State::HeaderItem) state = startRelation();
 		else if (state == State::Records) state = State::Relation;
-		else if (state == State::Record) state = State::Record;
-		else std::wcerr << L"writeCollectionEnd(): state=" << (int) state << std::endl; // TODO: remove
-		
-		if (state == State::Records) {
-			writer->startRelation(currentRelationName, currentAttributes, true);
-			currentRelationName = L"";
-			currentAttributes.clear();
-		}
+		else if (state == State::Record) state = State::Records;
+		else if (state == State::Relation) state = State::End;
+		else throw std::logic_error("Illegal state in writeCollectionEnd(): " + std::to_string((int) state));
 	}
 
 	void writeBitString(const Header& header, std::vector<bool> value) override {
+		throw std::logic_error("Unsupported data type: BitString");
 	}
 
 	void writeBoolean(const Header& header, bool value) override {
 		if (state == State::Record) writer->writeAttribute(&value, typeid (value));
+		else throw std::logic_error("Illegal state in writeBoolean(): " + std::to_string((int) state));
 	}
 
 	void writeDateTime(const Header& header, DateTime value) override {
+		throw std::logic_error("Unsupported data type: DateTime");
 	}
 
 	void writeInteger(const Header& header, Integer value) override {
 		relpipe::common::type::Integer integer = value.toInt64();
 		if (state == State::Record) writer->writeAttribute(&integer, typeid (integer));
+		else throw std::logic_error("Illegal state in writeInteger(): " + std::to_string((int) state));
 	}
 
 	void writeNull(const Header& header) override {
+		throw std::logic_error("Unsupported data type: Null");
 	}
 
 	void writeOID(const Header& header, ObjectIdentifier value) override {
+		throw std::logic_error("Unsupported data type: OID");
 	}
 
 	void writeOctetString(const Header& header, std::string value) override {
+		throw std::logic_error("Unsupported data type: OctetString");
 	}
 
 	void writeTextString(const Header& header, std::string value) override {
 		assertTag(header, lib::UniversalType::UTF8String);
 		relpipe::common::type::StringX str = convertor.from_bytes(value);
 
-		if (state == State::RelationName) {
-			currentRelationName = convertor.from_bytes(value);
-			state = State::Header;
-		} else if (state == State::AttributeName) {
-			currentAttributes.push_back({str, relpipe::writer::TypeId::STRING});
-			state = State::AttributeType;
-		} else if (state == State::AttributeType) {
-			currentAttributes.back().typeId = writer->toTypeId(str);
-		} else if (state == State::Record) {
-			writer->writeAttribute(&str, typeid (str));
-		} else std::wcerr << L"writeTextString(): state=" << (int) state << std::endl; // TODO: remove
+		if (state == State::RelationName) state = setRelationName(value);
+		else if (state == State::AttributeName) state = setAttributeName(str);
+		else if (state == State::AttributeType) state = setAttributeType(str);
+		else if (state == State::Record) writer->writeAttribute(&str, typeid (str));
+		else throw std::logic_error("Illegal state in writeTextString(): " + std::to_string((int) state));
 	}
 
 	void writeSpecific(const Header& header, std::string value) override {
+		throw std::logic_error("Unsupported data type: Specific");
 	}