summaryrefslogtreecommitdiffstats
path: root/src/corelib/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/io')
-rw-r--r--src/corelib/io/qdatastream.cpp36
-rw-r--r--src/corelib/io/qdatastream.h8
-rw-r--r--src/corelib/io/qdebug.cpp19
-rw-r--r--src/corelib/io/qdebug.h15
-rw-r--r--src/corelib/io/qfileselector.cpp9
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice.cpp39
-rw-r--r--src/corelib/io/qnoncontiguousbytedevice_p.h6
-rw-r--r--src/corelib/io/qsavefile.cpp24
-rw-r--r--src/corelib/io/qsavefile_p.h1
-rw-r--r--src/corelib/io/qstandardpaths.cpp35
-rw-r--r--src/corelib/io/qstandardpaths.h4
-rw-r--r--src/corelib/io/qstandardpaths_android.cpp5
-rw-r--r--src/corelib/io/qstandardpaths_blackberry.cpp5
-rw-r--r--src/corelib/io/qstandardpaths_ios.mm3
-rw-r--r--src/corelib/io/qstandardpaths_mac.cpp16
-rw-r--r--src/corelib/io/qstandardpaths_unix.cpp8
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp34
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp7
-rw-r--r--src/corelib/io/qurl.cpp60
-rw-r--r--src/corelib/io/qurl.h9
-rw-r--r--src/corelib/io/qwinoverlappedionotifier.cpp60
-rw-r--r--src/corelib/io/qwinoverlappedionotifier_p.h1
22 files changed, 293 insertions, 111 deletions
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index a6fbffee7e..127244e994 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -250,10 +250,6 @@ QT_BEGIN_NAMESPACE
if (q_status != Ok) \
return retVal;
-enum {
- DefaultStreamVersion = QDataStream::Qt_5_3
-};
-
/*!
Constructs a data stream that has no I/O device.
@@ -265,7 +261,7 @@ QDataStream::QDataStream()
dev = 0;
owndev = false;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -287,7 +283,7 @@ QDataStream::QDataStream(QIODevice *d)
dev = d; // set device
owndev = false;
byteorder = BigEndian; // default byte order
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -315,7 +311,7 @@ QDataStream::QDataStream(QByteArray *a, QIODevice::OpenMode flags)
dev = buf;
owndev = true;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -339,7 +335,7 @@ QDataStream::QDataStream(const QByteArray &a)
dev = buf;
owndev = true;
byteorder = BigEndian;
- ver = DefaultStreamVersion;
+ ver = Qt_DefaultCompiledVersion;
noswap = QSysInfo::ByteOrder == QSysInfo::BigEndian;
q_status = Ok;
}
@@ -542,6 +538,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_5_1 Version 14 (Qt 5.1)
\value Qt_5_2 Version 15 (Qt 5.2)
\value Qt_5_3 Same as Qt_5_2
+ \value Qt_5_4 Version 16 (Qt 5.4)
+ \omitvalue Qt_DefaultCompiledVersion
\sa setVersion(), version()
*/
@@ -557,7 +555,8 @@ void QDataStream::setByteOrder(ByteOrder bo)
/*!
\fn void QDataStream::setVersion(int v)
- Sets the version number of the data serialization format to \a v.
+ Sets the version number of the data serialization format to \a v,
+ a value of the \l Version enum.
You don't \e have to set a version if you are using the current
version of Qt, but for your own custom binary formats we
@@ -571,25 +570,6 @@ void QDataStream::setByteOrder(ByteOrder bo)
with an earlier version of Qt, use this function to modify the
serialization format used by QDataStream.
- \table
- \header \li Qt Version \li QDataStream Version
- \row \li Qt 5.2 \li 15
- \row \li Qt 5.1 \li 14
- \row \li Qt 5.0 \li 13
- \row \li Qt 4.6 \li 12
- \row \li Qt 4.5 \li 11
- \row \li Qt 4.4 \li 10
- \row \li Qt 4.3 \li 9
- \row \li Qt 4.2 \li 8
- \row \li Qt 4.0, 4.1 \li 7
- \row \li Qt 3.3 \li 6
- \row \li Qt 3.1, 3.2 \li 5
- \row \li Qt 3.0 \li 4
- \row \li Qt 2.1, 2.2, 2.3 \li 3
- \row \li Qt 2.0 \li 2
- \row \li Qt 1.x \li 1
- \endtable
-
The \l Version enum provides symbolic constants for the different
versions of Qt. For example:
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index 28f1d51a12..808fbe73f6 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -88,10 +88,12 @@ public:
Qt_5_0 = 13,
Qt_5_1 = 14,
Qt_5_2 = 15,
- Qt_5_3 = Qt_5_2
-#if QT_VERSION >= 0x050400
-#error Add the datastream version for this Qt version
+ Qt_5_3 = Qt_5_2,
+ Qt_5_4 = 16,
+#if QT_VERSION >= 0x050500
+#error Add the datastream version for this Qt version and update Qt_DefaultCompiledVersion
#endif
+ Qt_DefaultCompiledVersion = Qt_5_4
};
enum ByteOrder {
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 3370cce6d5..44d0a788ff 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -128,6 +128,20 @@ QT_BEGIN_NAMESPACE
Flushes any pending data to be written and destroys the debug stream.
*/
+// Has been defined in the header / inlined before Qt 5.4
+QDebug::~QDebug()
+{
+ if (!--stream->ref) {
+ if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
+ stream->buffer.chop(1);
+ if (stream->message_output) {
+ qt_message_output(stream->type,
+ stream->context,
+ stream->buffer);
+ }
+ delete stream;
+ }
+}
/*!
\fn QDebug::swap(QDebug &other)
@@ -334,7 +348,9 @@ QT_BEGIN_NAMESPACE
\brief Convenience class for custom QDebug operators
- Saves the settings used by QDebug, and restores them upon destruction.
+ Saves the settings used by QDebug, and restores them upon destruction,
+ then calls maybeSpace(), to separate arguments with a space if
+ autoInsertSpaces() was true at the time of constructing the QDebugStateSaver.
The automatic insertion of spaces between writes is one of the settings
that QDebugStateSaver stores for the duration of the current block.
@@ -391,6 +407,7 @@ QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
QDebugStateSaver::~QDebugStateSaver()
{
d->restoreState();
+ d->m_dbg.maybeSpace();
}
QT_END_NAMESPACE
diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h
index bdaaa05768..94b19f9cab 100644
--- a/src/corelib/io/qdebug.h
+++ b/src/corelib/io/qdebug.h
@@ -78,20 +78,7 @@ public:
inline QDebug(QtMsgType t) : stream(new Stream(t)) {}
inline QDebug(const QDebug &o):stream(o.stream) { ++stream->ref; }
inline QDebug &operator=(const QDebug &other);
- inline ~QDebug() {
- if (!--stream->ref) {
- if (stream->space && stream->buffer.endsWith(QLatin1Char(' ')))
- stream->buffer.chop(1);
- if (stream->message_output) {
- QT_TRY {
- qt_message_output(stream->type,
- stream->context,
- stream->buffer);
- } QT_CATCH(std::bad_alloc&) { /* We're out of memory - give up. */ }
- }
- delete stream;
- }
- }
+ ~QDebug();
inline void swap(QDebug &other) { qSwap(stream, other.stream); }
inline QDebug &space() { stream->space = true; stream->ts << ' '; return *this; }
diff --git a/src/corelib/io/qfileselector.cpp b/src/corelib/io/qfileselector.cpp
index 0fa1f02f5c..4301536cf7 100644
--- a/src/corelib/io/qfileselector.cpp
+++ b/src/corelib/io/qfileselector.cpp
@@ -51,10 +51,6 @@
#include <QtCore/QLocale>
#include <QtCore/QDebug>
-#ifdef Q_OS_UNIX
-#include <sys/utsname.h>
-#endif
-
QT_BEGIN_NAMESPACE
//Environment variable to allow tooling full control of file selectors
@@ -360,6 +356,7 @@ void QFileSelectorPrivate::updateSelectors()
QStringList QFileSelectorPrivate::platformSelectors()
{
+ // similar, but not identical to QSysInfo::osType
QStringList ret;
#if defined(Q_OS_WIN)
ret << QStringLiteral("windows");
@@ -390,9 +387,7 @@ QStringList QFileSelectorPrivate::platformSelectors()
ret << QStringLiteral("osx");
# endif
# else
- struct utsname u;
- if (uname(&u) != -1)
- ret << QString::fromLatin1(u.sysname).toLower();
+ ret << QSysInfo::osType();
# endif
#endif
return ret;
diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp
index b1e4dd7584..4c5fb38c67 100644
--- a/src/corelib/io/qnoncontiguousbytedevice.cpp
+++ b/src/corelib/io/qnoncontiguousbytedevice.cpp
@@ -506,6 +506,25 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QIODevice *dev
}
/*!
+ Create a QNonContiguousByteDevice out of a QIODevice, return it in a QSharedPointer.
+ For QFile, QBuffer and all other QIODevice, sequential or not.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QIODevice *device)
+{
+ // shortcut if it is a QBuffer
+ if (QBuffer *buffer = qobject_cast<QBuffer*>(device))
+ return QSharedPointer<QNonContiguousByteDeviceBufferImpl>::create(buffer);
+
+ // ### FIXME special case if device is a QFile that supports map()
+ // then we can actually deal with the file without using read/peek
+
+ // generic QIODevice
+ return QSharedPointer<QNonContiguousByteDeviceIoDeviceImpl>::create(device); // FIXME
+}
+
+/*!
\fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QSharedPointer<QRingBuffer> ringBuffer)
Create a QNonContiguousByteDevice out of a QRingBuffer.
@@ -518,6 +537,16 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QSharedPointer
}
/*!
+ Create a QNonContiguousByteDevice out of a QRingBuffer, return it in a QSharedPointer.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QSharedPointer<QRingBuffer> ringBuffer)
+{
+ return QSharedPointer<QNonContiguousByteDeviceRingBufferImpl>::create(qMove(ringBuffer));
+}
+
+/*!
\fn static QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *byteArray)
Create a QNonContiguousByteDevice out of a QByteArray.
@@ -530,6 +559,16 @@ QNonContiguousByteDevice* QNonContiguousByteDeviceFactory::create(QByteArray *by
}
/*!
+ Create a QNonContiguousByteDevice out of a QByteArray.
+
+ \internal
+*/
+QSharedPointer<QNonContiguousByteDevice> QNonContiguousByteDeviceFactory::createShared(QByteArray *byteArray)
+{
+ return QSharedPointer<QNonContiguousByteDeviceByteArrayImpl>::create(byteArray);
+}
+
+/*!
\fn static QIODevice* QNonContiguousByteDeviceFactory::wrap(QNonContiguousByteDevice* byteDevice)
Wrap the \a byteDevice (possibly again) into a QIODevice.
diff --git a/src/corelib/io/qnoncontiguousbytedevice_p.h b/src/corelib/io/qnoncontiguousbytedevice_p.h
index 4606ac2686..1e746db80f 100644
--- a/src/corelib/io/qnoncontiguousbytedevice_p.h
+++ b/src/corelib/io/qnoncontiguousbytedevice_p.h
@@ -90,8 +90,14 @@ class Q_CORE_EXPORT QNonContiguousByteDeviceFactory
{
public:
static QNonContiguousByteDevice* create(QIODevice *device);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QIODevice *device);
+
static QNonContiguousByteDevice* create(QByteArray *byteArray);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QByteArray *byteArray);
+
static QNonContiguousByteDevice* create(QSharedPointer<QRingBuffer> ringBuffer);
+ static QSharedPointer<QNonContiguousByteDevice> createShared(QSharedPointer<QRingBuffer> ringBuffer);
+
static QIODevice* wrap(QNonContiguousByteDevice* byteDevice);
};
diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp
index 2b901c7ccd..8be4125ef5 100644
--- a/src/corelib/io/qsavefile.cpp
+++ b/src/corelib/io/qsavefile.cpp
@@ -205,14 +205,32 @@ bool QSaveFile::open(OpenMode mode)
d->writeError = QFileDevice::WriteError;
return false;
}
- d->fileEngine = new QTemporaryFileEngine(d->fileName);
+
+ if (existingFile.isDir()) {
+ d->setError(QFileDevice::WriteError, QSaveFile::tr("Filename refers to a directory"));
+ d->writeError = QFileDevice::WriteError;
+ return false;
+ }
+
+ // Resolve symlinks. Don't use QFileInfo::canonicalFilePath so it still give the expected
+ // target even if the file does not exist
+ d->finalFileName = d->fileName;
+ if (existingFile.isSymLink()) {
+ int maxDepth = 128;
+ while (--maxDepth && existingFile.isSymLink())
+ existingFile.setFile(existingFile.symLinkTarget());
+ if (maxDepth > 0)
+ d->finalFileName = existingFile.filePath();
+ }
+
+ d->fileEngine = new QTemporaryFileEngine(d->finalFileName);
// Same as in QFile: QIODevice provides the buffering, so there's no need to request it from the file engine.
if (!d->fileEngine->open(mode | QIODevice::Unbuffered)) {
QFileDevice::FileError err = d->fileEngine->error();
#ifdef Q_OS_UNIX
if (d->directWriteFallback && err == QFileDevice::OpenError && errno == EACCES) {
delete d->fileEngine;
- d->fileEngine = QAbstractFileEngine::create(d->fileName);
+ d->fileEngine = QAbstractFileEngine::create(d->finalFileName);
if (d->fileEngine->open(mode | QIODevice::Unbuffered)) {
d->useTemporaryFile = false;
QFileDevice::open(mode);
@@ -285,7 +303,7 @@ bool QSaveFile::commit()
// atomically replace old file with new file
// Can't use QFile::rename for that, must use the file engine directly
Q_ASSERT(d->fileEngine);
- if (!d->fileEngine->renameOverwrite(d->fileName)) {
+ if (!d->fileEngine->renameOverwrite(d->finalFileName)) {
d->setError(d->fileEngine->error(), d->fileEngine->errorString());
d->fileEngine->remove();
delete d->fileEngine;
diff --git a/src/corelib/io/qsavefile_p.h b/src/corelib/io/qsavefile_p.h
index b9efd1ee7c..2134c4c9bc 100644
--- a/src/corelib/io/qsavefile_p.h
+++ b/src/corelib/io/qsavefile_p.h
@@ -70,6 +70,7 @@ protected:
~QSaveFilePrivate();
QString fileName;
+ QString finalFileName; // fileName with symbolic links resolved
QFileDevice::FileError writeError;
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index bd9fa68d93..8c47ad1391 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -117,10 +117,9 @@ QT_BEGIN_NAMESPACE
\value HomeLocation Returns the user's home directory (the same as QDir::homePath()). On Unix
systems, this is equal to the HOME environment variable. This value might be
generic or application-specific, but the returned path is never empty.
- \value DataLocation Returns a directory location where persistent
- application data can be stored. This is an application-specific directory. To obtain a
- path to store data to be shared with other applications, use
- QStandardPaths::GenericDataLocation. The returned path is never empty.
+ \value DataLocation Returns the same value as AppLocalDataLocation. This enumeration value
+ is deprecated. Using AppDataLocation is preferable since on Windows, the roaming path is
+ recommended.
\value CacheLocation Returns a directory location where user-specific
non-essential (cached) data should be written. This is an application-specific directory.
The returned path is never empty.
@@ -142,6 +141,15 @@ QT_BEGIN_NAMESPACE
\value GenericConfigLocation Returns a directory location where user-specific
configuration files shared between multiple applications should be written.
This is a generic value and the returned path is never empty.
+ \value AppDataLocation Returns a directory location where persistent
+ application data can be stored. This is an application-specific directory.
+ To obtain a path to store data to be shared with other applications, use
+ QStandardPaths::GenericDataLocation. The returned path is never empty.
+ On the Windows operating system, this returns the roaming path.
+ This enum value was added in Qt 5.4.
+ \value AppLocalDataLocation Returns the local settings path on the Windows operating
+ system. On all other platforms, it returns the same value as AppDataLocation.
+ This enum value was added in Qt 5.4.
The following table gives examples of paths on different operating systems.
The first path is the writable path (unless noted). Other, additional
@@ -200,6 +208,12 @@ QT_BEGIN_NAMESPACE
\row \li GenericCacheLocation
\li "~/Library/Caches", "/Library/Caches"
\li "C:/Users/<USER>/AppData/Local/cache"
+ \row \li AppDataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Roaming/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
+ \row \li AppLocalDataLocation
+ \li "~/Library/Application Support/<APPNAME>", "/Library/Application Support/<APPNAME>". "<APPDIR>/../Resources"
+ \li "C:/Users/<USER>/AppData/Local/<APPNAME>", "C:/ProgramData/<APPNAME>", "<APPDIR>", "<APPDIR>/data"
\endtable
\table
@@ -255,6 +269,12 @@ QT_BEGIN_NAMESPACE
\row \li GenericCacheLocation
\li "<APPROOT>/data/Cache" (there is no shared cache)
\li "~/.cache"
+ \row \li AppDataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
+ \row \li AppLocalDataLocation
+ \li "<APPROOT>/data", "<APPROOT>/app/native/assets"
+ \li "~/.local/share/<APPNAME>", "/usr/local/share/<APPNAME>", "/usr/share/<APPNAME>"
\endtable
\table
@@ -293,6 +313,8 @@ QT_BEGIN_NAMESPACE
\li "<USER>/Downloads", "<USER>/<APPNAME>/Downloads"
\row \li GenericCacheLocation
\li "<APPROOT>/cache" (there is no shared cache)
+ \row \li AppDataLocation
+ \li "<APPROOT>/files", "<USER>/<APPNAME>/files"
\endtable
In the table above, \c <APPNAME> is usually the organization name, the
@@ -534,8 +556,6 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Temporary Directory");
case HomeLocation:
return QCoreApplication::translate("QStandardPaths", "Home");
- case DataLocation:
- return QCoreApplication::translate("QStandardPaths", "Application Data");
case CacheLocation:
return QCoreApplication::translate("QStandardPaths", "Cache");
case GenericDataLocation:
@@ -550,6 +570,9 @@ QString QStandardPaths::displayName(StandardLocation type)
return QCoreApplication::translate("QStandardPaths", "Shared Cache");
case DownloadLocation:
return QCoreApplication::translate("QStandardPaths", "Download");
+ case AppDataLocation:
+ case AppLocalDataLocation:
+ return QCoreApplication::translate("QStandardPaths", "Application Data");
}
// not reached
return QString();
diff --git a/src/corelib/io/qstandardpaths.h b/src/corelib/io/qstandardpaths.h
index 08d6d7b50c..b93adbf156 100644
--- a/src/corelib/io/qstandardpaths.h
+++ b/src/corelib/io/qstandardpaths.h
@@ -70,7 +70,9 @@ public:
ConfigLocation,
DownloadLocation,
GenericCacheLocation,
- GenericConfigLocation
+ GenericConfigLocation,
+ AppDataLocation,
+ AppLocalDataLocation = DataLocation
};
static QString writableLocation(StandardLocation type);
diff --git a/src/corelib/io/qstandardpaths_android.cpp b/src/corelib/io/qstandardpaths_android.cpp
index 60b285a3d6..9bd4b4b428 100644
--- a/src/corelib/io/qstandardpaths_android.cpp
+++ b/src/corelib/io/qstandardpaths_android.cpp
@@ -244,7 +244,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
return getFilesDir() + testDir() + QLatin1String("/settings");
case QStandardPaths::GenericDataLocation:
return getExternalStorageDirectory() + testDir();
- case QStandardPaths::DataLocation:
+ case QStandardPaths::AppDataLocation:
+ case QStandardPaths::AppLocalDataLocation:
return getFilesDir() + testDir();
case QStandardPaths::GenericCacheLocation:
case QStandardPaths::RuntimeLocation:
@@ -301,7 +302,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
<< getExternalFilesDir("DIRECTORY_DOWNLOADS");
}
- if (type == DataLocation) {
+ if (type == AppDataLocation || type == AppLocalDataLocation) {
return QStringList() << writableLocation(type)
<< getExternalFilesDir();
}
diff --git a/src/corelib/io/qstandardpaths_blackberry.cpp b/src/corelib/io/qstandardpaths_blackberry.cpp
index ec2e61bd15..2e9d62cd05 100644
--- a/src/corelib/io/qstandardpaths_blackberry.cpp
+++ b/src/corelib/io/qstandardpaths_blackberry.cpp
@@ -63,7 +63,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
const QString sharedRoot = sharedDir.absolutePath();
switch (type) {
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
return QDir::homePath() + testModeInsert();
case DesktopLocation:
case HomeLocation:
@@ -108,7 +109,7 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
if (type == FontsLocation)
return QStringList(QLatin1String("/base/usr/fonts"));
- if (type == DataLocation)
+ if (type == AppDataLocation || type == AppLocalDataLocation)
dirs.append(QDir::homePath() + testModeInsert() + QLatin1String("native/assets"));
const QString localDir = writableLocation(type);
diff --git a/src/corelib/io/qstandardpaths_ios.mm b/src/corelib/io/qstandardpaths_ios.mm
index e2100045a6..cdca28b8b5 100644
--- a/src/corelib/io/qstandardpaths_ios.mm
+++ b/src/corelib/io/qstandardpaths_ios.mm
@@ -90,7 +90,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case HomeLocation:
location = bundlePath();
break;
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
location = pathForDirectory(NSDocumentDirectory);
break;
diff --git a/src/corelib/io/qstandardpaths_mac.cpp b/src/corelib/io/qstandardpaths_mac.cpp
index aff9112fb7..a27920899c 100644
--- a/src/corelib/io/qstandardpaths_mac.cpp
+++ b/src/corelib/io/qstandardpaths_mac.cpp
@@ -83,7 +83,8 @@ OSType translateLocation(QStandardPaths::StandardLocation type)
return kTemporaryFolderType;
case QStandardPaths::GenericDataLocation:
case QStandardPaths::RuntimeLocation:
- case QStandardPaths::DataLocation:
+ case QStandardPaths::AppDataLocation:
+ case QStandardPaths::AppLocalDataLocation:
return kApplicationSupportFolderType;
case QStandardPaths::GenericCacheLocation:
case QStandardPaths::CacheLocation:
@@ -128,7 +129,7 @@ static QString macLocation(QStandardPaths::StandardLocation type, short domain)
QString path = getFullPath(ref);
- if (type == QStandardPaths::DataLocation || type == QStandardPaths::CacheLocation)
+ if (type == QStandardPaths::AppDataLocation || type == QStandardPaths::AppLocalDataLocation || type == QStandardPaths::CacheLocation)
appendOrganizationAndApp(path);
return path;
}
@@ -140,9 +141,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QString path;
switch (type) {
case GenericDataLocation:
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
path = qttestDir + QLatin1String("/Application Support");
- if (type == DataLocation)
+ if (type != GenericDataLocation)
appendOrganizationAndApp(path);
return path;
case GenericCacheLocation:
@@ -165,7 +167,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case TempLocation:
return QDir::tempPath();
case GenericDataLocation:
- case DataLocation:
+ case AppLocalDataLocation:
case GenericCacheLocation:
case CacheLocation:
case RuntimeLocation:
@@ -179,13 +181,13 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
{
QStringList dirs;
- if (type == GenericDataLocation || type == DataLocation || type == GenericCacheLocation || type == CacheLocation) {
+ if (type == GenericDataLocation || type == AppDataLocation || type == AppLocalDataLocation || type == GenericCacheLocation || type == CacheLocation) {
const QString path = macLocation(type, kOnAppropriateDisk);
if (!path.isEmpty())
dirs.append(path);
}
- if (type == DataLocation) {
+ if (type == AppDataLocation || type == AppLocalDataLocation) {
CFBundleRef mainBundle = CFBundleGetMainBundle();
if (mainBundle) {
CFURLRef bundleUrl = CFBundleCopyBundleURL(mainBundle);
diff --git a/src/corelib/io/qstandardpaths_unix.cpp b/src/corelib/io/qstandardpaths_unix.cpp
index e2ed7c3766..cde1e4bc72 100644
--- a/src/corelib/io/qstandardpaths_unix.cpp
+++ b/src/corelib/io/qstandardpaths_unix.cpp
@@ -90,7 +90,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
appendOrganizationAndApp(xdgCacheHome);
return xdgCacheHome;
}
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
{
QString xdgDataHome = QFile::decodeName(qgetenv("XDG_DATA_HOME"));
@@ -98,7 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
xdgDataHome = QDir::homePath() + QLatin1String("/.qttest/share");
if (xdgDataHome.isEmpty())
xdgDataHome = QDir::homePath() + QLatin1String("/.local/share");
- if (type == QStandardPaths::DataLocation)
+ if (type == AppDataLocation || type == AppLocalDataLocation)
appendOrganizationAndApp(xdgDataHome);
return xdgDataHome;
}
@@ -305,7 +306,8 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
for (int i = 0; i < dirs.count(); ++i)
dirs[i].append(QLatin1String("/applications"));
break;
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
dirs = xdgDataDirs();
for (int i = 0; i < dirs.count(); ++i)
appendOrganizationAndApp(dirs[i]);
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index 062ab49207..aaa390ac34 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -81,6 +81,18 @@ static QString convertCharArray(const wchar_t *path)
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
}
+static inline int clsidForAppDataLocation(QStandardPaths::StandardLocation type)
+{
+#ifndef Q_OS_WINCE
+ return type == QStandardPaths::AppDataLocation ?
+ CSIDL_APPDATA : // "Roaming" path
+ CSIDL_LOCAL_APPDATA; // Local path
+#else
+ Q_UNUSED(type)
+ return CSIDL_APPDATA;
+#endif
+}
+
QString QStandardPaths::writableLocation(StandardLocation type)
{
QString result;
@@ -92,15 +104,12 @@ QString QStandardPaths::writableLocation(StandardLocation type)
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
- case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows
+ case GenericConfigLocation: // same as GenericDataLocation on Windows
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
-#if defined Q_OS_WINCE
- if (SHGetSpecialFolderPath(0, path, CSIDL_APPDATA, FALSE))
-#else
- if (SHGetSpecialFolderPath(0, path, CSIDL_LOCAL_APPDATA, FALSE))
-#endif
+ if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE))
result = convertCharArray(path);
if (isTestModeEnabled())
result += QLatin1String("/qttest");
@@ -165,7 +174,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
// Although Microsoft has a Cache key it is a pointer to IE's cache, not a cache
// location for everyone. Most applications seem to be using a
// cache directory located in their AppData directory
- return writableLocation(DataLocation) + QLatin1String("/cache");
+ return writableLocation(AppLocalDataLocation) + QLatin1String("/cache");
case GenericCacheLocation:
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
@@ -192,11 +201,12 @@ QStringList QStandardPaths::standardLocations(StandardLocation type)
{
wchar_t path[MAX_PATH];
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows (oversight, but too late to fix it)
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows (oversight, but too late to fix it)
case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation:
- if (SHGetSpecialFolderPath(0, path, CSIDL_COMMON_APPDATA, FALSE)) {
+ if (SHGetSpecialFolderPath(0, path, clsidForAppDataLocation(type), FALSE)) {
QString result = convertCharArray(path);
if (type != GenericDataLocation && type != GenericConfigLocation) {
#ifndef QT_BOOTSTRAPPED
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
index 84a3930ee0..aa3b710f52 100644
--- a/src/corelib/io/qstandardpaths_winrt.cpp
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -73,9 +73,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
QString result;
switch (type) {
- case ConfigLocation: // same as DataLocation, on Windows
+ case ConfigLocation: // same as AppLocalDataLocation, on Windows
case GenericConfigLocation: // same as GenericDataLocation, on Windows
- case DataLocation:
+ case AppDataLocation:
+ case AppLocalDataLocation:
case GenericDataLocation: {
ComPtr<IApplicationDataStatics> applicationDataStatics;
if (FAILED(GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), &applicationDataStatics)))
@@ -98,7 +99,7 @@ QString QStandardPaths::writableLocation(StandardLocation type)
break;
}
case CacheLocation:
- return writableLocation(DataLocation) + QLatin1String("/cache");
+ return writableLocation(AppLocalDataLocation) + QLatin1String("/cache");
case GenericCacheLocation:
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 7018b333f2..58b169e588 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -364,6 +364,29 @@
*/
/*!
+ \enum QUrl::UserInputResolutionOption
+ \since 5.4
+
+ The user input resolution options define how fromUserInput() should
+ interpret strings that could either be a relative path or the short
+ form of a HTTP URL. For instance \c{file.pl} can be either a local file
+ or the URL \c{http://file.pl}.
+
+ \value DefaultResolution The default resolution mechanism is to check
+ whether a local file exists, in the working
+ directory given to fromUserInput, and only
+ return a local path in that case. Otherwise a URL
+ is assumed.
+ \value AssumeLocalFile This option makes fromUserInput() always return
+ a local path unless the input contains a scheme, such as
+ \c{http://file.pl}. This is useful for applications
+ such as text editors, which are able to create
+ the file if it doesn't exist.
+
+ \sa fromUserInput()
+*/
+
+/*!
\fn QUrl::QUrl(QUrl &&other)
Move-constructs a QUrl instance, making it point at the same
@@ -4095,6 +4118,43 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Returns a valid URL from a user supplied \a userInput string if one can be
deducted. In the case that is not possible, an invalid QUrl() is returned.
+ This overload takes a \a workingDirectory path, in order to be able to
+ handle relative paths. This is especially useful when handling command
+ line arguments.
+ If \a workingDirectory is empty, no handling of relative paths will be done,
+ so this method will behave like its one argument overload.
+
+ By default, an input string that looks like a relative path will only be treated
+ as such if the file actually exists in the given working directory.
+
+ If the application can handle files that don't exist yet, it should pass the
+ flag AssumeLocalFile in \a options.
+
+ \since 5.4
+*/
+QUrl QUrl::fromUserInput(const QString &userInput, const QString &workingDirectory,
+ UserInputResolutionOptions options)
+{
+ QString trimmedString = userInput.trimmed();
+
+ if (trimmedString.isEmpty())
+ return QUrl();
+
+ // Check both QUrl::isRelative (to detect full URLs) and QDir::isAbsolutePath (since on Windows drive letters can be interpreted as schemes)
+ QUrl url = QUrl(trimmedString, QUrl::TolerantMode);
+ if (url.isRelative() && !QDir::isAbsolutePath(trimmedString)) {
+ QFileInfo fileInfo(QDir(workingDirectory), trimmedString);
+ if ((options & AssumeLocalFile) || fileInfo.exists())
+ return QUrl::fromLocalFile(fileInfo.absoluteFilePath());
+ }
+
+ return fromUserInput(trimmedString);
+}
+
+/*!
+ Returns a valid URL from a user supplied \a userInput string if one can be
+ deducted. In the case that is not possible, an invalid QUrl() is returned.
+
\since 4.6
Most applications that can browse the web, allow the user to input a URL
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 602e91ce30..d621d7ef03 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -199,7 +199,16 @@ public:
QByteArray toEncoded(FormattingOptions options = FullyEncoded) const;
static QUrl fromEncoded(const QByteArray &url, ParsingMode mode = TolerantMode);
+ enum UserInputResolutionOption {
+ DefaultResolution,
+ AssumeLocalFile
+ };
+ Q_DECLARE_FLAGS(UserInputResolutionOptions, UserInputResolutionOption)
+
static QUrl fromUserInput(const QString &userInput);
+ // ### Qt6 merge with fromUserInput(QString), by adding = QString()
+ static QUrl fromUserInput(const QString &userInput, const QString &workingDirectory,
+ UserInputResolutionOptions options = DefaultResolution);
bool isValid() const;
QString errorString() const;
diff --git a/src/corelib/io/qwinoverlappedionotifier.cpp b/src/corelib/io/qwinoverlappedionotifier.cpp
index 33583afb78..06746c0597 100644
--- a/src/corelib/io/qwinoverlappedionotifier.cpp
+++ b/src/corelib/io/qwinoverlappedionotifier.cpp
@@ -41,6 +41,7 @@
#include "qwinoverlappedionotifier_p.h"
#include <qdebug.h>
+#include <qelapsedtimer.h>
#include <qmutex.h>
#include <qpointer.h>
#include <qqueue.h>
@@ -293,35 +294,58 @@ void QWinOverlappedIoNotifier::setEnabled(bool enabled)
}
/*!
- * Wait synchronously for the notified signal.
+ * Wait synchronously for any notified signal.
*
- * The function returns true if the notified signal was emitted for
- * the I/O operation that corresponds to the OVERLAPPED object.
+ * The function returns a pointer to the OVERLAPPED object corresponding to the completed I/O
+ * operation. In case no I/O operation was completed during the \a msec timeout, this function
+ * returns a null pointer.
*/
-bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
+OVERLAPPED *QWinOverlappedIoNotifier::waitForAnyNotified(int msecs)
{
Q_D(QWinOverlappedIoNotifier);
if (!d->iocp->isRunning()) {
- qWarning("Called QWinOverlappedIoNotifier::waitForNotified on inactive notifier.");
- return false;
+ qWarning("Called QWinOverlappedIoNotifier::waitForAnyNotified on inactive notifier.");
+ return 0;
}
+ if (msecs == 0)
+ d->iocp->drainQueue();
+
+ switch (WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs))) {
+ case WAIT_OBJECT_0:
+ ReleaseSemaphore(d->hSemaphore, 1, NULL);
+ return d->_q_notified();
+ case WAIT_TIMEOUT:
+ return 0;
+ default:
+ qErrnoWarning("QWinOverlappedIoNotifier::waitForAnyNotified: WaitForSingleObject failed.");
+ return 0;
+ }
+}
+
+/*!
+ * Wait synchronously for the notified signal.
+ *
+ * The function returns true if the notified signal was emitted for
+ * the I/O operation that corresponds to the OVERLAPPED object.
+ */
+bool QWinOverlappedIoNotifier::waitForNotified(int msecs, OVERLAPPED *overlapped)
+{
+ int t = msecs;
+ QElapsedTimer stopWatch;
+ stopWatch.start();
forever {
- if (msecs == 0)
- d->iocp->drainQueue();
- DWORD result = WaitForSingleObject(d->hSemaphore, msecs == -1 ? INFINITE : DWORD(msecs));
- if (result == WAIT_OBJECT_0) {
- ReleaseSemaphore(d->hSemaphore, 1, NULL);
- if (d->_q_notified() == overlapped)
- return true;
- continue;
- } else if (result == WAIT_TIMEOUT) {
+ OVERLAPPED *triggeredOverlapped = waitForAnyNotified(t);
+ if (!triggeredOverlapped)
return false;
+ if (triggeredOverlapped == overlapped)
+ return true;
+ if (msecs != -1) {
+ t = msecs - stopWatch.elapsed();
+ if (t < 0)
+ return false;
}
}
-
- qErrnoWarning("QWinOverlappedIoNotifier::waitForNotified: WaitForSingleObject failed.");
- return false;
}
/*!
diff --git a/src/corelib/io/qwinoverlappedionotifier_p.h b/src/corelib/io/qwinoverlappedionotifier_p.h
index f90fd2e615..25c0f3a081 100644
--- a/src/corelib/io/qwinoverlappedionotifier_p.h
+++ b/src/corelib/io/qwinoverlappedionotifier_p.h
@@ -76,6 +76,7 @@ public:
Qt::HANDLE handle() const;
void setEnabled(bool enabled);
+ OVERLAPPED *waitForAnyNotified(int msecs);
bool waitForNotified(int msecs, OVERLAPPED *overlapped);
Q_SIGNALS: