Commit 29fbb432 authored by Volker Krause's avatar Volker Krause
Browse files

Turn BitVector into a non-owning view

For FCB tickets our input is a byte array view, so this avoids having
to do an extra copy there.
parent 537b9769
Pipeline #248910 passed with stage
in 3 minutes and 55 seconds
......@@ -25,7 +25,7 @@ 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)
ecm_add_test(jsapitest.cpp ../src/lib/jsapi/jsonld.cpp TEST_NAME jsapitest LINK_LIBRARIES Qt::Test KPim::Itinerary Qt${QT_MAJOR_VERSION}::Qml)
ecm_add_test(bitarraytest.cpp ../src/lib/jsapi/bitarray.cpp ../src/lib/asn1/bitvector.cpp TEST_NAME bitarraytest LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(bitarraytest.cpp ../src/lib/jsapi/bitarray.cpp ../src/lib/asn1/bitvectorview.cpp TEST_NAME bitarraytest LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(structureddataextractortest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
ecm_add_test(pdfdocumenttest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary Qt${QT_MAJOR_VERSION}::Gui)
ecm_add_test(htmldocumenttest.cpp LINK_LIBRARIES Qt::Test KPim::Itinerary)
......
......@@ -5,7 +5,7 @@
#include <asn1/uperdecoder.h>
#include <asn1/uperdecoder.cpp>
#include <asn1/bitvector.cpp>
#include <asn1/bitvectorview.cpp>
#include <QDebug>
#include <QObject>
......@@ -19,7 +19,8 @@ class UPERDecoderTest : public QObject
private Q_SLOTS:
void testReadNumbers()
{
UPERDecoder d(BitVector(QByteArray::fromHex("723004D580D1845E168AEAE4C2D2D840845CAC5C500550E8")));
auto data = QByteArray::fromHex("723004D580D1845E168AEAE4C2D2D840845CAC5C500550E8");
UPERDecoder d(BitVectorView(std::string_view(data.constData(), data.size())));
QCOMPARE(d.readBoolean(), false);
QCOMPARE(d.readBitset<4>(), std::bitset<4>(0b1110));
QCOMPARE(d.offset(), 5);
......@@ -41,7 +42,8 @@ private Q_SLOTS:
QCOMPARE(d.readBoolean(), true);
QCOMPARE(d.offset(), 162);
d = UPERDecoder(BitVector(QByteArray::fromHex("22FB162E1BC9")));
data = QByteArray::fromHex("22FB162E1BC9");
d = UPERDecoder(BitVectorView(std::string_view(data.constData(), data.size())));
d.seek(13);
QCOMPARE(d.readIA5String(4, 4), "1187");
}
......
......@@ -9,7 +9,7 @@ add_library(KPim::Itinerary ALIAS KPimItinerary)
target_sources(KPimItinerary PRIVATE
asn1/berelement.cpp
asn1/bitvector.cpp
asn1/bitvectorview.cpp
asn1/uperdecoder.cpp
asn1/uperelement.cpp
......
......@@ -3,32 +3,34 @@
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "bitvector.h"
#include "bitvectorview.h"
#include <QByteArray>
using namespace KItinerary;
BitVector::BitVector() = default;
BitVectorView::BitVectorView() = default;
BitVector::BitVector(const QByteArray& data)
BitVectorView::BitVectorView(std::string_view data)
: m_data(data)
{
}
BitVector::~BitVector() = default;
BitVectorView::~BitVectorView() = default;
BitVector::size_type BitVector::size() const
BitVectorView::size_type BitVectorView::size() const
{
return m_data.size() * 8;
}
uint8_t BitVector::at(BitVector::size_type index) const
uint8_t BitVectorView::at(BitVectorView::size_type index) const
{
const auto majIdx = index / 8;
const auto minIdx = 7 - (index % 8);
return (m_data.at(majIdx) & (1 << minIdx)) >> minIdx;
}
QByteArray BitVector::byteArrayAt(BitVector::size_type index, BitVector::size_type bytes) const
QByteArray BitVectorView::byteArrayAt(BitVectorView::size_type index, BitVectorView::size_type bytes) const
{
QByteArray result;
result.reserve(bytes);
......
......@@ -6,24 +6,24 @@
#ifndef KITINERARY_BITVECTOR_H
#define KITINERARY_BITVECTOR_H
#include <QByteArray>
#include <QDebug>
#include <bitset>
#include <cassert>
#include <string_view>
#include <type_traits>
class QByteArray;
namespace KItinerary {
/** Vector for working with data that isn't byte-aligned. */
class BitVector
/** Non-owning bit-level view for working with data that isn't byte-aligned. */
class BitVectorView
{
public:
BitVector();
explicit BitVector(const QByteArray &data);
~BitVector();
BitVectorView();
explicit BitVectorView(std::string_view data);
~BitVectorView();
using size_type = QByteArray::size_type;
using size_type = std::string_view::size_type;
/** Size of this vector in bits. */
size_type size() const;
......@@ -64,7 +64,7 @@ public:
}
private:
QByteArray m_data;
std::string_view m_data;
};
}
......
......@@ -9,7 +9,7 @@
using namespace KItinerary;
UPERDecoder::UPERDecoder(const BitVector &data)
UPERDecoder::UPERDecoder(BitVectorView data)
: m_data(data)
{
}
......@@ -71,17 +71,8 @@ bool UPERDecoder::readBoolean()
return m_data.at(m_idx++) != 0;
}
QByteArray UPERDecoder::readIA5String(size_type minLength, size_type maxLength)
QByteArray UPERDecoder::readIA5StringData(size_type len)
{
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) {
......@@ -89,6 +80,21 @@ QByteArray UPERDecoder::readIA5String(size_type minLength, size_type maxLength)
m_idx += 7;
result.push_back(c);
}
return result;
}
QByteArray UPERDecoder::readIA5String()
{
return readIA5StringData(readLengthDeterminant());
}
QByteArray UPERDecoder::readIA5String(size_type minLength, size_type maxLength)
{
size_type len = 0;
if (minLength == maxLength) {
len = minLength;
} else {
len = readConstrainedWholeNumber(minLength, maxLength);
}
return readIA5StringData(len);
}
......@@ -6,7 +6,7 @@
#ifndef KITINERARY_UPERDECODER_H
#define KITINERARY_UPERDECODER_H
#include "bitvector.h"
#include "bitvectorview.h"
#include <QMetaEnum>
......@@ -16,10 +16,10 @@ namespace KItinerary {
class UPERDecoder
{
public:
explicit UPERDecoder(const BitVector &data);
explicit UPERDecoder(BitVectorView data);
~UPERDecoder();
using size_type = BitVector::size_type;
using size_type = BitVectorView::size_type;
size_type offset() const;
void seek(size_type index);
......@@ -45,10 +45,15 @@ public:
/** Read boolean value. */
bool readBoolean();
/** Read a IA5String (7 bit ASCII).
/** Read an unconstrained IA5String (7 bit ASCII).
* @see X.691 §30
*/
QByteArray readIA5String(size_type minLenght = 0, size_type maxLength = -1);
QByteArray readIA5String();
/** Read length-constrained IA5String (7 bit ASCII).
* @see X.691 §30
*/
QByteArray readIA5String(size_type minLenght, size_type maxLength);
/** Read an @tparam N sized bitmap. */
template <std::size_t N>
......@@ -94,7 +99,9 @@ public:
}
private:
BitVector m_data;
QByteArray readIA5StringData(size_type len);
BitVectorView m_data;
size_type m_idx = {};
};
......
......@@ -7,6 +7,8 @@
#include "asn1/uperdecoder.h"
#include <QDebug>
#define FCB_READ_CONSTAINED_INT(Name, Min, Max) \
if (Name ## IsSet()) \
Name = decoder.readConstrainedWholeNumber(Min, Max)
......@@ -202,7 +204,7 @@ Fcb::UicRailTicketData::UicRailTicketData() = default;
Fcb::UicRailTicketData::UicRailTicketData(const Uic9183Block &block)
: m_block(block)
{
UPERDecoder decoder(BitVector(QByteArray(block.content(), block.contentSize()))); // TODO make BitVector a view
UPERDecoder decoder(BitVectorView(std::string_view(block.content(), block.contentSize())));
decode(decoder);
}
......
......@@ -6,6 +6,8 @@
#include "bitarray.h"
#include "asn1/bitvectorview.h"
#include <QDebug>
#include <cstdint>
......@@ -22,9 +24,10 @@ BitArray::~BitArray() = default;
quint64 BitArray::readNumberMSB(int startBit, int size) const
{
if (m_data.size() < startBit + size || size < 0 || size > 64 || startBit < 0) {
BitVectorView view(std::string_view(m_data.constData(), m_data.size()));
if ((int)view.size() < startBit + size || size < 0 || size > 64 || startBit < 0) {
return 0;
}
return m_data.valueAtMSB<quint64>(startBit, size);
return view.valueAtMSB<quint64>(startBit, size);
}
......@@ -6,7 +6,7 @@
#pragma once
#include <asn1/bitvector.h>
#include <QByteArray>
#include <QMetaType>
namespace KItinerary {
......@@ -25,7 +25,7 @@ public:
Q_INVOKABLE quint64 readNumberMSB(int startBit, int size) const;
private:
BitVector m_data;
QByteArray m_data;
};
}}
......
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