diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2020-08-03 23:40:25 +0200 |
---|---|---|
committer | Tor Arne Vestbø <tor.arne.vestbo@qt.io> | 2020-08-06 10:14:26 +0000 |
commit | 6d9ec41f6fef7af0129d13fc99fffc7a548f6125 (patch) | |
tree | 80110f0e4170256fcf03c3fd6e8563feb7a45bbb /src/corelib/io/qsettings_mac.cpp | |
parent | 76068d0114157c6b59523f3fb032cd8de64e9a63 (diff) |
Mac: (temporarily?) drop support for QMultiMap in QSettings
In preparation for the QMap/QMultiMap split. The previous code
had a workaround for storing multimaps, because the CF classes
actually don't support it: build a dictionary from one key
to a _list_ of values. Stop doing that.
In principle, if QMultiMap support does get added to QVariant
(which it probably should), then a similar workaround could be
readded for QMultiMap support.
[ChangeLog][Important Behavior Changes][QSettings] On Apple platforms,
when using the native format, QSettings is no longer able to handle
QVariantMap values which are actually multimaps. Since the native storage
does not actually support multimaps, QSettings used to flatten and
unflatten the maps. However, with QMap being changed to no longer
allow for equivalent keys, flattening when writing does not make
sense any more (there cannot be equivalent keys, because QMap in Qt 6
is a single-key map). Reading existing settings is supported by having
a key in the map mapping to a QVariantList of values.
Support for QMultiMap may be added back to QVariant and QSettings in a
future version of Qt.
Change-Id: Iaa9535100fe5ef55693f22a2068454a84180b4a6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/io/qsettings_mac.cpp')
-rw-r--r-- | src/corelib/io/qsettings_mac.cpp | 64 |
1 files changed, 20 insertions, 44 deletions
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp index a2b943f9ec..70a2fe49e5 100644 --- a/src/corelib/io/qsettings_mac.cpp +++ b/src/corelib/io/qsettings_mac.cpp @@ -122,52 +122,25 @@ static QCFType<CFPropertyListRef> macValue(const QVariant &value) break; case QVariant::Map: { - /* - QMap<QString, QVariant> is potentially a multimap, - whereas CFDictionary is a single-valued map. To allow - for multiple values with the same key, we store - multiple values in a CFArray. To avoid ambiguities, - we also wrap lists in a CFArray singleton. - */ - QMap<QString, QVariant> map = value.toMap(); - QMap<QString, QVariant>::const_iterator i = map.constBegin(); - - int maxUniqueKeys = map.size(); - int numUniqueKeys = 0; - QVarLengthArray<QCFType<CFPropertyListRef> > cfkeys(maxUniqueKeys); - QVarLengthArray<QCFType<CFPropertyListRef> > cfvalues(maxUniqueKeys); - - while (i != map.constEnd()) { - const QString &key = i.key(); - QList<QVariant> values; - - do { - values << i.value(); - ++i; - } while (i != map.constEnd() && i.key() == key); - - bool singleton = (values.count() == 1); - if (singleton) { - switch (values.constFirst().type()) { - // should be same as above (look for LIST) - case QVariant::List: - case QVariant::StringList: - case QVariant::Polygon: - singleton = false; - default: - ; - } - } + const QVariantMap &map = value.toMap(); + const int mapSize = map.size(); - cfkeys[numUniqueKeys] = key.toCFString(); - cfvalues[numUniqueKeys] = singleton ? macValue(values.constFirst()) : macList(values); - ++numUniqueKeys; - } + QVarLengthArray<QCFType<CFPropertyListRef>> cfkeys; + cfkeys.reserve(mapSize); + std::transform(map.keyBegin(), map.keyEnd(), + std::back_inserter(cfkeys), + [](const auto &key) { return key.toCFString(); }); + + QVarLengthArray<QCFType<CFPropertyListRef>> cfvalues; + cfvalues.reserve(mapSize); + std::transform(map.begin(), map.end(), + std::back_inserter(cfvalues), + [](const auto &value) { return macValue(value); }); result = CFDictionaryCreate(kCFAllocatorDefault, reinterpret_cast<const void **>(cfkeys.data()), reinterpret_cast<const void **>(cfvalues.data()), - CFIndex(numUniqueKeys), + CFIndex(mapSize), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); } @@ -283,15 +256,18 @@ static QVariant qtValue(CFPropertyListRef cfvalue) QVarLengthArray<CFPropertyListRef> values(size); CFDictionaryGetKeysAndValues(cfdict, keys.data(), values.data()); - QMultiMap<QString, QVariant> map; + QVariantMap map; for (int i = 0; i < size; ++i) { QString key = QString::fromCFString(static_cast<CFStringRef>(keys[i])); if (CFGetTypeID(values[i]) == arrayTypeId) { CFArrayRef cfarray = static_cast<CFArrayRef>(values[i]); CFIndex arraySize = CFArrayGetCount(cfarray); - for (CFIndex j = arraySize - 1; j >= 0; --j) - map.insert(key, qtValue(CFArrayGetValueAtIndex(cfarray, j))); + QVariantList list; + list.reserve(arraySize); + for (CFIndex j = 0; j < arraySize; ++j) + list.append(qtValue(CFArrayGetValueAtIndex(cfarray, j))); + map.insert(key, list); } else { map.insert(key, qtValue(values[i])); } |