KItinerary

iatabcbp.cpp
1 /*
2  SPDX-FileCopyrightText: 2021 Volker Krause <[email protected]>
3 
4  SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "iatabcbp.h"
8 #include "iatabcbpconstants_p.h"
9 #include "logging.h"
10 
11 #include <QScopeGuard>
12 
13 #include <cctype>
14 
15 using namespace KItinerary;
16 using namespace KItinerary::IataBcbpConstants;
17 
18 IataBcbp::IataBcbp() = default;
19 
20 IataBcbp::IataBcbp(const QString& data)
21 {
22  if (data.size() < MinimumViableSize || data[0] != QLatin1Char('M') || !data[1].isDigit()) {
23  return;
24  }
25  const auto trimmed = QStringView(data).trimmed(); // tolerance against e.g. trailing newlines
26  if (std::any_of(trimmed.begin(), trimmed.end(), [](QChar c) { return c.row() != 0 || !c.isPrint(); })) {
27  return;
28  }
29  m_data = data;
30  auto resetOnInvalid = qScopeGuard([this] { m_data.clear(); });
31 
32  if (!uniqueMandatorySection().isValid()) {
33  return;
34  }
35  if (hasUniqueConditionalSection() && !uniqueConditionalSection().isValid()) {
36  return;
37  }
38 
39  const auto legCount = uniqueMandatorySection().numberOfLegs();
40  int offset = UniqueMandatorySize;
41  for (int i = 0; i < legCount; ++i) {
42  if (offset > m_data.size()) {
43  return;
44  }
45  auto rms = IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset));
46  if (!rms.isValid()) {
47  return;
48  }
49  offset += rms.variableFieldSize() + RepeatedMandatorySize;
50  }
51 
52  resetOnInvalid.dismiss();
53 }
54 
55 IataBcbp::~IataBcbp() = default;
56 
57 bool IataBcbp::isValid() const
58 {
59  return !m_data.isEmpty();
60 }
61 
62 IataBcbpUniqueMandatorySection IataBcbp::uniqueMandatorySection() const
63 {
64  return IataBcbpUniqueMandatorySection(QStringView(m_data).left(UniqueMandatorySize));
65 }
66 
67 bool IataBcbp::hasUniqueConditionalSection() const
68 {
69  return (m_data.size() > (UniqueMandatorySize + RepeatedMandatorySize))
70  && (m_data.at(UniqueMandatorySize + RepeatedMandatorySize) == QLatin1Char('>'))
71  && repeatedMandatorySection(0).variableFieldSize() > MinimumUniqueConditionalSize;
72 }
73 
74 IataBcbpUniqueConditionalSection IataBcbp::uniqueConditionalSection() const
75 {
76  if (hasUniqueConditionalSection()) {
77  return IataBcbpUniqueConditionalSection(QStringView(m_data).mid(UniqueMandatorySize + RepeatedMandatorySize));
78  }
80 }
81 
83 {
84  int offset = UniqueMandatorySize;
85  for (auto i = 0; i < leg; ++i) {
86  offset += RepeatedMandatorySize + IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
87  }
88  return IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset, RepeatedMandatorySize));
89 }
90 
92 {
93  int offset = UniqueMandatorySize;
94  if (leg == 0 && hasUniqueConditionalSection()) {
95  offset += uniqueConditionalSection().fieldSize() + MinimumUniqueConditionalSize;
96  }
97  for (auto i = 0; i < leg; ++i) {
98  offset += RepeatedMandatorySize + IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
99  }
100  return IataBcbpRepeatedConditionalSection(QStringView(m_data).mid(offset + RepeatedMandatorySize));
101 }
102 
104 {
105  int offset = UniqueMandatorySize;
106  for (auto i = 0; i < leg; ++i) {
107  offset += RepeatedMandatorySize + IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
108  }
109  auto length = IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
110  if (leg == 0 && hasUniqueConditionalSection()) {
111  const auto s = uniqueConditionalSection().fieldSize() + MinimumUniqueConditionalSize;
112  offset += uniqueConditionalSection().fieldSize() + MinimumUniqueConditionalSize;
113  length -= s;
114  }
115  if (leg == 0 && !hasUniqueConditionalSection()) { // Easyjet special case that has a airline use section right after the mandatory block
116  return m_data.mid(offset + RepeatedMandatorySize, length);
117  }
118  const auto offset2 = IataBcbpRepeatedConditionalSection(QStringView(m_data).mid(offset + RepeatedMandatorySize)).conditionalFieldSize() + 2 + RepeatedMandatorySize;
119  return m_data.mid(offset + offset2, length - offset2 + RepeatedMandatorySize);
120 }
121 
122 bool IataBcbp::hasSecuritySection() const
123 {
124  int offset = UniqueMandatorySize;
125  for (auto i = 0; i < uniqueMandatorySection().numberOfLegs(); ++i) {
126  offset += RepeatedMandatorySize + IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
127  }
128  return offset < m_data.size() && m_data[offset] == QLatin1Char('^');
129 }
130 
131 IataBcbpSecuritySection IataBcbp::securitySection() const
132 {
133  int offset = UniqueMandatorySize;
134  for (auto i = 0; i < uniqueMandatorySection().numberOfLegs(); ++i) {
135  offset += RepeatedMandatorySize + IataBcbpRepeatedMandatorySection(QStringView(m_data).mid(offset)).variableFieldSize();
136  }
137  return IataBcbpSecuritySection(QStringView(m_data).mid(offset));
138 }
139 
140 QString IataBcbp::rawData() const
141 {
142  return m_data;
143 }
144 
146 {
147  return data.size() >= MinimumViableSize && data[0] == 'M' && std::isdigit(data[1]);
148 }
149 
150 bool IataBcbp::maybeIataBcbp(const QString &data)
151 {
152  return data.size() >= MinimumViableSize && data[0] == QLatin1Char('M') && data[1].isDigit();
153 }
154 
155 #include "moc_iatabcbp.cpp"
int size() const const
Unique mandatory section of an IATA BCBP.
QTextStream & left(QTextStream &stream)
Repeated mandatory sections of an IATA BCBP, occurs once per leg.
Conditional (optional) sections of an IATA BCBP, occurs once per leg.
Security section of an IATA BCBP.
Q_INVOKABLE QString airlineUseSection(int leg) const
Airline use (non-standard/vendor specific) section of leg.
Definition: iatabcbp.cpp:103
QStringView trimmed() const const
Q_INVOKABLE KItinerary::IataBcbpRepeatedMandatorySection repeatedMandatorySection(int leg) const
Mandatory section of leg.
Definition: iatabcbp.cpp:82
Q_INVOKABLE KItinerary::IataBcbpRepeatedConditionalSection repeatedConditionalSection(int leg) const
Conditional (optional) section of leg.
Definition: iatabcbp.cpp:91
bool isValid(QStringView ifopt)
static bool maybeIataBcbp(const QByteArray &data)
Fast checks whether this might be an IATA BCBP.
Definition: iatabcbp.cpp:145
Unique conditional (optional) section of an IATA BCBP.
int size() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Fri Sep 29 2023 04:01:26 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.