diff options
Diffstat (limited to 'src/corelib/io')
26 files changed, 531 insertions, 183 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/qdebug.cpp b/src/corelib/io/qdebug.cpp index 4d56d1a179..15c5e0ce96 100644 --- a/src/corelib/io/qdebug.cpp +++ b/src/corelib/io/qdebug.cpp @@ -356,7 +356,7 @@ QDebug &QDebug::resetFormat() stream->space = true; if (stream->context.version > 1) stream->flags = 0; - stream->setVerbosity(Stream::DefaultVerbosity); + stream->setVerbosity(DefaultVerbosity); return *this; } @@ -461,7 +461,7 @@ QDebug &QDebug::resetFormat() The allowed range is from 0 to 7. The default value is 2. - \sa setVerbosity() + \sa setVerbosity(), VerbosityLevel */ /*! @@ -472,7 +472,31 @@ QDebug &QDebug::resetFormat() The allowed range is from 0 to 7. The default value is 2. - \sa verbosity() + \sa verbosity(), VerbosityLevel +*/ + +/*! + \fn QDebug &QDebug::verbosity(int verbosityLevel) + \since 5.13 + + Sets the verbosity of the stream to \a verbosityLevel and returns a reference to the stream. + + The allowed range is from 0 to 7. The default value is 2. + + \sa verbosity(), setVerbosity(), VerbosityLevel +*/ + +/*! + \enum QDebug::VerbosityLevel + \since 5.13 + + This enum describes the range of verbosity levels. + + \value MinimumVerbosity + \value DefaultVerbosity + \value MaximumVerbosity + + \sa verbosity(), setVerbosity() */ /*! @@ -892,37 +916,127 @@ void qt_QMetaEnum_flagDebugOperator(QDebug &debug, size_t sizeofT, int value) #ifndef QT_NO_QOBJECT /*! + \fn QDebug qt_QMetaEnum_debugOperator(QDebug &, int value, const QMetaObject *, const char *name) \internal + + Formats the given enum \a value for debug output. + + The supported verbosity are: + + 0: Just the key, or value with enum name if no key is found: + + MyEnum2 + MyEnum(123) + MyScopedEnum::Enum3 + MyScopedEnum(456) + + 1: Same as 0, but treating all enums as scoped: + + MyEnum::MyEnum2 + MyEnum(123) + MyScopedEnum::Enum3 + MyScopedEnum(456) + + 2: The QDebug default. Same as 0, and includes class/namespace scope: + + MyNamespace::MyClass::MyEnum2 + MyNamespace::MyClass::MyEnum(123) + MyNamespace::MyClass::MyScopedEnum::Enum3 + MyNamespace::MyClass::MyScopedEnum(456) + + 3: Same as 2, but treating all enums as scoped: + + MyNamespace::MyClass::MyEnum::MyEnum2 + MyNamespace::MyClass::MyEnum(123) + MyNamespace::MyClass::MyScopedEnum::Enum3 + MyNamespace::MyClass::MyScopedEnum(456) */ QDebug qt_QMetaEnum_debugOperator(QDebug &dbg, int value, const QMetaObject *meta, const char *name) { QDebugStateSaver saver(dbg); dbg.nospace(); QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); - const char *key = me.valueToKey(value); - if (key) { + + const int verbosity = dbg.verbosity(); + if (verbosity >= QDebug::DefaultVerbosity) { if (const char *scope = me.scope()) dbg << scope << "::"; - if (me.isScoped()) - dbg << me.enumName() << "::"; - dbg << key; - } else { - dbg << meta->className() << "::" << name << "(" << value << ")"; } + + const char *key = me.valueToKey(value); + const bool scoped = me.isScoped() || verbosity & 1; + if (scoped || !key) + dbg << me.enumName() << (!key ? "(" : "::"); + + if (key) + dbg << key; + else + dbg << value << ")"; + return dbg; } +/*! + \fn QDebug qt_QMetaEnum_flagDebugOperator(QDebug &, quint64 value, const QMetaObject *, const char *name) + \internal + + Formats the given flag \a value for debug output. + + The supported verbosity are: + + 0: Just the key(s): + + MyFlag1 + MyFlag2|MyFlag3 + MyScopedFlag(MyFlag2) + MyScopedFlag(MyFlag2|MyFlag3) + + 1: Same as 0, but treating all flags as scoped: + + MyFlag(MyFlag1) + MyFlag(MyFlag2|MyFlag3) + MyScopedFlag(MyFlag2) + MyScopedFlag(MyFlag2|MyFlag3) + + 2: The QDebug default. Same as 1, and includes class/namespace scope: + + QFlags<MyNamespace::MyClass::MyFlag>(MyFlag1) + QFlags<MyNamespace::MyClass::MyFlag>(MyFlag2|MyFlag3) + QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2) + QFlags<MyNamespace::MyClass::MyScopedFlag>(MyFlag2|MyFlag3) + */ QDebug qt_QMetaEnum_flagDebugOperator(QDebug &debug, quint64 value, const QMetaObject *meta, const char *name) { + const int verbosity = debug.verbosity(); + QDebugStateSaver saver(debug); debug.resetFormat(); debug.noquote(); debug.nospace(); - debug << "QFlags<"; + const QMetaEnum me = meta->enumerator(meta->indexOfEnumerator(name)); - if (const char *scope = me.scope()) - debug << scope << "::"; - debug << me.enumName() << ">(" << me.valueToKeys(value) << ')'; + + const bool classScope = verbosity >= QDebug::DefaultVerbosity; + if (classScope) { + debug << "QFlags<"; + + if (const char *scope = me.scope()) + debug << scope << "::"; + } + + const bool enumScope = me.isScoped() || verbosity > QDebug::MinimumVerbosity; + if (enumScope) { + debug << me.enumName(); + if (classScope) + debug << ">"; + debug << "("; + } + + debug << me.valueToKeys(value); + + if (enumScope) + debug << ')'; + return debug; } #endif // !QT_NO_QOBJECT diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 9d1ce51da5..91fde75fa5 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -67,7 +67,7 @@ class Q_CORE_EXPORT QDebug friend class QMessageLogger; friend class QDebugStateSaverPrivate; struct Stream { - enum { DefaultVerbosity = 2, VerbosityShift = 29, VerbosityMask = 0x7 }; + enum { VerbosityShift = 29, VerbosityMask = 0x7 }; Stream(QIODevice *device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false), flags(DefaultVerbosity << VerbosityShift) {} @@ -92,7 +92,7 @@ class Q_CORE_EXPORT QDebug void setFlag(FormatFlag flag) { if (context.version > 1) { flags |= flag; } } void unsetFlag(FormatFlag flag) { if (context.version > 1) { flags &= ~flag; } } int verbosity() const - { return context.version > 1 ? (flags >> VerbosityShift) & VerbosityMask : int(Stream::DefaultVerbosity); } + { return context.version > 1 ? (flags >> VerbosityShift) & VerbosityMask : int(DefaultVerbosity); } void setVerbosity(int v) { if (context.version > 1) { @@ -123,8 +123,10 @@ public: inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; } inline QDebug &nospace() { stream->space = false; return *this; } inline QDebug &maybeSpace() { if (stream->space) stream->ts << ' '; return *this; } + inline QDebug &verbosity(int verbosityLevel) { setVerbosity(verbosityLevel); return *this; } int verbosity() const { return stream->verbosity(); } void setVerbosity(int verbosityLevel) { stream->setVerbosity(verbosityLevel); } + enum VerbosityLevel { MinimumVerbosity = 0, DefaultVerbosity = 2, MaximumVerbosity = 7 }; bool autoInsertSpaces() const { return stream->space; } void setAutoInsertSpaces(bool b) { stream->space = b; } @@ -195,6 +197,7 @@ public: inline QNoDebug "e() { return *this; } inline QNoDebug &noquote() { return *this; } inline QNoDebug &maybeQuote(const char = '"') { return *this; } + inline QNoDebug &verbosity(int) { return *this; } template<typename T> inline QNoDebug &operator<<(const T &) { return *this; } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index f7778943c9..9c4ae5a1c0 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -1069,6 +1069,7 @@ void QDir::setNameFilters(const QStringList &nameFilters) d->nameFilters = nameFilters; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -1088,6 +1089,7 @@ void QDir::addResourceSearchPath(const QString &path) Q_UNUSED(path) #endif } +#endif #ifdef QT_BUILD_CORE_LIB /*! @@ -1815,6 +1817,7 @@ QDir &QDir::operator=(const QDir &dir) return *this; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \overload \obsolete @@ -1828,6 +1831,7 @@ QDir &QDir::operator=(const QString &path) d_ptr->setPath(path); return *this; } +#endif /*! \fn void QDir::swap(QDir &other) diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index 45c59d9e1d..9abb833ab1 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -105,7 +105,10 @@ public: ~QDir(); QDir &operator=(const QDir &); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QDir::setPath() instead") QDir &operator=(const QString &path); +#endif #ifdef Q_COMPILER_RVALUE_REFS QDir &operator=(QDir &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif @@ -118,7 +121,10 @@ public: QString absolutePath() const; QString canonicalPath() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QDir::addSearchPath() instead") static void addResourceSearchPath(const QString &path); +#endif static void setSearchPaths(const QString &prefix, const QStringList &searchPaths); static void addSearchPath(const QString &prefix, const QString &path); diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 3166fa1b83..ef97d67653 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -454,7 +454,13 @@ QFile::exists(const QString &fileName) \sa fileName(), setFileName() */ +QString QFile::symLinkTarget() const +{ + Q_D(const QFile); + return d->engine()->fileName(QAbstractFileEngine::LinkName); +} +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -463,9 +469,9 @@ QFile::exists(const QString &fileName) QString QFile::readLink() const { - Q_D(const QFile); - return d->engine()->fileName(QAbstractFileEngine::LinkName); + return symLinkTarget(); } +#endif /*! \fn static QString QFile::symLinkTarget(const QString &fileName) @@ -478,7 +484,12 @@ QFile::readLink() const This name may not represent an existing file; it is only a string. QFile::exists() returns \c true if the symlink points to an existing file. */ +QString QFile::symLinkTarget(const QString &fileName) +{ + return QFileInfo(fileName).symLinkTarget(); +} +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -487,8 +498,9 @@ QFile::readLink() const QString QFile::readLink(const QString &fileName) { - return QFileInfo(fileName).readLink(); + return symLinkTarget(fileName); } +#endif /*! Removes the file specified by fileName(). Returns \c true if successful; @@ -808,7 +820,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/qfile.h b/src/corelib/io/qfile.h index e6f3d942fe..cf1465ec70 100644 --- a/src/corelib/io/qfile.h +++ b/src/corelib/io/qfile.h @@ -107,10 +107,14 @@ public: bool exists() const; static bool exists(const QString &fileName); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QFile::symLinkTarget() instead") QString readLink() const; + QT_DEPRECATED_X("Use QFile::symLinkTarget(QString) instead") static QString readLink(const QString &fileName); - inline QString symLinkTarget() const { return readLink(); } - inline static QString symLinkTarget(const QString &fileName) { return readLink(fileName); } +#endif + QString symLinkTarget() const; + static QString symLinkTarget(const QString &fileName); bool remove(); static bool remove(const QString &fileName); 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/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 185e061d8f..998382021d 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -1107,6 +1107,7 @@ bool QFileInfo::isRoot() const \sa exists(), isSymLink(), isDir(), isFile() */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -1114,6 +1115,12 @@ bool QFileInfo::isRoot() const */ QString QFileInfo::readLink() const { + return symLinkTarget(); +} +#endif + +QString QFileInfo::symLinkTarget() const +{ Q_D(const QFileInfo); if (d->isDefaultConstructed) return QLatin1String(""); diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index f295a86015..baea18fab1 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -116,8 +116,11 @@ public: bool isRoot() const; bool isBundle() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QFileInfo::symLinkTarget() instead") QString readLink() const; - inline QString symLinkTarget() const { return readLink(); } +#endif + QString symLinkTarget() const; QString owner() const; uint ownerId() const; 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.cpp b/src/corelib/io/qprocess.cpp index e1f4a3a311..83849980ae 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -813,6 +813,7 @@ void QProcessPrivate::Channel::clear() \a newState argument is the state QProcess changed to. */ +#if QT_DEPRECATED_SINCE(5, 13) /*! \fn void QProcess::finished(int exitCode) \obsolete @@ -820,6 +821,7 @@ void QProcessPrivate::Channel::clear() Use finished(int exitCode, QProcess::ExitStatus status) instead. */ +#endif /*! \fn void QProcess::finished(int exitCode, QProcess::ExitStatus exitStatus) @@ -1172,7 +1174,9 @@ bool QProcessPrivate::_q_processDied() //emit q->standardOutputClosed(); //emit q->standardErrorClosed(); +#if QT_DEPRECATED_SINCE(5, 13) emit q->finished(exitCode); +#endif emit q->finished(exitCode, exitStatus); } #if defined QPROCESS_DEBUG @@ -1264,6 +1268,7 @@ QProcess::~QProcess() d->cleanup(); } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete Returns the read channel mode of the QProcess. This function is @@ -1287,6 +1292,7 @@ void QProcess::setReadChannelMode(ProcessChannelMode mode) { setProcessChannelMode(mode); } +#endif /*! \since 4.2 @@ -2473,7 +2479,7 @@ QProcess::ExitStatus QProcess::exitStatus() const int QProcess::execute(const QString &program, const QStringList &arguments) { QProcess process; - process.setReadChannelMode(ForwardedChannels); + process.setProcessChannelMode(ForwardedChannels); process.start(program, arguments); if (!process.waitForFinished(-1) || process.error() == FailedToStart) return -2; @@ -2496,7 +2502,7 @@ int QProcess::execute(const QString &program, const QStringList &arguments) int QProcess::execute(const QString &command) { QProcess process; - process.setReadChannelMode(ForwardedChannels); + process.setProcessChannelMode(ForwardedChannels); process.start(command); if (!process.waitForFinished(-1) || process.error() == FailedToStart) return -2; diff --git a/src/corelib/io/qprocess.h b/src/corelib/io/qprocess.h index 474fc87de8..42cf769698 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 @@ -172,8 +172,12 @@ public: QStringList arguments() const; void setArguments(const QStringList & arguments); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QProcess::processChannelMode() instead") ProcessChannelMode readChannelMode() const; + QT_DEPRECATED_X("Use QProcess::setProcessChannelMode() instead") void setReadChannelMode(ProcessChannelMode mode); +#endif ProcessChannelMode processChannelMode() const; void setProcessChannelMode(ProcessChannelMode mode); InputChannelMode inputChannelMode() const; @@ -269,7 +273,10 @@ public Q_SLOTS: Q_SIGNALS: void started(QPrivateSignal); +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QProcess::finished(int, QProcess::ExitStatus) instead") void finished(int exitCode); // ### Qt 6: merge the two signals with a default value +#endif void finished(int exitCode, QProcess::ExitStatus exitStatus); #if QT_DEPRECATED_SINCE(5,6) void error(QProcess::ProcessError error); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 564a3e5f51..e541b0ee20 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); } /*! @@ -573,6 +659,7 @@ QStringList QResource::children() const return d->children; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -614,6 +701,7 @@ QResource::searchPaths() QMutexLocker lock(resourceMutex()); return *resourceSearchPaths(); } +#endif inline uint QResourceRoot::hash(int node) const { @@ -853,7 +941,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 +967,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 +994,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 +1026,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 +1055,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 +1077,78 @@ public: } } QString mappingFile() const { return fileName; } - virtual ResourceRootType type() const override { return Resource_File; } - - bool registerSelf(const QString &f) { - bool fromMM = false; - uchar *data = 0; - unsigned int data_len = 0; + ResourceRootType type() const override { return Resource_File; } -#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 +1621,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..5e798de436 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,12 +73,17 @@ public: bool isValid() const; bool isCompressed() const; + Compression compressionAlgorithm() const; qint64 size() const; const uchar *data() const; QDateTime lastModified() const; +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QDir::addSearchPath() instead") static void addSearchPath(const QString &path); + QT_DEPRECATED_X("Use QDir::searchPaths() instead") static QStringList searchPaths(); +#endif static bool registerResource(const QString &rccFilename, const QString &resourceRoot=QString()); static bool unregisterResource(const QString &rccFilename, const QString &resourceRoot=QString()); 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..47b3548817 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 /*! @@ -3411,6 +3444,7 @@ QSettings::Format QSettings::defaultFormat() return globalDefaultFormat; } +#if QT_DEPRECATED_SINCE(5, 13) /*! \obsolete @@ -3444,7 +3478,7 @@ void QSettings::setUserIniPath(const QString &dir) setPath(NativeFormat, UserScope, dir); #endif } - +#endif /*! \since 4.1 diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index 7a9eebe11b..07c746d043 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(); @@ -183,8 +187,12 @@ public: static void setDefaultFormat(Format format); static Format defaultFormat(); - static void setSystemIniPath(const QString &dir); // ### Qt 6: remove (use setPath() instead) - static void setUserIniPath(const QString &dir); // ### Qt 6: remove (use setPath() instead) +#if QT_DEPRECATED_SINCE(5, 13) + QT_DEPRECATED_X("Use QSettings::setPath() instead") + static void setSystemIniPath(const QString &dir); + QT_DEPRECATED_X("Use QSettings::setPath() instead") + static void setUserIniPath(const QString &dir); +#endif static void setPath(Format format, Scope scope, const QString &path); typedef QMap<QString, QVariant> SettingsMap; diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp index 0667d170c7..83108e4387 100644 --- a/src/corelib/io/qstandardpaths_android.cpp +++ b/src/corelib/io/qstandardpaths_android.cpp @@ -239,10 +239,7 @@ QString QStandardPaths::writableLocation(StandardLocation type) case QStandardPaths::PicturesLocation: return getExternalStoragePublicDirectory("DIRECTORY_PICTURES"); case QStandardPaths::DocumentsLocation: - if (QtAndroidPrivate::androidSdkVersion() > 18) - return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS"); - else - return getExternalStorageDirectory() + QLatin1String("/Documents"); + return getExternalStoragePublicDirectory("DIRECTORY_DOCUMENTS"); case QStandardPaths::DownloadLocation: return getExternalStoragePublicDirectory("DIRECTORY_DOWNLOADS"); case QStandardPaths::GenericConfigLocation: @@ -295,13 +292,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type) } if (type == DocumentsLocation) { - if (QtAndroidPrivate::androidSdkVersion() > 18) { - return QStringList() << writableLocation(type) - << getExternalFilesDir("DIRECTORY_DOCUMENTS"); - } else { - return QStringList() << writableLocation(type) - << getExternalFilesDir() + QLatin1String("/Documents"); - } + return QStringList() << writableLocation(type) + << getExternalFilesDir("DIRECTORY_DOCUMENTS"); } if (type == DownloadLocation) { 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(); |