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"