src/FreeformASN1ContentHandler.h
branchv_0
changeset 4 368ba99bb98f
parent 3 807f8543d10e
child 8 3192dc8772de
equal deleted inserted replaced
3:807f8543d10e 4:368ba99bb98f
    24 
    24 
    25 namespace relpipe {
    25 namespace relpipe {
    26 namespace in {
    26 namespace in {
    27 namespace asn1 {
    27 namespace asn1 {
    28 
    28 
       
    29 /**
       
    30  * Converts arbitrary ASN.1 stream of events to a relation
       
    31  * i.e. does not require any specific structures/schema.
       
    32  *
       
    33  * Useful especially for testing and debugging and sometimes instead of relpipe-in-asn1table,
       
    34  * because this handler supports streaming and does not depend on any third-party library (no XML dependency).
       
    35  */
    29 class FreeformASN1ContentHandler : public lib::ASN1ContentHandler {
    36 class FreeformASN1ContentHandler : public lib::ASN1ContentHandler {
    30 private:
    37 private:
       
    38 	wstring_convert < codecvt_utf8<wchar_t>> convertor; // ASN.1 parser works with UTF-8
    31 	std::shared_ptr<relpipe::writer::RelationalWriter> writer;
    39 	std::shared_ptr<relpipe::writer::RelationalWriter> writer;
    32 	Configuration configuration;
    40 	Configuration configuration;
    33 	std::vector<relpipe::common::type::Integer> position;
    41 	std::vector<relpipe::common::type::Integer> position;
    34 
    42 
    35 	class Record {
    43 	class Record {
    36 	public:
    44 	public:
    37 		const Header* header;
    45 		const Header* header;
    38 		const std::vector<relpipe::common::type::Integer>& position;
    46 		const std::vector<relpipe::common::type::Integer>& position;
    39 		relpipe::common::type::Integer level = 0;
    47 		relpipe::common::type::Integer level = 0;
    40 		relpipe::common::type::StringX event;
    48 		relpipe::common::type::StringX event;
       
    49 		relpipe::common::type::StringX valueText;
       
    50 		relpipe::common::type::StringX valueBinary;
    41 
    51 
    42 		Record(const Header* header, std::vector<relpipe::common::type::Integer>& position, relpipe::common::type::StringX event) : header(header), position(position), event(event) {
    52 		Record(const Header* header, std::vector<relpipe::common::type::Integer>& position, relpipe::common::type::StringX event) : header(header), position(position), event(event) {
    43 		}
    53 		}
    44 
    54 
    45 		virtual ~Record() {
    55 		virtual ~Record() {
    72 		writer->writeAttribute(&level, typeid (level));
    82 		writer->writeAttribute(&level, typeid (level));
    73 		writer->writeAttribute(&r.event, typeid (r.event));
    83 		writer->writeAttribute(&r.event, typeid (r.event));
    74 		// writer->writeAttribute(&pc, typeid (pc));
    84 		// writer->writeAttribute(&pc, typeid (pc));
    75 		writer->writeAttribute(&tagClass, typeid (tagClass));
    85 		writer->writeAttribute(&tagClass, typeid (tagClass));
    76 		writer->writeAttribute(&tag, typeid (tag));
    86 		writer->writeAttribute(&tag, typeid (tag));
       
    87 		writer->writeAttribute(&r.valueText, typeid (r.valueText));
       
    88 		writer->writeAttribute(&r.valueBinary, typeid (r.valueBinary));
       
    89 	}
       
    90 
       
    91 	/**
       
    92 	 * @param header
       
    93 	 * @param value an octet string
       
    94 	 * @return original value if octet string was a text string; otherwise an empty string
       
    95 	 */
       
    96 	const std::string getText(const Header& header, const std::string& value) {
       
    97 		// TODO: support also UTF-8
       
    98 		for (uint8_t b : value) if (b < 32 || b >= 127) return "";
       
    99 		return value;
    77 	}
   100 	}
    78 
   101 
    79 public:
   102 public:
    80 
   103 
    81 	FreeformASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) {
   104 	FreeformASN1ContentHandler(std::shared_ptr<relpipe::writer::RelationalWriter> writer, Configuration configuration) : writer(writer), configuration(configuration) {
    92 			{L"level", relpipe::writer::TypeId::INTEGER},
   115 			{L"level", relpipe::writer::TypeId::INTEGER},
    93 			{L"event", relpipe::writer::TypeId::STRING},
   116 			{L"event", relpipe::writer::TypeId::STRING},
    94 			// {L"pc", relpipe::writer::TypeId::STRING},
   117 			// {L"pc", relpipe::writer::TypeId::STRING},
    95 			{L"tag_class", relpipe::writer::TypeId::STRING},
   118 			{L"tag_class", relpipe::writer::TypeId::STRING},
    96 			{L"tag", relpipe::writer::TypeId::INTEGER},
   119 			{L"tag", relpipe::writer::TypeId::INTEGER},
       
   120 			{L"value_text", relpipe::writer::TypeId::STRING},
       
   121 			{L"value_binary", relpipe::writer::TypeId::STRING}, // TODO: OctetString data type (when available) instead of text
    97 		}, true);
   122 		}, true);
    98 
   123 
    99 		position.push_back(-1); // TODO: null
   124 		position.push_back(-1); // TODO: null
   100 		position.push_back(1);
   125 		position.push_back(1);
   101 		Record r(nullptr, position, L"stream-start");
   126 		Record r(nullptr, position, L"stream-start");
   105 
   130 
   106 	void writeStreamEnd() override {
   131 	void writeStreamEnd() override {
   107 		auto id = position.back() + 1;
   132 		auto id = position.back() + 1;
   108 		position.pop_back();
   133 		position.pop_back();
   109 		position.back() = id;
   134 		position.back() = id;
       
   135 		// TODO: put end event under the start parent?
   110 		Record r(nullptr, position, L"stream-end");
   136 		Record r(nullptr, position, L"stream-end");
   111 		write(r);
   137 		write(r);
   112 	}
   138 	}
   113 
   139 
   114 	void writeCollectionStart(const Header& header) override {
   140 	void writeCollectionStart(const Header& header) override {
   120 
   146 
   121 	void writeCollectionEnd() override {
   147 	void writeCollectionEnd() override {
   122 		auto id = position.back() + 1;
   148 		auto id = position.back() + 1;
   123 		position.pop_back();
   149 		position.pop_back();
   124 		position.back() = id;
   150 		position.back() = id;
       
   151 		// TODO: put end event under the start parent?
   125 		Record r(nullptr, position, L"collection-end");
   152 		Record r(nullptr, position, L"collection-end");
   126 		write(r);
   153 		write(r);
   127 	}
   154 	}
   128 
   155 
   129 	void writeBitString(const Header& header, std::vector<bool> value) override {
   156 	void writeBitString(const Header& header, std::vector<bool> value) override {
       
   157 		std::stringstream bits;
       
   158 		for (bool b : value) bits << (int) b;
       
   159 		// for (bool b : value) bits << (b ? ':' : '.'); // TODO: configurable true/false symbols?
       
   160 
   130 		position.back()++;
   161 		position.back()++;
   131 		Record r(&header, position, L"bit-string");
   162 		Record r(&header, position, L"bit-string");
       
   163 		r.valueText = convertor.from_bytes(bits.str());
   132 		write(r);
   164 		write(r);
   133 	}
   165 	}
   134 
   166 
   135 	void writeBoolean(const Header& header, bool value) override {
   167 	void writeBoolean(const Header& header, bool value) override {
   136 		position.back()++;
   168 		position.back()++;
   137 		Record r(&header, position, L"boolean");
   169 		Record r(&header, position, L"boolean");
       
   170 		r.valueText = value ? L"true" : L"false";
       
   171 		r.valueBinary = value ? L"FF" : L"00";
   138 		write(r);
   172 		write(r);
   139 	}
   173 	}
   140 
   174 
   141 	void writeDateTime(const Header& header, DateTime value) override {
   175 	void writeDateTime(const Header& header, DateTime value) override {
   142 		position.back()++;
   176 		position.back()++;
   143 		Record r(&header, position, L"date-time");
   177 		Record r(&header, position, L"date-time");
       
   178 		r.valueText = convertor.from_bytes(value.toString());
   144 		write(r);
   179 		write(r);
   145 	}
   180 	}
   146 
   181 
   147 	void writeInteger(const Header& header, Integer value) override {
   182 	void writeInteger(const Header& header, Integer value) override {
   148 		position.back()++;
   183 		position.back()++;
   149 		Record r(&header, position, L"integer");
   184 		Record r(&header, position, L"integer");
       
   185 		r.valueText = convertor.from_bytes(value.toString());
       
   186 		r.valueBinary = convertor.from_bytes(value.toHex());
   150 		write(r);
   187 		write(r);
   151 	}
   188 	}
   152 
   189 
   153 	void writeNull(const Header& header) override {
   190 	void writeNull(const Header& header) override {
   154 		position.back()++;
   191 		position.back()++;
   155 		Record r(&header, position, L"null");
   192 		Record r(&header, position, L"null");
       
   193 		r.valueText = L"null";
   156 		write(r);
   194 		write(r);
   157 	}
   195 	}
   158 
   196 
   159 	void writeOID(const Header& header, ObjectIdentifier value) override {
   197 	void writeOID(const Header& header, ObjectIdentifier value) override {
   160 		position.back()++;
   198 		position.back()++;
   161 		Record r(&header, position, L"oid");
   199 		Record r(&header, position, L"oid");
       
   200 		r.valueText = convertor.from_bytes(value.toString());
   162 		write(r);
   201 		write(r);
   163 	}
   202 	}
   164 
   203 
   165 	void writeOctetString(const Header& header, std::string value) override {
   204 	void writeOctetString(const Header& header, std::string value) override {
       
   205 		std::string text = getText(header, value);
       
   206 		std::stringstream hex;
       
   207 		hex << std::hex << std::setfill('0');
       
   208 		for (uint8_t b : value) hex << std::setw(2) << (int) b;
       
   209 
   166 		position.back()++;
   210 		position.back()++;
   167 		Record r(&header, position, L"octet-string");
   211 		Record r(&header, position, L"octet-string");
       
   212 		r.valueText = convertor.from_bytes(text);
       
   213 		r.valueBinary = convertor.from_bytes(hex.str());
   168 		write(r);
   214 		write(r);
   169 	}
   215 	}
   170 
   216 
   171 	void writeTextString(const Header& header, std::string value) override {
   217 	void writeTextString(const Header& header, std::string value) override {
   172 		position.back()++;
   218 		position.back()++;
   173 		Record r(&header, position, L"text-string");
   219 		Record r(&header, position, L"text-string");
       
   220 		r.valueText = convertor.from_bytes(value);
   174 		write(r);
   221 		write(r);
   175 	}
   222 	}
   176 
   223 
   177 	void writeSpecific(const Header& header, std::string value) override {
   224 	void writeSpecific(const Header& header, std::string value) override {
       
   225 		std::stringstream hex;
       
   226 		hex << std::hex << std::setfill('0');
       
   227 		for (uint8_t b : value) hex << std::setw(2) << (int) b;
       
   228 
       
   229 		std::stringstream ascii;
       
   230 		for (uint8_t b : value) ascii << (b >= 32 && b < 127 ? (char) b : '.'); // TODO: configurable unsupported symbol?
       
   231 
   178 		position.back()++;
   232 		position.back()++;
   179 		Record r(&header, position, L"specific");
   233 		Record r(&header, position, L"specific");
       
   234 		r.valueText = convertor.from_bytes(ascii.str());
       
   235 		r.valueBinary = convertor.from_bytes(hex.str());
   180 		write(r);
   236 		write(r);
   181 	}
   237 	}
   182 
   238 
   183 
   239 
   184 
   240