File indexing completed on 2024-04-28 11:34:14

0001 /*
0002   This file is part of the kcalcore library.
0003 
0004   SPDX-FileCopyrightText: 2017 Daniel Vrátil <dvratil@kde.org>
0005 
0006   SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include "utils_p.h"
0010 
0011 #include <QDataStream>
0012 #include <QTimeZone>
0013 
0014 // To remain backwards compatible we need to (de)serialize QDateTime the way KDateTime
0015 // was (de)serialized
0016 void KCalendarCore::serializeQDateTimeAsKDateTime(QDataStream &out, const QDateTime &dt)
0017 {
0018     out << dt.date() << dt.time();
0019     switch (dt.timeSpec()) {
0020     case Qt::UTC:
0021         out << static_cast<quint8>('u');
0022         break;
0023     case Qt::OffsetFromUTC:
0024         out << static_cast<quint8>('o') << dt.offsetFromUtc();
0025         break;
0026     case Qt::TimeZone:
0027         serializeQTimeZoneAsSpec(out, dt.timeZone());
0028         break;
0029     case Qt::LocalTime:
0030         out << static_cast<quint8>('c');
0031         break;
0032     }
0033     const bool isDateOnly = dt.date().isValid() && !dt.time().isValid();
0034     out << quint8(isDateOnly ? 0x01 : 0x00);
0035 }
0036 
0037 void KCalendarCore::deserializeKDateTimeAsQDateTime(QDataStream &in, QDateTime &dt)
0038 {
0039     QDate date;
0040     QTime time;
0041     quint8 ts;
0042     quint8 flags;
0043 
0044     in >> date >> time >> ts;
0045     switch (static_cast<uchar>(ts)) {
0046     case 'u':
0047         dt = QDateTime(date, time, Qt::UTC);
0048         break;
0049     case 'o': {
0050         int offset;
0051         in >> offset;
0052         dt = QDateTime(date, time, Qt::OffsetFromUTC, offset);
0053         break;
0054     }
0055     case 'z': {
0056         QString tzid;
0057         in >> tzid;
0058         dt = QDateTime(date, time, QTimeZone(tzid.toUtf8()));
0059         break;
0060     }
0061     case 'c':
0062         dt = QDateTime(date, time, Qt::LocalTime);
0063         break;
0064     }
0065 
0066     // unused, we don't have a special handling for date-only QDateTime
0067     in >> flags;
0068 }
0069 
0070 QDateTime KCalendarCore::deserializeKDateTimeAsQDateTime(QDataStream &in)
0071 {
0072     QDateTime dt;
0073     QDate date;
0074     QTime time;
0075     quint8 ts;
0076     quint8 flags;
0077 
0078     in >> date >> time >> ts;
0079     switch (static_cast<uchar>(ts)) {
0080     case 'u':
0081         dt = QDateTime(date, time, Qt::UTC);
0082         break;
0083     case 'o': {
0084         int offset;
0085         in >> offset;
0086         dt = QDateTime(date, time, Qt::OffsetFromUTC, offset);
0087         break;
0088     }
0089     case 'z': {
0090         QString tzid;
0091         in >> tzid;
0092         dt = QDateTime(date, time, QTimeZone(tzid.toUtf8()));
0093         break;
0094     }
0095     case 'c':
0096         dt = QDateTime(date, time, Qt::LocalTime);
0097         break;
0098     }
0099 
0100     // unused, we don't have a special handling for date-only QDateTime
0101     in >> flags;
0102 
0103     return dt;
0104 }
0105 
0106 void KCalendarCore::serializeQTimeZoneAsSpec(QDataStream &out, const QTimeZone &tz)
0107 {
0108     out << static_cast<quint8>('z') << (tz.isValid() ? QString::fromUtf8(tz.id()) : QString());
0109 }
0110 
0111 void KCalendarCore::deserializeSpecAsQTimeZone(QDataStream &in, QTimeZone &tz)
0112 {
0113     quint8 ts;
0114     in >> ts;
0115     switch (static_cast<uchar>(ts)) {
0116     case 'u':
0117         tz = QTimeZone::utc();
0118         return;
0119     case 'o': {
0120         int offset;
0121         in >> offset;
0122         tz = QTimeZone(offset);
0123         return;
0124     }
0125     case 'z': {
0126         QString tzid;
0127         in >> tzid;
0128         tz = QTimeZone(tzid.toUtf8());
0129         return;
0130     }
0131     case 'c':
0132         tz = QTimeZone::systemTimeZone();
0133         break;
0134     }
0135 }
0136 
0137 void KCalendarCore::serializeQDateTimeList(QDataStream &out, const QList<QDateTime> &list)
0138 {
0139     out << (qint32)list.size();
0140     for (const auto &i : list) {
0141         serializeQDateTimeAsKDateTime(out, i);
0142     }
0143 }
0144 
0145 void KCalendarCore::deserializeQDateTimeList(QDataStream &in, QList<QDateTime> &list)
0146 {
0147     int size;
0148     in >> size;
0149     list.clear();
0150     list.reserve(size);
0151     for (int i = 0; i < size; ++i) {
0152         QDateTime dt;
0153         deserializeKDateTimeAsQDateTime(in, dt);
0154         list << dt;
0155     }
0156 }