File indexing completed on 2024-11-24 04:45:11
0001 /* 0002 SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "iatabcbpsections.h" 0008 #include "iatabcbpconstants_p.h" 0009 #include "logging.h" 0010 0011 using namespace KItinerary; 0012 using namespace KItinerary::IataBcbpConstants; 0013 0014 QString IataBcbpSectionBase::readString(int offset, int length) const 0015 { 0016 if (m_data.size() >= offset + length) { 0017 return m_data.mid(offset, length).trimmed().toString(); 0018 } 0019 return {}; 0020 } 0021 0022 int IataBcbpSectionBase::readNumericValue(int offset, int length, int base) const 0023 { 0024 if (m_data.size() >= offset + length) { 0025 return m_data.mid(offset, length).toInt(nullptr, base); 0026 } 0027 return 0; 0028 } 0029 0030 0031 IataBcbpUniqueMandatorySection::IataBcbpUniqueMandatorySection(QStringView data) 0032 { 0033 m_data = data; 0034 } 0035 0036 bool IataBcbpUniqueMandatorySection::isValid() const 0037 { 0038 const auto legCount = numberOfLegs(); 0039 return legCount >= 1 && legCount <= 4; 0040 } 0041 0042 IataBcbpUniqueConditionalSection::IataBcbpUniqueConditionalSection(QStringView data) 0043 { 0044 if (data.size() < MinimumUniqueConditionalSize) { 0045 return; 0046 } 0047 m_data = data; 0048 m_data = data.left(MinimumUniqueConditionalSize + fieldSize()); 0049 } 0050 0051 bool IataBcbpUniqueConditionalSection::isValid() const 0052 { 0053 if (m_data.size() >= 11) { 0054 // issue date 0055 if (std::any_of(m_data.begin() + 8, m_data.begin() + 11, [](auto c) { return !c.isDigit() && c != QLatin1Char(' '); }) || dayOfIssue() > 366) { 0056 return false; 0057 } 0058 } 0059 return true; 0060 } 0061 0062 QDate IataBcbpUniqueConditionalSection::dateOfIssue(const QDateTime &contextDate) const 0063 { 0064 const auto day = dayOfIssue() - 1; 0065 if (m_data.size() < 11 || day < 0) { 0066 return {}; 0067 } 0068 0069 const auto year = contextDate.date().year() - contextDate.date().year() % 10 + yearOfIssue(); 0070 const auto d = QDate(year, 1, 1).addDays(day); 0071 // TODO shouldn't this rather be d > contextDate? 0072 if (year > contextDate.date().year()) { 0073 return QDate(year - 10, 1, 1).addDays(day); 0074 } 0075 return d; 0076 } 0077 0078 IataBcbpRepeatedMandatorySection::IataBcbpRepeatedMandatorySection(QStringView data) 0079 { 0080 m_data = data; 0081 } 0082 0083 static bool isValidAirportCode(QStringView s) 0084 { 0085 return std::all_of(s.begin(), s.end(), [](const QChar c) { return c.isLetter() && c.isUpper(); }); 0086 } 0087 0088 bool IataBcbpRepeatedMandatorySection::isValid() const 0089 { 0090 if (m_data.size() < RepeatedMandatoryMinimalViableSize) { 0091 return false; 0092 } 0093 0094 return isValidAirportCode(m_data.mid(7, 3)) 0095 && isValidAirportCode(m_data.mid(10, 3)) 0096 && std::all_of(m_data.begin() + 21, m_data.begin() + 24, [](auto c) { return c.isDigit() || c == QLatin1Char(' '); }) 0097 && dayOfFlight() <= 366; 0098 } 0099 0100 QDate IataBcbpRepeatedMandatorySection::dateOfFlight(const QDateTime& contextDate) const 0101 { 0102 const auto day = dayOfFlight() - 1; 0103 if (day < 0) { 0104 return {}; // no set 0105 } 0106 const auto d = QDate(contextDate.date().year(), 1, 1).addDays(day); 0107 if (d < contextDate.date()) { 0108 return QDate(d.year() + 1, 1, 1).addDays(day); 0109 } 0110 return d; 0111 } 0112 0113 IataBcbpRepeatedConditionalSection::IataBcbpRepeatedConditionalSection(QStringView data) 0114 { 0115 if (data.size() < 2) { 0116 return; 0117 } 0118 m_data = data; 0119 m_data = data.left(conditionalFieldSize() + 2); 0120 } 0121 0122 IataBcbpSecuritySection::IataBcbpSecuritySection(QStringView data) 0123 { 0124 if (data.size() < MinimumSecuritySectionSize) { 0125 return; 0126 } 0127 m_data = data; 0128 m_data = data.left(size() + MinimumSecuritySectionSize); 0129 } 0130 0131 #include "moc_iatabcbpsections.cpp"