File indexing completed on 2024-12-29 04:50:10

0001 /*
0002     SPDX-FileCopyrightText: 2018-2020 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "kitinerary_export.h"
0010 
0011 #include "alphaid.h"
0012 #include "knowledgedb.h"
0013 
0014 class QString;
0015 
0016 namespace KItinerary {
0017 namespace KnowledgeDb {
0018 
0019 /** Base class for UIC/IBNR station identifiers. */
0020 class UICIdentiferBase : public UnalignedNumber<3> {
0021 public:
0022     inline explicit constexpr UICIdentiferBase() = default;
0023     inline explicit constexpr UICIdentiferBase(uint32_t id) :
0024         UnalignedNumber<3>(id > 9999999 ? id / 10 : id) // strip off check digit if present
0025     {}
0026 
0027     KITINERARY_EXPORT UICIdentiferBase(const QString &id);
0028 
0029     inline constexpr bool isValid() const
0030     {
0031         return value() >= 1000000 && value() <= 9999999;
0032     }
0033 };
0034 
0035 /** IBNR station id.
0036  *  2 digits UIC country code, 5 digits station id.
0037  *  Same format as UICStation, but nevertheless different values.
0038  */
0039 class IBNR : public UICIdentiferBase {
0040     using UICIdentiferBase::UICIdentiferBase;
0041 };
0042 
0043 /** UIC station id.
0044  *  2 digits UIC country code, 5 digits station id.
0045  *  Same format as IBNR, but nevertheless different values.
0046  */
0047 class UICStation : public UICIdentiferBase {
0048     using UICIdentiferBase::UICIdentiferBase;
0049 };
0050 
0051 
0052 /** Base class for SNCF/Benerail station identifiers. */
0053 class FiveAlphaId : public UnalignedNumber<3> {
0054 public:
0055     inline explicit constexpr FiveAlphaId() = default;
0056     inline explicit constexpr FiveAlphaId(const char s[5])
0057         : UnalignedNumber<3>(fromChars(s))
0058     {
0059     }
0060 
0061     KITINERARY_EXPORT explicit FiveAlphaId(const QString &id);
0062 
0063     inline constexpr bool isValid() const
0064     {
0065         return value() > 0;
0066     }
0067 
0068     KITINERARY_EXPORT QString toString() const;
0069 
0070 private:
0071     static inline constexpr uint32_t fromChars(const char s[5])
0072     {
0073         return (s[4] - '@') + 27 * ((s[3] - '@') + 27 * ((s[2] - '@') + 27 * ((s[1] - '@') + 27 * (s[0] - '@'))));
0074     }
0075 };
0076 
0077 /** SNCF station id.
0078  *  2 letters ISO country code, 3 letters station id, expected to be in upper case.
0079  */
0080 class SncfStationId : public FiveAlphaId
0081 {
0082     using FiveAlphaId::FiveAlphaId;
0083 };
0084 
0085 /** Benerail station id.
0086  *  2 letters ISO country code, 3 letters station id, expected to be in upper case.
0087  */
0088 class BenerailStationId : public FiveAlphaId
0089 {
0090     using FiveAlphaId::FiveAlphaId;
0091 };
0092 
0093 
0094 /** VR (Finland) station codes.
0095  *  2 to 4 letter uppercase alphabetic code.
0096  */
0097 class VRStationCode : public UnalignedNumber<3>
0098 {
0099 public:
0100     inline constexpr VRStationCode() = default;
0101     inline explicit constexpr VRStationCode(const char s[4])
0102         : UnalignedNumber<3>(fromChars(s))
0103     {}
0104     KITINERARY_EXPORT explicit VRStationCode(const QString &id);
0105 
0106     inline constexpr bool isValid() const
0107     {
0108         return value() > 0;
0109     }
0110 
0111     KITINERARY_EXPORT QString toString() const;
0112 
0113 private:
0114     static inline constexpr uint32_t charVal(const char c)
0115     {
0116         // TODO in theory there's apparently also 'Ä' amd 'Ö'?
0117         return c == '\0' ? 0 : c - '@';
0118     }
0119     static inline constexpr uint32_t fromChars(const char s[4])
0120     {
0121         return (charVal(s[0]) << 18) + (charVal(s[1]) << 12) + (charVal(s[2]) << 6) + charVal(s[3]);
0122     }
0123 };
0124 
0125 /** Amtrak staion codes. */
0126 using AmtrakStationCode = AlphaId<uint16_t, 3>;
0127 /** Via Rail station code. */
0128 using ViaRailStationCode = AlphaId<UnalignedNumber<3>, 4>;
0129 /** UK railway station code. */
0130 using UKRailwayStationCode = AlphaId<uint16_t, 3>;
0131 }
0132 }