src/lib/BasicASN1Reader.h
branchv_0
changeset 13 d5e2cb9e31f1
parent 12 243ef6c91dbb
child 14 02725d301010
--- a/src/lib/BasicASN1Reader.h	Sun Jun 20 10:23:50 2021 +0200
+++ b/src/lib/BasicASN1Reader.h	Sun Jun 20 20:16:46 2021 +0200
@@ -33,19 +33,65 @@
 class BasicASN1Reader : public ASN1Reader {
 private:
 
-	enum class State {
-		A,
-		B,
-		C
+	bool started = false;
+
+	enum class TagClass : uint8_t {
+		Universal = 0,
+		Application = 1,
+		ContextSpecific = 2,
+		Private = 3
+	};
+
+	enum class PC : uint8_t {
+		Primitive = 0,
+		Constructed = 1
+	};
+
+	class Header {
+	public:
+		TagClass tagClass;
+		PC pc;
+		uint64_t tag;
+		bool definiteLength;
+		size_t length;
 	};
 
-	State state = State::A;
+	Header readHeader() {
+		Header h;
+
+		memset(&h, 0, sizeof (h)); // TODO: remove, not needed
+
+		uint8_t tagByte;
+		read(&tagByte, 1);
+
+		h.tagClass = (TagClass) (tagByte >> 6);
+		h.pc = (PC) ((tagByte >> 5) & 1);
+		h.tag = tagByte & (0xFF >> 3);
+		if (h.tag > 30) throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 tag > 30"); // FIXME: higher tag values → read more bytes
+
+		uint8_t lengthByte;
+		read(&lengthByte, 1);
 
-	bool started = false;
+		std::wcerr << L"lengthByte = " << lengthByte << std::endl;
+
+		if (lengthByte >> 7 == 0) {
+			h.definiteLength = true;
+			h.length = lengthByte;
+		} else if (lengthByte == 0b10000000) {
+			h.definiteLength = false;
+			h.length = 0;
+		} else if (lengthByte == 0xFF) {
+			throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception
+		} else {
+			// FIXME: longer values
+			throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 lengthBytes: longer value"); // TODO: better exception
+		}
+		
+		return h;
+	}
 
 	void readNext() {
-		std::array<char, 2> typeAndLength;
-		read(typeAndLength.data(), typeAndLength.size());
+		Header typeHeader = readHeader();
 		commit();
 
 		if (!started) {
@@ -56,18 +102,20 @@
 		handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence);
 		handlers.writeNull();
 		handlers.writeBoolean(true);
-		handlers.writeInteger(typeAndLength[0]);
-		handlers.writeInteger(typeAndLength[1]);
+
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tagClass:");
+		handlers.writeInteger((int64_t) typeHeader.tagClass);
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "pc:");
+		handlers.writeInteger((int64_t) typeHeader.pc);
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tag:");
+		handlers.writeInteger((int64_t) typeHeader.tag);
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "definiteLength:");
+		handlers.writeBoolean(typeHeader.definiteLength);
+		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "length:");
+		handlers.writeInteger((int64_t) typeHeader.length);
+
 		handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "relational pipes");
 		handlers.writeCollectionEnd();
-
-		if (state == State::A) {
-
-		} else if (state == State::B) {
-
-		} else if (state == State::C) {
-
-		}
 	}
 
 protected: