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

Add support for 1154UT UIC 918.3 vendor blocks

Used by Czech national railway (CD), similar to the S-block part of 0080BL.
parent 770fa7d4
Pipeline #263711 passed with stage
in 16 minutes and 11 seconds
......@@ -115,6 +115,7 @@ target_sources(KPimItinerary PRIVATE
uic9183/uic9183utils.cpp
uic9183/vendor0080block.cpp
uic9183/vendor0080vublockdata.cpp
uic9183/vendor1154block.cpp
vdv/iso9796_2decoder.cpp
vdv/vdvcertificate.cpp
......@@ -323,6 +324,7 @@ ecm_generate_headers(KItinerary_Uic9183_FORWARDING_HEADERS
Uic9183Utils
Vendor0080Block
Vendor0080VUBlockData
Vendor1154Block
PREFIX KItinerary
REQUIRED_HEADERS KItinerary_Uic9183_HEADERS
RELATIVE uic9183
......
......@@ -12,6 +12,7 @@
#include "uic9183header.h"
#include "uic9183ticketlayout.h"
#include "vendor0080block.h"
#include "vendor1154block.h"
#include "era/fcbticket.h"
#include "era/fcbutil.h"
......@@ -79,6 +80,7 @@ QVariant Uic9183Parser::block(const QString &name) const
BLOCK_FROM_NAME(Fcb::UicRailTicketData)
BLOCK_FROM_NAME(Vendor0080BLBlock)
BLOCK_FROM_NAME(Vendor0080VUBlock)
BLOCK_FROM_NAME(Vendor1154UTBlock)
#undef BLOCK_FROM_NAME
......
......@@ -99,7 +99,7 @@ int Vendor0080BLSubBlock::contentSize() const
if (isNull()) {
return 0;
}
return QByteArray(m_block.content() + m_offset + SBlockLengthOffset, SBlockLengthSize).toInt();
return Uic9183Utils::readAsciiEncodedNumber(m_block.content(), m_block.size(), m_offset + SBlockLengthOffset, SBlockLengthSize);
}
const char* Vendor0080BLSubBlock::id() const
......
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "vendor1154block.h"
#include "uic9183utils.h"
#include "logging.h"
using namespace KItinerary;
// 1154UT vendor block sub-block format
// 2x field type
// 3x field size as ASCII number
// nx field content
enum {
SubBlockTypeOffset = 0,
SubBlockTypeSize = 2,
SubBlockLengthOffset = SubBlockTypeOffset + SubBlockTypeSize,
SubBlockLengthSize = 3,
SubBlockHeaderSize = SubBlockTypeSize + SubBlockLengthSize,
SubBlockContentOffset = SubBlockLengthOffset + SubBlockLengthSize,
};
// known field types:
// KJ: passenger name
// OD: begin of validity
// DO: end of validity
// EM: ?
// KD: type of card (0 == none?)
// KC: card number
// KK: transaction code
// KS: routing, as a | separated list of UIC station codes?
// KM: distance in kilometers
Vendor1154UTSubBlock::Vendor1154UTSubBlock() = default;
Vendor1154UTSubBlock::Vendor1154UTSubBlock(const Uic9183Block &block, int offset)
: m_offset(offset)
{
if (block.isNull()) {
return;
}
if (block.contentSize() < offset + SubBlockHeaderSize) {
qCWarning(Log) << "1154UT sub-block too small";
return;
}
m_block = block;
if (block.contentSize() < offset + size()) {
qCWarning(Log) << "1154UT sub-block size exceeds 1154UT block size";
m_block = {};
}
}
bool Vendor1154UTSubBlock::isNull() const
{
return m_block.isNull();
}
int Vendor1154UTSubBlock::size() const
{
return contentSize() + SubBlockHeaderSize;
}
Vendor1154UTSubBlock Vendor1154UTSubBlock::nextBlock() const
{
if (m_offset + size() >= m_block.contentSize()) { // we are the last block
return {};
}
return Vendor1154UTSubBlock(m_block, m_offset + size());
}
int Vendor1154UTSubBlock::contentSize() const
{
if (isNull()) {
return 0;
}
return Uic9183Utils::readAsciiEncodedNumber(m_block.content(), m_block.size(), m_offset + SubBlockLengthOffset, SubBlockLengthSize);
}
const char* Vendor1154UTSubBlock::id() const
{
if (isNull()) {
return nullptr;
}
return m_block.content() + m_offset + SubBlockTypeOffset;
}
const char* Vendor1154UTSubBlock::content() const
{
if (isNull()) {
return nullptr;
}
return m_block.content() + m_offset + SubBlockHeaderSize;
}
QString Vendor1154UTSubBlock::toString() const
{
if (isNull()) {
return {};
}
return QString::fromUtf8(content(), contentSize());
}
Vendor1154UTBlock::Vendor1154UTBlock(const Uic9183Block &block)
: m_block(block)
{
}
bool Vendor1154UTBlock::isValid() const
{
return !m_block.isNull();
}
Vendor1154UTSubBlock Vendor1154UTBlock::firstBlock() const
{
return Vendor1154UTSubBlock(m_block, 0);
}
Vendor1154UTSubBlock Vendor1154UTBlock::findSubBlock(const char id[3]) const
{
auto sblock = firstBlock();
while (!sblock.isNull()) {
if (strncmp(sblock.id(), id, 3) == 0) {
return sblock;
}
sblock = sblock.nextBlock();
}
return {};
}
QVariant Vendor1154UTBlock::findSubBlock(const QString &str) const
{
if (str.size() != 3 || !isValid()) {
return {};
}
const auto b = findSubBlock(str.toUtf8().constData());
return b.isNull() ? QVariant() : QVariant::fromValue(b);
}
/*
SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KITINERARY_VENDOR1154BLOCK_H
#define KITINERARY_VENDOR1154BLOCK_H
#include "kitinerary_export.h"
#include "uic9183block.h"
namespace KItinerary {
/** UIC 918.3 1154UT vendor data block sub-block. */
class KITINERARY_EXPORT Vendor1154UTSubBlock
{
Q_GADGET
Q_PROPERTY(QString content READ toString)
public:
Vendor1154UTSubBlock();
Vendor1154UTSubBlock(const Uic9183Block &block, int offset);
bool isNull() const;
/** Type of the block. */
const char *id() const;
/** Size of the entire S-block. */
int size() const;
/** Next sub-block in the 1154UT block. */
Vendor1154UTSubBlock nextBlock() const;
/** Size of the content the sub-block. */
int contentSize() const;
/** Content data of the sub-block. */
const char *content() const;
/** Content as Unicode string. */
QString toString() const;
private:
Uic9183Block m_block;
int m_offset = 0;
};
/** UIC 918.3 1154UT vendor data block. */
class KITINERARY_EXPORT Vendor1154UTBlock
{
Q_GADGET
public:
Vendor1154UTBlock(const Uic9183Block &block = Uic9183Block());
bool isValid() const;
/** First S-block, for iterating. */
Vendor1154UTSubBlock firstBlock() const;
/** Finds a S-block by type. */
Vendor1154UTSubBlock findSubBlock(const char id[3]) const;
Q_INVOKABLE QVariant findSubBlock(const QString &str) const;
static constexpr const char RecordId[] = "1154UT";
private:
Uic9183Block m_block;
};
}
Q_DECLARE_METATYPE(KItinerary::Vendor1154UTBlock)
Q_DECLARE_METATYPE(KItinerary::Vendor1154UTSubBlock)
#endif // KITINERARY_VENDOR1154BLOCK_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