partial implementation of DOMBuildingXMLContentHandler v_0
authorFrantišek Kučera <franta-hg@frantovo.cz>
Sat, 12 Jun 2021 22:37:44 +0200
branchv_0
changeset 9 7a6abdd00ab5
parent 8 d37c1a5d09ce
child 10 6904e4448807
partial implementation of DOMBuildingXMLContentHandler
src/lib/ASN1ContentHandler.h
src/lib/AbstractParser.h
src/lib/BasicASN1Reader.h
src/lib/DOMBuildingXMLContentHandler.h
src/lib/GenericASN1ContentHandler.h
src/lib/XMLContentHandler.h
--- a/src/lib/ASN1ContentHandler.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/ASN1ContentHandler.h	Sat Jun 12 22:37:44 2021 +0200
@@ -50,6 +50,9 @@
 
 	virtual ~ASN1ContentHandler() = default;
 
+	virtual void writeStreamStart() = 0;
+	virtual void writeStreamEnd() = 0;
+
 	virtual void writeCollectionStart(CollectionType type) = 0;
 	virtual void writeCollectionEnd() = 0;
 	virtual void writeBoolean(bool value) = 0;
@@ -85,27 +88,35 @@
 
 #define handler for (auto ___h : handlers) ___h
 
-	void writeCollectionStart(CollectionType type) {
+	void writeStreamStart() override {
+		handler->writeStreamStart();
+	}
+
+	void writeStreamEnd() override {
+		handler->writeStreamEnd();
+	}
+
+	void writeCollectionStart(CollectionType type) override {
 		handler->writeCollectionStart(type);
 	}
 
-	void writeCollectionEnd() {
+	void writeCollectionEnd() override {
 		handler->writeCollectionEnd();
 	}
 
-	void writeBoolean(bool value) {
+	void writeBoolean(bool value) override {
 		handler->writeBoolean(value);
 	}
 
-	void writeNull() {
+	void writeNull() override {
 		handler->writeNull();
 	}
 
-	void writeInteger(int64_t value) {
+	void writeInteger(int64_t value) override {
 		handler->writeInteger(value);
 	}
 
-	void writeString(StringType type, std::string value) {
+	void writeString(StringType type, std::string value) override {
 		handler->writeString(type, value);
 	}
 
--- a/src/lib/AbstractParser.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/AbstractParser.h	Sat Jun 12 22:37:44 2021 +0200
@@ -59,7 +59,7 @@
 	 * No write() call is expected after close() and would fail.
 	 * However the parser object remains valid and may be used to get some auxiliary information (if supperted by given implementation).
 	 */
-	void close();
+	virtual void close();
 protected:
 	AbstractParser();
 
--- a/src/lib/BasicASN1Reader.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/BasicASN1Reader.h	Sat Jun 12 22:37:44 2021 +0200
@@ -40,11 +40,23 @@
 
 	State state = State::A;
 
+	bool started = false;
+
 protected:
 
 	void update() override {
-		
+
+		if (!started) {
+			handlers.writeStreamStart();
+			started = true;
+		}
+
+		handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence);
 		handlers.writeNull();
+		handlers.writeBoolean(true);
+		handlers.writeInteger(123);
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "relational pipes");
+		handlers.writeCollectionEnd();
 
 		if (state == State::A) {
 
@@ -53,9 +65,12 @@
 		} else if (state == State::C) {
 
 		}
-
+	}
 
+public:
 
+	void close() override {
+		if (started) handlers.writeStreamEnd();
 	}
 
 };
--- a/src/lib/DOMBuildingXMLContentHandler.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/DOMBuildingXMLContentHandler.h	Sat Jun 12 22:37:44 2021 +0200
@@ -28,24 +28,35 @@
 class DOMBuildingXMLContentHandler : public XMLContentHandler {
 private:
 	xmlpp::Document* document;
+	xmlpp::Element* current = nullptr;
+	// TODO: check current == nullptr and throw exception
 
 public:
 
 	DOMBuildingXMLContentHandler(xmlpp::Document* document) : document(document) {
-		document->create_root_node("DOMBuildingXMLContentHandler"); // FIXME: real implementation
 	}
 
 	void writeStartElement(const std::string& name, const std::vector<std::string>& attributes) override {
+		if (current) current = current->add_child(name);
+		else current = document->create_root_node(name);
+
+		for (int i = 0; i < attributes.size(); i = i + 2) {
+			std::string attributeName = attributes[i];
+			std::string attributeValue = attributes[i + 1];
+			current->set_attribute(attributeName, attributeValue);
+		}
 	}
 
 	void writeEndElement() override {
+		current = current->get_parent();
 	}
 
-	void writeCharacters(const std::string& text) override {
+	void writeCharacters(const std::string& value) override {
+		current->add_child_text(value);
 	}
 
-	void writeComment(const std::string& text, bool addSpaces) override {
-		document->get_root_node()->add_child_comment(addSpaces ? " " + text + " " : text);
+	void writeComment(const std::string& value, bool addSpaces) override {
+		current->add_child_comment(addSpaces ? " " + value + " " : value);
 	}
 
 };
--- a/src/lib/GenericASN1ContentHandler.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/GenericASN1ContentHandler.h	Sat Jun 12 22:37:44 2021 +0200
@@ -41,28 +41,45 @@
 	virtual ~GenericASN1ContentHandler() {
 	}
 
+	void writeStreamStart() override {
+		handlers.writeStartElement("asn1");
+	}
+
+	void writeStreamEnd() override {
+		handlers.writeEndElement();
+	}
+
 	void writeCollectionStart(CollectionType type) override {
-		handlers.writeComment("collection start");
+		if (type == CollectionType::Sequence) handlers.writeStartElement("sequence");
+		else if (type == CollectionType::Set) handlers.writeStartElement("set");
+		else handlers.writeStartElement("unknown-collection"); // TODO: exception?
 	}
 
 	void writeCollectionEnd() override {
-		handlers.writeComment("collection end");
+		handlers.writeEndElement();
 	}
 
 	void writeBoolean(bool value) override {
-		handlers.writeComment("boolean");
+		handlers.writeStartElement("boolean");
+		handlers.writeCharacters(value ? "true" : "false");
+		handlers.writeEndElement();
 	}
 
 	void writeNull() override {
-		handlers.writeComment("null");
+		handlers.writeStartElement("null");
+		handlers.writeEndElement();
 	}
 
 	void writeInteger(int64_t value) override {
-		handlers.writeComment("integer");
+		handlers.writeStartElement("integer");
+		handlers.writeCharacters(std::to_string(value));
+		handlers.writeEndElement();
 	}
 
 	void writeString(StringType type, std::string value) override {
-		handlers.writeComment("string");
+		handlers.writeStartElement("string");
+		handlers.writeCharacters(value);
+		handlers.writeEndElement();
 	}
 
 };
--- a/src/lib/XMLContentHandler.h	Sat Jun 12 21:29:18 2021 +0200
+++ b/src/lib/XMLContentHandler.h	Sat Jun 12 22:37:44 2021 +0200
@@ -16,6 +16,8 @@
  */
 #pragma once
 
+#include <vector>
+
 namespace relpipe {
 namespace in {
 namespace asn1 {
@@ -26,10 +28,12 @@
 
 	virtual ~XMLContentHandler() = default;
 
+	// FIXME: namespaces, check names
+
 	virtual void writeStartElement(const std::string& name, const std::vector<std::string>& attributes = {}) = 0;
 	virtual void writeEndElement() = 0;
-	virtual void writeCharacters(const std::string& text) = 0;
-	virtual void writeComment(const std::string& text, bool addSpaces = true) = 0;
+	virtual void writeCharacters(const std::string& value) = 0;
+	virtual void writeComment(const std::string& value, bool addSpaces = true) = 0;
 
 };
 
@@ -44,20 +48,20 @@
 
 #define handler for (auto ___h : handlers) ___h
 
-	void writeStartElement(const std::string& name, const std::vector<std::string>& attributes = {}) {
+	void writeStartElement(const std::string& name, const std::vector<std::string>& attributes = {}) override {
 		handler->writeStartElement(name, attributes);
 	}
 
-	void writeEndElement() {
+	void writeEndElement() override {
 		handler->writeEndElement();
 	}
 
-	void writeCharacters(const std::string& text) {
-		handler->writeCharacters(text);
+	void writeCharacters(const std::string& value) override {
+		handler->writeCharacters(value);
 	}
 
-	void writeComment(const std::string& text, bool addSpaces = true) {
-		handler->writeComment(text, addSpaces);
+	void writeComment(const std::string& value, bool addSpaces = true) override {
+		handler->writeComment(value, addSpaces);
 	}
 
 #undef handler