Commit 242cb179 authored by hjk's avatar hjk

Debugger: Adjust QDateTime dumper for Qt 5.2

Change-Id: I53a5701c9d1791e2705eafb258ff440f97e53b87
Reviewed-by: default avatarJohn Layt <jlayt@kde.org>
Reviewed-by: default avatarhjk <hjk121@nokiamail.com>
parent dc30a4a2
......@@ -816,7 +816,7 @@ Hex2EncodedFloat4, \
Hex2EncodedFloat8, \
IPv6AddressAndHexScopeId, \
Hex2EncodedUtf8WithoutQuotes, \
MillisecondsSinceEpoch \
DateTimeInternal \
= range(30)
# Display modes. Keep that synchronized with DebuggerDisplay in watchutils.h
......
......@@ -239,11 +239,25 @@ def qdump__QDateTime(d, value):
base = d.dereferenceValue(value)
if qtVersion >= 0x050200:
dateBase = base + d.ptrSize() # Only QAtomicInt, but will be padded.
ms = d.extractInt64(dateBase)
offset = d.extractInt(dateBase + 12)
isValid = ms > 0
if isValid:
d.putValue("%s" % (ms - offset * 1000), MillisecondsSinceEpoch)
# qint64 m_msecs
# Qt::TimeSpec m_spec
# int m_offsetFromUtc
# QTimeZone m_timeZone // only #ifndef QT_BOOTSTRAPPED
# StatusFlags m_status
status = d.extractInt(dateBase + 16 + d.ptrSize())
if int(status & 0x10): # ValidDateTime
isValid = True
msecs = d.extractInt64(dateBase)
spec = d.extractInt(dateBase + 8)
offset = d.extractInt(dateBase + 12)
tzp = d.dereference(dateBase + 16)
if tzp == 0:
tz = ""
else:
idBase = tzp + 2 * d.ptrSize() # [QSharedData] + [vptr]
tz = d.encodeByteArrayHelper(d.dereference(idBase))
d.putValue("%s/%s/%s/%s/%s" % (msecs, spec, offset, tz, status),
DateTimeInternal)
else:
# This relies on the Qt4/Qt5 internal structure layout:
# {sharedref(4), date(8), time(4+x)}
......
......@@ -33,6 +33,7 @@
#include <QDateTime>
#include <QDebug>
#include <QHostAddress>
#include <QTimeZone>
#include <ctype.h>
......@@ -503,6 +504,53 @@ static QTime timeFromData(int ms)
return ms == -1 ? QTime() : QTime(0, 0, 0, 0).addMSecs(ms);
}
// Stolen and adapted from qdatetime.cpp
static void getDateTime(qint64 msecs, int status, QDate *date, QTime *time)
{
enum {
SECS_PER_DAY = 86400,
MSECS_PER_DAY = 86400000,
SECS_PER_HOUR = 3600,
MSECS_PER_HOUR = 3600000,
SECS_PER_MIN = 60,
MSECS_PER_MIN = 60000,
TIME_T_MAX = 2145916799, // int maximum 2037-12-31T23:59:59 UTC
JULIAN_DAY_FOR_EPOCH = 2440588 // result of julianDayFromDate(1970, 1, 1)
};
// Status of date/time
enum StatusFlag {
NullDate = 0x01,
NullTime = 0x02,
ValidDate = 0x04,
ValidTime = 0x08,
ValidDateTime = 0x10,
TimeZoneCached = 0x20,
SetToStandardTime = 0x40,
SetToDaylightTime = 0x80
};
qint64 jd = JULIAN_DAY_FOR_EPOCH;
qint64 ds = 0;
if (qAbs(msecs) >= MSECS_PER_DAY) {
jd += (msecs / MSECS_PER_DAY);
msecs %= MSECS_PER_DAY;
}
if (msecs < 0) {
ds = MSECS_PER_DAY - msecs - 1;
jd -= ds / MSECS_PER_DAY;
ds = ds % MSECS_PER_DAY;
ds = MSECS_PER_DAY - ds - 1;
} else {
ds = msecs;
}
*date = (status & NullDate) ? QDate() : QDate::fromJulianDay(jd);
*time = (status & NullTime) ? QTime() : QTime::fromMSecsSinceStartOfDay(ds);
}
QString decodeData(const QByteArray &ba, int encoding)
{
switch (encoding) {
......@@ -629,15 +677,37 @@ QString decodeData(const QByteArray &ba, int encoding)
const QByteArray decodedBa = QByteArray::fromHex(ba);
return QString::fromUtf8(decodedBa);
}
case MillisecondsSinceEpoch: {
bool ok = false;
const qint64 ms = ba.toLongLong(&ok);
if (!ok)
return QLatin1String(ba);
QDateTime d;
d.setTimeSpec(Qt::UTC);
d.setMSecsSinceEpoch(ms);
return d.isValid() ? d.toString(Qt::TextDate) : QLatin1String("(invalid)");
case DateTimeInternal: { // 29, DateTimeInternal: msecs, spec, offset, tz, status
int p0 = ba.indexOf('/');
int p1 = ba.indexOf('/', p0 + 1);
int p2 = ba.indexOf('/', p1 + 1);
int p3 = ba.indexOf('/', p2 + 1);
qint64 msecs = ba.left(p0).toLongLong();
++p0;
Qt::TimeSpec spec = Qt::TimeSpec(ba.mid(p0, p1 - p0).toInt());
++p1;
qulonglong offset = ba.mid(p1, p2 - p1).toInt();
++p2;
QByteArray timeZoneId = QByteArray::fromHex(ba.mid(p2, p3 - p2));
++p3;
int status = ba.mid(p3).toInt();
QDate date;
QTime time;
getDateTime(msecs, status, &date, &time);
QDateTime dateTime;
if (spec == Qt::OffsetFromUTC) {
dateTime = QDateTime(date, time, spec, offset);
} else if (spec == Qt::TimeZone) {
if (!QTimeZone::isTimeZoneIdAvailable(timeZoneId))
return QLatin1String("<unavailable>");
dateTime = QDateTime(date, time, QTimeZone(timeZoneId));
} else {
dateTime = QDateTime(date, time, spec);
}
return dateTime.toString();
}
}
qDebug() << "ENCODING ERROR: " << encoding;
......
......@@ -205,7 +205,7 @@ enum DebuggerEncoding
Hex2EncodedFloat8 = 26,
IPv6AddressAndHexScopeId = 27,
Hex2EncodedUtf8WithoutQuotes = 28,
MillisecondsSinceEpoch = 29
DateTimeInternal = 29
};
// Keep in sync with dumper.py, symbolgroupvalue.cpp of CDB
......
......@@ -5475,8 +5475,11 @@ namespace basic {
void testLongEvaluation1()
{
QTimeZone tz("UTC+05:00");
QDateTime time = QDateTime::currentDateTime();
const int N = 10000;
QDateTime x = time;
x.setTimeZone(tz);
QDateTime bigv[N];
for (int i = 0; i < 10000; ++i) {
bigv[i] = time;
......
Markdown is supported
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