KItinerary

tickettokencomparator.cpp
1/*
2 SPDX-FileCopyrightText: 2018-2023 Volker Krause <vkrause@kde.org>
3 SPDX-License-Identifier: LGPL-2.0-or-later
4*/
5
6#include "tickettokencomparator_p.h"
7#include "compare-logging.h"
8
9#include "uic9183/uic9183block.h"
10#include "uic9183/uic9183header.h"
11#include "uic9183/uic9183parser.h"
12
13#include <cstring>
14
15using namespace KItinerary;
16
17/** Checks that @p lhs and @p rhs have a different prefix is they are both set. */
18static bool prefixConflictIfPresent(const QString &lhs, const QString &rhs, Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive)
19{
20 return !lhs.isEmpty() && !rhs.isEmpty() && !lhs.startsWith(rhs, caseSensitive) && !rhs.startsWith(lhs, caseSensitive);
21}
22static bool prefixConflictIfPresent(const QByteArray &lhs, const QByteArray &rhs)
23{
24 return !lhs.isEmpty() && !rhs.isEmpty() && !lhs.startsWith(rhs) && !rhs.startsWith(lhs);
25}
26
27static bool isUicBlockSubset(const Uic9183Parser &lhs, const Uic9183Parser &rhs)
28{
29 for (auto block = lhs.firstBlock(); !block.isNull(); block = block.nextBlock()) {
30 // ignore 0080VU blocks, those change in DB online tickets on every retrieval
31 if (std::strncmp(block.name(), "0080VU", 6) == 0) {
32 continue;
33 }
34 const auto rhsBlock = rhs.findBlock(block.name());
35 if (rhsBlock.isNull() || rhsBlock != block) {
36 return false;
37 }
38 }
39 return true;
40}
41
42static bool compareUic918Token(const QByteArray &lhs, const QByteArray &rhs)
43{
45 return false;
46 }
47
48 Uic9183Parser lhsUic;
49 lhsUic.parse(lhs);
50 Uic9183Parser rhsUic;
51 rhsUic.parse(rhs);
52 if (!lhsUic.isValid() || !rhsUic.isValid()) {
53 return false;
54 }
55
56 return lhsUic.header() == rhsUic.header() && isUicBlockSubset(lhsUic, rhsUic) && isUicBlockSubset(rhsUic, lhsUic);
57}
58
59bool KItinerary::TicketTokenComparator::isSame(const QVariant &lhs, const QVariant &rhs)
60{
61 if (lhs.isNull() || rhs.isNull()) {
62 return true;
63 }
64 if (lhs.userType() != rhs.userType()) {
65 return false;
66 }
67
68 if (lhs.userType() == QMetaType::QString) {
69 return !prefixConflictIfPresent(lhs.toString(), rhs.toString(), Qt::CaseInsensitive);
70 }
71 if (lhs.userType() == QMetaType::QByteArray) {
72 const auto lhsBA = lhs.toByteArray();
73 const auto rhsBA = rhs.toByteArray();
74 if (!prefixConflictIfPresent(lhsBA, rhsBA)) {
75 return true;
76 }
77
78 return compareUic918Token(lhsBA, rhsBA);
79 }
80
81 qCWarning(CompareLog) << "unhandled ticket token type" << lhs << rhs;
82 return false;
83}
Parser for UIC 918.3 and 918.3* train tickets.
Uic9183Block findBlock(const char name[6]) const
Returns the first block with the given name.
static bool maybeUic9183(const QByteArray &data)
Quickly checks if might be UIC 918.3 content.
Uic9183Block firstBlock() const
First data block in this ticket.
Uic9183Header header() const
Header found before the compressed payload.
Classes for reservation/travel data models, data extraction and data augmentation.
Definition berelement.h:17
bool isEmpty() const const
bool startsWith(QByteArrayView bv) const const
bool isEmpty() const const
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
CaseSensitivity
bool isNull() const const
QByteArray toByteArray() const const
QString toString() const const
int userType() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 3 2024 11:45:33 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.