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

Implement uPER decoding of bools, IA5Strings and bitmaps

parent 0b3b51da
......@@ -20,7 +20,12 @@ private Q_SLOTS:
void testReadNumbers()
{
UPERDecoder d(BitVector(QByteArray::fromHex("723004D580D1845E168AEAE4C2D2D840845CAC5C500550E8")));
d.seek(20);
QCOMPARE(d.readBoolean(), false);
QCOMPARE(d.readBitset<4>(), std::bitset<4>(0b1110));
QCOMPARE(d.offset(), 5);
QCOMPARE(d.readBoolean(), false);
QCOMPARE(d.readBitset<14>(), std::bitset<14>(0b10001100000000));
QCOMPARE(d.offset(), 20);
QCOMPARE(d.readConstrainedWholeNumber(1, 32000), 9901);
QCOMPARE(d.offset(), 35);
QCOMPARE(d.readConstrainedWholeNumber(2016, 2269), 2022);
......@@ -31,6 +36,14 @@ private Q_SLOTS:
QCOMPARE(d.offset(), 63);
QCOMPARE(d.readUtf8String(), QLatin1String("Eurail B.V."));
QCOMPARE(d.offset(), 159);
QCOMPARE(d.readBoolean(), false);
QCOMPARE(d.readBoolean(), false);
QCOMPARE(d.readBoolean(), true);
QCOMPARE(d.offset(), 162);
d = UPERDecoder(BitVector(QByteArray::fromHex("22FB162E1BC9")));
d.seek(13);
QCOMPARE(d.readIA5String(4, 4), "1187");
}
};
......
......@@ -9,6 +9,7 @@
#include <QByteArray>
#include <QDebug>
#include <bitset>
#include <cassert>
#include <type_traits>
......@@ -51,6 +52,17 @@ public:
/** Returns @p bytes starting at bit offset @p index. */
QByteArray byteArrayAt(size_type index, size_type bytes) const;
/** Reads a std::bitset from @p index. */
template <std::size_t N>
std::bitset<N> bitsetAt(size_type index) const
{
std::bitset<N> result = {};
for (size_type i = 0; i < (size_type)N; ++i) {
result[N - i - 1] = at(index + i);
}
return result;
}
private:
QByteArray m_data;
};
......
......@@ -30,6 +30,9 @@ 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 size_type bits = 64 - std::countl_zero(range);
const auto result = m_data.valueAtMSB<int64_t>(m_idx, bits);
m_idx += bits;
......@@ -56,3 +59,30 @@ QString UPERDecoder::readUtf8String()
m_idx += len * 8;
return res;
}
bool UPERDecoder::readBoolean()
{
return m_data.at(m_idx++) != 0;
}
QByteArray UPERDecoder::readIA5String(size_type minLength, size_type maxLength)
{
size_type len = 0;
if (minLength == maxLength) {
len = minLength;
} else if (maxLength > 0) {
len = readConstrainedWholeNumber(minLength, maxLength);
} else {
len = readLengthDeterminant();
}
QByteArray result;
result.reserve(len);
for (size_type i = 0; i < len; ++i) {
const auto c = m_data.valueAtMSB<char>(m_idx, 7);
m_idx += 7;
result.push_back(c);
}
return result;
}
......@@ -35,6 +35,23 @@ public:
/** Read UTF-8 string. */
QString readUtf8String();
/** Read boolean value. */
bool readBoolean();
/** Read a IA5String (7 bit ASCII).
* @see X.691 §30
*/
QByteArray readIA5String(size_type minLenght = 0, size_type maxLength = -1);
/** Read an @tparam N sized bitmap. */
template <std::size_t N>
inline std::bitset<N> readBitset()
{
auto result = m_data.bitsetAt<N>(m_idx);
m_idx += N;
return result;
}
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