QSettings: Special-case serialization of QDateTime.

QDateTime values with a UTC offset are not correctly serialized with
QDataStream::Qt_4_0. So use a newer QDataStream format for this type and
mark it with "@DateTime" instead of "@Variant".

Task-number: QTBUG-46551
Change-Id: I211c89e8cd0211c949ec993e6ffd5192d0eebbb3
Reviewed-by: Joerg Bornemann <joerg.bornemann@theqtcompany.com>
bb10
Christian Kandeler 2015-09-23 08:45:08 +02:00
parent 9f779088f4
commit 73b8cd879c
2 changed files with 28 additions and 5 deletions

View File

@ -453,14 +453,23 @@ QString QSettingsPrivate::variantToString(const QVariant &v)
default: {
#ifndef QT_NO_DATASTREAM
QDataStream::Version version;
const char *typeSpec;
if (v.type() == QVariant::DateTime) {
version = QDataStream::Qt_5_6;
typeSpec = "@DateTime(";
} else {
version = QDataStream::Qt_4_0;
typeSpec = "@Variant(";
}
QByteArray a;
{
QDataStream s(&a, QIODevice::WriteOnly);
s.setVersion(QDataStream::Qt_4_0);
s.setVersion(version);
s << v;
}
result = QLatin1String("@Variant(");
result = QLatin1String(typeSpec);
result += QString::fromLatin1(a.constData(), a.size());
result += QLatin1Char(')');
#else
@ -480,11 +489,21 @@ QVariant QSettingsPrivate::stringToVariant(const QString &s)
if (s.endsWith(QLatin1Char(')'))) {
if (s.startsWith(QLatin1String("@ByteArray("))) {
return QVariant(s.toLatin1().mid(11, s.size() - 12));
} else if (s.startsWith(QLatin1String("@Variant("))) {
} else if (s.startsWith(QLatin1String("@Variant("))
|| s.startsWith(QLatin1String("@DateTime("))) {
#ifndef QT_NO_DATASTREAM
QByteArray a(s.toLatin1().mid(9));
QDataStream::Version version;
int offset;
if (s.at(1) == QLatin1Char('D')) {
version = QDataStream::Qt_5_6;
offset = 10;
} else {
version = QDataStream::Qt_4_0;
offset = 9;
}
QByteArray a(s.toLatin1().mid(offset));
QDataStream stream(&a, QIODevice::ReadOnly);
stream.setVersion(QDataStream::Qt_4_0);
stream.setVersion(version);
QVariant result;
stream >> result;
return result;

View File

@ -37,6 +37,7 @@
#include <QtCore/QSettings>
#include <private/qsettings_p.h>
#include <QtCore/QCoreApplication>
#include <QtCore/QDateTime>
#include <QtCore/QtGlobal>
#include <QtCore/QMetaType>
#include <QtCore/QString>
@ -1201,6 +1202,9 @@ void tst_QSettings::testVariantTypes()
QList<QVariant> l4;
l4 << QVariant(m2) << QVariant(l2) << QVariant(l3);
testVal("key13", l4, QVariantList, List);
QDateTime dt = QDateTime::currentDateTime();
dt.setOffsetFromUtc(3600);
testVal("key14", dt, QDateTime, DateTime);
// We store key sequences as strings instead of binary variant blob, for improved
// readability in the resulting format.