47 UniversalString, |
50 UniversalString, |
48 CharacterString, |
51 CharacterString, |
49 BMPString, |
52 BMPString, |
50 }; |
53 }; |
51 |
54 |
|
55 class Integer { |
|
56 private: |
|
57 std::vector<uint8_t> data; |
|
58 public: |
|
59 |
|
60 /** |
|
61 * @param data integer octets as in BER encoding |
|
62 */ |
|
63 Integer(std::vector<uint8_t> data) : data(data) { |
|
64 } |
|
65 |
|
66 virtual ~Integer() { |
|
67 } |
|
68 |
|
69 size_t size() const { |
|
70 return data.size(); |
|
71 } |
|
72 |
|
73 const uint8_t& operator[](std::size_t index) const { |
|
74 return data[index]; |
|
75 } |
|
76 |
|
77 const std::string toHex() const { |
|
78 std::stringstream hex; |
|
79 hex << std::hex << std::setfill('0'); |
|
80 for (uint8_t b : data) hex << std::setw(2) << (int) b; |
|
81 return hex.str(); |
|
82 } |
|
83 |
|
84 const std::string toString() const { |
|
85 try { |
|
86 return std::to_string(toInt64()); |
|
87 } catch (...) { |
|
88 // TODO: support longer values than 64 bits |
|
89 // integer has more than 64 bits → only HEX form value will be available |
|
90 return ""; |
|
91 } |
|
92 } |
|
93 |
|
94 const int64_t toInt64() const { |
|
95 int64_t value = 0; |
|
96 |
|
97 if (data.size() > sizeof (value)) throw std::invalid_argument("integer is too long"); |
|
98 |
|
99 for (size_t i = 0, limit = data.size(), negative = 0; i < limit; i++) { |
|
100 uint8_t b = data[i]; |
|
101 if (i == 0 && b & 0x80) negative = true; |
|
102 value = (value << 8) | b; |
|
103 if (i == (limit - 1) && negative) value -= std::pow(256, data.size()); |
|
104 } |
|
105 |
|
106 return value; |
|
107 } |
|
108 |
|
109 }; |
|
110 |
52 virtual ~ASN1ContentHandler() = default; |
111 virtual ~ASN1ContentHandler() = default; |
53 |
112 |
54 virtual void writeStreamStart() = 0; |
113 virtual void writeStreamStart() = 0; |
55 virtual void writeStreamEnd() = 0; |
114 virtual void writeStreamEnd() = 0; |
56 |
115 |
57 virtual void writeCollectionStart(CollectionType type) = 0; |
116 virtual void writeCollectionStart(CollectionType type) = 0; |
58 virtual void writeCollectionEnd() = 0; |
117 virtual void writeCollectionEnd() = 0; |
59 virtual void writeBoolean(bool value) = 0; |
118 virtual void writeBoolean(bool value) = 0; |
60 virtual void writeNull() = 0; |
119 virtual void writeNull() = 0; |
61 virtual void writeInteger(int64_t value) = 0; |
120 virtual void writeInteger(Integer value) = 0; |
62 virtual void writeString(StringType type, std::string value) = 0; |
121 virtual void writeString(StringType type, std::string value) = 0; |
63 // virtual void writeOID(std::string value) = 0; |
122 // virtual void writeOID(std::string value) = 0; |
64 // Object descriptor |
123 // Object descriptor |
65 // virtual void writeReal(float value) = 0; |
124 // virtual void writeReal(float value) = 0; |
66 // Enumerated |
125 // Enumerated |
111 |
170 |
112 void writeNull() override { |
171 void writeNull() override { |
113 handler->writeNull(); |
172 handler->writeNull(); |
114 } |
173 } |
115 |
174 |
116 void writeInteger(int64_t value) override { // TODO: Integer class containing raw data + methods for converting them to particular numeric data types |
175 void writeInteger(Integer value) override { |
117 handler->writeInteger(value); |
176 handler->writeInteger(value); |
118 } |
177 } |
119 |
178 |
120 void writeString(StringType type, std::string value) override { |
179 void writeString(StringType type, std::string value) override { |
121 handler->writeString(type, value); |
180 handler->writeString(type, value); |