33 * Does not need to know anything about the model/schema – works with generic events (nodes). |
34 * Does not need to know anything about the model/schema – works with generic events (nodes). |
34 */ |
35 */ |
35 class GenericASN1ContentHandler : public ASN1ContentHandler { |
36 class GenericASN1ContentHandler : public ASN1ContentHandler { |
36 private: |
37 private: |
37 XMLContentHandlerProxy handlers; |
38 XMLContentHandlerProxy handlers; |
|
39 |
|
40 std::vector<std::string> getCommonAttributes(const Header& header, std::vector<std::string> attributes = {}) { |
|
41 std::string tag = std::to_string(header.tag); |
|
42 std::string tagClass = std::to_string((uint64_t) header.tagClass); |
|
43 std::string pc = std::to_string((uint8_t) header.pc); |
|
44 |
|
45 if (header.tagClass == TagClass::Universal) tagClass = "universal"; |
|
46 else if (header.tagClass == TagClass::ContextSpecific) tagClass = "context"; |
|
47 else if (header.tagClass == TagClass::Application) tagClass = "application"; |
|
48 else if (header.tagClass == TagClass::Private) tagClass = "private"; |
|
49 |
|
50 // if (header.pc == PC::Constructed) pc = "constructed"; |
|
51 // else if (header.pc == PC::Primitive) pc = "primitive"; |
|
52 |
|
53 attributes.push_back("tag"); |
|
54 attributes.push_back(tag); |
|
55 // attributes.push_back("pc"); |
|
56 // attributes.push_back(pc); |
|
57 attributes.push_back("class"); |
|
58 attributes.push_back(tagClass); |
|
59 |
|
60 return attributes; |
|
61 } |
|
62 |
38 public: |
63 public: |
39 |
64 |
40 void addHandler(std::shared_ptr<XMLContentHandler> handler) { |
65 void addHandler(std::shared_ptr<XMLContentHandler> handler) { |
41 handlers.addHandler(handler); |
66 handlers.addHandler(handler); |
42 } |
67 } |
51 void writeStreamEnd() override { |
76 void writeStreamEnd() override { |
52 handlers.writeEndElement(); |
77 handlers.writeEndElement(); |
53 } |
78 } |
54 |
79 |
55 void writeCollectionStart(const Header& header) override { |
80 void writeCollectionStart(const Header& header) override { |
56 if (header.tag == UniversalType::Sequence) handlers.writeStartElement("sequence"); |
81 if (header.tag == UniversalType::Sequence) handlers.writeStartElement("sequence", getCommonAttributes(header)); |
57 else if (header.tag == UniversalType::Set) handlers.writeStartElement("set"); |
82 else if (header.tag == UniversalType::Set) handlers.writeStartElement("set", getCommonAttributes(header)); |
58 else if (header.tag == UniversalType::OctetString || header.tag == UniversalType::BitString) handlers.writeStartElement("encapsulated",{"type", std::to_string(header.tag)}); // TODO: type name, better attributes |
83 else if (header.tag == UniversalType::OctetString || header.tag == UniversalType::BitString) handlers.writeStartElement("encapsulated", getCommonAttributes(header)); |
59 else handlers.writeStartElement("constructed"); |
84 else handlers.writeStartElement("constructed", getCommonAttributes(header)); |
60 } |
85 } |
61 |
86 |
62 void writeCollectionEnd() override { |
87 void writeCollectionEnd() override { |
63 handlers.writeEndElement(); |
88 handlers.writeEndElement(); |
64 } |
89 } |
65 |
90 |
66 void writeBoolean(const Header& header, bool value) override { |
91 void writeBoolean(const Header& header, bool value) override { |
67 handlers.writeStartElement("boolean"); |
92 handlers.writeStartElement("boolean", getCommonAttributes(header)); |
68 handlers.writeCharacters(value ? "true" : "false"); |
93 handlers.writeCharacters(value ? "true" : "false"); |
69 handlers.writeEndElement(); |
94 handlers.writeEndElement(); |
70 } |
95 } |
71 |
96 |
72 void writeNull(const Header& header) override { |
97 void writeNull(const Header& header) override { |
73 handlers.writeStartElement("null"); |
98 handlers.writeStartElement("null", getCommonAttributes(header)); |
74 handlers.writeEndElement(); |
99 handlers.writeEndElement(); |
75 } |
100 } |
76 |
101 |
77 void writeInteger(const Header& header, Integer value) override { |
102 void writeInteger(const Header& header, Integer value) override { |
78 handlers.writeStartElement("integer",{"hex", value.toHex()}); |
103 handlers.writeStartElement("integer", getCommonAttributes(header,{"hex", value.toHex()})); |
79 handlers.writeCharacters(value.toString()); |
104 handlers.writeCharacters(value.toString()); |
80 handlers.writeEndElement(); |
105 handlers.writeEndElement(); |
81 } |
106 } |
82 |
107 |
83 void writeTextString(const Header& header, std::string value) override { |
108 void writeTextString(const Header& header, std::string value) override { |
84 handlers.writeStartElement("text-string",{"type", std::to_string(header.tag)}); // TODO: type name, better attributes |
109 handlers.writeStartElement("text-string", getCommonAttributes(header)); |
85 handlers.writeCharacters(value); |
110 handlers.writeCharacters(value); |
86 handlers.writeEndElement(); |
111 handlers.writeEndElement(); |
87 } |
112 } |
88 |
113 |
89 void writeOctetString(const Header& header, std::string value) override { |
114 void writeOctetString(const Header& header, std::string value) override { |
90 std::stringstream hex; |
115 std::stringstream hex; |
91 hex << std::hex << std::setfill('0'); |
116 hex << std::hex << std::setfill('0'); |
92 for (uint8_t b : value) hex << std::setw(2) << (int) b; |
117 for (uint8_t b : value) hex << std::setw(2) << (int) b; |
93 handlers.writeStartElement("octet-string",{"length", std::to_string(value.size())}); |
118 handlers.writeStartElement("octet-string", getCommonAttributes(header,{"length", std::to_string(value.size())})); |
94 handlers.writeCharacters(hex.str()); |
119 handlers.writeCharacters(hex.str()); |
95 handlers.writeEndElement(); |
120 handlers.writeEndElement(); |
96 } |
121 } |
97 |
122 |
98 void writeBitString(const Header& header, std::vector<bool> value) override { |
123 void writeBitString(const Header& header, std::vector<bool> value) override { |
99 std::stringstream bits; |
124 std::stringstream bits; |
100 for (bool b : value) bits << (int) b; |
125 for (bool b : value) bits << (int) b; |
101 // for (bool b : value) bits << (b ? ':' : '.'); // TODO: configurable true/false symbols? |
126 // for (bool b : value) bits << (b ? ':' : '.'); // TODO: configurable true/false symbols? |
102 handlers.writeStartElement("bit-string",{"length", std::to_string(value.size())}); |
127 handlers.writeStartElement("bit-string", getCommonAttributes(header,{"length", std::to_string(value.size())})); |
103 handlers.writeCharacters(bits.str()); |
128 handlers.writeCharacters(bits.str()); |
104 handlers.writeEndElement(); |
129 handlers.writeEndElement(); |
105 } |
130 } |
106 |
131 |
107 void writeOID(const Header& header, ObjectIdentifier value) override { |
132 void writeOID(const Header& header, ObjectIdentifier value) override { |
108 // TODO: optionally expand into separate elements with additional metadata |
133 // TODO: optionally expand into separate elements with additional metadata |
109 handlers.writeStartElement("oid"); |
134 handlers.writeStartElement("oid", getCommonAttributes(header)); // TODO: {"length", std::to_string(value.size())} |
110 handlers.writeCharacters(value.toString()); |
135 handlers.writeCharacters(value.toString()); |
111 handlers.writeEndElement(); |
136 handlers.writeEndElement(); |
112 } |
137 } |
113 |
138 |
114 void writeDateTime(const Header& header, DateTime value) override { |
139 void writeDateTime(const Header& header, DateTime value) override { |
115 handlers.writeStartElement("date-time"); |
140 handlers.writeStartElement("date-time", getCommonAttributes(header)); |
116 handlers.writeCharacters(value.toString()); |
141 handlers.writeCharacters(value.toString()); |
117 handlers.writeEndElement(); |
142 handlers.writeEndElement(); |
118 } |
143 } |
119 |
144 |
120 void writeSpecific(const Header& header, std::string value) override { |
145 void writeSpecific(const Header& header, std::string value) override { |