From bc0040b9700dd1eddcd4e2b7ca1479bce2abdd78 Mon Sep 17 00:00:00 2001 From: Ivailo Monev Date: Sun, 13 Nov 2022 19:27:13 +0200 Subject: [PATCH] drop support for storing types that are not QString-convertable via QSettings I am not interested in custom types feature at all - QMainWindow for example saves its state via QDataStream. ofcourse it involves conversion but that is the case with QVariant aswell. there is also the qreal type thing - it may be float, it may double. streaming QRectF has to be done in such a way to account for both cases but here is the catch - if conversion fails there has to be fallback which QSettings::value() kinda covers for types that are not composed of several more types. Signed-off-by: Ivailo Monev --- src/core/io/qsettings.cpp | 154 ++------------------------------- src/core/io/qsettings_p.h | 4 - tests/auto/qsettings/tst_qsettings.cpp | 71 --------------- 3 files changed, 6 insertions(+), 223 deletions(-) diff --git a/src/core/io/qsettings.cpp b/src/core/io/qsettings.cpp index 2a79f433f..3e8795ea1 100644 --- a/src/core/io/qsettings.cpp +++ b/src/core/io/qsettings.cpp @@ -111,7 +111,7 @@ static bool ini_settings_read(QIODevice &device, QSettings::SettingsMap &map) const QByteArray key = line.left(separatorpos).trimmed(); const QByteArray value = line.mid(separatorpos + 1).trimmed(); - const QVariant variantvalue = QSettingsPrivate::stringToVariant(value); + const QVariant variantvalue(value); if (section.isEmpty()) { map.insert(key, variantvalue); } else { @@ -154,7 +154,11 @@ static bool ini_settings_write(QIODevice &device, const QSettings::SettingsMap & return false; } - const QString stringvalue = QSettingsPrivate::variantToString(map.value(key)); + const QVariant variantvalue = map.value(key); + if (!variantvalue.canConvert()) { + return false; + } + const QString stringvalue = variantvalue.toString(); const QString datavalue = QLatin1Char('=') + stringvalue + QLatin1Char('\n'); if (!device.write(datavalue.toAscii())) { return false; @@ -317,152 +321,6 @@ QString QSettingsPrivate::toGroupKey(const QString &key) const return group + QLatin1Char('/') + key; } -QString QSettingsPrivate::variantToString(const QVariant &v) -{ - switch (v.type()) { - case QVariant::Invalid: { - return QLatin1String("@Invalid()"); - } - case QVariant::ByteArray: { - QByteArray a = v.toByteArray(); - QString result = QLatin1String("@ByteArray("); - result += QString::fromAscii(a.constData(), a.size()); - result += QLatin1Char(')'); - return result; - } - case QVariant::String: - case QVariant::LongLong: - case QVariant::ULongLong: - case QVariant::Int: - case QVariant::UInt: - case QVariant::Bool: - case QVariant::Double: - case QVariant::KeySequence: { - QString result = v.toString(); - if (result.startsWith(QLatin1Char('@'))) - result.prepend(QLatin1Char('@')); - return result; - } - case QVariant::Rect: { - QRect r = qvariant_cast(v); - QString result = QLatin1String("@Rect("); - result += QString::number(r.x()); - result += QLatin1Char(' '); - result += QString::number(r.y()); - result += QLatin1Char(' '); - result += QString::number(r.width()); - result += QLatin1Char(' '); - result += QString::number(r.height()); - result += QLatin1Char(')'); - return result; - } - case QVariant::Size: { - QSize s = qvariant_cast(v); - QString result = QLatin1String("@Size("); - result += QString::number(s.width()); - result += QLatin1Char(' '); - result += QString::number(s.height()); - result += QLatin1Char(')'); - return result; - } - case QVariant::Point: { - QPoint p = qvariant_cast(v); - QString result = QLatin1String("@Point("); - result += QString::number(p.x()); - result += QLatin1Char(' '); - result += QString::number(p.y()); - result += QLatin1Char(')'); - return result; - } - - default: { -#ifndef QT_NO_DATASTREAM - QByteArray a; - { - QDataStream s(&a, QIODevice::WriteOnly); - s << v; - } - - QString result = QLatin1String("@Variant("); - result += QString::fromAscii(a.constData(), a.size()); - result += QLatin1Char(')'); - return result; -#else - Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support"); - return QString(); -#endif - } - } - return QString(); -} - - -QVariant QSettingsPrivate::stringToVariant(const QString &s) -{ - if (s.startsWith(QLatin1Char('@'))) { - if (s.endsWith(QLatin1Char(')'))) { - if (s.startsWith(QLatin1String("@ByteArray("))) { - return QVariant(s.toAscii().mid(11, s.size() - 12)); - } else if (s.startsWith(QLatin1String("@Variant("))) { -#ifndef QT_NO_DATASTREAM - QByteArray a(s.toAscii().mid(9)); - QDataStream stream(&a, QIODevice::ReadOnly); - QVariant result; - stream >> result; - return result; -#else - Q_ASSERT(!"QSettings: Cannot load custom types without QDataStream support"); -#endif - } else if (s.startsWith(QLatin1String("@Rect("))) { - QStringList args = QSettingsPrivate::splitArgs(s, 5); - if (args.size() == 4) - return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt())); - } else if (s.startsWith(QLatin1String("@Size("))) { - QStringList args = QSettingsPrivate::splitArgs(s, 5); - if (args.size() == 2) - return QVariant(QSize(args[0].toInt(), args[1].toInt())); - } else if (s.startsWith(QLatin1String("@Point("))) { - QStringList args = QSettingsPrivate::splitArgs(s, 6); - if (args.size() == 2) - return QVariant(QPoint(args[0].toInt(), args[1].toInt())); - } else if (s == QLatin1String("@Invalid()")) { - return QVariant(); - } - - } - if (s.startsWith(QLatin1String("@@"))) - return QVariant(s.mid(1)); - } - - return QVariant(s); -} - -QStringList QSettingsPrivate::splitArgs(const QString &s, int idx) -{ - int l = s.length(); - Q_ASSERT(l > 0); - Q_ASSERT(s.at(idx) == QLatin1Char('(')); - Q_ASSERT(s.at(l - 1) == QLatin1Char(')')); - - QStringList result; - QString item; - - for (++idx; idx < l; ++idx) { - QChar c = s.at(idx); - if (c == QLatin1Char(')')) { - Q_ASSERT(idx == l - 1); - result.append(item); - } else if (c == QLatin1Char(' ')) { - result.append(item); - item.clear(); - } else { - item.append(c); - } - } - - return result; -} - /*! \class QSettings \brief The QSettings class provides persistent platform-independent application settings. diff --git a/src/core/io/qsettings_p.h b/src/core/io/qsettings_p.h index 4ef2a4b77..cd1c4e7a2 100644 --- a/src/core/io/qsettings_p.h +++ b/src/core/io/qsettings_p.h @@ -54,10 +54,6 @@ public: void notify(); QString toGroupKey(const QString &key) const; - // INI parser functions - static QString variantToString(const QVariant &v); - static QVariant stringToVariant(const QString &s); - static QStringList splitArgs(const QString &s, int idx); QSettings::Format format; QSettings::SettingsStatus status; diff --git a/tests/auto/qsettings/tst_qsettings.cpp b/tests/auto/qsettings/tst_qsettings.cpp index 733bc8b3d..7d564f56a 100644 --- a/tests/auto/qsettings/tst_qsettings.cpp +++ b/tests/auto/qsettings/tst_qsettings.cpp @@ -49,8 +49,6 @@ private slots: void variant(); void group_data(); void group(); - void custom_data(); - void custom(); }; void tst_QSettings::initTestCase() @@ -142,27 +140,12 @@ void tst_QSettings::variant() const QByteArray qbytearray("abc"); const QByteArray qstring("måndag"); const QStringList qstringlist = QStringList() << "a" << "b" << "c"; - const QPoint qpoint(1, 2); - const QRect qrect(1, 2, 3, 4); - const QSize qsize(1, 2); - const QDate qdate = QDate::currentDate(); - const QColor qcolor(1, 2, 3); - const QFont qfont = QApplication::font(); QVARIANT_TEST(qll); QVARIANT_TEST(qrl); QVARIANT_TEST(qbytearray); QVARIANT_TEST(qstring); QVARIANT_TEST(qstringlist); - if (format == QSettings::NativeFormat) { - QSKIP("Native format does not support some types", SkipAll); - } - QVARIANT_TEST(qpoint); - QVARIANT_TEST(qrect); - QVARIANT_TEST(qsize); - QVARIANT_TEST(qdate); - QVARIANT_TEST(qcolor); - QVARIANT_TEST(qfont); } #undef QVARIANT_TEST @@ -194,60 +177,6 @@ void tst_QSettings::group() settings.endGroup(); } -struct CustomType { - int a; - QByteArray b; - QSize c; -}; -Q_DECLARE_METATYPE(CustomType); - -QDataStream &operator<<(QDataStream &stream, const CustomType &custom) -{ - stream << custom.a; - stream << custom.b; - stream << custom.c; - return stream; -} - -QDataStream &operator>>(QDataStream &stream, CustomType &custom) -{ - stream >> custom.a; - stream >> custom.b; - stream >> custom.c; - return stream; -} - -void tst_QSettings::custom_data() -{ - tst_QSettings::value_data(); -} - -void tst_QSettings::custom() -{ - QFETCH(QString, filename); - QFETCH(QSettings::Format, format); - - if (format == QSettings::NativeFormat) { - QSKIP("Native format does not support custom types", SkipAll); - } - - qRegisterMetaType(); - qRegisterMetaTypeStreamOperators(); - - CustomType test; - test.a = 10; - test.b = QByteArray("test"); - test.c = QSize(10, 10); - - QSettings settings(filename, format); - settings.setValue("a", QVariant::fromValue(test)); - - CustomType result = qvariant_cast(settings.value("a")); - QCOMPARE(result.a, 10); - QCOMPARE(result.b, QByteArray("test")); - QCOMPARE(result.c, QSize(10, 10)); -} - QTEST_MAIN(tst_QSettings) #include "moc_tst_qsettings.cpp" -- 2.11.0