File indexing completed on 2024-11-24 04:46:19

0001 /*
0002     SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include <QDateTime>
0010 
0011 #include <cstdint>
0012 
0013 /** @file vdvbasictypes.h
0014  *  Low-level data types used in VDV ticket structs.
0015  */
0016 
0017 namespace KItinerary {
0018 
0019 #pragma pack(push)
0020 #pragma pack(1)
0021 
0022 /** Two-digit BCD encoded number. */
0023 template <int N>
0024 struct VdvBcdNumber
0025 {
0026     static_assert(N > 0 && N <= 4);
0027     uint8_t data[N];
0028 
0029     inline constexpr uint32_t value() const
0030     {
0031         uint32_t v = 0;
0032         for (int i = 0; i < N; ++i) {
0033             v *= 100;
0034             v += ((data[i] & 0xF0) >> 4) * 10 + (data[i] & 0x0F);
0035         }
0036         return v;
0037     }
0038 
0039     inline constexpr operator uint32_t() const { return value(); }
0040 };
0041 
0042 /** Date encoded as 8 BCD digits. */
0043 struct VdvBcdDate
0044 {
0045     VdvBcdNumber<2> bcdYear;
0046     VdvBcdNumber<1> bcdMonth;
0047     VdvBcdNumber<1> bcdDay;
0048 
0049     inline QDate value() const
0050     {
0051         return QDate(bcdYear, bcdMonth, bcdDay);
0052     }
0053 
0054     inline operator QDate() const { return value(); }
0055     inline bool operator==(const QDate &other) const { return value() == other; }
0056     inline bool operator!=(const QDate &other) const { return value() != other; }
0057 
0058     // dummy assignment operator for compatibility with the Q_PROPERTY system
0059     inline VdvBcdDate& operator=(const QDate&) { return *this; }
0060 };
0061 
0062 /** Big-endian numeric value. */
0063 template <int N>
0064 struct VdvNumber
0065 {
0066     static_assert(N > 0 && N <= 4);
0067     uint8_t data[N];
0068 
0069     inline constexpr uint32_t value() const
0070     {
0071         uint32_t v = 0;
0072         for (int i = 0; i < N; ++i) {
0073             v <<= 8;
0074             v |= data[i];
0075         }
0076         return v;
0077     }
0078 
0079     inline constexpr operator uint32_t() const { return value(); }
0080 
0081     // dummy assignment operator for compatibility with the Q_PROPERTY system
0082     inline VdvNumber<N>& operator=(uint32_t) { return *this; }
0083 };
0084 
0085 /** Date/time representation encoded in 4 byte. */
0086 struct VdvDateTimeCompact
0087 {
0088     VdvNumber<4> data;
0089 
0090     inline QDateTime value() const
0091     {
0092         return QDateTime(
0093             {
0094                 (int)((data & 0b1111'1110'0000'0000'0000'0000'0000'0000) >> 25) + 1990,
0095                 (int)(data & 0b0000'0001'1110'0000'0000'0000'0000'0000) >> 21,
0096                 (int)(data & 0b0000'0000'0001'1111'0000'0000'0000'0000) >> 16
0097             }, {
0098                 (int)(data & 0b0000'0000'0000'0000'1111'1000'0000'0000) >> 11,
0099                 (int)(data & 0b0000'0000'0000'0000'0000'0111'1110'0000) >> 5,
0100                 (int)(data & 0b0000'0000'0000'0000'0000'0000'0001'1111) * 2
0101             });
0102     }
0103 
0104     inline operator QDateTime() const { return value(); }
0105     inline bool operator==(const QDateTime &other) const { return value() == other; }
0106     inline bool operator!=(const QDateTime &other) const { return value() != other; }
0107 
0108     // dummy assignment operator for compatibility with the Q_PROPERTY system
0109     inline VdvDateTimeCompact& operator=(const QDateTime&) { return *this; }
0110 };
0111 
0112 #pragma pack(pop)
0113 
0114 }
0115