summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qtimezoneprivate_tz.cpp
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2017-02-21 13:25:43 +0100
committerMarc Mutz <marc.mutz@kdab.com>2017-02-22 07:58:19 +0000
commitadca47cbc10f2458ea54cee841c06dc169763fe6 (patch)
tree60c77345475a1b6ca91d540c6115abe85a8da113 /src/corelib/tools/qtimezoneprivate_tz.cpp
parentc585802e946d97e7d177ea334a162dc7bc286b84 (diff)
QTzTimeZonePrivate: introduce PosixZone class
... as a replacement for QPair<QString, int>, and move some repsonsibilities into it. This avoids the repeated use of the magic number INT_MIN to indicate absence of an offset and does away with the confusing .first and .second, replacing them instead with proper names, .name and .offset. Change-Id: I0f6906467b8efa16bed2bf5677f2bbbd534da1ae Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/tools/qtimezoneprivate_tz.cpp')
-rw-r--r--src/corelib/tools/qtimezoneprivate_tz.cpp69
1 files changed, 43 insertions, 26 deletions
diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp
index 38dff88919..9cbe339225 100644
--- a/src/corelib/tools/qtimezoneprivate_tz.cpp
+++ b/src/corelib/tools/qtimezoneprivate_tz.cpp
@@ -452,13 +452,31 @@ static inline bool asciiIsLetter(char ch)
return ch >= 'a' && ch <= 'z';
}
+namespace {
+
+struct PosixZone
+{
+ enum {
+ InvalidOffset = INT_MIN,
+ };
+
+ QString name;
+ int offset;
+
+ static PosixZone invalid() { return {QString(), InvalidOffset}; }
+ static PosixZone parse(const char *&pos, const char *end);
+
+ bool hasValidOffset() const Q_DECL_NOTHROW { return offset != InvalidOffset; }
+};
+
+} // unnamed namespace
+
// Returns the zone name, the offset (in seconds) and advances \a begin to
// where the parsing ended. Returns a zone of INT_MIN in case an offset
// couldn't be read.
-static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const char *end)
+PosixZone PosixZone::parse(const char *&pos, const char *end)
{
static const char offsetChars[] = "0123456789:";
- QPair<QString, int> result = qMakePair(QString(), INT_MIN);
const char *nameBegin = pos;
const char *nameEnd;
@@ -480,7 +498,7 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c
pos = nameEnd;
}
if (nameEnd - nameBegin < 3)
- return result; // name must be at least 3 characters long
+ return invalid(); // name must be at least 3 characters long
// zone offset, form [+-]hh:mm:ss
const char *zoneBegin = pos;
@@ -493,11 +511,10 @@ static QPair<QString, int> parsePosixZoneNameAndOffset(const char *&pos, const c
++zoneEnd;
}
- result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
- if (zoneEnd > zoneBegin)
- result.second = parsePosixOffset(zoneBegin, zoneEnd);
+ QString name = QString::fromUtf8(nameBegin, nameEnd - nameBegin);
+ const int offset = zoneEnd > zoneBegin ? parsePosixOffset(zoneBegin, zoneEnd) : InvalidOffset;
pos = zoneEnd;
- return result;
+ return {std::move(name), offset};
}
static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArray &posixRule,
@@ -517,19 +534,19 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
// See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html
QList<QByteArray> parts = posixRule.split(',');
- QPair<QString, int> stdZone, dstZone;
+ PosixZone stdZone, dstZone;
{
const QByteArray &zoneinfo = parts.at(0);
const char *begin = zoneinfo.constBegin();
- stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
- if (stdZone.second == INT_MIN) {
- stdZone.second = 0; // reset to UTC if we failed to parse
+ stdZone = PosixZone::parse(begin, zoneinfo.constEnd());
+ if (!stdZone.hasValidOffset()) {
+ stdZone.offset = 0; // reset to UTC if we failed to parse
} else if (begin < zoneinfo.constEnd()) {
- dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd());
- if (dstZone.second == INT_MIN) {
+ dstZone = PosixZone::parse(begin, zoneinfo.constEnd());
+ if (!dstZone.hasValidOffset()) {
// if the dst offset isn't provided, it is 1 hour ahead of the standard offset
- dstZone.second = stdZone.second + (60 * 60);
+ dstZone.offset = stdZone.offset + (60 * 60);
}
}
}
@@ -538,10 +555,10 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
if (parts.count() == 1) {
QTimeZonePrivate::Data data;
data.atMSecsSinceEpoch = lastTranMSecs;
- data.offsetFromUtc = stdZone.second;
- data.standardTimeOffset = stdZone.second;
+ data.offsetFromUtc = stdZone.offset;
+ data.standardTimeOffset = stdZone.offset;
data.daylightTimeOffset = 0;
- data.abbreviation = stdZone.first;
+ data.abbreviation = stdZone.name;
result << data;
return result;
}
@@ -568,18 +585,18 @@ static QVector<QTimeZonePrivate::Data> calculatePosixTransitions(const QByteArra
for (int year = startYear; year <= endYear; ++year) {
QTimeZonePrivate::Data dstData;
QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC);
- dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000);
- dstData.offsetFromUtc = dstZone.second;
- dstData.standardTimeOffset = stdZone.second;
- dstData.daylightTimeOffset = dstZone.second - stdZone.second;
- dstData.abbreviation = dstZone.first;
+ dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.offset * 1000);
+ dstData.offsetFromUtc = dstZone.offset;
+ dstData.standardTimeOffset = stdZone.offset;
+ dstData.daylightTimeOffset = dstZone.offset - stdZone.offset;
+ dstData.abbreviation = dstZone.name;
QTimeZonePrivate::Data stdData;
QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC);
- stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000);
- stdData.offsetFromUtc = stdZone.second;
- stdData.standardTimeOffset = stdZone.second;
+ stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.offset * 1000);
+ stdData.offsetFromUtc = stdZone.offset;
+ stdData.standardTimeOffset = stdZone.offset;
stdData.daylightTimeOffset = 0;
- stdData.abbreviation = stdZone.first;
+ stdData.abbreviation = stdZone.name;
// Part of the high year will overflow
if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) {
if (dstData.atMSecsSinceEpoch > 0) {