summaryrefslogtreecommitdiffstats
path: root/src/corelib/io/qsettings_mac.cpp
diff options
context:
space:
mode:
authorGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2020-08-03 23:40:25 +0200
committerTor Arne Vestbø <tor.arne.vestbo@qt.io>2020-08-06 10:14:26 +0000
commit6d9ec41f6fef7af0129d13fc99fffc7a548f6125 (patch)
tree80110f0e4170256fcf03c3fd6e8563feb7a45bbb /src/corelib/io/qsettings_mac.cpp
parent76068d0114157c6b59523f3fb032cd8de64e9a63 (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.cpp64
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]));
}