Qt 4.8
qsettings.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
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 Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/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 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include <qdebug.h>
43 #include "qplatformdefs.h"
44 #include "qsettings.h"
45 
46 #ifndef QT_NO_SETTINGS
47 
48 #include "qsettings_p.h"
49 #include "qcache.h"
50 #include "qfile.h"
51 #include "qdir.h"
52 #include "qfileinfo.h"
53 #include "qmutex.h"
54 #include "qlibraryinfo.h"
55 #include "qtemporaryfile.h"
56 
57 #ifndef QT_NO_TEXTCODEC
58 # include "qtextcodec.h"
59 #endif
60 
61 #ifndef QT_NO_GEOM_VARIANT
62 #include "qsize.h"
63 #include "qpoint.h"
64 #include "qrect.h"
65 #endif // !QT_NO_GEOM_VARIANT
66 
67 #ifndef QT_NO_QOBJECT
68 #include "qcoreapplication.h"
69 #endif
70 
71 #ifdef Q_OS_WIN // for homedirpath reading from registry
72 #include "qt_windows.h"
73 #include <private/qsystemlibrary_p.h>
74 #endif
75 
76 #ifdef Q_OS_VXWORKS
77 # include <ioLib.h>
78 #endif
79 
80 #include <stdlib.h>
81 
82 #ifndef CSIDL_COMMON_APPDATA
83 #define CSIDL_COMMON_APPDATA 0x0023 // All Users\Application Data
84 #endif
85 
86 #ifndef CSIDL_APPDATA
87 #define CSIDL_APPDATA 0x001a // <username>\Application Data
88 #endif
89 
90 #ifdef Q_AUTOTEST_EXPORT
91 # define Q_AUTOTEST_EXPORT_HELPER Q_AUTOTEST_EXPORT
92 #else
93 # define Q_AUTOTEST_EXPORT_HELPER static
94 #endif
95 
96 // ************************************************************************
97 // QConfFile
98 
99 /*
100  QConfFile objects are explicitly shared within the application.
101  This ensures that modification to the settings done through one
102  QSettings object are immediately reflected in other setting
103  objects of the same application.
104 */
105 
107 
109 {
114 };
115 
120 
121 Q_GLOBAL_STATIC(ConfFileHash, usedHashFunc)
122 Q_GLOBAL_STATIC(ConfFileCache, unusedCacheFunc)
123 Q_GLOBAL_STATIC(PathHash, pathHashFunc)
124 Q_GLOBAL_STATIC(CustomFormatVector, customFormatVectorFunc)
125 Q_GLOBAL_STATIC(QMutex, globalMutex)
126 static QSettings::Format globalDefaultFormat = QSettings::NativeFormat;
127 
128 #ifndef Q_OS_WIN
129 inline bool qt_isEvilFsTypeName(const char *name)
130 {
131  return (qstrncmp(name, "nfs", 3) == 0
132  || qstrncmp(name, "autofs", 6) == 0
133  || qstrncmp(name, "cachefs", 7) == 0);
134 }
135 
136 #if defined(Q_OS_BSD4) && !defined(Q_OS_NETBSD)
138 # include <sys/param.h>
139 # include <sys/mount.h>
141 
142 Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
143 {
144  struct statfs buf;
145  if (fstatfs(handle, &buf) != 0)
146  return false;
147  return qt_isEvilFsTypeName(buf.f_fstypename);
148 }
149 
150 #elif defined(Q_OS_LINUX) || defined(Q_OS_HURD)
152 # include <sys/vfs.h>
153 # ifdef QT_LINUXBASE
154  // LSB 3.2 has fstatfs in sys/statfs.h, sys/vfs.h is just an empty dummy header
155 # include <sys/statfs.h>
156 # endif
158 # ifndef NFS_SUPER_MAGIC
159 # define NFS_SUPER_MAGIC 0x00006969
160 # endif
161 # ifndef AUTOFS_SUPER_MAGIC
162 # define AUTOFS_SUPER_MAGIC 0x00000187
163 # endif
164 # ifndef AUTOFSNG_SUPER_MAGIC
165 # define AUTOFSNG_SUPER_MAGIC 0x7d92b1a0
166 # endif
167 
168 Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
169 {
170  struct statfs buf;
171  if (fstatfs(handle, &buf) != 0)
172  return false;
173  return buf.f_type == NFS_SUPER_MAGIC
174  || buf.f_type == AUTOFS_SUPER_MAGIC
175  || buf.f_type == AUTOFSNG_SUPER_MAGIC;
176 }
177 
178 #elif defined(Q_OS_SOLARIS) || defined(Q_OS_IRIX) || defined(Q_OS_AIX) || defined(Q_OS_HPUX) \
179  || defined(Q_OS_OSF) || defined(Q_OS_QNX) || defined(Q_OS_SCO) \
180  || defined(Q_OS_UNIXWARE) || defined(Q_OS_RELIANT) || defined(Q_OS_NETBSD)
182 # include <sys/statvfs.h>
184 
185 Q_AUTOTEST_EXPORT_HELPER bool qIsLikelyToBeNfs(int handle)
186 {
187  struct statvfs buf;
188  if (fstatvfs(handle, &buf) != 0)
189  return false;
190 #if defined(Q_OS_NETBSD)
191  return qt_isEvilFsTypeName(buf.f_fstypename);
192 #else
193  return qt_isEvilFsTypeName(buf.f_basetype);
194 #endif
195 }
196 #else
197 Q_AUTOTEST_EXPORT_HELPER inline bool qIsLikelyToBeNfs(int /* handle */)
198 {
199  return true;
200 }
201 #endif
202 
203 static bool unixLock(int handle, int lockType)
204 {
205  /*
206  NFS hangs on the fcntl() call below when statd or lockd isn't
207  running. There's no way to detect this. Our work-around for
208  now is to disable locking when we detect NFS (or AutoFS or
209  CacheFS, which are probably wrapping NFS).
210  */
211  if (qIsLikelyToBeNfs(handle))
212  return false;
213 
214  struct flock fl;
215  fl.l_whence = SEEK_SET;
216  fl.l_start = 0;
217  fl.l_len = 0;
218  fl.l_type = lockType;
219  return fcntl(handle, F_SETLKW, &fl) == 0;
220 }
221 #endif
222 
223 QConfFile::QConfFile(const QString &fileName, bool _userPerms)
224  : name(fileName), size(0), ref(1), userPerms(_userPerms)
225 {
226  usedHashFunc()->insert(name, this);
227 }
228 
230 {
231  if (usedHashFunc())
232  usedHashFunc()->remove(name);
233 }
234 
236 {
239 
240  for (i = removedKeys.begin(); i != removedKeys.end(); ++i)
241  result.remove(i.key());
242  for (i = addedKeys.begin(); i != addedKeys.end(); ++i)
243  result.insert(i.key(), i.value());
244  return result;
245 }
246 
248 {
249  QFileInfo fileInfo(name);
250 
251 #ifndef QT_NO_TEMPORARYFILE
252  if (fileInfo.exists()) {
253 #endif
254  QFile file(name);
255  return file.open(QFile::ReadWrite);
256 #ifndef QT_NO_TEMPORARYFILE
257  } else {
258  // Create the directories to the file.
259  QDir dir(fileInfo.absolutePath());
260  if (!dir.exists()) {
261  if (!dir.mkpath(dir.absolutePath()))
262  return false;
263  }
264 
265  // we use a temporary file to avoid race conditions
266  QTemporaryFile file(name);
267  return file.open();
268  }
269 #endif
270 }
271 
273 {
274  QString absPath = QFileInfo(fileName).absoluteFilePath();
275 
276  ConfFileHash *usedHash = usedHashFunc();
277  ConfFileCache *unusedCache = unusedCacheFunc();
278 
279  QConfFile *confFile = 0;
280  QMutexLocker locker(globalMutex());
281 
282  if (!(confFile = usedHash->value(absPath))) {
283  if ((confFile = unusedCache->take(absPath)))
284  usedHash->insert(absPath, confFile);
285  }
286  if (confFile) {
287  confFile->ref.ref();
288  return confFile;
289  }
290  return new QConfFile(absPath, _userPerms);
291 }
292 
294 {
295  QMutexLocker locker(globalMutex());
296  unusedCacheFunc()->clear();
297 }
298 
299 // ************************************************************************
300 // QSettingsPrivate
301 
303  : format(format), scope(QSettings::UserScope /* nothing better to put */), iniCodec(0), spec(0), fallbacks(true),
304  pendingChanges(false), status(QSettings::NoError)
305 {
306 }
307 
309  const QString &organization, const QString &application)
310  : format(format), scope(scope), organizationName(organization), applicationName(application),
311  iniCodec(0), spec(0), fallbacks(true), pendingChanges(false), status(QSettings::NoError)
312 {
313 }
314 
316 {
317 }
318 
320 {
321  QString n = normalizedKey(key);
322  Q_ASSERT_X(!n.isEmpty(), "QSettings", "empty key");
323  n.prepend(groupPrefix);
324  return n;
325 }
326 
327 /*
328  Returns a string that never starts nor ends with a slash (or an
329  empty string). Examples:
330 
331  "foo" becomes "foo"
332  "/foo//bar///" becomes "foo/bar"
333  "///" becomes ""
334 
335  This function is optimized to avoid a QString deep copy in the
336  common case where the key is already normalized.
337 */
339 {
340  QString result = key;
341 
342  int i = 0;
343  while (i < result.size()) {
344  while (result.at(i) == QLatin1Char('/')) {
345  result.remove(i, 1);
346  if (i == result.size())
347  goto after_loop;
348  }
349  while (result.at(i) != QLatin1Char('/')) {
350  ++i;
351  if (i == result.size())
352  return result;
353  }
354  ++i; // leave the slash alone
355  }
356 
357 after_loop:
358  if (!result.isEmpty())
359  result.truncate(i - 1); // remove the trailing slash
360  return result;
361 }
362 
363 // see also qsettings_win.cpp and qsettings_mac.cpp
364 
365 #if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
367  const QString &organization, const QString &application)
368 {
369  return new QConfFileSettingsPrivate(format, scope, organization, application);
370 }
371 #endif
372 
373 #if !defined(Q_OS_WIN)
375 {
376  return new QConfFileSettingsPrivate(fileName, format);
377 }
378 #endif
379 
381 {
382  if (spec != AllKeys) {
383  int slashPos = key.indexOf(QLatin1Char('/'));
384  if (slashPos == -1) {
385  if (spec != ChildKeys)
386  return;
387  } else {
388  if (spec != ChildGroups)
389  return;
390  key.truncate(slashPos);
391  }
392  }
393  result.insert(key, QString());
394 }
395 
397 {
398  groupStack.push(group);
399  if (!group.name().isEmpty()) {
400  groupPrefix += group.name();
401  groupPrefix += QLatin1Char('/');
402  }
403 }
404 
405 /*
406  We only set an error if there isn't one set already. This way the user always gets the
407  first error that occurred. We always allow clearing errors.
408 */
409 
411 {
412  if (status == QSettings::NoError || this->status == QSettings::NoError)
413  this->status = status;
414 }
415 
417 {
418  flush();
419  pendingChanges = false;
420 }
421 
423 {
424  if (!pendingChanges) {
425  pendingChanges = true;
426 #ifndef QT_NO_QOBJECT
427  Q_Q(QSettings);
429 #else
430  update();
431 #endif
432  }
433 }
434 
436 {
437  QStringList result;
439  for (; it != l.constEnd(); ++it)
440  result.append(variantToString(*it));
441  return result;
442 }
443 
445 {
446  QStringList outStringList = l;
447  for (int i = 0; i < outStringList.count(); ++i) {
448  const QString &str = outStringList.at(i);
449 
450  if (str.startsWith(QLatin1Char('@'))) {
451  if (str.length() >= 2 && str.at(1) == QLatin1Char('@')) {
452  outStringList[i].remove(0, 1);
453  } else {
454  QVariantList variantList;
455  for (int j = 0; j < l.count(); ++j)
456  variantList.append(stringToVariant(l.at(j)));
457  return variantList;
458  }
459  }
460  }
461  return outStringList;
462 }
463 
465 {
466  QString result;
467 
468  switch (v.type()) {
469  case QVariant::Invalid:
470  result = QLatin1String("@Invalid()");
471  break;
472 
473  case QVariant::ByteArray: {
474  QByteArray a = v.toByteArray();
475  result = QLatin1String("@ByteArray(");
476  result += QString::fromLatin1(a.constData(), a.size());
477  result += QLatin1Char(')');
478  break;
479  }
480 
481  case QVariant::String:
482  case QVariant::LongLong:
483  case QVariant::ULongLong:
484  case QVariant::Int:
485  case QVariant::UInt:
486  case QVariant::Bool:
487  case QVariant::Double:
488  case QVariant::KeySequence: {
489  result = v.toString();
490  if (result.startsWith(QLatin1Char('@')))
491  result.prepend(QLatin1Char('@'));
492  break;
493  }
494 #ifndef QT_NO_GEOM_VARIANT
495  case QVariant::Rect: {
496  QRect r = qvariant_cast<QRect>(v);
497  result += QLatin1String("@Rect(");
498  result += QString::number(r.x());
499  result += QLatin1Char(' ');
500  result += QString::number(r.y());
501  result += QLatin1Char(' ');
502  result += QString::number(r.width());
503  result += QLatin1Char(' ');
504  result += QString::number(r.height());
505  result += QLatin1Char(')');
506  break;
507  }
508  case QVariant::Size: {
509  QSize s = qvariant_cast<QSize>(v);
510  result += QLatin1String("@Size(");
511  result += QString::number(s.width());
512  result += QLatin1Char(' ');
513  result += QString::number(s.height());
514  result += QLatin1Char(')');
515  break;
516  }
517  case QVariant::Point: {
518  QPoint p = qvariant_cast<QPoint>(v);
519  result += QLatin1String("@Point(");
520  result += QString::number(p.x());
521  result += QLatin1Char(' ');
522  result += QString::number(p.y());
523  result += QLatin1Char(')');
524  break;
525  }
526 #endif // !QT_NO_GEOM_VARIANT
527 
528  default: {
529 #ifndef QT_NO_DATASTREAM
530  QByteArray a;
531  {
534  s << v;
535  }
536 
537  result = QLatin1String("@Variant(");
538  result += QString::fromLatin1(a.constData(), a.size());
539  result += QLatin1Char(')');
540 #else
541  Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");
542 #endif
543  break;
544  }
545  }
546 
547  return result;
548 }
549 
550 
552 {
553  if (s.startsWith(QLatin1Char('@'))) {
554  if (s.endsWith(QLatin1Char(')'))) {
555  if (s.startsWith(QLatin1String("@ByteArray("))) {
556  return QVariant(s.toLatin1().mid(11, s.size() - 12));
557  } else if (s.startsWith(QLatin1String("@Variant("))) {
558 #ifndef QT_NO_DATASTREAM
559  QByteArray a(s.toLatin1().mid(9));
561  stream.setVersion(QDataStream::Qt_4_0);
562  QVariant result;
563  stream >> result;
564  return result;
565 #else
566  Q_ASSERT(!"QSettings: Cannot load custom types without QDataStream support");
567 #endif
568 #ifndef QT_NO_GEOM_VARIANT
569  } else if (s.startsWith(QLatin1String("@Rect("))) {
571  if (args.size() == 4)
572  return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()));
573  } else if (s.startsWith(QLatin1String("@Size("))) {
575  if (args.size() == 2)
576  return QVariant(QSize(args[0].toInt(), args[1].toInt()));
577  } else if (s.startsWith(QLatin1String("@Point("))) {
579  if (args.size() == 2)
580  return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
581 #endif
582  } else if (s == QLatin1String("@Invalid()")) {
583  return QVariant();
584  }
585 
586  }
587  if (s.startsWith(QLatin1String("@@")))
588  return QVariant(s.mid(1));
589  }
590 
591  return QVariant(s);
592 }
593 
594 static const char hexDigits[] = "0123456789ABCDEF";
595 
597 {
598  result.reserve(result.length() + key.length() * 3 / 2);
599  for (int i = 0; i < key.size(); ++i) {
600  uint ch = key.at(i).unicode();
601 
602  if (ch == '/') {
603  result += '\\';
604  } else if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')
605  || ch == '_' || ch == '-' || ch == '.') {
606  result += (char)ch;
607  } else if (ch <= 0xFF) {
608  result += '%';
609  result += hexDigits[ch / 16];
610  result += hexDigits[ch % 16];
611  } else {
612  result += "%U";
613  QByteArray hexCode;
614  for (int i = 0; i < 4; ++i) {
615  hexCode.prepend(hexDigits[ch % 16]);
616  ch >>= 4;
617  }
618  result += hexCode;
619  }
620  }
621 }
622 
623 bool QSettingsPrivate::iniUnescapedKey(const QByteArray &key, int from, int to, QString &result)
624 {
625  bool lowercaseOnly = true;
626  int i = from;
627  result.reserve(result.length() + (to - from));
628  while (i < to) {
629  int ch = (uchar)key.at(i);
630 
631  if (ch == '\\') {
632  result += QLatin1Char('/');
633  ++i;
634  continue;
635  }
636 
637  if (ch != '%' || i == to - 1) {
638  if (uint(ch - 'A') <= 'Z' - 'A') // only for ASCII
639  lowercaseOnly = false;
640  result += QLatin1Char(ch);
641  ++i;
642  continue;
643  }
644 
645  int numDigits = 2;
646  int firstDigitPos = i + 1;
647 
648  ch = key.at(i + 1);
649  if (ch == 'U') {
650  ++firstDigitPos;
651  numDigits = 4;
652  }
653 
654  if (firstDigitPos + numDigits > to) {
655  result += QLatin1Char('%');
656  // ### missing U
657  ++i;
658  continue;
659  }
660 
661  bool ok;
662  ch = key.mid(firstDigitPos, numDigits).toInt(&ok, 16);
663  if (!ok) {
664  result += QLatin1Char('%');
665  // ### missing U
666  ++i;
667  continue;
668  }
669 
670  QChar qch(ch);
671  if (qch.isUpper())
672  lowercaseOnly = false;
673  result += qch;
674  i = firstDigitPos + numDigits;
675  }
676  return lowercaseOnly;
677 }
678 
680 {
681  bool needsQuotes = false;
682  bool escapeNextIfDigit = false;
683  int i;
684  int startPos = result.size();
685 
686  result.reserve(startPos + str.size() * 3 / 2);
687  for (i = 0; i < str.size(); ++i) {
688  uint ch = str.at(i).unicode();
689  if (ch == ';' || ch == ',' || ch == '=')
690  needsQuotes = true;
691 
692  if (escapeNextIfDigit
693  && ((ch >= '0' && ch <= '9')
694  || (ch >= 'a' && ch <= 'f')
695  || (ch >= 'A' && ch <= 'F'))) {
696  result += "\\x";
697  result += QByteArray::number(ch, 16);
698  continue;
699  }
700 
701  escapeNextIfDigit = false;
702 
703  switch (ch) {
704  case '\0':
705  result += "\\0";
706  escapeNextIfDigit = true;
707  break;
708  case '\a':
709  result += "\\a";
710  break;
711  case '\b':
712  result += "\\b";
713  break;
714  case '\f':
715  result += "\\f";
716  break;
717  case '\n':
718  result += "\\n";
719  break;
720  case '\r':
721  result += "\\r";
722  break;
723  case '\t':
724  result += "\\t";
725  break;
726  case '\v':
727  result += "\\v";
728  break;
729  case '"':
730  case '\\':
731  result += '\\';
732  result += (char)ch;
733  break;
734  default:
735  if (ch <= 0x1F || (ch >= 0x7F && !codec)) {
736  result += "\\x";
737  result += QByteArray::number(ch, 16);
738  escapeNextIfDigit = true;
739 #ifndef QT_NO_TEXTCODEC
740  } else if (codec) {
741  // slow
742  result += codec->fromUnicode(str.at(i));
743 #endif
744  } else {
745  result += (char)ch;
746  }
747  }
748  }
749 
750  if (needsQuotes
751  || (startPos < result.size() && (result.at(startPos) == ' '
752  || result.at(result.size() - 1) == ' '))) {
753  result.insert(startPos, '"');
754  result += '"';
755  }
756 }
757 
758 inline static void iniChopTrailingSpaces(QString &str)
759 {
760  int n = str.size() - 1;
761  QChar ch;
762  while (n >= 0 && ((ch = str.at(n)) == QLatin1Char(' ') || ch == QLatin1Char('\t')))
763  str.truncate(n--);
764 }
765 
767 {
768  if (strs.isEmpty()) {
769  /*
770  We need to distinguish between empty lists and one-item
771  lists that contain an empty string. Ideally, we'd have a
772  @EmptyList() symbol but that would break compatibility
773  with Qt 4.0. @Invalid() stands for QVariant(), and
774  QVariant().toStringList() returns an empty QStringList,
775  so we're in good shape.
776 
777  ### Qt 5: Use a nicer syntax, e.g. @List, for variant lists
778  */
779  result += "@Invalid()";
780  } else {
781  for (int i = 0; i < strs.size(); ++i) {
782  if (i != 0)
783  result += ", ";
784  iniEscapedString(strs.at(i), result, codec);
785  }
786  }
787 }
788 
789 bool QSettingsPrivate::iniUnescapedStringList(const QByteArray &str, int from, int to,
790  QString &stringResult, QStringList &stringListResult,
791  QTextCodec *codec)
792 {
793 #ifdef QT_NO_TEXTCODE
794  Q_UNUSED(codec);
795 #endif
796  static const char escapeCodes[][2] =
797  {
798  { 'a', '\a' },
799  { 'b', '\b' },
800  { 'f', '\f' },
801  { 'n', '\n' },
802  { 'r', '\r' },
803  { 't', '\t' },
804  { 'v', '\v' },
805  { '"', '"' },
806  { '?', '?' },
807  { '\'', '\'' },
808  { '\\', '\\' }
809  };
810  static const int numEscapeCodes = sizeof(escapeCodes) / sizeof(escapeCodes[0]);
811 
812  bool isStringList = false;
813  bool inQuotedString = false;
814  bool currentValueIsQuoted = false;
815  int escapeVal = 0;
816  int i = from;
817  char ch;
818 
819 StSkipSpaces:
820  while (i < to && ((ch = str.at(i)) == ' ' || ch == '\t'))
821  ++i;
822  // fallthrough
823 
824 StNormal:
825  while (i < to) {
826  switch (str.at(i)) {
827  case '\\':
828  ++i;
829  if (i >= to)
830  goto end;
831 
832  ch = str.at(i++);
833  for (int j = 0; j < numEscapeCodes; ++j) {
834  if (ch == escapeCodes[j][0]) {
835  stringResult += QLatin1Char(escapeCodes[j][1]);
836  goto StNormal;
837  }
838  }
839 
840  if (ch == 'x') {
841  escapeVal = 0;
842 
843  if (i >= to)
844  goto end;
845 
846  ch = str.at(i);
847  if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'))
848  goto StHexEscape;
849  } else if (ch >= '0' && ch <= '7') {
850  escapeVal = ch - '0';
851  goto StOctEscape;
852  } else if (ch == '\n' || ch == '\r') {
853  if (i < to) {
854  char ch2 = str.at(i);
855  // \n, \r, \r\n, and \n\r are legitimate line terminators in INI files
856  if ((ch2 == '\n' || ch2 == '\r') && ch2 != ch)
857  ++i;
858  }
859  } else {
860  // the character is skipped
861  }
862  break;
863  case '"':
864  ++i;
865  currentValueIsQuoted = true;
866  inQuotedString = !inQuotedString;
867  if (!inQuotedString)
868  goto StSkipSpaces;
869  break;
870  case ',':
871  if (!inQuotedString) {
872  if (!currentValueIsQuoted)
873  iniChopTrailingSpaces(stringResult);
874  if (!isStringList) {
875  isStringList = true;
876  stringListResult.clear();
877  stringResult.squeeze();
878  }
879  stringListResult.append(stringResult);
880  stringResult.clear();
881  currentValueIsQuoted = false;
882  ++i;
883  goto StSkipSpaces;
884  }
885  // fallthrough
886  default: {
887  int j = i + 1;
888  while (j < to) {
889  ch = str.at(j);
890  if (ch == '\\' || ch == '"' || ch == ',')
891  break;
892  ++j;
893  }
894 
895 #ifndef QT_NO_TEXTCODEC
896  if (codec) {
897  stringResult += codec->toUnicode(str.constData() + i, j - i);
898  } else
899 #endif
900  {
901  int n = stringResult.size();
902  stringResult.resize(n + (j - i));
903  QChar *resultData = stringResult.data() + n;
904  for (int k = i; k < j; ++k)
905  *resultData++ = QLatin1Char(str.at(k));
906  }
907  i = j;
908  }
909  }
910  }
911  goto end;
912 
913 StHexEscape:
914  if (i >= to) {
915  stringResult += QChar(escapeVal);
916  goto end;
917  }
918 
919  ch = str.at(i);
920  if (ch >= 'a')
921  ch -= 'a' - 'A';
922  if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F')) {
923  escapeVal <<= 4;
924  escapeVal += strchr(hexDigits, ch) - hexDigits;
925  ++i;
926  goto StHexEscape;
927  } else {
928  stringResult += QChar(escapeVal);
929  goto StNormal;
930  }
931 
932 StOctEscape:
933  if (i >= to) {
934  stringResult += QChar(escapeVal);
935  goto end;
936  }
937 
938  ch = str.at(i);
939  if (ch >= '0' && ch <= '7') {
940  escapeVal <<= 3;
941  escapeVal += ch - '0';
942  ++i;
943  goto StOctEscape;
944  } else {
945  stringResult += QChar(escapeVal);
946  goto StNormal;
947  }
948 
949 end:
950  if (!currentValueIsQuoted)
951  iniChopTrailingSpaces(stringResult);
952  if (isStringList)
953  stringListResult.append(stringResult);
954  return isStringList;
955 }
956 
958 {
959  int l = s.length();
960  Q_ASSERT(l > 0);
961  Q_ASSERT(s.at(idx) == QLatin1Char('('));
962  Q_ASSERT(s.at(l - 1) == QLatin1Char(')'));
963 
964  QStringList result;
965  QString item;
966 
967  for (++idx; idx < l; ++idx) {
968  QChar c = s.at(idx);
969  if (c == QLatin1Char(')')) {
970  Q_ASSERT(idx == l - 1);
971  result.append(item);
972  } else if (c == QLatin1Char(' ')) {
973  result.append(item);
974  item.clear();
975  } else {
976  item.append(c);
977  }
978  }
979 
980  return result;
981 }
982 
983 // ************************************************************************
984 // QConfFileSettingsPrivate
985 
987 {
988  extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini");
989  readFunc = 0;
990  writeFunc = 0;
991 #if defined(Q_OS_MAC)
992  caseSensitivity = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : IniCaseSensitivity;
993 #else
994  caseSensitivity = IniCaseSensitivity;
995 #endif
996 
997  if (format > QSettings::IniFormat) {
998  QMutexLocker locker(globalMutex());
999  const CustomFormatVector *customFormatVector = customFormatVectorFunc();
1000 
1001  int i = (int)format - (int)QSettings::CustomFormat1;
1002  if (i >= 0 && i < customFormatVector->size()) {
1003  QConfFileCustomFormat info = customFormatVector->at(i);
1004  extension = info.extension;
1005  readFunc = info.readFunc;
1006  writeFunc = info.writeFunc;
1007  caseSensitivity = info.caseSensitivity;
1008  }
1009  }
1010 }
1011 
1013 {
1014  if (confFiles[spec]) {
1015  if (format > QSettings::IniFormat) {
1016  if (!readFunc)
1018  }
1019  }
1020 
1021  sync(); // loads the files the first time
1022 }
1023 
1024 #ifdef Q_OS_WIN
1026 {
1027  QString result;
1028 
1029 #ifndef Q_OS_WINCE
1030  QSystemLibrary library(QLatin1String("shell32"));
1031 #else
1032  QSystemLibrary library(QLatin1String("coredll"));
1033 #endif // Q_OS_WINCE
1034  typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPWSTR, int, BOOL);
1035  GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)library.resolve("SHGetSpecialFolderPathW");
1036  if (SHGetSpecialFolderPath) {
1037  wchar_t path[MAX_PATH];
1038  SHGetSpecialFolderPath(0, path, type, FALSE);
1039  result = QString::fromWCharArray(path);
1040  }
1041 
1042  if (result.isEmpty()) {
1043  switch (type) {
1044 #ifndef Q_OS_WINCE
1045  case CSIDL_COMMON_APPDATA:
1046  result = QLatin1String("C:\\temp\\qt-common");
1047  break;
1048  case CSIDL_APPDATA:
1049  result = QLatin1String("C:\\temp\\qt-user");
1050  break;
1051 #else
1052  case CSIDL_COMMON_APPDATA:
1053  result = QLatin1String("\\Temp\\qt-common");
1054  break;
1055  case CSIDL_APPDATA:
1056  result = QLatin1String("\\Temp\\qt-user");
1057  break;
1058 #endif
1059  default:
1060  ;
1061  }
1062  }
1063 
1064  return result;
1065 }
1066 #endif // Q_OS_WIN
1067 
1068 static inline int pathHashKey(QSettings::Format format, QSettings::Scope scope)
1069 {
1070  return int((uint(format) << 1) | uint(scope == QSettings::SystemScope));
1071 }
1072 
1073 static void initDefaultPaths(QMutexLocker *locker)
1074 {
1075  PathHash *pathHash = pathHashFunc();
1076  QString homePath = QDir::homePath();
1077  QString systemPath;
1078 
1079  locker->unlock();
1080 
1081  /*
1082  QLibraryInfo::location() uses QSettings, so in order to
1083  avoid a dead-lock, we can't hold the global mutex while
1084  calling it.
1085  */
1087  systemPath += QLatin1Char('/');
1088 
1089  locker->relock();
1090  if (pathHash->isEmpty()) {
1091  /*
1092  Lazy initialization of pathHash. We initialize the
1093  IniFormat paths and (on Unix) the NativeFormat paths.
1094  (The NativeFormat paths are not configurable for the
1095  Windows registry and the Mac CFPreferences.)
1096  */
1097 #ifdef Q_OS_WIN
1102 #else
1103  QString userPath;
1104  char *env = getenv("XDG_CONFIG_HOME");
1105  if (env == 0) {
1106  userPath = homePath;
1107  userPath += QLatin1Char('/');
1108 #if defined(Q_WS_QWS) || defined(Q_WS_QPA)
1109  userPath += QLatin1String("Settings");
1110 #else
1111  userPath += QLatin1String(".config");
1112 #endif
1113  } else if (*env == '/') {
1114  userPath = QFile::decodeName(env);
1115  } else {
1116  userPath = homePath;
1117  userPath += QLatin1Char('/');
1118  userPath += QFile::decodeName(env);
1119  }
1120  userPath += QLatin1Char('/');
1121 
1124 #ifndef Q_OS_MAC
1127 #endif
1128 #endif
1129  }
1130 }
1131 
1133 {
1134  Q_ASSERT((int)QSettings::NativeFormat == 0);
1135  Q_ASSERT((int)QSettings::IniFormat == 1);
1136 
1137  QMutexLocker locker(globalMutex());
1138  PathHash *pathHash = pathHashFunc();
1139  if (pathHash->isEmpty())
1140  initDefaultPaths(&locker);
1141 
1142  QString result = pathHash->value(pathHashKey(format, scope));
1143  if (!result.isEmpty())
1144  return result;
1145 
1146  // fall back on INI path
1147  return pathHash->value(pathHashKey(QSettings::IniFormat, scope));
1148 }
1149 
1151  QSettings::Scope scope,
1152  const QString &organization,
1153  const QString &application)
1154  : QSettingsPrivate(format, scope, organization, application),
1155  nextPosition(0x40000000) // big positive number
1156 {
1157  int i;
1158  initFormat();
1159 
1160  QString org = organization;
1161  if (org.isEmpty()) {
1163  org = QLatin1String("Unknown Organization");
1164  }
1165 
1166 #if !defined(Q_OS_BLACKBERRY)
1167  QString appFile = org + QDir::separator() + application + extension;
1168  QString orgFile = org + extension;
1169 
1170  if (scope == QSettings::UserScope) {
1171  QString userPath = getPath(format, QSettings::UserScope);
1172  if (!application.isEmpty())
1173  confFiles[F_User | F_Application].reset(QConfFile::fromName(userPath + appFile, true));
1174  confFiles[F_User | F_Organization].reset(QConfFile::fromName(userPath + orgFile, true));
1175  }
1176 
1177  QString systemPath = getPath(format, QSettings::SystemScope);
1178  if (!application.isEmpty())
1179  confFiles[F_System | F_Application].reset(QConfFile::fromName(systemPath + appFile, false));
1180  confFiles[F_System | F_Organization].reset(QConfFile::fromName(systemPath + orgFile, false));
1181 #else
1182  QString confName = getPath(format, QSettings::UserScope) + org;
1183  if (!application.isEmpty())
1184  confName += QDir::separator() + application;
1185  confName += extension;
1186  confFiles[SandboxConfFile].reset(QConfFile::fromName(confName, true));
1187 #endif
1188 
1189  for (i = 0; i < NumConfFiles; ++i) {
1190  if (confFiles[i]) {
1191  spec = i;
1192  break;
1193  }
1194  }
1195 
1196  initAccess();
1197 }
1198 
1200  QSettings::Format format)
1201  : QSettingsPrivate(format),
1202  nextPosition(0x40000000) // big positive number
1203 {
1204  initFormat();
1205 
1206  confFiles[0].reset(QConfFile::fromName(fileName, true));
1207 
1208  initAccess();
1209 }
1210 
1212 {
1213  QMutexLocker locker(globalMutex());
1214  ConfFileHash *usedHash = usedHashFunc();
1215  ConfFileCache *unusedCache = unusedCacheFunc();
1216 
1217  for (int i = 0; i < NumConfFiles; ++i) {
1218  if (confFiles[i] && !confFiles[i]->ref.deref()) {
1219  if (confFiles[i]->size == 0) {
1220  delete confFiles[i].take();
1221  } else {
1222  if (usedHash)
1223  usedHash->remove(confFiles[i]->name);
1224  if (unusedCache) {
1225  QT_TRY {
1226  // compute a better size?
1227  unusedCache->insert(confFiles[i]->name, confFiles[i].data(),
1228  10 + (confFiles[i]->originalKeys.size() / 4));
1229  confFiles[i].take();
1230  } QT_CATCH(...) {
1231  // out of memory. Do not cache the file.
1232  delete confFiles[i].take();
1233  }
1234  } else {
1235  // unusedCache is gone - delete the entry to prevent a memory leak
1236  delete confFiles[i].take();
1237  }
1238  }
1239  }
1240  // prevent the ScopedPointer to deref it again.
1241  confFiles[i].take();
1242  }
1243 }
1244 
1246 {
1247  QConfFile *confFile = confFiles[spec].data();
1248  if (!confFile)
1249  return;
1250 
1251  QSettingsKey theKey(key, caseSensitivity);
1252  QSettingsKey prefix(key + QLatin1Char('/'), caseSensitivity);
1253  QMutexLocker locker(&confFile->mutex);
1254 
1255  ensureSectionParsed(confFile, theKey);
1256  ensureSectionParsed(confFile, prefix);
1257 
1258  ParsedSettingsMap::iterator i = confFile->addedKeys.lowerBound(prefix);
1259  while (i != confFile->addedKeys.end() && i.key().startsWith(prefix))
1260  i = confFile->addedKeys.erase(i);
1261  confFile->addedKeys.remove(theKey);
1262 
1263  ParsedSettingsMap::const_iterator j = const_cast<const ParsedSettingsMap *>(&confFile->originalKeys)->lowerBound(prefix);
1264  while (j != confFile->originalKeys.constEnd() && j.key().startsWith(prefix)) {
1265  confFile->removedKeys.insert(j.key(), QVariant());
1266  ++j;
1267  }
1268  if (confFile->originalKeys.contains(theKey))
1269  confFile->removedKeys.insert(theKey, QVariant());
1270 }
1271 
1273 {
1274  QConfFile *confFile = confFiles[spec].data();
1275  if (!confFile)
1276  return;
1277 
1278  QSettingsKey theKey(key, caseSensitivity, nextPosition++);
1279  QMutexLocker locker(&confFile->mutex);
1280  confFile->removedKeys.remove(theKey);
1281  confFile->addedKeys.insert(theKey, value);
1282 }
1283 
1285 {
1286  QSettingsKey theKey(key, caseSensitivity);
1288  bool found = false;
1289 
1290  for (int i = 0; i < NumConfFiles; ++i) {
1291  if (QConfFile *confFile = confFiles[i].data()) {
1292  QMutexLocker locker(&confFile->mutex);
1293 
1294  if (!confFile->addedKeys.isEmpty()) {
1295  j = confFile->addedKeys.constFind(theKey);
1296  found = (j != confFile->addedKeys.constEnd());
1297  }
1298  if (!found) {
1299  ensureSectionParsed(confFile, theKey);
1300  j = confFile->originalKeys.constFind(theKey);
1301  found = (j != confFile->originalKeys.constEnd()
1302  && !confFile->removedKeys.contains(theKey));
1303  }
1304 
1305  if (found && value)
1306  *value = *j;
1307 
1308  if (found)
1309  return true;
1310  if (!fallbacks)
1311  break;
1312  }
1313  }
1314  return false;
1315 }
1316 
1318 {
1319  QMap<QString, QString> result;
1321 
1322  QSettingsKey thePrefix(prefix, caseSensitivity);
1323  int startPos = prefix.size();
1324 
1325  for (int i = 0; i < NumConfFiles; ++i) {
1326  if (QConfFile *confFile = confFiles[i].data()) {
1327  QMutexLocker locker(&confFile->mutex);
1328 
1329  if (thePrefix.isEmpty()) {
1330  ensureAllSectionsParsed(confFile);
1331  } else {
1332  ensureSectionParsed(confFile, thePrefix);
1333  }
1334 
1335  j = const_cast<const ParsedSettingsMap *>(
1336  &confFile->originalKeys)->lowerBound( thePrefix);
1337  while (j != confFile->originalKeys.constEnd() && j.key().startsWith(thePrefix)) {
1338  if (!confFile->removedKeys.contains(j.key()))
1339  processChild(j.key().originalCaseKey().mid(startPos), spec, result);
1340  ++j;
1341  }
1342 
1343  j = const_cast<const ParsedSettingsMap *>(
1344  &confFile->addedKeys)->lowerBound(thePrefix);
1345  while (j != confFile->addedKeys.constEnd() && j.key().startsWith(thePrefix)) {
1346  processChild(j.key().originalCaseKey().mid(startPos), spec, result);
1347  ++j;
1348  }
1349 
1350  if (!fallbacks)
1351  break;
1352  }
1353  }
1354  return result.keys();
1355 }
1356 
1358 {
1359  QConfFile *confFile = confFiles[spec].data();
1360  if (!confFile)
1361  return;
1362 
1363  QMutexLocker locker(&confFile->mutex);
1364  ensureAllSectionsParsed(confFile);
1365  confFile->addedKeys.clear();
1366  confFile->removedKeys = confFile->originalKeys;
1367 }
1368 
1370 {
1371  // people probably won't be checking the status a whole lot, so in case of
1372  // error we just try to go on and make the best of it
1373 
1374  for (int i = 0; i < NumConfFiles; ++i) {
1375  QConfFile *confFile = confFiles[i].data();
1376  if (confFile) {
1377  QMutexLocker locker(&confFile->mutex);
1378  syncConfFile(i);
1379  }
1380  }
1381 }
1382 
1384 {
1385  sync();
1386 }
1387 
1389 {
1390  QConfFile *confFile = confFiles[spec].data();
1391  if (!confFile)
1392  return QString();
1393  return confFile->name;
1394 }
1395 
1397 {
1398  if (format > QSettings::IniFormat && !writeFunc)
1399  return false;
1400 
1401  QConfFile *confFile = confFiles[spec].data();
1402  if (!confFile)
1403  return false;
1404 
1405  return confFile->isWritable();
1406 }
1407 
1409 {
1410  QConfFile *confFile = confFiles[confFileNo].data();
1411  bool readOnly = confFile->addedKeys.isEmpty() && confFile->removedKeys.isEmpty();
1412  bool ok;
1413 
1414  /*
1415  We can often optimize the read-only case, if the file on disk
1416  hasn't changed.
1417  */
1418  if (readOnly && confFile->size > 0) {
1419  QFileInfo fileInfo(confFile->name);
1420  if (confFile->size == fileInfo.size() && confFile->timeStamp == fileInfo.lastModified())
1421  return;
1422  }
1423 
1424  /*
1425  Open the configuration file and try to use it using a named
1426  semaphore on Windows and an advisory lock on Unix-based
1427  systems. This protect us against other QSettings instances
1428  trying to access the same file from other threads or
1429  processes.
1430 
1431  As it stands now, the locking mechanism doesn't work for
1432  .plist files.
1433  */
1434  QFile file(confFile->name);
1435  bool createFile = !file.exists();
1436  if (!readOnly && confFile->isWritable())
1437  file.open(QFile::ReadWrite);
1438  if (!file.isOpen())
1439  file.open(QFile::ReadOnly);
1440 
1441  if (!createFile && !file.isOpen())
1443 
1444 #ifdef Q_OS_WIN
1445  HANDLE readSemaphore = 0;
1446  HANDLE writeSemaphore = 0;
1447  static const int FileLockSemMax = 50;
1448  int numReadLocks = readOnly ? 1 : FileLockSemMax;
1449 
1450  if (file.isOpen()) {
1451  // Acquire the write lock if we will be writing
1452  if (!readOnly) {
1453  QString writeSemName = QLatin1String("QSettingsWriteSem ");
1454  writeSemName.append(file.fileName());
1455 
1456  writeSemaphore = CreateSemaphore(0, 1, 1, reinterpret_cast<const wchar_t *>(writeSemName.utf16()));
1457 
1458  if (writeSemaphore) {
1459  WaitForSingleObject(writeSemaphore, INFINITE);
1460  } else {
1462  return;
1463  }
1464  }
1465 
1466  // Acquire all the read locks if we will be writing, to make sure nobody
1467  // reads while we're writing. If we are only reading, acquire a single
1468  // read lock.
1469  QString readSemName(QLatin1String("QSettingsReadSem "));
1470  readSemName.append(file.fileName());
1471 
1472  readSemaphore = CreateSemaphore(0, FileLockSemMax, FileLockSemMax, reinterpret_cast<const wchar_t *>(readSemName.utf16()));
1473 
1474  if (readSemaphore) {
1475  for (int i = 0; i < numReadLocks; ++i)
1476  WaitForSingleObject(readSemaphore, INFINITE);
1477  } else {
1479  if (writeSemaphore != 0) {
1480  ReleaseSemaphore(writeSemaphore, 1, 0);
1481  CloseHandle(writeSemaphore);
1482  }
1483  return;
1484  }
1485  }
1486 #else
1487  if (file.isOpen())
1488  unixLock(file.handle(), readOnly ? F_RDLCK : F_WRLCK);
1489 #endif
1490 
1491  // If we have created the file, apply the file perms
1492  if (file.isOpen()) {
1493  if (createFile) {
1494  QFile::Permissions perms = file.permissions() | QFile::ReadOwner | QFile::WriteOwner;
1495  if (!confFile->userPerms)
1497  file.setPermissions(perms);
1498  }
1499  }
1500 
1501  /*
1502  We hold the lock. Let's reread the file if it has changed
1503  since last time we read it.
1504  */
1505  QFileInfo fileInfo(confFile->name);
1506  bool mustReadFile = true;
1507 
1508  if (!readOnly)
1509  mustReadFile = (confFile->size != fileInfo.size()
1510  || (confFile->size != 0 && confFile->timeStamp != fileInfo.lastModified()));
1511 
1512  if (mustReadFile) {
1513  confFile->unparsedIniSections.clear();
1514  confFile->originalKeys.clear();
1515 
1516  /*
1517  Files that we can't read (because of permissions or
1518  because they don't exist) are treated as empty files.
1519  */
1520  if (file.isReadable() && fileInfo.size() != 0) {
1521 #ifdef Q_OS_MAC
1522  if (format == QSettings::NativeFormat) {
1523  ok = readPlistFile(confFile->name, &confFile->originalKeys);
1524  } else
1525 #endif
1526  {
1527  if (format <= QSettings::IniFormat) {
1528  QByteArray data = file.readAll();
1529  ok = readIniFile(data, &confFile->unparsedIniSections);
1530  } else {
1531  if (readFunc) {
1532  QSettings::SettingsMap tempNewKeys;
1533  ok = readFunc(file, tempNewKeys);
1534 
1535  if (ok) {
1537  while (i != tempNewKeys.constEnd()) {
1538  confFile->originalKeys.insert(QSettingsKey(i.key(),
1539  caseSensitivity),
1540  i.value());
1541  ++i;
1542  }
1543  }
1544  } else {
1545  ok = false;
1546  }
1547  }
1548  }
1549 
1550  if (!ok)
1552  }
1553 
1554  confFile->size = fileInfo.size();
1555  confFile->timeStamp = fileInfo.lastModified();
1556  }
1557 
1558  /*
1559  We also need to save the file. We still hold the file lock,
1560  so everything is under control.
1561  */
1562  if (!readOnly) {
1563  ensureAllSectionsParsed(confFile);
1564  ParsedSettingsMap mergedKeys = confFile->mergedKeyMap();
1565 
1566  if (file.isWritable()) {
1567 #ifdef Q_OS_MAC
1568  if (format == QSettings::NativeFormat) {
1569  ok = writePlistFile(confFile->name, mergedKeys);
1570  } else
1571 #endif
1572  {
1573  file.seek(0);
1574  file.resize(0);
1575 
1576  if (format <= QSettings::IniFormat) {
1577  ok = writeIniFile(file, mergedKeys);
1578  if (!ok) {
1579  // try to restore old data; might work if the disk was full and the new data
1580  // was larger than the old data
1581  file.seek(0);
1582  file.resize(0);
1583  writeIniFile(file, confFile->originalKeys);
1584  }
1585  } else {
1586  if (writeFunc) {
1587  QSettings::SettingsMap tempOriginalKeys;
1588 
1590  while (i != mergedKeys.constEnd()) {
1591  tempOriginalKeys.insert(i.key(), i.value());
1592  ++i;
1593  }
1594  ok = writeFunc(file, tempOriginalKeys);
1595  } else {
1596  ok = false;
1597  }
1598  }
1599  }
1600  } else {
1601  ok = false;
1602  }
1603 
1604  if (ok) {
1605  confFile->unparsedIniSections.clear();
1606  confFile->originalKeys = mergedKeys;
1607  confFile->addedKeys.clear();
1608  confFile->removedKeys.clear();
1609 
1610  QFileInfo fileInfo(confFile->name);
1611  confFile->size = fileInfo.size();
1612  confFile->timeStamp = fileInfo.lastModified();
1613  } else {
1615  }
1616  }
1617 
1618  /*
1619  Release the file lock.
1620  */
1621 #ifdef Q_OS_WIN
1622  if (readSemaphore != 0) {
1623  ReleaseSemaphore(readSemaphore, numReadLocks, 0);
1624  CloseHandle(readSemaphore);
1625  }
1626  if (writeSemaphore != 0) {
1627  ReleaseSemaphore(writeSemaphore, 1, 0);
1628  CloseHandle(writeSemaphore);
1629  }
1630 #endif
1631 }
1632 
1633 enum { Space = 0x1, Special = 0x2 };
1634 
1635 static const char charTraits[256] =
1636 {
1637  // Space: '\t', '\n', '\r', ' '
1638  // Special: '\n', '\r', '"', ';', '=', '\\'
1639 
1640  0, 0, 0, 0, 0, 0, 0, 0, 0, Space, Space | Special, 0, 0, Space | Special, 0, 0,
1641  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1642  Space, 0, Special, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1643  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Special, 0, Special, 0, 0,
1644  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1645  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Special, 0, 0, 0,
1646  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1647  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1648 
1649  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1650  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1651  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1652  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1653  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1654  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1655  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1656  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
1657 };
1658 
1660  int &lineStart, int &lineLen, int &equalsPos)
1661 {
1662  int dataLen = data.length();
1663  bool inQuotes = false;
1664 
1665  equalsPos = -1;
1666 
1667  lineStart = dataPos;
1668  while (lineStart < dataLen && (charTraits[uint(uchar(data.at(lineStart)))] & Space))
1669  ++lineStart;
1670 
1671  int i = lineStart;
1672  while (i < dataLen) {
1673  while (!(charTraits[uint(uchar(data.at(i)))] & Special)) {
1674  if (++i == dataLen)
1675  goto break_out_of_outer_loop;
1676  }
1677 
1678  char ch = data.at(i++);
1679  if (ch == '=') {
1680  if (!inQuotes && equalsPos == -1)
1681  equalsPos = i - 1;
1682  } else if (ch == '\n' || ch == '\r') {
1683  if (i == lineStart + 1) {
1684  ++lineStart;
1685  } else if (!inQuotes) {
1686  --i;
1687  goto break_out_of_outer_loop;
1688  }
1689  } else if (ch == '\\') {
1690  if (i < dataLen) {
1691  char ch = data.at(i++);
1692  if (i < dataLen) {
1693  char ch2 = data.at(i);
1694  // \n, \r, \r\n, and \n\r are legitimate line terminators in INI files
1695  if ((ch == '\n' && ch2 == '\r') || (ch == '\r' && ch2 == '\n'))
1696  ++i;
1697  }
1698  }
1699  } else if (ch == '"') {
1700  inQuotes = !inQuotes;
1701  } else {
1702  Q_ASSERT(ch == ';');
1703 
1704  if (i == lineStart + 1) {
1705  char ch;
1706  while (i < dataLen && ((ch = data.at(i) != '\n') && ch != '\r'))
1707  ++i;
1708  lineStart = i;
1709  } else if (!inQuotes) {
1710  --i;
1711  goto break_out_of_outer_loop;
1712  }
1713  }
1714  }
1715 
1716 break_out_of_outer_loop:
1717  dataPos = i;
1718  lineLen = i - lineStart;
1719  return lineLen > 0;
1720 }
1721 
1722 /*
1723  Returns false on parse error. However, as many keys are read as
1724  possible, so if the user doesn't check the status he will get the
1725  most out of the file anyway.
1726 */
1728  UnparsedSettingsMap *unparsedIniSections)
1729 {
1730 #define FLUSH_CURRENT_SECTION() \
1731  { \
1732  QByteArray &sectionData = (*unparsedIniSections)[QSettingsKey(currentSection, \
1733  IniCaseSensitivity, \
1734  sectionPosition)]; \
1735  if (!sectionData.isEmpty()) \
1736  sectionData.append('\n'); \
1737  sectionData += data.mid(currentSectionStart, lineStart - currentSectionStart); \
1738  sectionPosition = ++position; \
1739  }
1740 
1741  QString currentSection;
1742  int currentSectionStart = 0;
1743  int dataPos = 0;
1744  int lineStart;
1745  int lineLen;
1746  int equalsPos;
1747  int position = 0;
1748  int sectionPosition = 0;
1749  bool ok = true;
1750 
1751  while (readIniLine(data, dataPos, lineStart, lineLen, equalsPos)) {
1752  char ch = data.at(lineStart);
1753  if (ch == '[') {
1755 
1756  // this is a section
1757  QByteArray iniSection;
1758  int idx = data.indexOf(']', lineStart);
1759  if (idx == -1 || idx >= lineStart + lineLen) {
1760  ok = false;
1761  iniSection = data.mid(lineStart + 1, lineLen - 1);
1762  } else {
1763  iniSection = data.mid(lineStart + 1, idx - lineStart - 1);
1764  }
1765 
1766  iniSection = iniSection.trimmed();
1767 
1768  if (qstricmp(iniSection, "general") == 0) {
1769  currentSection.clear();
1770  } else {
1771  if (qstricmp(iniSection, "%general") == 0) {
1772  currentSection = QLatin1String(iniSection.constData() + 1);
1773  } else {
1774  currentSection.clear();
1775  iniUnescapedKey(iniSection, 0, iniSection.size(), currentSection);
1776  }
1777  currentSection += QLatin1Char('/');
1778  }
1779  currentSectionStart = dataPos;
1780  }
1781  ++position;
1782  }
1783 
1784  Q_ASSERT(lineStart == data.length());
1786 
1787  return ok;
1788 
1789 #undef FLUSH_CURRENT_SECTION
1790 }
1791 
1793  ParsedSettingsMap *settingsMap, QTextCodec *codec)
1794 {
1795  QStringList strListValue;
1796  bool sectionIsLowercase = (section == section.originalCaseKey());
1797  int equalsPos;
1798 
1799  bool ok = true;
1800  int dataPos = 0;
1801  int lineStart;
1802  int lineLen;
1803  int position = section.originalKeyPosition();
1804 
1805  while (readIniLine(data, dataPos, lineStart, lineLen, equalsPos)) {
1806  char ch = data.at(lineStart);
1807  Q_ASSERT(ch != '[');
1808 
1809  if (equalsPos == -1) {
1810  if (ch != ';')
1811  ok = false;
1812  continue;
1813  }
1814 
1815  int keyEnd = equalsPos;
1816  while (keyEnd > lineStart && ((ch = data.at(keyEnd - 1)) == ' ' || ch == '\t'))
1817  --keyEnd;
1818  int valueStart = equalsPos + 1;
1819 
1820  QString key = section.originalCaseKey();
1821  bool keyIsLowercase = (iniUnescapedKey(data, lineStart, keyEnd, key) && sectionIsLowercase);
1822 
1823  QString strValue;
1824  strValue.reserve(lineLen - (valueStart - lineStart));
1825  bool isStringList = iniUnescapedStringList(data, valueStart, lineStart + lineLen,
1826  strValue, strListValue, codec);
1827  QVariant variant;
1828  if (isStringList) {
1829  variant = stringListToVariantList(strListValue);
1830  } else {
1831  variant = stringToVariant(strValue);
1832  }
1833 
1834  /*
1835  We try to avoid the expensive toLower() call in
1836  QSettingsKey by passing Qt::CaseSensitive when the
1837  key is already in lowercase.
1838  */
1839  settingsMap->insert(QSettingsKey(key, keyIsLowercase ? Qt::CaseSensitive
1841  position),
1842  variant);
1843  ++position;
1844  }
1845 
1846  return ok;
1847 }
1848 
1849 class QSettingsIniKey : public QString
1850 {
1851 public:
1852  inline QSettingsIniKey() : position(-1) {}
1853  inline QSettingsIniKey(const QString &str, int pos = -1) : QString(str), position(pos) {}
1854 
1856 };
1857 
1858 static bool operator<(const QSettingsIniKey &k1, const QSettingsIniKey &k2)
1859 {
1860  if (k1.position != k2.position)
1861  return k1.position < k2.position;
1862  return static_cast<const QString &>(k1) < static_cast<const QString &>(k2);
1863 }
1864 
1866 
1868 {
1870  IniKeyMap keyMap;
1871 
1872  inline QSettingsIniSection() : position(-1) {}
1873 };
1874 
1876 
1877 /*
1878  This would be more straightforward if we didn't try to remember the original
1879  key order in the .ini file, but we do.
1880 */
1882 {
1883  IniMap iniMap;
1885 
1886 #ifdef Q_OS_WIN
1887  const char * const eol = "\r\n";
1888 #else
1889  const char eol = '\n';
1890 #endif
1891 
1892  for (ParsedSettingsMap::const_iterator j = map.constBegin(); j != map.constEnd(); ++j) {
1893  QString section;
1894  QSettingsIniKey key(j.key().originalCaseKey(), j.key().originalKeyPosition());
1895  int slashPos;
1896 
1897  if ((slashPos = key.indexOf(QLatin1Char('/'))) != -1) {
1898  section = key.left(slashPos);
1899  key.remove(0, slashPos + 1);
1900  }
1901 
1902  QSettingsIniSection &iniSection = iniMap[section];
1903 
1904  // -1 means infinity
1905  if (uint(key.position) < uint(iniSection.position))
1906  iniSection.position = key.position;
1907  iniSection.keyMap[key] = j.value();
1908  }
1909 
1910  const int sectionCount = iniMap.size();
1911  QVector<QSettingsIniKey> sections;
1912  sections.reserve(sectionCount);
1913  for (i = iniMap.constBegin(); i != iniMap.constEnd(); ++i)
1914  sections.append(QSettingsIniKey(i.key(), i.value().position));
1915  qSort(sections);
1916 
1917  bool writeError = false;
1918  for (int j = 0; !writeError && j < sectionCount; ++j) {
1919  i = iniMap.constFind(sections.at(j));
1920  Q_ASSERT(i != iniMap.constEnd());
1921 
1922  QByteArray realSection;
1923 
1924  iniEscapedKey(i.key(), realSection);
1925 
1926  if (realSection.isEmpty()) {
1927  realSection = "[General]";
1928  } else if (qstricmp(realSection, "general") == 0) {
1929  realSection = "[%General]";
1930  } else {
1931  realSection.prepend('[');
1932  realSection.append(']');
1933  }
1934 
1935  if (j != 0)
1936  realSection.prepend(eol);
1937  realSection += eol;
1938 
1939  device.write(realSection);
1940 
1941  const IniKeyMap &ents = i.value().keyMap;
1942  for (IniKeyMap::const_iterator j = ents.constBegin(); j != ents.constEnd(); ++j) {
1943  QByteArray block;
1944  iniEscapedKey(j.key(), block);
1945  block += '=';
1946 
1947  const QVariant &value = j.value();
1948 
1949  /*
1950  The size() != 1 trick is necessary because
1951  QVariant(QString("foo")).toList() returns an empty
1952  list, not a list containing "foo".
1953  */
1954  if (value.type() == QVariant::StringList
1955  || (value.type() == QVariant::List && value.toList().size() != 1)) {
1957  } else {
1958  iniEscapedString(variantToString(value), block, iniCodec);
1959  }
1960  block += eol;
1961  if (device.write(block) == -1) {
1962  writeError = true;
1963  break;
1964  }
1965  }
1966  }
1967  return !writeError;
1968 }
1969 
1971 {
1974 
1975  for (; i != end; ++i) {
1976  if (!QConfFileSettingsPrivate::readIniSection(i.key(), i.value(), &confFile->originalKeys, iniCodec))
1978  }
1979  confFile->unparsedIniSections.clear();
1980 }
1981 
1983  const QSettingsKey &key) const
1984 {
1985  if (confFile->unparsedIniSections.isEmpty())
1986  return;
1987 
1989 
1990  int indexOfSlash = key.indexOf(QLatin1Char('/'));
1991  if (indexOfSlash != -1) {
1992  i = confFile->unparsedIniSections.upperBound(key);
1993  if (i == confFile->unparsedIniSections.begin())
1994  return;
1995  --i;
1996  if (i.key().isEmpty() || !key.startsWith(i.key()))
1997  return;
1998  } else {
1999  i = confFile->unparsedIniSections.begin();
2000  if (i == confFile->unparsedIniSections.end() || !i.key().isEmpty())
2001  return;
2002  }
2003 
2004  if (!QConfFileSettingsPrivate::readIniSection(i.key(), i.value(), &confFile->originalKeys, iniCodec))
2006  confFile->unparsedIniSections.erase(i);
2007 }
2008 
2651 #ifndef QT_NO_QOBJECT
2652 
2666 QSettings::QSettings(const QString &organization, const QString &application, QObject *parent)
2667  : QObject(*QSettingsPrivate::create(NativeFormat, UserScope, organization, application),
2668  parent)
2669 {
2670 }
2671 
2691 QSettings::QSettings(Scope scope, const QString &organization, const QString &application,
2692  QObject *parent)
2693  : QObject(*QSettingsPrivate::create(NativeFormat, scope, organization, application), parent)
2694 {
2695 }
2696 
2715 QSettings::QSettings(Format format, Scope scope, const QString &organization,
2716  const QString &application, QObject *parent)
2717  : QObject(*QSettingsPrivate::create(format, scope, organization, application), parent)
2718 {
2719 }
2720 
2752  : QObject(*QSettingsPrivate::create(fileName, format), parent)
2753 {
2754 }
2755 
2792 #ifdef Q_OS_MAC
2793  QCoreApplication::organizationDomain().isEmpty()
2795  : QCoreApplication::organizationDomain()
2796 #else
2798  ? QCoreApplication::organizationDomain()
2800 #endif
2802  parent)
2803 {
2804 }
2805 
2806 #else
2807 QSettings::QSettings(const QString &organization, const QString &application)
2809 {
2810  d_ptr->q_ptr = this;
2811 }
2812 
2813 QSettings::QSettings(Scope scope, const QString &organization, const QString &application)
2814  : d_ptr(QSettingsPrivate::create(globalDefaultFormat, scope, organization, application))
2815 {
2816  d_ptr->q_ptr = this;
2817 }
2818 
2819 QSettings::QSettings(Format format, Scope scope, const QString &organization,
2820  const QString &application)
2821  : d_ptr(QSettingsPrivate::create(format, scope, organization, application))
2822 {
2823  d_ptr->q_ptr = this;
2824 }
2825 
2826 QSettings::QSettings(const QString &fileName, Format format)
2827  : d_ptr(QSettingsPrivate::create(fileName, format))
2828 {
2829  d_ptr->q_ptr = this;
2830 }
2831 #endif
2832 
2842 {
2843  Q_D(QSettings);
2844  if (d->pendingChanges) {
2845  QT_TRY {
2846  d->flush();
2847  } QT_CATCH(...) {
2848  ; // ok. then don't flush but at least don't throw in the destructor
2849  }
2850  }
2851 }
2852 
2865 {
2866  Q_D(QSettings);
2867  d->clear();
2868  d->requestUpdate();
2869 }
2870 
2883 {
2884  Q_D(QSettings);
2885  d->sync();
2886 }
2887 
2898 {
2899  Q_D(const QSettings);
2900  return d->fileName();
2901 }
2902 
2914 {
2915  Q_D(const QSettings);
2916  return d->format;
2917 }
2918 
2930 {
2931  Q_D(const QSettings);
2932  return d->scope;
2933 }
2934 
2946 {
2947  Q_D(const QSettings);
2948  return d->organizationName;
2949 }
2950 
2962 {
2963  Q_D(const QSettings);
2964  return d->applicationName;
2965 }
2966 
2967 #ifndef QT_NO_TEXTCODEC
2968 
2987 {
2988  Q_D(QSettings);
2989  d->iniCodec = codec;
2990 }
2991 
3006 void QSettings::setIniCodec(const char *codecName)
3007 {
3008  Q_D(QSettings);
3009  if (QTextCodec *codec = QTextCodec::codecForName(codecName))
3010  d->iniCodec = codec;
3011 }
3012 
3024 {
3025  Q_D(const QSettings);
3026  return d->iniCodec;
3027 }
3028 
3029 #endif // QT_NO_TEXTCODEC
3030 
3042 {
3043  Q_D(const QSettings);
3044  return d->status;
3045 }
3046 
3073 void QSettings::beginGroup(const QString &prefix)
3074 {
3075  Q_D(QSettings);
3076  d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix)));
3077 }
3078 
3090 {
3091  Q_D(QSettings);
3092  if (d->groupStack.isEmpty()) {
3093  qWarning("QSettings::endGroup: No matching beginGroup()");
3094  return;
3095  }
3096 
3097  QSettingsGroup group = d->groupStack.pop();
3098  int len = group.toString().size();
3099  if (len > 0)
3100  d->groupPrefix.truncate(d->groupPrefix.size() - (len + 1));
3101 
3102  if (group.isArray())
3103  qWarning("QSettings::endGroup: Expected endArray() instead");
3104 }
3105 
3112 {
3113  Q_D(const QSettings);
3114  return d->groupPrefix.left(d->groupPrefix.size() - 1);
3115 }
3116 
3130 {
3131  Q_D(QSettings);
3132  d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix), false));
3133  return value(QLatin1String("size")).toInt();
3134 }
3135 
3165 void QSettings::beginWriteArray(const QString &prefix, int size)
3166 {
3167  Q_D(QSettings);
3168  d->beginGroupOrArray(QSettingsGroup(d->normalizedKey(prefix), size < 0));
3169 
3170  if (size < 0)
3171  remove(QLatin1String("size"));
3172  else
3173  setValue(QLatin1String("size"), size);
3174 }
3175 
3183 {
3184  Q_D(QSettings);
3185  if (d->groupStack.isEmpty()) {
3186  qWarning("QSettings::endArray: No matching beginArray()");
3187  return;
3188  }
3189 
3190  QSettingsGroup group = d->groupStack.top();
3191  int len = group.toString().size();
3192  d->groupStack.pop();
3193  if (len > 0)
3194  d->groupPrefix.truncate(d->groupPrefix.size() - (len + 1));
3195 
3196  if (group.arraySizeGuess() != -1)
3197  setValue(group.name() + QLatin1String("/size"), group.arraySizeGuess());
3198 
3199  if (!group.isArray())
3200  qWarning("QSettings::endArray: Expected endGroup() instead");
3201 }
3202 
3212 {
3213  Q_D(QSettings);
3214  if (d->groupStack.isEmpty() || !d->groupStack.top().isArray()) {
3215  qWarning("QSettings::setArrayIndex: Missing beginArray()");
3216  return;
3217  }
3218 
3219  QSettingsGroup &top = d->groupStack.top();
3220  int len = top.toString().size();
3221  top.setArrayIndex(qMax(i, 0));
3222  d->groupPrefix.replace(d->groupPrefix.size() - len - 1, len, top.toString());
3223 }
3224 
3241 {
3242  Q_D(const QSettings);
3243  return d->children(d->groupPrefix, QSettingsPrivate::AllKeys);
3244 }
3245 
3265 {
3266  Q_D(const QSettings);
3267  return d->children(d->groupPrefix, QSettingsPrivate::ChildKeys);
3268 }
3269 
3289 {
3290  Q_D(const QSettings);
3291  return d->children(d->groupPrefix, QSettingsPrivate::ChildGroups);
3292 }
3293 
3307 {
3308  Q_D(const QSettings);
3309  return d->isWritable();
3310 }
3311 
3329 {
3330  Q_D(QSettings);
3331  QString k = d->actualKey(key);
3332  d->set(k, value);
3333  d->requestUpdate();
3334 }
3335 
3360 {
3361  Q_D(QSettings);
3362  /*
3363  We cannot use actualKey(), because remove() supports empty
3364  keys. The code is also tricky because of slash handling.
3365  */
3366  QString theKey = d->normalizedKey(key);
3367  if (theKey.isEmpty())
3368  theKey = group();
3369  else
3370  theKey.prepend(d->groupPrefix);
3371 
3372  if (theKey.isEmpty()) {
3373  d->clear();
3374  } else {
3375  d->remove(theKey);
3376  }
3377  d->requestUpdate();
3378 }
3379 
3394 bool QSettings::contains(const QString &key) const
3395 {
3396  Q_D(const QSettings);
3397  QString k = d->actualKey(key);
3398  return d->get(k, 0);
3399 }
3400 
3409 {
3410  Q_D(QSettings);
3411  d->fallbacks = !!b;
3412 }
3413 
3422 {
3423  Q_D(const QSettings);
3424  return d->fallbacks;
3425 }
3426 
3427 #ifndef QT_NO_QOBJECT
3428 
3432 {
3433  Q_D(QSettings);
3434  if (event->type() == QEvent::UpdateRequest) {
3435  d->update();
3436  return true;
3437  }
3438  return QObject::event(event);
3439 }
3440 #endif
3441 
3460 QVariant QSettings::value(const QString &key, const QVariant &defaultValue) const
3461 {
3462  Q_D(const QSettings);
3463  QVariant result = defaultValue;
3464  QString k = d->actualKey(key);
3465  d->get(k, &result);
3466  return result;
3467 }
3468 
3482 {
3484 }
3485 
3495 {
3496  return globalDefaultFormat;
3497 }
3498 
3515 {
3516  setPath(IniFormat, SystemScope, dir);
3517 #if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
3518  setPath(NativeFormat, SystemScope, dir);
3519 #endif
3520 }
3521 
3532 {
3533  setPath(IniFormat, UserScope, dir);
3534 #if !defined(Q_OS_WIN) && !defined(Q_OS_MAC)
3535  setPath(NativeFormat, UserScope, dir);
3536 #endif
3537 }
3538 
3578 void QSettings::setPath(Format format, Scope scope, const QString &path)
3579 {
3580  QMutexLocker locker(globalMutex());
3581  PathHash *pathHash = pathHashFunc();
3582  if (pathHash->isEmpty())
3583  initDefaultPaths(&locker);
3584  pathHash->insert(pathHashKey(format, scope), path + QDir::separator());
3585 }
3586 
3664  WriteFunc writeFunc,
3665  Qt::CaseSensitivity caseSensitivity)
3666 {
3667 #ifdef QT_QSETTINGS_ALWAYS_CASE_SENSITIVE_AND_FORGET_ORIGINAL_KEY_ORDER
3668  Q_ASSERT(caseSensitivity == Qt::CaseSensitive);
3669 #endif
3670 
3671  QMutexLocker locker(globalMutex());
3672  CustomFormatVector *customFormatVector = customFormatVectorFunc();
3673  int index = customFormatVector->size();
3674  if (index == 16) // the QSettings::Format enum has room for 16 custom formats
3675  return QSettings::InvalidFormat;
3676 
3678  info.extension = QLatin1Char('.');
3679  info.extension += extension;
3680  info.readFunc = readFunc;
3681  info.writeFunc = writeFunc;
3682  info.caseSensitivity = caseSensitivity;
3683  customFormatVector->append(info);
3684 
3685  return QSettings::Format((int)QSettings::CustomFormat1 + index);
3686 }
3687 
3688 #ifdef QT3_SUPPORT
3689 void QSettings::setPath_helper(Scope scope, const QString &organization, const QString &application)
3690 {
3691  Q_D(QSettings);
3692  if (d->pendingChanges)
3693  d->flush();
3694  QSettingsPrivate *oldPriv = d;
3695  QSettingsPrivate *newPriv = QSettingsPrivate::create(oldPriv->format, scope, organization, application);
3696  static_cast<QObjectPrivate &>(*newPriv) = static_cast<QObjectPrivate &>(*oldPriv); // copy the QObject stuff over (hack)
3697  oldPriv->threadData = 0; // QTBUG-36908, newPriv takes ownership.
3698  d_ptr.reset(newPriv);
3699 }
3700 
3986 #endif
3987 
3989 
3990 #endif // QT_NO_SETTINGS
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qstring.cpp:6448
The QVariant class acts like a union for the most common Qt data types.
Definition: qvariant.h:92
static QString fromWCharArray(const wchar_t *, int size=-1)
Returns a copy of the string, where the encoding of string depends on the size of wchar...
Definition: qstring.cpp:1019
Scope
) in file paths:
Definition: qsettings.h:115
The QDir class provides access to directory structures and their contents.
Definition: qdir.h:58
double d
Definition: qnumeric_p.h:62
static QStringList splitArgs(const QString &s, int idx)
Definition: qsettings.cpp:957
void setStatus(QSettings::Status status) const
Definition: qsettings.cpp:410
QString fileName() const
Returns the name set by setFileName() or to the QFile constructors.
Definition: qfile.cpp:470
QString originalCaseKey() const
Definition: qsettings_p.h:89
Status
The following status values are possible:
Definition: qsettings.h:86
static const char charTraits[256]
Definition: qsettings.cpp:1635
void setValue(const QString &key, const QVariant &value)
Sets the value of setting key to value.
Definition: qsettings.cpp:3328
Qt::CaseSensitivity caseSensitivity
Definition: qsettings_p.h:315
int type
Definition: qmetatype.cpp:239
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Returns the value for setting key.
Definition: qsettings.cpp:3460
QMap< QString, QSettingsIniSection > IniMap
Definition: qsettings.cpp:1875
Scope scope() const
Returns the scope used for storing the settings.
Definition: qsettings.cpp:2929
bool readPlistFile(const QString &fileName, ParsedSettingsMap *map) const
static Format defaultFormat()
Definition: qsettings.cpp:3494
static mach_timebase_info_data_t info
unsigned char c[8]
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
The QMutex class provides access serialization between threads.
Definition: qmutex.h:60
QHash< int, QString > PathHash
Definition: qsettings.cpp:118
QHash< QString, QConfFile * > ConfFileHash
Definition: qsettings.cpp:116
ParsedSettingsMap mergedKeyMap() const
Definition: qsettings.cpp:235
QMap< QSettingsIniKey, QVariant > IniKeyMap
Definition: qsettings.cpp:1865
static void initDefaultPaths(QMutexLocker *locker)
Definition: qsettings.cpp:1073
int remove(const Key &key)
Removes all the items that have the key from the hash.
Definition: qhash.h:784
const QChar at(int i) const
Returns the character at the given index position in the string.
Definition: qstring.h:698
bool isReadable() const
Returns true if data can be read from the device; otherwise returns false.
Definition: qiodevice.cpp:544
bool isWritable() const
Returns true if data can be written to the device; otherwise returns false.
Definition: qiodevice.cpp:558
bool isWritable() const
Returns true if settings can be written using this QSettings object; returns false otherwise...
Definition: qsettings.cpp:3306
QSettingsPrivate(QSettings::Format format)
Definition: qsettings.cpp:302
QConfFile(const QConfFile &)
T * data() const
Returns the value of the pointer referenced by this object.
ushort unicode() const
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: qchar.h:251
#define it(className, varName)
QObject * q_ptr
Definition: qobject.h:91
bool open(OpenMode flags)
Opens the file using OpenMode mode, returning true if successful; otherwise false.
Definition: qfile.cpp:1064
static void postEvent(QObject *receiver, QEvent *event)
Adds the event event, with the object receiver as the receiver of the event, to an event queue and re...
int beginReadArray(const QString &prefix)
Adds prefix to the current group and starts reading from an array.
Definition: qsettings.cpp:3129
The QSettings class provides persistent platform-independent application settings.
Definition: qsettings.h:73
void endGroup()
Resets the group to what it was before the corresponding beginGroup() call.
Definition: qsettings.cpp:3089
static bool iniUnescapedStringList(const QByteArray &str, int from, int to, QString &stringResult, QStringList &stringListResult, QTextCodec *codec)
Definition: qsettings.cpp:789
The QByteArray class provides an array of bytes.
Definition: qbytearray.h:135
static Expression::Ptr create(Expression *const expr, const YYLTYPE &sourceLocator, const ParserContext *const parseInfo)
Definition: qcache.h:54
QSettings::WriteFunc writeFunc
Definition: qsettings.cpp:112
Q_CORE_EXPORT QTextStream & reset(QTextStream &s)
int length() const
Returns the number of characters in this string.
Definition: qstring.h:696
The QTemporaryFile class is an I/O device that operates on temporary files.
QSettings::WriteFunc writeFunc
Definition: qsettings_p.h:313
Format
This enum type specifies the storage format used by QSettings.
Definition: qsettings.h:92
QString & prepend(QChar c)
Definition: qstring.h:261
T * take()
Returns the value of the pointer referenced by this object.
bool(* WriteFunc)(QIODevice &device, const SettingsMap &map)
Typedef for a pointer to a function with the following signature:
Definition: qsettings.h:192
static qreal position(QGraphicsObject *item, QDeclarativeAnchorLine::AnchorLine anchorLine)
void beginGroup(const QString &prefix)
Appends prefix to the current group.
Definition: qsettings.cpp:3073
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
QString toString() const
Returns the variant as a QString if the variant has type() String , Bool , ByteArray ...
Definition: qvariant.cpp:2270
int size() const
Returns the number of (key, value) pairs in the map.
Definition: qmap.h:201
QSettings::ReadFunc readFunc
Definition: qsettings.cpp:111
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the list.
Definition: qlist.h:269
bool writePlistFile(const QString &fileName, const ParsedSettingsMap &map) const
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
bool startsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string starts with s; otherwise returns false.
Definition: qstring.cpp:3734
QSettings::Scope scope
Definition: qsettings_p.h:259
QList< QVariant > toList() const
Returns the variant as a QVariantList if the variant has type() List or StringList ; otherwise return...
Definition: qvariant.cpp:2751
static LibLoadStatus status
Definition: qlocale_icu.cpp:69
bool open()
A QTemporaryFile will always be opened in QIODevice::ReadWrite mode, this allows easy access to the d...
void setIniCodec(QTextCodec *codec)
Sets the codec for accessing INI files (including .
Definition: qsettings.cpp:2986
QString absoluteFilePath() const
Returns an absolute path including the file name.
Definition: qfileinfo.cpp:534
#define QT_END_INCLUDE_NAMESPACE
This macro is equivalent to QT_BEGIN_NAMESPACE.
Definition: qglobal.h:92
QLatin1String(DBUS_INTERFACE_DBUS))) Q_GLOBAL_STATIC_WITH_ARGS(QString
bool exists() const
Returns true if the file exists; otherwise returns false.
Definition: qfileinfo.cpp:675
QString applicationName
Definition: qsettings_p.h:261
static QConfFile * fromName(const QString &name, bool _userPerms)
Definition: qsettings.cpp:272
const Key & key() const
Returns the current item&#39;s key.
Definition: qmap.h:324
QDateTime timeStamp
Definition: qsettings_p.h:162
long ASN1_INTEGER_get ASN1_INTEGER * a
int count(const T &t) const
Returns the number of occurrences of value in the list.
Definition: qlist.h:891
bool ref()
Atomically increments the value of this QAtomicInt.
QString name
Definition: qsettings_p.h:161
static bool operator<(const QSettingsIniKey &k1, const QSettingsIniKey &k2)
Definition: qsettings.cpp:1858
QByteArray & prepend(char c)
Prepends the character ch to this byte array.
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
The QString class provides a Unicode character string.
Definition: qstring.h:83
static QSettingsPrivate * create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application)
static QStringList variantListToStringList(const QVariantList &l)
Definition: qsettings.cpp:435
The QHash class is a template class that provides a hash-table-based dictionary.
Definition: qdatastream.h:66
Format format() const
Returns the format used for storing the settings.
Definition: qsettings.cpp:2913
bool resize(qint64 sz)
Sets the file size (in bytes) sz.
Definition: qfile.cpp:1528
#define Q_ASSERT(cond)
Definition: qglobal.h:1823
The QVector class is a template class that provides a dynamic array.
Definition: qdatastream.h:64
bool event(QEvent *event)
Reimplemented Function
Definition: qsettings.cpp:3431
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
virtual bool event(QEvent *)
This virtual function receives events to an object and should return true if the event e was recogniz...
Definition: qobject.cpp:1200
QStringList allKeys() const
Returns a list of all keys, including subkeys, that can be read using the QSettings object...
Definition: qsettings.cpp:3240
QString actualKey(const QString &key) const
Definition: qsettings.cpp:319
#define Q_D(Class)
Definition: qglobal.h:2482
static QChar separator()
Returns the native directory separator: "/" under Unix (including Mac OS X) and "\\" under Windows...
Definition: qdir.cpp:1831
static void setPath(Format format, Scope scope, const QString &path)
Sets the path used for storing settings for the given format and scope, to path.
Definition: qsettings.cpp:3578
void sync()
Writes any unsaved changes to permanent storage, and reloads any settings that have been changed in t...
Definition: qsettings.cpp:2882
T * take(const Key &key)
Definition: qcache.h:167
QThreadData * threadData
Definition: qobject_p.h:195
void endArray()
Closes the array that was started using beginReadArray() or beginWriteArray().
Definition: qsettings.cpp:3182
int arraySizeGuess() const
Definition: qsettings_p.h:130
The QChar class provides a 16-bit Unicode character.
Definition: qchar.h:72
QChar * data()
Returns a pointer to the data stored in the QString.
Definition: qstring.h:710
virtual QString fileName() const =0
QByteArray toByteArray() const
Returns the variant as a QByteArray if the variant has type() ByteArray or String (converted using QS...
Definition: qvariant.cpp:2383
const T value(const Key &key) const
Returns the value associated with the key.
Definition: qhash.h:606
static void iniChopTrailingSpaces(QString &str)
Definition: qsettings.cpp:758
QTextCodec * iniCodec() const
Returns the codec that is used for accessing INI files.
Definition: qsettings.cpp:3023
QString group() const
Returns the current group.
Definition: qsettings.cpp:3111
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
QStringList childGroups() const
Returns a list of all key top-level groups that contain keys that can be read using the QSettings obj...
Definition: qsettings.cpp:3288
QString toString() const
Definition: qsettings_p.h:139
bool isEmpty() const
Returns true if the list contains no items; otherwise returns false.
Definition: qlist.h:152
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition: qhash.h:753
void setVersion(int)
Sets the version number of the data serialization format to v.
Definition: qdatastream.h:215
#define Q_Q(Class)
Definition: qglobal.h:2483
void set(const QString &key, const QVariant &value)
Definition: qsettings.cpp:1272
int toInt(bool *ok=0) const
Returns the variant as an int if the variant has type() Int , Bool , ByteArray , Char ...
Definition: qvariant.cpp:2625
static QString decodeName(const QByteArray &localFileName)
This does the reverse of QFile::encodeName() using localFileName.
Definition: qfile.cpp:552
bool exists() const
Returns true if the file specified by fileName() exists; otherwise returns false. ...
Definition: qfile.cpp:626
void relock()
Relocks an unlocked mutex locker.
Definition: qmutex.h:125
Qt::CaseSensitivity caseSensitivity
Definition: qsettings.cpp:113
void reserve(int size)
Attempts to allocate memory for at least size characters.
Definition: qstring.h:881
#define Q_OS_MAC
Defined on MAC OS (synonym for Darwin).
Definition: qglobal.h:274
friend class const_iterator
Definition: qlist.h:264
unsigned char uchar
Definition: qglobal.h:994
int width() const
Returns the width.
Definition: qsize.h:126
void append(const T &t)
Inserts value at the end of the list.
Definition: qlist.h:507
void syncConfFile(int confFileNo)
Definition: qsettings.cpp:1408
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
QStringList children(const QString &prefix, ChildSpec spec) const
Definition: qsettings.cpp:1317
QByteArray fromUnicode(const QString &uc) const
Converts str from Unicode to the encoding of this codec, and returns the result in a QByteArray...
bool isOpen() const
Returns true if the device is open; otherwise returns false.
Definition: qiodevice.cpp:530
static FILE * stream
Status status() const
Returns a status code indicating the first error that was met by QSettings, or QSettings::NoError if ...
Definition: qsettings.cpp:3041
static bool isEmpty(const char *str)
virtual ~QSettingsPrivate()
Definition: qsettings.cpp:315
void truncate(int pos)
Truncates the string at the given position index.
Definition: qstring.cpp:4603
QSettings::ReadFunc readFunc
Definition: qsettings_p.h:312
int size() const
Returns the number of characters in this string.
Definition: qstring.h:102
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition: qstring.h:704
virtual void sync()=0
static int numDigits(qlonglong n)
Definition: qvalidator.cpp:385
void beginGroupOrArray(const QSettingsGroup &group)
Definition: qsettings.cpp:396
static void setUserIniPath(const QString &dir)
Use setPath() instead.
Definition: qsettings.cpp:3531
const char * name
QByteArray trimmed() const
Returns a byte array that has whitespace removed from the start and the end.
const T value(const Key &key) const
Returns the value associated with the key key.
Definition: qmap.h:499
#define Q_GLOBAL_STATIC(TYPE, NAME)
Declares a global static variable with the given type and name.
Definition: qglobal.h:1968
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QStringList class provides a list of strings.
Definition: qstringlist.h:66
ParsedSettingsMap addedKeys
Definition: qsettings_p.h:166
static int toInt(const QByteArray &str)
Definition: generator.cpp:167
bool isEmpty() const
Returns true if the hash contains no items; otherwise returns false.
Definition: qhash.h:297
void append(const T &t)
Inserts value at the end of the vector.
Definition: qvector.h:573
Q_CORE_EXPORT void qWarning(const char *,...)
#define FLUSH_CURRENT_SECTION()
QMutex mutex
Definition: qsettings_p.h:169
static const char * data(const QByteArray &arr)
unsigned int uint
Definition: qglobal.h:996
int indexOf(QChar c, int from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Definition: qstring.cpp:2838
The QLatin1String class provides a thin wrapper around an US-ASCII/Latin-1 encoded string literal...
Definition: qstring.h:654
static const char hexDigits[]
Definition: qsettings.cpp:594
static QTextCodec * codec(MYSQL *mysql)
Definition: qsql_mysql.cpp:220
QString name() const
Definition: qsettings_p.h:127
#define FALSE
Synonym for false.
Definition: qglobal.h:1019
bool(* ReadFunc)(QIODevice &device, SettingsMap &map)
Typedef for a pointer to a function with the following signature:
Definition: qsettings.h:191
void ensureSectionParsed(QConfFile *confFile, const QSettingsKey &key) const
Definition: qsettings.cpp:1982
QString organizationName() const
Returns the organization name used for storing the settings.
Definition: qsettings.cpp:2945
void ensureAllSectionsParsed(QConfFile *confFile) const
Definition: qsettings.cpp:1970
QList< Key > keys() const
Returns a list containing all the keys in the map in ascending order.
Definition: qmap.h:818
QByteArray toLatin1() const Q_REQUIRED_RESULT
Returns a Latin-1 representation of the string as a QByteArray.
Definition: qstring.cpp:3993
void clear()
Removes all items from the list.
Definition: qlist.h:764
QStringList childKeys() const
Returns a list of all top-level keys that can be read using the QSettings object. ...
Definition: qsettings.cpp:3264
void * HANDLE
Definition: qnamespace.h:1671
static QString variantToString(const QVariant &v)
Definition: qsettings.cpp:464
QByteArray mid(int index, int len=-1) const
Returns a byte array containing len bytes from this byte array, starting at position pos...
static const Qt::CaseSensitivity IniCaseSensitivity
Definition: qsettings_p.h:81
const_iterator constBegin() const
Returns a const STL-style iterator pointing to the first item in the map.
Definition: qmap.h:374
static void clearCache()
Definition: qsettings.cpp:293
QString fileName() const
Returns the path where settings written using this QSettings object are stored.
Definition: qsettings.cpp:2897
#define QT_CATCH(A)
Definition: qglobal.h:1537
int indexOf(char c, int from=0) const
Returns the index position of the first occurrence of the character ch in the byte array...
void push(const T &t)
Adds element t to the top of the stack.
Definition: qstack.h:60
void squeeze()
Releases any memory not required to store the character data.
Definition: qstring.h:114
int handle() const
Returns the file handle of the file.
Definition: qfile.cpp:1419
void qSort(RandomAccessIterator start, RandomAccessIterator end)
Definition: qalgorithms.h:177
int originalKeyPosition() const
Definition: qsettings_p.h:90
void reset(T *other=0)
Deletes the existing object it is pointing to if any, and sets its pointer to other.
void setArrayIndex(int i)
Sets the current array index to i.
Definition: qsettings.cpp:3211
const T & at(int i) const
Returns the item at index position i in the vector.
Definition: qvector.h:350
bool isUpper() const
Returns true if the character is an uppercase letter, i.
Definition: qchar.h:273
iterator begin()
Returns an STL-style iterator pointing to the first item in the map.
Definition: qmap.h:372
static void iniEscapedKey(const QString &key, QByteArray &result)
Definition: qsettings.cpp:596
bool insert(const Key &key, T *object, int cost=1)
Definition: qcache.h:181
int length() const
Same as size().
Definition: qbytearray.h:356
void resize(int size)
Sets the size of the string to size characters.
Definition: qstring.cpp:1353
QTextCodec * iniCodec
Definition: qsettings_p.h:262
QConfFileSettingsPrivate(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application)
Definition: qsettings.cpp:1150
static QVariant stringListToVariantList(const QStringList &l)
Definition: qsettings.cpp:444
const char * constData() const
Returns a pointer to the data stored in the byte array.
Definition: qbytearray.h:433
QString toUnicode(const QByteArray &) const
Converts a from the encoding of this codec to Unicode, and returns the result in a QString...
int remove(const Key &key)
Removes all the items that have the key key from the map.
Definition: qmap.h:662
QString mid(int position, int n=-1) const Q_REQUIRED_RESULT
Returns a string that contains n characters of this string, starting at the specified position index...
Definition: qstring.cpp:3706
CaseSensitivity
Definition: qnamespace.h:1451
ParsedSettingsMap originalKeys
Definition: qsettings_p.h:165
The QMap::const_iterator class provides an STL-style const iterator for QMap and QMultiMap.
Definition: qmap.h:301
The QCoreApplication class provides an event loop for console Qt applications.
int fcntl(int, int,...)
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:380
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
void setArrayIndex(int i)
Definition: qsettings_p.h:131
void * resolve(const char *symbol)
virtual void flush()=0
QString & append(QChar c)
Definition: qstring.cpp:1777
bool userPerms
Definition: qsettings_p.h:170
qint64 size() const
Returns the file size in bytes.
Definition: qfileinfo.cpp:1248
The QFile class provides an interface for reading from and writing to files.
Definition: qfile.h:65
~QSettings()
Destroys the QSettings object.
Definition: qsettings.cpp:2841
static bool readIniSection(const QSettingsKey &section, const QByteArray &data, ParsedSettingsMap *settingsMap, QTextCodec *codec)
Definition: qsettings.cpp:1792
void remove(const QString &key)
Removes the setting key and any sub-settings of key.
Definition: qsettings.cpp:3359
ParsedSettingsMap removedKeys
Definition: qsettings_p.h:167
static QString getPath(QSettings::Format format, QSettings::Scope scope)
Definition: qsettings.cpp:1132
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
void clear()
Clears the contents of the string and makes it empty.
Definition: qstring.h:723
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the map...
Definition: qmap.h:375
QSettings::Format format
Definition: qsettings_p.h:258
static QString fromLatin1(const char *, int size=-1)
Returns a QString initialized with the first size characters of the Latin-1 string str...
Definition: qstring.cpp:4188
Type type() const
Returns the storage type of the value stored in the variant.
Definition: qvariant.cpp:1901
iterator insert(const Key &key, const T &value)
Inserts a new item with the key key and a value of value.
Definition: qmap.h:559
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
int toInt(bool *ok=0, int base=10) const
Returns the byte array converted to an int using base base, which is 10 by default and must be betwee...
static QString location(LibraryLocation)
Returns the location specified by loc.
QString fileName() const
Definition: qsettings.cpp:1388
static QSettings::Format globalDefaultFormat
Definition: qsettings.cpp:126
QObject * parent() const
Returns a pointer to the parent object.
Definition: qobject.h:273
int key
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
#define CSIDL_APPDATA
Definition: qsettings.cpp:87
QString groupPrefix
Definition: qsettings_p.h:266
int size() const
Returns the number of items in the list.
Definition: qlist.h:137
bool contains(const QString &key) const
Returns true if there exists a setting called key; returns false otherwise.
Definition: qsettings.cpp:3394
QVector< QConfFileCustomFormat > CustomFormatVector
Definition: qsettings.cpp:119
QSettings(const QString &organization, const QString &application=QString(), QObject *parent=0)
Constructs a QSettings object for accessing settings of the application called application from the o...
Definition: qsettings.cpp:2666
bool isEmpty() const
Returns true if the map contains no items; otherwise returns false.
Definition: qmap.h:203
int qstrncmp(const char *str1, const char *str2, uint len)
Definition: qbytearray.h:101
UnparsedSettingsMap unparsedIniSections
Definition: qsettings_p.h:164
int height() const
Returns the height.
Definition: qsize.h:129
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
bool setPermissions(Permissions permissionSpec)
Sets the permissions for the file to the permissions specified.
Definition: qfile.cpp:1605
QFactoryLoader * l
const T & value() const
Returns the current item&#39;s value.
Definition: qmap.h:325
void clear()
Removes all entries in the primary location associated to this QSettings object.
Definition: qsettings.cpp:2864
QCache< QString, QConfFile > ConfFileCache
Definition: qsettings.cpp:117
static QTextCodec * codecForName(const QByteArray &name)
Searches all installed QTextCodec objects and returns the one which best matches name; the match is c...
QByteArray readAll()
Reads all available data from the device, and returns it as a QByteArray.
Definition: qiodevice.cpp:1025
bool contains(const Key &key) const
Returns true if the map contains an item with key key; otherwise returns false.
Definition: qmap.h:553
T qvariant_cast(const QVariant &)
Definition: qvariant.h:571
const_iterator constFind(const Key &key) const
Returns an const iterator pointing to the item with key key in the map.
Definition: qmap.h:612
int size() const
Returns the number of bytes in this byte array.
Definition: qbytearray.h:402
int y() const
Returns the y coordinate of this point.
Definition: qpoint.h:131
quint16 index
static Format registerFormat(const QString &extension, ReadFunc readFunc, WriteFunc writeFunc, Qt::CaseSensitivity caseSensitivity=Qt::CaseSensitive)
Registers a custom storage format.
Definition: qsettings.cpp:3663
static int pathHashKey(QSettings::Format format, QSettings::Scope scope)
Definition: qsettings.cpp:1068
void remove(const QString &key)
Definition: qsettings.cpp:1245
QObject * parent
Definition: qobject.h:92
#define QT_BEGIN_INCLUDE_NAMESPACE
This macro is equivalent to QT_END_NAMESPACE.
Definition: qglobal.h:91
Permissions permissions() const
Returns the complete OR-ed together combination of QFile::Permission for the file.
Definition: qfile.cpp:1574
QScopedPointer< QObjectData > d_ptr
Definition: qobject.h:320
iterator erase(iterator it)
Removes the (key, value) pair pointed to by the iterator pos from the map, and returns an iterator to...
Definition: qmap.h:717
iterator upperBound(const Key &key)
Returns an iterator pointing to the item that immediately follows the last item with key key in the m...
Definition: qmap.h:918
QSettingsIniKey(const QString &str, int pos=-1)
Definition: qsettings.cpp:1853
static bool readIniLine(const QByteArray &data, int &dataPos, int &lineStart, int &lineLen, int &equalsPos)
Definition: qsettings.cpp:1659
#define CSIDL_COMMON_APPDATA
Definition: qsettings.cpp:83
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
static void iniEscapedString(const QString &str, QByteArray &result, QTextCodec *codec)
Definition: qsettings.cpp:679
The QDataStream class provides serialization of binary data to a QIODevice.
Definition: qdatastream.h:71
QStack< QSettingsGroup > groupStack
Definition: qsettings_p.h:265
bool writeIniFile(QIODevice &device, const ParsedSettingsMap &map)
Definition: qsettings.cpp:1881
iterator lowerBound(const Key &key)
Returns an iterator pointing to the first item with key key in the map.
Definition: qmap.h:899
void reserve(int size)
Attempts to allocate memory for at least size elements.
Definition: qvector.h:339
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
static QVariant stringToVariant(const QString &s)
Definition: qsettings.cpp:551
const char * variant
static void setSystemIniPath(const QString &dir)
Use setPath() instead.
Definition: qsettings.cpp:3514
QAtomicInt ref
Definition: qsettings_p.h:168
static QString normalizedKey(const QString &key)
Definition: qsettings.cpp:338
qint64 write(const char *data, qint64 len)
Writes at most maxSize bytes of data from data to the device.
Definition: qiodevice.cpp:1342
QString & remove(int i, int len)
Removes n characters from the string, starting at the given position index, and returns a reference t...
Definition: qstring.cpp:1867
Q_CORE_EXPORT int qstricmp(const char *, const char *)
The QTextCodec class provides conversions between text encodings.
Definition: qtextcodec.h:62
QSettings::Status status
Definition: qsettings_p.h:270
T value() const
Returns the stored value converted to the template type T.
Definition: qvariant.h:332
char at(int i) const
Returns the character at index position i in the byte array.
Definition: qbytearray.h:413
bool endsWith(const QString &s, Qt::CaseSensitivity cs=Qt::CaseSensitive) const
Returns true if the string ends with s; otherwise returns false.
Definition: qstring.cpp:3796
The QFileInfo class provides system-independent file information.
Definition: qfileinfo.h:60
QString applicationName() const
Returns the application name used for storing the settings.
Definition: qsettings.cpp:2961
void reserve(int size)
Attempts to allocate memory for at least size bytes.
Definition: qbytearray.h:449
static const KeyPair *const end
void beginWriteArray(const QString &prefix, int size=-1)
Adds prefix to the current group and starts writing an array of size size.
Definition: qsettings.cpp:3165
The QIODevice class is the base interface class of all I/O devices in Qt.
Definition: qiodevice.h:66
qint64 size
Definition: qsettings_p.h:163
The QEvent class is the base class of all event classes.
Definition: qcoreevent.h:56
Type type() const
Returns the event type.
Definition: qcoreevent.h:303
bool seek(qint64 offset)
For random-access devices, this function sets the current position to pos, returning true on success...
Definition: qfile.cpp:1784
static QString windowsConfigPath(int type)
Definition: qsettings.cpp:1025
#define Q_AUTOTEST_EXPORT_HELPER
Definition: qsettings.cpp:91
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
static QString fileName(const QString &fileUrl)
bool get(const QString &key, QVariant *value) const
Definition: qsettings.cpp:1284
static void processChild(QString key, ChildSpec spec, QMap< QString, QString > &result)
Definition: qsettings.cpp:380
int size() const
Returns the number of items in the vector.
Definition: qvector.h:137
QString absolutePath() const
Returns a file&#39;s path absolute path.
Definition: qfileinfo.cpp:577
static QByteArray number(int, int base=10)
Returns a byte array containing the string equivalent of the number n to base base (10 by default)...
#define QT_TRY
Definition: qglobal.h:1536
The QLatin1Char class provides an 8-bit ASCII/Latin-1 character.
Definition: qchar.h:55
bool isArray() const
Definition: qsettings_p.h:129
static void setDefaultFormat(Format format)
Definition: qsettings.cpp:3481
QString organizationName
Definition: qsettings_p.h:260
void requestUpdate()
Definition: qsettings.cpp:422
void clear()
Removes all items from the map.
Definition: qmap.h:444
static bool iniUnescapedKey(const QByteArray &key, int from, int to, QString &result)
Definition: qsettings.cpp:623
QScopedSharedPointer< QConfFile > confFiles[NumConfFiles]
Definition: qsettings_p.h:311
static void iniEscapedStringList(const QStringList &strs, QByteArray &result, QTextCodec *codec)
Definition: qsettings.cpp:766
static bool readIniFile(const QByteArray &data, UnparsedSettingsMap *unparsedIniSections)
Definition: qsettings.cpp:1727
const_iterator constEnd() const
Returns a const STL-style iterator pointing to the imaginary item after the last item in the list...
Definition: qlist.h:272
const ushort * utf16() const
Returns the QString as a &#39;\0\&#39;-terminated array of unsigned shorts.
Definition: qstring.cpp:5290
friend class const_iterator
Definition: qmap.h:369
void setFallbacksEnabled(bool b)
Sets whether fallbacks are enabled to b.
Definition: qsettings.cpp:3408
QByteArray & insert(int i, char c)
Inserts character ch at index position i in the byte array.
bool isWritable() const
Definition: qsettings.cpp:247
static QString homePath()
Returns the absolute path of the user&#39;s home directory.
Definition: qdir.cpp:1942
QDateTime lastModified() const
Returns the date and time when the file was last modified.
Definition: qfileinfo.cpp:1296
bool fallbacksEnabled() const
Returns true if fallbacks are enabled; returns false otherwise.
Definition: qsettings.cpp:3421