File indexing completed on 2024-12-22 04:59:46
0001 /* 0002 SPDX-FileCopyrightText: 2018-2023 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "tickettokencomparator_p.h" 0007 #include "compare-logging.h" 0008 0009 #include "uic9183/uic9183block.h" 0010 #include "uic9183/uic9183header.h" 0011 #include "uic9183/uic9183parser.h" 0012 0013 #include <cstring> 0014 0015 using namespace KItinerary; 0016 0017 /** Checks that @p lhs and @p rhs have a different prefix is they are both set. */ 0018 static bool prefixConflictIfPresent(const QString &lhs, const QString &rhs, Qt::CaseSensitivity caseSensitive = Qt::CaseSensitive) 0019 { 0020 return !lhs.isEmpty() && !rhs.isEmpty() && !lhs.startsWith(rhs, caseSensitive) && !rhs.startsWith(lhs, caseSensitive); 0021 } 0022 static bool prefixConflictIfPresent(const QByteArray &lhs, const QByteArray &rhs) 0023 { 0024 return !lhs.isEmpty() && !rhs.isEmpty() && !lhs.startsWith(rhs) && !rhs.startsWith(lhs); 0025 } 0026 0027 static bool isUicBlockSubset(const Uic9183Parser &lhs, const Uic9183Parser &rhs) 0028 { 0029 for (auto block = lhs.firstBlock(); !block.isNull(); block = block.nextBlock()) { 0030 // ignore 0080VU blocks, those change in DB online tickets on every retrieval 0031 if (std::strncmp(block.name(), "0080VU", 6) == 0) { 0032 continue; 0033 } 0034 const auto rhsBlock = rhs.findBlock(block.name()); 0035 if (rhsBlock.isNull() || rhsBlock != block) { 0036 return false; 0037 } 0038 } 0039 return true; 0040 } 0041 0042 static bool compareUic918Token(const QByteArray &lhs, const QByteArray &rhs) 0043 { 0044 if (!Uic9183Parser::maybeUic9183(lhs) || !Uic9183Parser::maybeUic9183(rhs)) { 0045 return false; 0046 } 0047 0048 Uic9183Parser lhsUic; 0049 lhsUic.parse(lhs); 0050 Uic9183Parser rhsUic; 0051 rhsUic.parse(rhs); 0052 if (!lhsUic.isValid() || !rhsUic.isValid()) { 0053 return false; 0054 } 0055 0056 return lhsUic.header() == rhsUic.header() && isUicBlockSubset(lhsUic, rhsUic) && isUicBlockSubset(rhsUic, lhsUic); 0057 } 0058 0059 bool KItinerary::TicketTokenComparator::isSame(const QVariant &lhs, const QVariant &rhs) 0060 { 0061 if (lhs.isNull() || rhs.isNull()) { 0062 return true; 0063 } 0064 if (lhs.userType() != rhs.userType()) { 0065 return false; 0066 } 0067 0068 if (lhs.userType() == QMetaType::QString) { 0069 return !prefixConflictIfPresent(lhs.toString(), rhs.toString(), Qt::CaseInsensitive); 0070 } 0071 if (lhs.userType() == QMetaType::QByteArray) { 0072 const auto lhsBA = lhs.toByteArray(); 0073 const auto rhsBA = rhs.toByteArray(); 0074 if (!prefixConflictIfPresent(lhsBA, rhsBA)) { 0075 return true; 0076 } 0077 0078 return compareUic918Token(lhsBA, rhsBA); 0079 } 0080 0081 qCWarning(CompareLog) << "unhandled ticket token type" << lhs << rhs; 0082 return false; 0083 }