--- a/src/lib/ASN1ContentHandler.h Tue Jun 22 21:41:59 2021 +0200
+++ b/src/lib/ASN1ContentHandler.h Sat Jun 26 20:04:52 2021 +0200
@@ -18,6 +18,9 @@
#include <memory>
#include <vector>
+#include <sstream>
+#include <iomanip>
+#include <cmath>
namespace relpipe {
namespace in {
@@ -49,6 +52,62 @@
BMPString,
};
+ class Integer {
+ private:
+ std::vector<uint8_t> data;
+ public:
+
+ /**
+ * @param data integer octets as in BER encoding
+ */
+ Integer(std::vector<uint8_t> data) : data(data) {
+ }
+
+ virtual ~Integer() {
+ }
+
+ size_t size() const {
+ return data.size();
+ }
+
+ const uint8_t& operator[](std::size_t index) const {
+ return data[index];
+ }
+
+ const std::string toHex() const {
+ std::stringstream hex;
+ hex << std::hex << std::setfill('0');
+ for (uint8_t b : data) hex << std::setw(2) << (int) b;
+ return hex.str();
+ }
+
+ const std::string toString() const {
+ try {
+ return std::to_string(toInt64());
+ } catch (...) {
+ // TODO: support longer values than 64 bits
+ // integer has more than 64 bits → only HEX form value will be available
+ return "";
+ }
+ }
+
+ const int64_t toInt64() const {
+ int64_t value = 0;
+
+ if (data.size() > sizeof (value)) throw std::invalid_argument("integer is too long");
+
+ for (size_t i = 0, limit = data.size(), negative = 0; i < limit; i++) {
+ uint8_t b = data[i];
+ if (i == 0 && b & 0x80) negative = true;
+ value = (value << 8) | b;
+ if (i == (limit - 1) && negative) value -= std::pow(256, data.size());
+ }
+
+ return value;
+ }
+
+ };
+
virtual ~ASN1ContentHandler() = default;
virtual void writeStreamStart() = 0;
@@ -58,7 +117,7 @@
virtual void writeCollectionEnd() = 0;
virtual void writeBoolean(bool value) = 0;
virtual void writeNull() = 0;
- virtual void writeInteger(int64_t value) = 0;
+ virtual void writeInteger(Integer value) = 0;
virtual void writeString(StringType type, std::string value) = 0;
// virtual void writeOID(std::string value) = 0;
// Object descriptor
@@ -113,7 +172,7 @@
handler->writeNull();
}
- void writeInteger(int64_t value) override { // TODO: Integer class containing raw data + methods for converting them to particular numeric data types
+ void writeInteger(Integer value) override {
handler->writeInteger(value);
}