diff options
Diffstat (limited to 'src/corelib/io')
-rw-r--r-- | src/corelib/io/io.pri | 2 | ||||
-rw-r--r-- | src/corelib/io/qabstractfileengine_p.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qbuffer.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfile.cpp | 2 | ||||
-rw-r--r-- | src/corelib/io/qfiledevice.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemiterator_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qnoncontiguousbytedevice_p.h | 12 | ||||
-rw-r--r-- | src/corelib/io/qprocess.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qresource.cpp | 304 | ||||
-rw-r--r-- | src/corelib/io/qresource.h | 7 | ||||
-rw-r--r-- | src/corelib/io/qresource_p.h | 56 | ||||
-rw-r--r-- | src/corelib/io/qsettings.cpp | 47 | ||||
-rw-r--r-- | src/corelib/io/qsettings.h | 4 | ||||
-rw-r--r-- | src/corelib/io/qurlquery.cpp | 8 | ||||
-rw-r--r-- | src/corelib/io/qurlquery.h | 9 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipereader_p.h | 2 | ||||
-rw-r--r-- | src/corelib/io/qwindowspipewriter_p.h | 2 |
17 files changed, 324 insertions, 145 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 086d642c26..9b6044752f 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -79,6 +79,8 @@ SOURCES += \ io/qloggingcategory.cpp \ io/qloggingregistry.cpp +qtConfig(zstd): QMAKE_USE_PRIVATE += zstd + qtConfig(filesystemwatcher) { HEADERS += \ io/qfilesystemwatcher.h \ diff --git a/src/corelib/io/qabstractfileengine_p.h b/src/corelib/io/qabstractfileengine_p.h index 00c415b521..4a7fe7bff5 100644 --- a/src/corelib/io/qabstractfileengine_p.h +++ b/src/corelib/io/qabstractfileengine_p.h @@ -208,7 +208,7 @@ protected: QScopedPointer<QAbstractFileEnginePrivate> d_ptr; private: Q_DECLARE_PRIVATE(QAbstractFileEngine) - Q_DISABLE_COPY(QAbstractFileEngine) + Q_DISABLE_COPY_MOVE(QAbstractFileEngine) }; Q_DECLARE_OPERATORS_FOR_FLAGS(QAbstractFileEngine::FileFlags) @@ -245,7 +245,7 @@ protected: virtual QVariant entryInfo(EntryInfoType type) const; private: - Q_DISABLE_COPY(QAbstractFileEngineIterator) + Q_DISABLE_COPY_MOVE(QAbstractFileEngineIterator) friend class QDirIterator; friend class QDirIteratorPrivate; void setPath(const QString &path); diff --git a/src/corelib/io/qbuffer.cpp b/src/corelib/io/qbuffer.cpp index e0b9c41323..7b3fa2ccad 100644 --- a/src/corelib/io/qbuffer.cpp +++ b/src/corelib/io/qbuffer.cpp @@ -60,8 +60,8 @@ public: QByteArray *buf; QByteArray defaultBuf; - virtual qint64 peek(char *data, qint64 maxSize) override; - virtual QByteArray peek(qint64 maxSize) override; + qint64 peek(char *data, qint64 maxSize) override; + QByteArray peek(qint64 maxSize) override; #ifndef QT_NO_QOBJECT // private slots diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 3166fa1b83..d3f846bc1d 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -808,7 +808,7 @@ QFile::copy(const QString &newName) if (error) { out.close(); close(); - d->setError(QFile::CopyError, tr("Cannot open for output")); + d->setError(QFile::CopyError, tr("Cannot open for output: %1").arg(out.errorString())); } else { if (!d->engine()->cloneTo(out.d_func()->engine())) { char block[4096]; diff --git a/src/corelib/io/qfiledevice.h b/src/corelib/io/qfiledevice.h index af41bec2f6..2d524193c5 100644 --- a/src/corelib/io/qfiledevice.h +++ b/src/corelib/io/qfiledevice.h @@ -100,7 +100,7 @@ public: FileError error() const; void unsetError(); - virtual void close() override; + void close() override; bool isSequential() const override; diff --git a/src/corelib/io/qfilesystemiterator_p.h b/src/corelib/io/qfilesystemiterator_p.h index 081487e66e..5e4e424e69 100644 --- a/src/corelib/io/qfilesystemiterator_p.h +++ b/src/corelib/io/qfilesystemiterator_p.h @@ -96,7 +96,7 @@ private: int lastError; #endif - Q_DISABLE_COPY(QFileSystemIterator) + Q_DISABLE_COPY_MOVE(QFileSystemIterator) }; QT_END_NAMESPACE diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h index ebed1120db..bbc4ea5ae2 100644 --- a/src/corelib/io/qnoncontiguousbytedevice_p.h +++ b/src/corelib/io/qnoncontiguousbytedevice_p.h @@ -179,13 +179,13 @@ class QByteDeviceWrappingIoDevice : public QIODevice public: QByteDeviceWrappingIoDevice (QNonContiguousByteDevice *bd); ~QByteDeviceWrappingIoDevice (); - virtual bool isSequential () const override; - virtual bool atEnd () const override; - virtual bool reset () override; - virtual qint64 size () const override; + bool isSequential() const override; + bool atEnd() const override; + bool reset() override; + qint64 size() const override; protected: - virtual qint64 readData ( char * data, qint64 maxSize ) override; - virtual qint64 writeData ( const char * data, qint64 maxSize ) override; + qint64 readData(char *data, qint64 maxSize) override; + qint64 writeData(const char *data, qint64 maxSize) override; QNonContiguousByteDevice *byteDevice; }; diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 474fc87de8..5e022e3a52 100644 --- a/src/corelib/io/qprocess.h +++ b/src/corelib/io/qprocess.h @@ -52,7 +52,7 @@ QT_BEGIN_NAMESPACE class QProcessPrivate; -#if !defined(Q_OS_WIN) || defined(Q_CLANG_QDOC) +#if !defined(Q_OS_WIN) typedef qint64 Q_PID; #else QT_END_NAMESPACE diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 564a3e5f51..804029725a 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** -** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2018 The Qt Company Ltd. +** Copyright (C) 2018 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -56,16 +57,46 @@ #include "private/qabstractfileengine_p.h" #include "private/qnumeric_p.h" #include "private/qsimd_p.h" +#include "private/qtools_p.h" #include "private/qsystemerror_p.h" +#if QT_CONFIG(zstd) +# include <zstd.h> +#endif + #ifdef Q_OS_UNIX # include "private/qcore_unix_p.h" #endif +#if defined(Q_OS_UNIX) && !defined(Q_OS_NACL) && !defined(Q_OS_INTEGRITY) +# define QT_USE_MMAP +# include <sys/mman.h> +#endif + //#define DEBUG_RESOURCE_MATCH QT_BEGIN_NAMESPACE +// Symbols used by code generated by RCC. +// They cause compilation errors if the RCC content couldn't +// be interpreted by this QtCore version. +#if defined(__ELF__) || defined(__APPLE__) // same as RCC generates +# define RCC_FEATURE_SYMBOL(feature) \ + extern Q_CORE_EXPORT const quint8 qt_resourceFeature ## feature; \ + const quint8 qt_resourceFeature ## feature = 0; +#else +# define RCC_FEATURE_SYMBOL(feature) \ + Q_CORE_EXPORT quint8 qResourceFeature ## feature() { return 0; } +#endif + +#ifndef QT_NO_COMPRESS +RCC_FEATURE_SYMBOL(Zlib) +#endif +#if QT_CONFIG(zstd) +RCC_FEATURE_SYMBOL(Zstd) +#endif + +#undef RCC_FEATURE_SYMBOL class QStringSplitter { @@ -98,11 +129,15 @@ public: //resource glue class QResourceRoot { +public: enum Flags { + // must match rcc.h Compressed = 0x01, - Directory = 0x02 + Directory = 0x02, + CompressedZstd = 0x04 }; +private: const uchar *tree, *names, *payloads; int version; inline int findOffset(int node) const { return node * (14 + (version >= 0x02 ? 8 : 0)); } //sizeof each tree element @@ -117,7 +152,15 @@ public: virtual ~QResourceRoot() { } int findNode(const QString &path, const QLocale &locale=QLocale()) const; inline bool isContainer(int node) const { return flags(node) & Directory; } - inline bool isCompressed(int node) const { return flags(node) & Compressed; } + QResource::Compression compressionAlgo(int node) + { + uint compressionFlags = flags(node) & (Compressed | CompressedZstd); + if (compressionFlags == Compressed) + return QResource::ZlibCompression; + if (compressionFlags == CompressedZstd) + return QResource::ZstdCompression; + return QResource::NoCompression; + } const uchar *data(int node, qint64 *size) const; quint64 lastModified(int node) const; QStringList children(int node) const; @@ -229,6 +272,23 @@ static inline QStringList *resourceSearchPaths() \sa {The Qt Resource System}, QFile, QDir, QFileInfo */ +/*! + \enum QResource::Compression + \since 5.13 + + This enum is used by compressionAlgorithm() to indicate which algorithm the + RCC tool used to compress the payload. + + \value NoCompression Contents are not compressed (isCompressed() is false). + \value ZlibCompression Contents are compressed using \l{zlib}{https://zlib.net} and can + be decompressed using the qUncompress() function. + \value ZstdCompression Contents are compressed using \l{zstd}{https://zstd.net}. To + decompress, use the \c{ZSTD_decompress} function from the zstd + library. + + \sa compressionAlgorithm(), isCopressed() +*/ + class QResourcePrivate { public: inline QResourcePrivate(QResource *_q) : q_ptr(_q) { clear(); } @@ -243,12 +303,13 @@ public: QLocale locale; QString fileName, absoluteFilePath; QList<QResourceRoot*> related; - uint container : 1; - mutable uint compressed : 1; mutable qint64 size; + mutable quint64 lastModified; mutable const uchar *data; mutable QStringList children; - mutable quint64 lastModified; + mutable quint8 compressionAlgo; + bool container; + /* 2 or 6 padding bytes */ QResource *q_ptr; Q_DECLARE_PUBLIC(QResource) @@ -258,7 +319,7 @@ void QResourcePrivate::clear() { absoluteFilePath.clear(); - compressed = 0; + compressionAlgo = QResource::NoCompression; data = 0; size = 0; children.clear(); @@ -287,11 +348,11 @@ QResourcePrivate::load(const QString &file) container = res->isContainer(node); if(!container) { data = res->data(node, &size); - compressed = res->isCompressed(node); + compressionAlgo = res->compressionAlgo(node); } else { - data = 0; + data = nullptr; size = 0; - compressed = 0; + compressionAlgo = QResource::NoCompression; } lastModified = res->lastModified(node); } else if(res->isContainer(node) != container) { @@ -301,9 +362,9 @@ QResourcePrivate::load(const QString &file) related.append(res); } else if(res->mappingRootSubdir(file)) { container = true; - data = 0; + data = nullptr; size = 0; - compressed = 0; + compressionAlgo = QResource::NoCompression; lastModified = 0; res->ref.ref(); related.append(res); @@ -493,16 +554,41 @@ bool QResource::isValid() const /*! Returns \c true if the resource represents a file and the data backing it - is in a compressed format, false otherwise. + is in a compressed format, false otherwise. If the data is compressed, + check compressionAlgorithm() to verify what algorithm to use to decompress + the data. - \sa data(), isFile() + \sa data(), compressionType(), isFile() */ bool QResource::isCompressed() const { + return compressionAlgorithm() != NoCompression; +} + +/*! + \since 5.13 + + Returns the compression type that this resource is compressed with, if any. + If it is not compressed, this function returns QResource::NoCompression. + + If this function returns QResource::ZlibCompression, you may decompress the + data using the qUncompress() function. Up until Qt 5.13, this was the only + possible compression algorithm. + + If this function returns QResource::ZstdCompression, you need to use the + Zstandard library functios (\c{<zstd.h> header). Qt does not provide a + wrapper. + + See \l{http://facebook.github.io/zstd/zstd_manual.html}{Zstandard manual}. + + \sa isCompressed(), data(), isFile() +*/ +QResource::Compression QResource::compressionAlgorithm() const +{ Q_D(const QResource); d->ensureInitialized(); - return d->compressed; + return Compression(d->compressionAlgo); } /*! @@ -853,7 +939,7 @@ Q_CORE_EXPORT bool qRegisterResourceData(int version, const unsigned char *tree, const unsigned char *name, const unsigned char *data) { QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x2) && resourceList()) { + if (version >= 0x01 && version <= 0x3 && resourceList()) { bool found = false; QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ++i) { @@ -879,7 +965,7 @@ Q_CORE_EXPORT bool qUnregisterResourceData(int version, const unsigned char *tre return false; QMutexLocker lock(resourceMutex()); - if ((version == 0x01 || version == 0x02) && resourceList()) { + if (version >= 0x01 && version <= 0x3 && resourceList()) { QResourceRoot res(version, tree, name, data); for(int i = 0; i < resourceList()->size(); ) { if(*resourceList()->at(i) == res) { @@ -906,11 +992,11 @@ public: inline QDynamicBufferResourceRoot(const QString &_root) : root(_root), buffer(0) { } inline ~QDynamicBufferResourceRoot() { } inline const uchar *mappingBuffer() const { return buffer; } - virtual QString mappingRoot() const override { return root; } - virtual ResourceRootType type() const override { return Resource_Buffer; } + QString mappingRoot() const override { return root; } + ResourceRootType type() const override { return Resource_Buffer; } // size == -1 means "unknown" - bool registerSelf(const uchar *b, int size) + bool registerSelf(const uchar *b, qsizetype size) { // 5 int "pointers" if (size >= 0 && size < 20) @@ -938,11 +1024,27 @@ public: const int name_offset = qFromBigEndian<qint32>(b + offset); offset += 4; + quint32 file_flags = 0; + if (version >= 3) { + file_flags = qFromBigEndian<qint32>(b + offset); + offset += 4; + } + // Some sanity checking for sizes. This is _not_ a security measure. if (size >= 0 && (tree_offset >= size || data_offset >= size || name_offset >= size)) return false; - if (version == 0x01 || version == 0x02) { + // And some sanity checking for features + quint32 acceptableFlags = 0; +#ifndef QT_NO_COMPRESS + acceptableFlags |= Compressed; +#endif + if (QT_CONFIG(zstd)) + acceptableFlags |= CompressedZstd; + if (file_flags & ~acceptableFlags) + return false; + + if (version >= 0x01 && version <= 0x03) { buffer = b; setSource(version, b+tree_offset, b+name_offset, b+data_offset); return true; @@ -951,28 +1053,12 @@ public: } }; -#if defined(Q_OS_UNIX) && !defined (Q_OS_NACL) && !defined(Q_OS_INTEGRITY) -#define QT_USE_MMAP -#endif - -// most of the headers below are already included in qplatformdefs.h -// also this lacks Large File support but that's probably irrelevant -#if defined(QT_USE_MMAP) -// for mmap -QT_BEGIN_INCLUDE_NAMESPACE -#include <sys/mman.h> -#include <errno.h> -QT_END_INCLUDE_NAMESPACE -#endif - - - class QDynamicFileResourceRoot: public QDynamicBufferResourceRoot { QString fileName; // for mmap'ed files, this is what needs to be unmapped. uchar *unmapPointer; - unsigned int unmapLength; + qsizetype unmapLength; public: inline QDynamicFileResourceRoot(const QString &_root) : QDynamicBufferResourceRoot(_root), unmapPointer(0), unmapLength(0) { } @@ -989,76 +1075,78 @@ public: } } QString mappingFile() const { return fileName; } - virtual ResourceRootType type() const override { return Resource_File; } + ResourceRootType type() const override { return Resource_File; } - bool registerSelf(const QString &f) { - bool fromMM = false; - uchar *data = 0; - unsigned int data_len = 0; - -#ifdef QT_USE_MMAP + bool registerSelf(const QString &f); +}; #ifndef MAP_FILE -#define MAP_FILE 0 +# define MAP_FILE 0 #endif #ifndef MAP_FAILED -#define MAP_FAILED -1 +# define MAP_FAILED reinterpret_cast<void *>(-1) #endif - int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, +bool QDynamicFileResourceRoot::registerSelf(const QString &f) +{ + bool fromMM = false; + uchar *data = nullptr; + qsizetype data_len = 0; + +#ifdef QT_USE_MMAP + int fd = QT_OPEN(QFile::encodeName(f), O_RDONLY, #if defined(Q_OS_WIN) - _S_IREAD | _S_IWRITE + _S_IREAD | _S_IWRITE #else - 0666 + 0666 #endif - ); - if (fd >= 0) { - QT_STATBUF st; - if (!QT_FSTAT(fd, &st)) { - uchar *ptr; - ptr = reinterpret_cast<uchar *>( - mmap(0, st.st_size, // any address, whole file - PROT_READ, // read-only memory - MAP_FILE | MAP_PRIVATE, // swap-backed map from file - fd, 0)); // from offset 0 of fd - if (ptr && ptr != reinterpret_cast<uchar *>(MAP_FAILED)) { - data = ptr; - data_len = st.st_size; - fromMM = true; - } + ); + if (fd >= 0) { + QT_STATBUF st; + if (!QT_FSTAT(fd, &st) && st.st_size <= std::numeric_limits<qsizetype>::max()) { + int protection = PROT_READ; // read-only memory + int flags = MAP_FILE | MAP_PRIVATE; // swap-backed map from file + void *ptr = QT_MMAP(nullptr, st.st_size, // any address, whole file + protection, flags, + fd, 0); // from offset 0 of fd + if (ptr != MAP_FAILED) { + data = static_cast<uchar *>(ptr); + data_len = st.st_size; + fromMM = true; } - ::close(fd); } + QT_CLOSE(fd); + } #endif // QT_USE_MMAP - if(!data) { - QFile file(f); - if (!file.exists()) - return false; - data_len = file.size(); - data = new uchar[data_len]; - - bool ok = false; - if (file.open(QIODevice::ReadOnly)) - ok = (data_len == (uint)file.read((char*)data, data_len)); - if (!ok) { - delete [] data; - data = 0; - data_len = 0; - return false; + if (!data) { + QFile file(f); + bool ok = false; + if (file.open(QIODevice::ReadOnly)) { + qint64 fsize = file.size(); + if (fsize <= std::numeric_limits<qsizetype>::max()) { + data_len = file.size(); + data = new uchar[data_len]; + ok = (data_len == file.read((char*)data, data_len)); } - fromMM = false; } - if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) { - if(fromMM) { - unmapPointer = data; - unmapLength = data_len; - } - fileName = f; - return true; + if (!ok) { + delete [] data; + data = nullptr; + data_len = 0; + return false; } - return false; + fromMM = false; } -}; + if (data && QDynamicBufferResourceRoot::registerSelf(data, data_len)) { + if (fromMM) { + unmapPointer = data; + unmapLength = data_len; + } + fileName = f; + return true; + } + return false; +} static QString qt_resource_fixResourceRoot(QString r) { if(!r.isEmpty()) { @@ -1531,12 +1619,40 @@ bool QResourceFileEnginePrivate::unmap(uchar *ptr) void QResourceFileEnginePrivate::uncompress() const { - if (resource.isCompressed() && uncompressed.isEmpty() && resource.size()) { + if (uncompressed.isEmpty() && resource.size()) { + quint64 size; + switch (resource.compressionAlgorithm()) { + case QResource::NoCompression: + return; // nothing to do + + case QResource::ZlibCompression: #ifndef QT_NO_COMPRESS - uncompressed = qUncompress(resource.data(), resource.size()); + uncompressed = qUncompress(resource.data(), resource.size()); #else - Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for compression"); + Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zlib compression"); #endif + break; + + case QResource::ZstdCompression: +#if QT_CONFIG(zstd) + size = ZSTD_getFrameContentSize(resource.data(), resource.size()); + if (!ZSTD_isError(size)) { + if (size >= MaxAllocSize) { + qWarning("QResourceFileEngine::open: content bigger than memory (size %lld)", size); + } else { + uncompressed = QByteArray(size, Qt::Uninitialized); + size = ZSTD_decompress(const_cast<char *>(uncompressed.data()), size, + resource.data(), resource.size()); + } + } + if (ZSTD_isError(size)) + qWarning("QResourceFileEngine::open: error decoding: %s", ZSTD_getErrorName(size)); +#else + Q_UNUSED(size); + Q_ASSERT(!"QResourceFileEngine::open: Qt built without support for Zstd compression"); +#endif + break; + } } } diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 895cf0456e..9aa17608ce 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -54,6 +54,12 @@ class QResourcePrivate; class Q_CORE_EXPORT QResource { public: + enum Compression { + NoCompression, + ZlibCompression, + ZstdCompression + }; + QResource(const QString &file=QString(), const QLocale &locale=QLocale()); ~QResource(); @@ -67,6 +73,7 @@ public: bool isValid() const; bool isCompressed() const; + Compression compressionAlgorithm() const; qint64 size() const; const uchar *data() const; QDateTime lastModified() const; diff --git a/src/corelib/io/qresource_p.h b/src/corelib/io/qresource_p.h index dcfe46704c..7451de8809 100644 --- a/src/corelib/io/qresource_p.h +++ b/src/corelib/io/qresource_p.h @@ -64,49 +64,49 @@ public: explicit QResourceFileEngine(const QString &path); ~QResourceFileEngine(); - virtual void setFileName(const QString &file) override; + void setFileName(const QString &file) override; - virtual bool open(QIODevice::OpenMode flags) override ; - virtual bool close() override; - virtual bool flush() override; - virtual qint64 size() const override; - virtual qint64 pos() const override; + bool open(QIODevice::OpenMode flags) override; + bool close() override; + bool flush() override; + qint64 size() const override; + qint64 pos() const override; virtual bool atEnd() const; - virtual bool seek(qint64) override; - virtual qint64 read(char *data, qint64 maxlen) override; - virtual qint64 write(const char *data, qint64 len) override; + bool seek(qint64) override; + qint64 read(char *data, qint64 maxlen) override; + qint64 write(const char *data, qint64 len) override; - virtual bool remove() override; - virtual bool copy(const QString &newName) override; - virtual bool rename(const QString &newName) override; - virtual bool link(const QString &newName) override; + bool remove() override; + bool copy(const QString &newName) override; + bool rename(const QString &newName) override; + bool link(const QString &newName) override; - virtual bool isSequential() const override; + bool isSequential() const override; - virtual bool isRelativePath() const override; + bool isRelativePath() const override; - virtual bool mkdir(const QString &dirName, bool createParentDirectories) const override; - virtual bool rmdir(const QString &dirName, bool recurseParentDirectories) const override; + bool mkdir(const QString &dirName, bool createParentDirectories) const override; + bool rmdir(const QString &dirName, bool recurseParentDirectories) const override; - virtual bool setSize(qint64 size) override; + bool setSize(qint64 size) override; - virtual QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override; + QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override; - virtual bool caseSensitive() const override; + bool caseSensitive() const override; - virtual FileFlags fileFlags(FileFlags type) const override; + FileFlags fileFlags(FileFlags type) const override; - virtual bool setPermissions(uint perms) override; + bool setPermissions(uint perms) override; - virtual QString fileName(QAbstractFileEngine::FileName file) const override; + QString fileName(QAbstractFileEngine::FileName file) const override; - virtual uint ownerId(FileOwner) const override; - virtual QString owner(FileOwner) const override; + uint ownerId(FileOwner) const override; + QString owner(FileOwner) const override; - virtual QDateTime fileTime(FileTime time) const override; + QDateTime fileTime(FileTime time) const override; - virtual Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override; - virtual Iterator *endEntryList() override; + Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override; + Iterator *endEntryList() override; bool extension(Extension extension, const ExtensionOption *option = 0, ExtensionReturn *output = 0) override; bool supportsExtension(Extension extension) const override; diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 0d2bd72d75..d2887ee184 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -62,8 +62,8 @@ #include "qrect.h" #endif // !QT_NO_GEOM_VARIANT -#ifndef QT_NO_QOBJECT -#include "qcoreapplication.h" +#ifndef QT_BUILD_QMAKE +# include "qcoreapplication.h" #endif #ifndef QT_BOOTSTRAPPED @@ -2661,9 +2661,10 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent) called, the QSettings object will not be able to read or write any settings, and status() will return AccessError. - On \macos and iOS, if both a name and an Internet domain are specified - for the organization, the domain is preferred over the name. On - other platforms, the name is preferred over the domain. + You should supply both the domain (used by default on \macos and iOS) and + the name (used by default elsewhere), although the code will cope if you + supply only one, which will then be used (on all platforms), at odds with + the usual naming of the file on platforms for which it isn't the default. \sa QCoreApplication::setOrganizationName(), QCoreApplication::setOrganizationDomain(), @@ -2671,8 +2672,21 @@ QSettings::QSettings(const QString &fileName, Format format, QObject *parent) setDefaultFormat() */ QSettings::QSettings(QObject *parent) - : QObject(*QSettingsPrivate::create(globalDefaultFormat, UserScope, -#ifdef Q_OS_MAC + : QSettings(UserScope, parent) +{ +} + +/*! + \since 5.13 + + Constructs a QSettings object in the same way as + QSettings(QObject *parent) but with the given \a scope. + + \sa QSettings(QObject *parent) +*/ +QSettings::QSettings(Scope scope, QObject *parent) + : QObject(*QSettingsPrivate::create(globalDefaultFormat, scope, +#ifdef Q_OS_DARWIN QCoreApplication::organizationDomain().isEmpty() ? QCoreApplication::organizationName() : QCoreApplication::organizationDomain() @@ -2711,6 +2725,25 @@ QSettings::QSettings(const QString &fileName, Format format) { d_ptr->q_ptr = this; } + +# ifndef QT_BUILD_QMAKE +QSettings::QSettings(Scope scope) + : d_ptr(QSettingsPrivate::create(globalDefaultFormat, scope, +# ifdef Q_OS_DARWIN + QCoreApplication::organizationDomain().isEmpty() + ? QCoreApplication::organizationName() + : QCoreApplication::organizationDomain() +# else + QCoreApplication::organizationName().isEmpty() + ? QCoreApplication::organizationDomain() + : QCoreApplication::organizationName() +# endif + , QCoreApplication::applicationName()) + ) +{ + d_ptr->q_ptr = this; +} +# endif #endif /*! diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index 7a9eebe11b..32290a3390 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -129,6 +129,7 @@ public: const QString &application = QString(), QObject *parent = nullptr); QSettings(const QString &fileName, Format format, QObject *parent = nullptr); explicit QSettings(QObject *parent = nullptr); + explicit QSettings(Scope scope, QObject *parent = nullptr); #else explicit QSettings(const QString &organization, const QString &application = QString()); @@ -137,6 +138,9 @@ public: QSettings(Format format, Scope scope, const QString &organization, const QString &application = QString()); QSettings(const QString &fileName, Format format); +# ifndef QT_BUILD_QMAKE + explicit QSettings(Scope scope = UserScope); +# endif #endif ~QSettings(); diff --git a/src/corelib/io/qurlquery.cpp b/src/corelib/io/qurlquery.cpp index 97e7b8a4eb..10c3f836c8 100644 --- a/src/corelib/io/qurlquery.cpp +++ b/src/corelib/io/qurlquery.cpp @@ -145,6 +145,14 @@ QT_BEGIN_NAMESPACE \since 5.2 */ +/*! + \fn QUrlQuery(std::initializer_list<QPair<QString, QString>> list) + + \since 5.13 + + Constructs a QUrlQuery object from the \a list of key/value pair. +*/ + typedef QList<QPair<QString, QString> > Map; class QUrlQueryPrivate : public QSharedData diff --git a/src/corelib/io/qurlquery.h b/src/corelib/io/qurlquery.h index 092d002543..e3688aae2c 100644 --- a/src/corelib/io/qurlquery.h +++ b/src/corelib/io/qurlquery.h @@ -48,6 +48,8 @@ #include <QtCore/qstringlist.h> #endif +#include <initializer_list> + QT_BEGIN_NAMESPACE Q_CORE_EXPORT uint qHash(const QUrlQuery &key, uint seed = 0) Q_DECL_NOTHROW; @@ -59,6 +61,13 @@ public: QUrlQuery(); explicit QUrlQuery(const QUrl &url); explicit QUrlQuery(const QString &queryString); + QUrlQuery(std::initializer_list<QPair<QString, QString>> list) + : QUrlQuery() + { + for (const QPair<QString, QString> &item : list) + addQueryItem(item.first, item.second); + } + QUrlQuery(const QUrlQuery &other); QUrlQuery &operator=(const QUrlQuery &other); #ifdef Q_COMPILER_RVALUE_REFS diff --git a/src/corelib/io/qwindowspipereader_p.h b/src/corelib/io/qwindowspipereader_p.h index e52aa4c33d..c757753c9c 100644 --- a/src/corelib/io/qwindowspipereader_p.h +++ b/src/corelib/io/qwindowspipereader_p.h @@ -97,7 +97,7 @@ private: class Overlapped : public OVERLAPPED { - Q_DISABLE_COPY(Overlapped) + Q_DISABLE_COPY_MOVE(Overlapped) public: explicit Overlapped(QWindowsPipeReader *reader); void clear(); diff --git a/src/corelib/io/qwindowspipewriter_p.h b/src/corelib/io/qwindowspipewriter_p.h index d6671c3f27..6c269e86b7 100644 --- a/src/corelib/io/qwindowspipewriter_p.h +++ b/src/corelib/io/qwindowspipewriter_p.h @@ -134,7 +134,7 @@ private: class Overlapped : public OVERLAPPED { - Q_DISABLE_COPY(Overlapped) + Q_DISABLE_COPY_MOVE(Overlapped) public: explicit Overlapped(QWindowsPipeWriter *pipeWriter); void clear(); |