70 if (h.tag > 30) throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 tag > 30"); // FIXME: higher tag values → read more bytes |
90 if (h.tag > 30) throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 tag > 30"); // FIXME: higher tag values → read more bytes |
71 |
91 |
72 uint8_t lengthByte; |
92 uint8_t lengthByte; |
73 read(&lengthByte, 1); |
93 read(&lengthByte, 1); |
74 |
94 |
75 std::wcerr << L"lengthByte = " << lengthByte << std::endl; |
|
76 |
|
77 if (lengthByte >> 7 == 0) { |
95 if (lengthByte >> 7 == 0) { |
|
96 // definite short |
78 h.definiteLength = true; |
97 h.definiteLength = true; |
79 h.length = lengthByte; |
98 h.length = lengthByte; |
80 } else if (lengthByte == 0b10000000) { |
99 } else if (lengthByte == 0b10000000) { |
|
100 // indefinite |
81 h.definiteLength = false; |
101 h.definiteLength = false; |
82 h.length = 0; |
102 h.length = 0; |
83 } else if (lengthByte == 0xFF) { |
103 } else if (lengthByte == 0xFF) { |
84 throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception |
104 throw relpipe::writer::RelpipeWriterException(L"ASN.1 lengthByte == 0xFF (reserved value)"); // TODO: better exception |
85 } else { |
105 } else { |
86 // FIXME: longer values |
106 // definite long |
87 throw relpipe::writer::RelpipeWriterException(L"not yet implemented, ASN.1 lengthBytes: longer value"); // TODO: better exception |
107 h.definiteLength = true; |
88 } |
108 h.length = 0; |
89 |
109 std::vector<uint8_t> lengthBytes(lengthByte & 0b01111111, 0); |
|
110 read(lengthBytes.data(), lengthBytes.size()); |
|
111 for (uint8_t l : lengthBytes) h.length = (h.length << 8) + l; |
|
112 } |
|
113 |
90 return h; |
114 return h; |
91 } |
115 } |
92 |
116 |
93 void readNext() { |
117 void readNext() { |
|
118 checkRemainingItems(); |
94 Header typeHeader = readHeader(); |
119 Header typeHeader = readHeader(); |
95 commit(); |
120 // commit(); // TODO: commit here and recover later instead of rollback? |
96 |
121 |
97 if (!started) { |
122 if (!started) { |
98 handlers.writeStreamStart(); |
123 handlers.writeStreamStart(); |
99 started = true; |
124 started = true; |
100 } |
125 } |
101 |
126 |
|
127 // TODO: check tagClass and pc |
|
128 |
|
129 // TODO: constants, more types |
|
130 if (typeHeader.tag == 0) handlers.writeCollectionEnd(); |
|
131 else if (typeHeader.tag == 16) { |
|
132 level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
|
133 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence); |
|
134 } else if (typeHeader.tag == 17) { |
|
135 level.push_back({typeHeader.definiteLength, typeHeader.length, getBytesRead()}); // TODO: transaction |
|
136 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Set); |
|
137 } else if (typeHeader.tag == 5 && typeHeader.length == 0) { |
|
138 handlers.writeNull(); |
|
139 } else if (typeHeader.tag == 1) { |
|
140 bool value; |
|
141 read((uint8_t*) & value, 1); |
|
142 handlers.writeBoolean(value); |
|
143 } else { |
|
144 // TODO: do not skip, parse |
|
145 std::vector<uint8_t> temp(typeHeader.length, 0); |
|
146 read(temp.data(), typeHeader.length); |
|
147 // TODO: recover transaction? |
|
148 |
|
149 std::stringstream description; |
|
150 description << "value:" |
|
151 << " tag = " << typeHeader.tag |
|
152 << " tagClass = " << (int) typeHeader.tagClass |
|
153 << " pc = " << (int) typeHeader.pc |
|
154 << " length = " << typeHeader.length |
|
155 << " definite = " << (typeHeader.definiteLength ? "true" : "false"); |
|
156 |
|
157 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, description.str()); |
|
158 } |
|
159 |
|
160 commit(); |
|
161 |
|
162 |
|
163 // TODO: remove debug/demo output: |
|
164 return; |
102 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence); |
165 handlers.writeCollectionStart(ASN1ContentHandler::CollectionType::Sequence); |
103 handlers.writeNull(); |
166 handlers.writeNull(); |
104 handlers.writeBoolean(true); |
167 handlers.writeBoolean(true); |
105 |
168 |
106 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tagClass:"); |
169 handlers.writeString(ASN1ContentHandler::StringType::UTF8String, "tagClass:"); |