--- 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: