1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the QtCore module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPL3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or (at your option) the GNU General
28** Public license version 3 or any later version approved by the KDE Free
29** Qt Foundation. The licenses are as published by the Free Software
30** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31** included in the packaging of this file. Please review the following
32** information to ensure the GNU General Public License requirements will
33** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34** https://www.gnu.org/licenses/gpl-3.0.html.
35**
36** $QT_END_LICENSE$
37**
38****************************************************************************/
39
40#ifndef QSETTINGS_P_H
41#define QSETTINGS_P_H
42
43//
44// W A R N I N G
45// -------------
46//
47// This file is not part of the Qt API. It exists purely as an
48// implementation detail. This header file may change from version to
49// version without notice, or even be removed.
50//
51// We mean it.
52//
53
54#include "QtCore/qdatetime.h"
55#include "QtCore/qmap.h"
56#include "QtCore/qmutex.h"
57#include "QtCore/qiodevice.h"
58#include "QtCore/qstack.h"
59#include "QtCore/qstringlist.h"
60
61#include <QtCore/qvariant.h>
62#include "qsettings.h"
63
64#ifndef QT_NO_QOBJECT
65#include "private/qobject_p.h"
66#endif
67#include "private/qscopedpointer_p.h"
68
69QT_BEGIN_NAMESPACE
70
71#ifndef Q_OS_WIN
72#define QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
73#endif
74
75#if defined(Q_OS_WINRT)
76#define QT_QTSETTINGS_FORGET_ORIGINAL_KEY_ORDER
77#endif
78
79// used in testing framework
80#define QSETTINGS_P_H_VERSION 3
81
82#ifdef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
83static const Qt::CaseSensitivity IniCaseSensitivity = Qt::CaseSensitive;
84
85class QSettingsKey : public QString
86{
87public:
88 inline QSettingsKey(const QString &key, Qt::CaseSensitivity cs, int /* position */ = -1)
89 : QString(key) { Q_ASSERT(cs == Qt::CaseSensitive); Q_UNUSED(cs); }
90
91 inline QString originalCaseKey() const { return *this; }
92 inline int originalKeyPosition() const { return -1; }
93};
94#else
95static const Qt::CaseSensitivity IniCaseSensitivity = Qt::CaseInsensitive;
96
97class QSettingsKey : public QString
98{
99public:
100 inline QSettingsKey(const QString &key, Qt::CaseSensitivity cs, int position = -1)
101 : QString(key), theOriginalKey(key), theOriginalKeyPosition(position)
102 {
103 if (cs == Qt::CaseInsensitive)
104 QString::operator=(toLower());
105 }
106
107 inline QString originalCaseKey() const { return theOriginalKey; }
108 inline int originalKeyPosition() const { return theOriginalKeyPosition; }
109
110private:
111 QString theOriginalKey;
112 int theOriginalKeyPosition;
113};
114#endif
115
116Q_DECLARE_TYPEINFO(QSettingsKey, Q_MOVABLE_TYPE);
117
118typedef QMap<QSettingsKey, QByteArray> UnparsedSettingsMap;
119typedef QMap<QSettingsKey, QVariant> ParsedSettingsMap;
120
121class QSettingsGroup
122{
123public:
124 inline QSettingsGroup()
125 : num(-1), maxNum(-1) {}
126 inline QSettingsGroup(const QString &s)
127 : str(s), num(-1), maxNum(-1) {}
128 inline QSettingsGroup(const QString &s, bool guessArraySize)
129 : str(s), num(0), maxNum(guessArraySize ? 0 : -1) {}
130
131 inline QString name() const { return str; }
132 inline QString toString() const;
133 inline bool isArray() const { return num != -1; }
134 inline int arraySizeGuess() const { return maxNum; }
135 inline void setArrayIndex(int i)
136 { num = i + 1; if (maxNum != -1 && num > maxNum) maxNum = num; }
137
138 QString str;
139 int num;
140 int maxNum;
141};
142Q_DECLARE_TYPEINFO(QSettingsGroup, Q_MOVABLE_TYPE);
143
144inline QString QSettingsGroup::toString() const
145{
146 QString result;
147 result = str;
148 if (num > 0) {
149 result += QLatin1Char('/');
150 result += QString::number(num);
151 }
152 return result;
153}
154
155class Q_AUTOTEST_EXPORT QConfFile
156{
157public:
158 ~QConfFile();
159
160 ParsedSettingsMap mergedKeyMap() const;
161 bool isWritable() const;
162
163 static QConfFile *fromName(const QString &name, bool _userPerms);
164 static void clearCache();
165
166 QString name;
167 QDateTime timeStamp;
168 qint64 size;
169 UnparsedSettingsMap unparsedIniSections;
170 ParsedSettingsMap originalKeys;
171 ParsedSettingsMap addedKeys;
172 ParsedSettingsMap removedKeys;
173 QAtomicInt ref;
174 QMutex mutex;
175 bool userPerms;
176
177private:
178#ifdef Q_DISABLE_COPY
179 QConfFile(const QConfFile &);
180 QConfFile &operator=(const QConfFile &);
181#endif
182 QConfFile(const QString &name, bool _userPerms);
183
184 friend class QConfFile_createsItself; // silences compiler warning
185};
186
187class Q_AUTOTEST_EXPORT QSettingsPrivate
188#ifndef QT_NO_QOBJECT
189 : public QObjectPrivate
190#endif
191{
192#ifdef QT_NO_QOBJECT
193 QSettings *q_ptr;
194#endif
195 Q_DECLARE_PUBLIC(QSettings)
196
197public:
198 QSettingsPrivate(QSettings::Format format);
199 QSettingsPrivate(QSettings::Format format, QSettings::Scope scope,
200 const QString &organization, const QString &application);
201 virtual ~QSettingsPrivate();
202
203 virtual void remove(const QString &key) = 0;
204 virtual void set(const QString &key, const QVariant &value) = 0;
205 virtual bool get(const QString &key, QVariant *value) const = 0;
206
207 enum ChildSpec { AllKeys, ChildKeys, ChildGroups };
208 virtual QStringList children(const QString &prefix, ChildSpec spec) const = 0;
209
210 virtual void clear() = 0;
211 virtual void sync() = 0;
212 virtual void flush() = 0;
213 virtual bool isWritable() const = 0;
214 virtual QString fileName() const = 0;
215
216 QString actualKey(const QString &key) const;
217 void beginGroupOrArray(const QSettingsGroup &group);
218 void setStatus(QSettings::Status status) const;
219 void requestUpdate();
220 void update();
221
222 static QString normalizedKey(const QString &key);
223 static QSettingsPrivate *create(QSettings::Format format, QSettings::Scope scope,
224 const QString &organization, const QString &application);
225 static QSettingsPrivate *create(const QString &fileName, QSettings::Format format);
226
227 static void processChild(QStringRef key, ChildSpec spec, QStringList &result);
228
229 // Variant streaming functions
230 static QStringList variantListToStringList(const QVariantList &l);
231 static QVariant stringListToVariantList(const QStringList &l);
232
233 // parser functions
234 static QString variantToString(const QVariant &v);
235 static QVariant stringToVariant(const QString &s);
236 static void iniEscapedKey(const QString &key, QByteArray &result);
237 static bool iniUnescapedKey(const QByteArray &key, int from, int to, QString &result);
238 static void iniEscapedString(const QString &str, QByteArray &result, QTextCodec *codec);
239 static void iniEscapedStringList(const QStringList &strs, QByteArray &result, QTextCodec *codec);
240 static bool iniUnescapedStringList(const QByteArray &str, int from, int to,
241 QString &stringResult, QStringList &stringListResult,
242 QTextCodec *codec);
243 static QStringList splitArgs(const QString &s, int idx);
244
245 QSettings::Format format;
246 QSettings::Scope scope;
247 QString organizationName;
248 QString applicationName;
249 QTextCodec *iniCodec;
250
251protected:
252 QStack<QSettingsGroup> groupStack;
253 QString groupPrefix;
254 bool fallbacks;
255 bool pendingChanges;
256 bool atomicSyncOnly = true;
257 mutable QSettings::Status status;
258};
259
260#ifdef Q_OS_WASM
261class QWasmSettingsPrivate;
262#endif
263
264class QConfFileSettingsPrivate : public QSettingsPrivate
265{
266public:
267 QConfFileSettingsPrivate(QSettings::Format format, QSettings::Scope scope,
268 const QString &organization, const QString &application);
269 QConfFileSettingsPrivate(const QString &fileName, QSettings::Format format);
270 ~QConfFileSettingsPrivate();
271
272 void remove(const QString &key) override;
273 void set(const QString &key, const QVariant &value) override;
274 bool get(const QString &key, QVariant *value) const override;
275
276 QStringList children(const QString &prefix, ChildSpec spec) const override;
277
278 void clear() override;
279 void sync() override;
280 void flush() override;
281 bool isWritable() const override;
282 QString fileName() const override;
283
284 bool readIniFile(const QByteArray &data, UnparsedSettingsMap *unparsedIniSections);
285 static bool readIniSection(const QSettingsKey &section, const QByteArray &data,
286 ParsedSettingsMap *settingsMap, QTextCodec *codec);
287 static bool readIniLine(const QByteArray &data, int &dataPos, int &lineStart, int &lineLen,
288 int &equalsPos);
289
290private:
291 void initFormat();
292 virtual void initAccess();
293 void syncConfFile(QConfFile *confFile);
294 bool writeIniFile(QIODevice &device, const ParsedSettingsMap &map);
295#ifdef Q_OS_MAC
296 bool readPlistFile(const QByteArray &data, ParsedSettingsMap *map) const;
297 bool writePlistFile(QIODevice &file, const ParsedSettingsMap &map) const;
298#endif
299 void ensureAllSectionsParsed(QConfFile *confFile) const;
300 void ensureSectionParsed(QConfFile *confFile, const QSettingsKey &key) const;
301
302 QVector<QConfFile *> confFiles;
303 QSettings::ReadFunc readFunc;
304 QSettings::WriteFunc writeFunc;
305 QString extension;
306 Qt::CaseSensitivity caseSensitivity;
307 int nextPosition;
308#ifdef Q_OS_WASM
309 friend class QWasmSettingsPrivate;
310#endif
311};
312
313QT_END_NAMESPACE
314
315#endif // QSETTINGS_P_H
316

source code of qtbase/src/corelib/io/qsettings_p.h