Commit 58edfbb3 authored by Volker Krause's avatar Volker Krause
Browse files

Factor out UIC station code handling from the Hafas parser

We'll also need that for OJP.
parent 08e74206
......@@ -12,6 +12,7 @@ ecm_add_test(indexeddatatabletest.cpp LINK_LIBRARIES Qt5::Test)
ecm_add_test(polylinetest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
ecm_add_test(ifopttest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
ecm_add_test(uicutiltest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
ecm_add_test(mergeutiltest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
ecm_add_test(locationtest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
ecm_add_test(linetest.cpp LINK_LIBRARIES Qt5::Test KPublicTransport)
......
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "../src/lib/uic/uicutil.cpp"
#include <QTest>
#define s(x) QStringLiteral(x)
using namespace KPublicTransport;
class UicUtilTest: public QObject
{
Q_OBJECT
private Q_SLOTS:
void tesIsStationId()
{
QVERIFY(UicUtil::isStationId(u"8501687"));
QVERIFY(UicUtil::isStationId(u"8501687", {80, 85}));
QVERIFY(UicUtil::isStationId(u"008501687", {80, 85}));
QVERIFY(!UicUtil::isStationId(u"850012A", {80, 85}));
QVERIFY(!UicUtil::isStationId(u"8501687", {80, 81}));
QVERIFY(!UicUtil::isStationId(u"008501687"));
QVERIFY(!UicUtil::isStationId(u"851587"));
QVERIFY(!UicUtil::isStationId(u"85016870"));
}
};
QTEST_APPLESS_MAIN(UicUtilTest)
#include "uicutiltest.moc"
......@@ -108,6 +108,8 @@ target_sources(KPublicTransport PRIVATE
networks/networks.qrc
networks/certs/network_certs.qrc
uic/uicutil.cpp
)
ecm_qt_declare_logging_category(KPublicTransport
HEADER logging.h
......
......@@ -6,6 +6,7 @@
#include "hafasparser.h"
#include "logging.h"
#include "uic/uicutil.h"
#include <KPublicTransport/Location>
......@@ -73,34 +74,12 @@ Line::Mode HafasParser::parseLineMode(int modeId) const
void HafasParser::setLocationIdentifier(Location &loc, const QString &id) const
{
if (!m_standardLocationIdentifierType.isEmpty() && isUicStationId(id)) {
if (!m_standardLocationIdentifierType.isEmpty() && UicUtil::isStationId(id, m_uicCountryCodes)) {
loc.setIdentifier(m_standardLocationIdentifierType, id.right(7));
}
loc.setIdentifier(m_locationIdentifierType, id);
}
bool HafasParser::isUicStationId(const QString &id) const
{
// too short, or not a number
if (id.size() < 7 || std::any_of(id.begin(), id.end(), [](QChar c) { return !c.isDigit(); })) {
return false;
}
// too long, but just 0 prefixed
if (id.size() > 7 && std::any_of(id.begin(), id.begin() + id.size() - 7, [](QChar c) { return c != QLatin1Char('0'); })) {
return false;
}
// one of the explicitly allowed UIC country codes
if (!m_uicCountryCodes.empty()) {
const uint8_t countryCode = id.midRef(id.size() - 7, 2).toInt();
return std::binary_search(m_uicCountryCodes.begin(), m_uicCountryCodes.end(), countryCode);
}
// if no UIC country codes are explicitly allowed, insist on the right length
return id.size() == 7 && id.at(0) != QLatin1Char('0');
}
void HafasParser::setStandardLocationIdentfierCountries(std::vector<uint8_t> &&uicCountryCodes)
{
m_uicCountryCodes = std::move(uicCountryCodes);
......
......@@ -50,7 +50,6 @@ protected:
private:
Q_DISABLE_COPY(HafasParser)
bool isUicStationId(const QString &id) const;
QString m_locationIdentifierType;
QString m_standardLocationIdentifierType;
......
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#include "uicutil.h"
#include <QString>
#include <QStringView>
using namespace KPublicTransport;
bool UicUtil::isStationId(QStringView id, const std::vector<uint8_t> &allowedCountryCodes)
{
// too short, or not a number
if (id.size() < 7 || std::any_of(id.begin(), id.end(), [](QChar c) { return !c.isDigit() || c.row() > 0; })) {
return false;
}
// too long, but just 0 prefixed
if (id.size() > 7 && std::any_of(id.begin(), id.begin() + id.size() - 7, [](QChar c) { return c != QLatin1Char('0'); })) {
return false;
}
// one of the explicitly allowed UIC country codes
if (!allowedCountryCodes.empty()) {
const uint8_t countryCode = id.mid(id.size() - 7, 2).toInt();
return std::binary_search(allowedCountryCodes.begin(), allowedCountryCodes.end(), countryCode);
}
// if no UIC country codes are explicitly allowed, insist on the right length
return id.size() == 7 && id.at(0) != QLatin1Char('0');
}
/*
SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
SPDX-License-Identifier: LGPL-2.0-or-later
*/
#ifndef KPUBLICTRANSPORT_UICUTIL_H
#define KPUBLICTRANSPORT_UICUTIL_H
#include <cstdint>
#include <vector>
class QStringView;
namespace KPublicTransport {
/** Utility functions for dealing with UIC station codes.
* Also works for the syntactically identical IBNR station codes.
*/
namespace UicUtil
{
/** Returns @c true if @p id is a valid UIC station code.
* @params allowedCountryCodes if non-empty, only UIC station codes with an UIC country code included
* in that list are considered valid. This list has to be sorted.
*/
bool isStationId(QStringView id, const std::vector<uint8_t> &allowedCountryCodes = {});
}
}
#endif // KPUBLICTRANSPORT_UICUTIL_H
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment