aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/kconfig.cpp56
-rw-r--r--src/core/kconfigdata_p.h30
2 files changed, 52 insertions, 34 deletions
diff --git a/src/core/kconfig.cpp b/src/core/kconfig.cpp
index 4bbceeda..9e62c167 100644
--- a/src/core/kconfig.cpp
+++ b/src/core/kconfig.cpp
@@ -130,10 +130,16 @@ bool KConfigPrivate::lockLocal()
return true;
}
+static bool isGroupOrSubGroupMatch(KEntryMapConstIterator entryMapIt, const QByteArray &group)
+{
+ const QByteArray &entryGroup = entryMapIt.key().mGroup;
+ Q_ASSERT_X(entryGroup.startsWith(group), Q_FUNC_INFO, "Precondition");
+ return entryGroup.size() == group.size() || entryGroup[group.size()] == '\x1d';
+}
+
void KConfigPrivate::copyGroup(const QByteArray &source, const QByteArray &destination, KConfigGroup *otherGroup, KConfigBase::WriteConfigFlags flags) const
{
KEntryMap &otherMap = otherGroup->config()->d_ptr->entryMap;
- const int len = source.length();
const bool sameName = (destination == source);
// we keep this bool outside the for loop so that if
@@ -141,16 +147,10 @@ void KConfigPrivate::copyGroup(const QByteArray &source, const QByteArray &desti
// as dirty erroneously
bool dirtied = false;
- for (auto entryMapIt = entryMap.cbegin(); entryMapIt != entryMap.cend(); ++entryMapIt) {
- const QByteArray &group = entryMapIt.key().mGroup;
-
- if (!group.startsWith(source)) { // nothing to do
- continue;
- }
-
+ entryMap.forEachEntryWhoseGroupStartsWith(source, [&source, &destination, flags, &otherMap, sameName, &dirtied](KEntryMapConstIterator entryMapIt) {
// don't copy groups that start with the same prefix, but are not sub-groups
- if (group.length() > len && group[len] != '\x1d') {
- continue;
+ if (!isGroupOrSubGroupMatch(entryMapIt, source)) {
+ return;
}
KEntryKey newKey = entryMapIt.key();
@@ -160,7 +160,7 @@ void KConfigPrivate::copyGroup(const QByteArray &source, const QByteArray &desti
}
if (!sameName) {
- newKey.mGroup.replace(0, len, destination);
+ newKey.mGroup.replace(0, source.size(), destination);
}
KEntry entry = entryMapIt.value();
@@ -175,7 +175,7 @@ void KConfigPrivate::copyGroup(const QByteArray &source, const QByteArray &desti
}
otherMap[newKey] = entry;
- }
+ });
if (dirtied) {
otherGroup->config()->d_ptr->bDirty = true;
@@ -318,50 +318,38 @@ QStringList KConfigPrivate::groupList(const QByteArray &group) const
const QByteArray theGroup = group + '\x1d';
ByteArrayViewSet groups;
- for (auto entryMapIt = entryMap.cbegin(); entryMapIt != entryMap.cend(); ++entryMapIt) {
+ entryMap.forEachEntryWhoseGroupStartsWith(theGroup, [&theGroup, &groups](KEntryMapConstIterator entryMapIt) {
const KEntryKey &key = entryMapIt.key();
- if (!key.mKey.isNull() && !entryMapIt->bDeleted && key.mGroup.startsWith(theGroup)) {
+ if (!key.mKey.isNull() && !entryMapIt->bDeleted) {
const auto subgroupStartPos = theGroup.size();
const auto subgroupEndPos = findFirstGroupEndPos(key.mGroup, subgroupStartPos);
groups.emplace(key.mGroup.constData() + subgroupStartPos, subgroupEndPos - subgroupStartPos);
}
- }
+ });
return stringListFromUtf8Collection(groups);
}
-static bool isGroupOrSubGroupMatch(const QByteArray &potentialGroup, const QByteArray &group)
-{
- if (!potentialGroup.startsWith(group)) {
- return false;
- }
- return potentialGroup.length() == group.length() || potentialGroup[group.length()] == '\x1d';
-}
-
/// Returns @p parentGroup itself, all its subgroups, subsubgroups, and so on, including deleted groups.
QSet<QByteArray> KConfigPrivate::allSubGroups(const QByteArray &parentGroup) const
{
QSet<QByteArray> groups;
- for (KEntryMap::const_iterator entryMapIt = entryMap.begin(); entryMapIt != entryMap.end(); ++entryMapIt) {
+ entryMap.forEachEntryWhoseGroupStartsWith(parentGroup, [&parentGroup, &groups](KEntryMapConstIterator entryMapIt) {
const KEntryKey &key = entryMapIt.key();
- if (key.mKey.isNull() && isGroupOrSubGroupMatch(key.mGroup, parentGroup)) {
+ if (key.mKey.isNull() && isGroupOrSubGroupMatch(entryMapIt, parentGroup)) {
groups << key.mGroup;
}
- }
+ });
+
return groups;
}
bool KConfigPrivate::hasNonDeletedEntries(const QByteArray &group) const
{
- for (KEntryMap::const_iterator it = entryMap.begin(); it != entryMap.end(); ++it) {
- const KEntryKey &key = it.key();
- // Check for any non-deleted entry
- if (isGroupOrSubGroupMatch(key.mGroup, group) && !key.mKey.isNull() && !it->bDeleted) {
- return true;
- }
- }
- return false;
+ return entryMap.anyEntryWhoseGroupStartsWith(group, [&group](KEntryMapConstIterator entryMapIt) {
+ return isGroupOrSubGroupMatch(entryMapIt, group) && !entryMapIt.key().mKey.isNull() && !entryMapIt->bDeleted;
+ });
}
QStringList KConfigPrivate::keyListImpl(const QByteArray &theGroup) const
diff --git a/src/core/kconfigdata_p.h b/src/core/kconfigdata_p.h
index 5e5246f3..beb18f45 100644
--- a/src/core/kconfigdata_p.h
+++ b/src/core/kconfigdata_p.h
@@ -155,6 +155,17 @@ inline bool operator<(const KEntryKey &k1, const KEntryKey &k2)
return (!k1.bDefault && k2.bDefault);
}
+/**
+ * Returns the minimum key that has @a mGroup == @p group.
+ *
+ * @note The returned "minimum key" is consistent with KEntryKey's operator<().
+ * The return value of this function can be passed to KEntryMap::lowerBound().
+ */
+inline KEntryKey minimumGroupKey(const QByteArray &group)
+{
+ return KEntryKey(group, QByteArray{}, true, false);
+}
+
QDebug operator<<(QDebug dbg, const KEntryKey &key);
QDebug operator<<(QDebug dbg, const KEntry &entry);
@@ -230,6 +241,25 @@ public:
}
bool revertEntry(const QByteArray &group, const QByteArray &key, EntryOptions options, SearchFlags flags = SearchFlags());
+
+ template<typename ConstIteratorUser>
+ void forEachEntryWhoseGroupStartsWith(const QByteArray &groupPrefix, ConstIteratorUser callback) const
+ {
+ for (auto it = lowerBound(minimumGroupKey(groupPrefix)), end = cend(); it != end && it.key().mGroup.startsWith(groupPrefix); ++it) {
+ callback(it);
+ }
+ }
+
+ template<typename ConstIteratorPredicate>
+ bool anyEntryWhoseGroupStartsWith(const QByteArray &groupPrefix, ConstIteratorPredicate predicate) const
+ {
+ for (auto it = lowerBound(minimumGroupKey(groupPrefix)), end = cend(); it != end && it.key().mGroup.startsWith(groupPrefix); ++it) {
+ if (predicate(it)) {
+ return true;
+ }
+ }
+ return false;
+ }
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::SearchFlags)
Q_DECLARE_OPERATORS_FOR_FLAGS(KEntryMap::EntryOptions)