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

Add beginning of an ASN.1 uPER decoder

Can only somewhat read two data type variants yet, but we have to start
somewhere. We'll need this for decoding ERA FCB tickets.
parent 866de9cf
Pipeline #246201 passed with stage
in 9 minutes and 7 seconds
......@@ -10,6 +10,7 @@ set(KF5_MIN_VERSION "5.91.0")
find_package(ECM ${KF5_MIN_VERSION} REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
set(CMAKE_CXX_STANDARD 20)
include(KDECompilerSettings NO_POLICY_SCOPE)
include(ECMAddTests)
......
......@@ -20,6 +20,7 @@ ecm_add_test(extractorscriptenginetest.cpp extractorscriptenginetest.qrc TEST_NA
ecm_add_test(berdecodertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(berencodertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(bcbpparsertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(uperdecodertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(uic9183parsertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(vdvtickettest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(rct2parsertest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
......
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include <asn1/uperdecoder.h>
#include <asn1/uperdecoder.cpp>
#include <asn1/bitvector.cpp>
#include <QDebug>
#include <QObject>
#include <QTest>
using namespace KItinerary;
class UPERDecoderTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void testReadNumbers()
{
UPERDecoder d(BitVector(QByteArray::fromHex("723004D580D1845E168AEAE4C2D2D840845CAC5C500550E8")));
d.seek(20);
QCOMPARE(d.readConstrainedWholeNumber(1, 32000), 9901);
QCOMPARE(d.offset(), 35);
QCOMPARE(d.readConstrainedWholeNumber(2016, 2269), 2022);
QCOMPARE(d.offset(), 43);
QCOMPARE(d.readConstrainedWholeNumber(1, 366), 281);
QCOMPARE(d.offset(), 52);
QCOMPARE(d.readConstrainedWholeNumber(0, 1440), 559);
QCOMPARE(d.offset(), 63);
QCOMPARE(d.readUtf8String(), QLatin1String("Eurail B.V."));
QCOMPARE(d.offset(), 159);
}
};
QTEST_APPLESS_MAIN(UPERDecoderTest)
#include "uperdecodertest.moc"
......@@ -10,6 +10,7 @@ add_library(KPim::Itinerary ALIAS KPimItinerary)
target_sources(KPimItinerary PRIVATE
asn1/berelement.cpp
asn1/bitvector.cpp
asn1/uperdecoder.cpp
datatypes/action.cpp
datatypes/boattrip.cpp
......
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "uperdecoder.h"
#include <bit>
using namespace KItinerary;
UPERDecoder::UPERDecoder(const BitVector &data)
: m_data(data)
{
}
UPERDecoder::~UPERDecoder() = default;
UPERDecoder::size_type UPERDecoder::offset() const
{
return m_idx;
}
void UPERDecoder::seek(UPERDecoder::size_type index)
{
m_idx = index;
}
int64_t UPERDecoder::readConstrainedWholeNumber(int64_t minimum, int64_t maximum)
{
assert(minimum <= maximum);
const uint64_t range = maximum - minimum + 1;
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;
}
UPERDecoder::size_type UPERDecoder::readLengthDeterminant()
{
size_type len = m_data.valueAtMSB<size_type>(m_idx, 8);
m_idx += 8;
if ((len & 0x80) == 0x00) {
return len;
}
// TODO
assert(false);
return 0;
}
QString UPERDecoder::readUtf8String()
{
const auto len = readLengthDeterminant();
const auto res = QString::fromUtf8(m_data.byteArrayAt(m_idx, len));
m_idx += len * 8;
return res;
}
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KITINERARY_UPERDECODER_H
#define KITINERARY_UPERDECODER_H
#include "bitvector.h"
namespace KItinerary {
/** Decoder for data encoded according to X.691 ASN.1 Unaligned Packed Encoding Rules (UPER). */
class UPERDecoder
{
public:
explicit UPERDecoder(const BitVector &data);
~UPERDecoder();
using size_type = BitVector::size_type;
size_type offset() const;
void seek(size_type index);
/** Read constrained whole number from the current position.
* @see X.691 §11.5
*/
int64_t readConstrainedWholeNumber(int64_t minimum, int64_t maximum);
/** Read length determinant.
* @see X.691 §11.9
*/
size_type readLengthDeterminant();
/** Read UTF-8 string. */
QString readUtf8String();
private:
BitVector m_data;
size_type m_idx = {};
};
}
#endif // KITINERARY_UPERDECODER_H
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