Commit fddaecef authored by Volker Krause's avatar Volker Krause
Browse files

Implement uPER decoding of unconstrained integers and enums

Negative integers aren't handled yet, but those seem to not occur in
ERA FCB data in an unconstrained form.
parent fe7780d5
......@@ -29,16 +29,22 @@ void UPERDecoder::seek(UPERDecoder::size_type index)
int64_t UPERDecoder::readConstrainedWholeNumber(int64_t minimum, int64_t maximum)
{
assert(minimum <= maximum);
const uint64_t range = maximum - minimum + 1;
if (range == 1) {
return 0;
}
const uint64_t range = maximum - minimum;
const size_type bits = 64 - std::countl_zero(range);
const auto result = m_data.valueAtMSB<int64_t>(m_idx, bits);
m_idx += bits;
return result + minimum;
}
int64_t UPERDecoder::readUnconstrainedWholeNumber()
{
const auto len = readLengthDeterminant();
assert(len <= 8); // TODO
int64_t result = m_data.valueAtMSB<int64_t>(m_idx, 8 * len);
m_idx += 8 * len;
return result; // TODO convert negative numbers
}
UPERDecoder::size_type UPERDecoder::readLengthDeterminant()
{
size_type len = m_data.valueAtMSB<size_type>(m_idx, 8);
......
......@@ -8,6 +8,8 @@
#include "bitvector.h"
#include <QMetaEnum>
namespace KItinerary {
/** Decoder for data encoded according to X.691 ASN.1 Unaligned Packed Encoding Rules (UPER). */
......@@ -27,6 +29,11 @@ public:
*/
int64_t readConstrainedWholeNumber(int64_t minimum, int64_t maximum);
/** Read unconstrained whole number.
* @see X.691 §11.8
*/
int64_t readUnconstrainedWholeNumber();
/** Read length determinant.
* @see X.691 §11.9
*/
......@@ -52,7 +59,9 @@ public:
return result;
}
/** Read a sequence-of field with unrestricted size. */
/** Read a sequence-of field with unrestricted size.
* @see X.691 §20
*/
template <typename T>
inline QList<T> readSequenceOf()
{
......@@ -67,6 +76,23 @@ public:
return result;
}
/** Read enumerated value.
* @see X.691 §14
*/
template <typename T>
inline T readEnumerated()
{
const auto me = QMetaEnum::fromType<T>();
const auto idx = readConstrainedWholeNumber(0, me.keyCount() - 1);
return static_cast<T>(me.value(idx));
}
template <typename T>
inline T readEnumeratedWithExtensionMarker()
{
assert(!readBoolean()); // TODO
return readEnumerated<T>();
}
private:
BitVector m_data;
size_type m_idx = {};
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment