Commit 48fa50c1 authored by Volker Krause's avatar Volker Krause
Browse files

Unify ERA SSB version-based parsing, and add a version override option

This now means all ERA SSB versions are now supported both in the document
node tree and in the JS API. The override option is needed in order to work
around certain vendors specifying a wrong version.
parent a9567dc3
......@@ -33,6 +33,7 @@ set(kitinerary_lib_srcs
engine/scriptextractor.cpp
era/ssbticketbase.cpp
era/ssbticketreader.cpp
era/ssbv1ticket.cpp
era/ssbv2ticket.cpp
era/ssbv3ticket.cpp
......
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "ssbticketreader.h"
#include "ssbv1ticket.h"
#include "ssbv2ticket.h"
#include "ssbv3ticket.h"
#include <QVariant>
using namespace KItinerary;
QVariant SSBTicketReader::read(const QByteArray& data, int versionOverride)
{
if (data.isEmpty()) {
return {};
}
auto ticketData = data;
auto version = data[0] >> 4;
if (versionOverride > 0 && version != versionOverride) {
ticketData[0] = (ticketData[0] & 0x0f) | (versionOverride << 4);
version = versionOverride;
}
switch (version) {
case 1:
{
SSBv1Ticket ticket(ticketData);
return ticket.isValid() ? QVariant::fromValue(ticket) : QVariant();
}
case 2:
{
SSBv2Ticket ticket(ticketData);
return ticket.isValid() ? QVariant::fromValue(ticket) : QVariant();
}
case 3:
{
SSBv3Ticket ticket(ticketData);
return ticket.isValid() ? QVariant::fromValue(ticket) : QVariant();
}
}
return {};
}
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KITINERARY_SSBTICKETREADER_H
#define KITINERARY_SSBTICKETREADER_H
class QByteArray;
class QVariant;
namespace KItinerary {
/** Factory function for the various ERA SSB variants. */
namespace SSBTicketReader
{
/** Attempt to read an SSB ticket.
* The variant is auto-detected, unless @p versionOverride is specified.
*/
QVariant read(const QByteArray &data, int versionOverride = 0);
}
}
#endif // KITINERARY_SSBTICKETREADER_H
......@@ -6,7 +6,7 @@
#include "barcode.h"
#include "bitarray.h"
#include <era/ssbv3ticket.h>
#include <era/ssbticketreader.h>
#include <pdf/pdfbarcodeutil_p.h>
#include <KItinerary/BarcodeDecoder>
......@@ -122,10 +122,9 @@ QVariant JsApi::Barcode::decodeVdvTicket(const QVariant &s) const
return QVariant::fromValue(p.ticket());
}
QVariant JsApi::Barcode::decodeEraSsbTicket(const QVariant &s) const
QVariant JsApi::Barcode::decodeEraSsbTicket(const QVariant &s, int versionOverride) const
{
SSBv3Ticket ticket(s.toByteArray());
return ticket.isValid() ? QVariant::fromValue(ticket) : QVariant();
return SSBTicketReader::read(s.toByteArray(), versionOverride);
}
QString JsApi::Barcode::toBase64(const QVariant &b) const
......
......@@ -64,9 +64,11 @@ public:
Q_INVOKABLE QVariant decodeVdvTicket(const QVariant &s) const;
/** Decode an ERA SSB ticket barcode.
* @param s A QByteArray containing the raw ERA SSB barcode data.
* @param versionOverride Override version auto-detection. Useful for tickets that are known to
* fill their version field incorrectly.
* @returns An instance of SSBTicket.
*/
Q_INVOKABLE QVariant decodeEraSsbTicket(const QVariant &s) const;
Q_INVOKABLE QVariant decodeEraSsbTicket(const QVariant &s, int versionOverride = 0) const;
/** Converts the given QByteArray into an base64 encoded string. */
Q_INVOKABLE QString toBase64(const QVariant &b) const;
......
......@@ -6,29 +6,21 @@
#include "ssbdocumentprocessor.h"
#include "era/ssbticketreader.h"
#include "era/ssbv1ticket.h"
#include "era/ssbv2ticket.h"
#include "era/ssbv3ticket.h"
using namespace KItinerary;
bool SsbDocumentProcessor::canHandleData(const QByteArray &encodedData, [[maybe_unused]] QStringView fileName) const
{
return SSBv3Ticket::maybeSSB(encodedData) || SSBv1Ticket::maybeSSB(encodedData);
return SSBv3Ticket::maybeSSB(encodedData) || SSBv2Ticket::maybeSSB(encodedData) || SSBv1Ticket::maybeSSB(encodedData);
}
ExtractorDocumentNode SsbDocumentProcessor::createNodeFromData(const QByteArray &encodedData) const
{
ExtractorDocumentNode node;
if (SSBv3Ticket::maybeSSB(encodedData)) {
auto ticket = SSBv3Ticket(encodedData);
if (ticket.isValid()) {
node.setContent(ticket);
}
} else if (SSBv1Ticket::maybeSSB(encodedData)) {
auto ticket = SSBv1Ticket(encodedData);
if (ticket.isValid()) {
node.setContent(ticket);
}
}
node.setContent(SSBTicketReader::read(encodedData));
return node;
}
Markdown is supported
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