diff options
Diffstat (limited to 'src/corelib/io')
25 files changed, 510 insertions, 311 deletions
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index fe81689932..c4c6f41387 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -136,6 +136,7 @@ qtConfig(settings) { } else: darwin:!nacl { SOURCES += io/qsettings_mac.cpp } + wasm : SOURCES += io/qsettings_wasm.cpp } win32 { diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index 8a1679c5af..070139b608 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -658,7 +658,7 @@ QStringList QAbstractFileEngine::entryList(QDir::Filters filters, const QStringL QAbstractFileEngine::FileFlags QAbstractFileEngine::fileFlags(FileFlags type) const { Q_UNUSED(type); - return nullptr; + return {}; } /*! diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 95f03ef816..5320ae2986 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -251,7 +251,7 @@ QFile::QFile(QFilePrivate &dd) Constructs a QFile object. */ QFile::QFile() - : QFileDevice(*new QFilePrivate, 0) + : QFileDevice(*new QFilePrivate, nullptr) { } /*! @@ -265,7 +265,7 @@ QFile::QFile(QObject *parent) Constructs a new file object to represent the file with the given \a name. */ QFile::QFile(const QString &name) - : QFileDevice(*new QFilePrivate, 0) + : QFileDevice(*new QFilePrivate, nullptr) { Q_D(QFile); d->fileName = name; diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp index ee619d99cc..b0aba3193c 100644 --- a/src/corelib/io/qfiledevice.cpp +++ b/src/corelib/io/qfiledevice.cpp @@ -202,7 +202,7 @@ QFileDevice::QFileDevice(QFileDevicePrivate &dd) \internal */ QFileDevice::QFileDevice() - : QIODevice(*new QFileDevicePrivate, 0) + : QIODevice(*new QFileDevicePrivate, nullptr) { } /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 89834de29f..3fe1aec41f 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -134,7 +134,7 @@ uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) cons // extra syscall. Bundle detecton on Mac can be slow, expecially on network // paths, so we separate out that as well. - QAbstractFileEngine::FileFlags req = nullptr; + QAbstractFileEngine::FileFlags req; uint cachedFlags = 0; if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) { @@ -1145,6 +1145,25 @@ bool QFileInfo::isShortcut() const [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); }); } + +/*! + Returns \c true if the object points to a junction; + otherwise returns \c false. + + Junctions only exist on Windows' NTFS file system, and are typically + created by the \c{mklink} command. They can be thought of as symlinks for + directories, and can only be created for absolute paths on the local + volume. +*/ +bool QFileInfo::isJunction() const +{ + Q_D(const QFileInfo); + return d->checkAttribute<bool>( + QFileSystemMetaData::LegacyLinkType, + [d]() { return d->metaData.isJunction(); }, + [d]() { return d->getFileFlags(QAbstractFileEngine::LinkType); }); +} + /*! Returns \c true if the object points to a directory or to a symbolic link to a directory, and that directory is the root directory; otherwise diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 3ac028085a..7c7ff56ae4 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -113,6 +113,7 @@ public: bool isSymLink() const; bool isSymbolicLink() const; bool isShortcut() const; + bool isJunction() const; bool isRoot() const; bool isBundle() const; diff --git a/src/corelib/io/qfilesystemengine_unix.cpp b/src/corelib/io/qfilesystemengine_unix.cpp index 38cb6a423d..3bbebc7fe9 100644 --- a/src/corelib/io/qfilesystemengine_unix.cpp +++ b/src/corelib/io/qfilesystemengine_unix.cpp @@ -1076,14 +1076,14 @@ bool QFileSystemEngine::cloneFile(int srcfd, int dstfd, const QFileSystemMetaDat // sendfile(2) is limited in the kernel to 2G - 4k const size_t SendfileSize = 0x7ffff000; - ssize_t n = ::sendfile(dstfd, srcfd, NULL, SendfileSize); + ssize_t n = ::sendfile(dstfd, srcfd, nullptr, SendfileSize); if (n == -1) { // if we got an error here, give up and try at an upper layer return false; } while (n) { - n = ::sendfile(dstfd, srcfd, NULL, SendfileSize); + n = ::sendfile(dstfd, srcfd, nullptr, SendfileSize); if (n == -1) { // uh oh, this is probably a real error (like ENOSPC), but we have // no way to notify QFile of partial success, so just erase any work diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index ae29190848..0579872f8d 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -1123,67 +1123,62 @@ static bool isDirPath(const QString &dirPath, bool *existed) return fileAttrib & FILE_ATTRIBUTE_DIRECTORY; } +// NOTE: if \a shouldMkdirFirst is false, we assume the caller did try to mkdir +// before calling this function. +static bool createDirectoryWithParents(const QString &nativeName, bool shouldMkdirFirst = true) +{ + const auto isUNCRoot = [](const QString &nativeName) { + return nativeName.startsWith(QLatin1String("\\\\")) && nativeName.count(QDir::separator()) <= 3; + }; + const auto isDriveName = [](const QString &nativeName) { + return nativeName.size() == 2 && nativeName.at(1) == QLatin1Char(':'); + }; + const auto isDir = [](const QString &nativeName) { + bool exists = false; + return isDirPath(nativeName, &exists) && exists; + }; + // Do not try to mkdir a UNC root path or a drive letter. + if (isUNCRoot(nativeName) || isDriveName(nativeName)) + return false; + + if (shouldMkdirFirst) { + if (mkDir(nativeName)) + return true; + } + + const int backSlash = nativeName.lastIndexOf(QDir::separator()); + if (backSlash < 1) + return false; + + const QString parentNativeName = nativeName.left(backSlash); + if (!createDirectoryWithParents(parentNativeName)) + return false; + + // try again + if (mkDir(nativeName)) + return true; + return isDir(nativeName); +} + //static bool QFileSystemEngine::createDirectory(const QFileSystemEntry &entry, bool createParents) { QString dirName = entry.filePath(); Q_CHECK_FILE_NAME(dirName, false); - if (createParents) { - dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); - // We spefically search for / so \ would break it.. - int oldslash = -1; - if (dirName.startsWith(QLatin1String("\\\\"))) { - // Don't try to create the root path of a UNC path; - // CreateDirectory() will just return ERROR_INVALID_NAME. - for (int i = 0; i < dirName.size(); ++i) { - if (dirName.at(i) != QDir::separator()) { - oldslash = i; - break; - } - } - if (oldslash != -1) - oldslash = dirName.indexOf(QDir::separator(), oldslash); - } else if (dirName.size() > 2 - && dirName.at(1) == QLatin1Char(':')) { - // Don't try to call mkdir with just a drive letter - oldslash = 2; - } - for (int slash=0; slash != -1; oldslash = slash) { - slash = dirName.indexOf(QDir::separator(), oldslash+1); - if (slash == -1) { - if (oldslash == dirName.length()) - break; - slash = dirName.length(); - } - if (slash) { - DWORD lastError; - QString chunk = dirName.left(slash); - if (!mkDir(chunk, &lastError)) { - if (lastError == ERROR_ALREADY_EXISTS || lastError == ERROR_ACCESS_DENIED) { - bool existed = false; - if (isDirPath(chunk, &existed) && existed) - continue; -#ifdef Q_OS_WINRT - static QThreadStorage<QString> dataLocation; - if (!dataLocation.hasLocalData()) - dataLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::DataLocation))); - static QThreadStorage<QString> tempLocation; - if (!tempLocation.hasLocalData()) - tempLocation.setLocalData(QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::TempLocation))); - // We try to create something outside the sandbox, which is forbidden - // However we could still try to pass into the sandbox - if (dataLocation.localData().startsWith(chunk) || tempLocation.localData().startsWith(chunk)) - continue; -#endif - } - return false; - } - } - } + dirName = QDir::toNativeSeparators(QDir::cleanPath(dirName)); + + // try to mkdir this directory + DWORD lastError; + if (mkDir(dirName, &lastError)) return true; - } - return mkDir(entry.filePath()); + // mkpath should return true, if the directory already exists, mkdir false. + if (!createParents) + return false; + if (lastError == ERROR_ALREADY_EXISTS) + return isDirPath(dirName, nullptr); + + return createDirectoryWithParents(dirName, false); } //static diff --git a/src/corelib/io/qfilesystemmetadata_p.h b/src/corelib/io/qfilesystemmetadata_p.h index 81f4b3ba13..3154658e5c 100644 --- a/src/corelib/io/qfilesystemmetadata_p.h +++ b/src/corelib/io/qfilesystemmetadata_p.h @@ -76,8 +76,7 @@ class Q_AUTOTEST_EXPORT QFileSystemMetaData { public: QFileSystemMetaData() - : knownFlagsMask(nullptr), - size_(-1) + : size_(-1) { } @@ -111,8 +110,10 @@ public: AliasType = 0x0, #endif #if defined(Q_OS_WIN) + JunctionType = 0x04000000, WinLnkType = 0x08000000, // Note: Uses the same position for AliasType on Mac #else + JunctionType = 0x0, WinLnkType = 0x0, #endif SequentialType = 0x00800000, // Note: overlaps with QAbstractFileEngine::RootFlag @@ -184,7 +185,7 @@ public: void clear() { - knownFlagsMask = nullptr; + knownFlagsMask = {}; } void clearFlags(MetaDataFlags flags = AllMetaDataFlags) @@ -205,8 +206,10 @@ public: bool wasDeleted() const { return (entryFlags & WasDeletedAttribute); } #if defined(Q_OS_WIN) bool isLnkFile() const { return (entryFlags & WinLnkType); } + bool isJunction() const { return (entryFlags & JunctionType); } #else bool isLnkFile() const { return false; } + bool isJunction() const { return false; } #endif qint64 size() const { return size_; } @@ -356,9 +359,15 @@ inline void QFileSystemMetaData::fillFromFindData(WIN32_FIND_DATA &findData, boo if (setLinkType) { knownFlagsMask |= LinkType; entryFlags &= ~LinkType; - if ((fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) - && (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) { - entryFlags |= LinkType; + if (fileAttribute_ & FILE_ATTRIBUTE_REPARSE_POINT) { + if (findData.dwReserved0 == IO_REPARSE_TAG_SYMLINK) { + entryFlags |= LinkType; +#if defined(IO_REPARSE_TAG_MOUNT_POINT) + } else if ((fileAttribute_ & FILE_ATTRIBUTE_DIRECTORY) + && (findData.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT)) { + entryFlags |= JunctionType; +#endif + } } } } diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 54460aff77..86c8963cb6 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -88,7 +88,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject } QFileSystemWatcherPrivate::QFileSystemWatcherPrivate() - : native(0), poller(0) + : native(nullptr), poller(nullptr) { } diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp index ca1f6cc359..888af998a5 100644 --- a/src/corelib/io/qfilesystemwatcher_inotify.cpp +++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp @@ -242,7 +242,7 @@ QInotifyFileSystemWatcherEngine *QInotifyFileSystemWatcherEngine::create(QObject if (fd == -1) { fd = inotify_init(); if (fd == -1) - return 0; + return nullptr; } return new QInotifyFileSystemWatcherEngine(fd, parent); } diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp index 0d73839f8d..3042eac2f0 100644 --- a/src/corelib/io/qfsfileengine.cpp +++ b/src/corelib/io/qfsfileengine.cpp @@ -911,14 +911,7 @@ bool QFSFileEngine::supportsExtension(Extension extension) const } /*! \fn bool QFSFileEngine::caseSensitive() const - Returns \c true for Windows, false for Unix. -*/ - -/*! \fn bool QFSFileEngine::copy(const QString ©Name) - - For Windows or Apple platforms, copy the file to file \a copyName. - - Not implemented for other Unix platforms. + Returns \c false for Windows, true for Unix. */ /*! \fn QString QFSFileEngine::currentPath(const QString &fileName) @@ -950,11 +943,34 @@ bool QFSFileEngine::supportsExtension(Extension extension) const \reimp */ -/*! \fn QString QFSFileEngine::homePath() +/*! Returns the home path of the current user. \sa rootPath() */ +QString QFSFileEngine::homePath() +{ + return QFileSystemEngine::homePath(); +} + +/*! + Returns the root path. + + \sa homePath() +*/ +QString QFSFileEngine::rootPath() +{ + return QFileSystemEngine::rootPath(); +} + +/*! + Returns the temporary path (i.e., a path in which it is safe + to store temporary files). +*/ +QString QFSFileEngine::tempPath() +{ + return QFileSystemEngine::tempPath(); +} /*! \fn bool QFSFileEngine::isRelativePath() const \reimp @@ -968,9 +984,6 @@ bool QFSFileEngine::supportsExtension(Extension extension) const true if successful; otherwise returns \c false. */ -/*! \fn bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const - \reimp -*/ /*! \fn uint QFSFileEngine::ownerId(QAbstractFileEngine::FileOwner own) const In Unix, if stat() is successful, the \c uid is returned if @@ -984,35 +997,87 @@ bool QFSFileEngine::supportsExtension(Extension extension) const \reimp */ -/*! \fn bool QFSFileEngine::remove() - \reimp +/*! + For Windows or Apple platforms, copy the file to file \a copyName. + + Not implemented for other Unix platforms. */ +bool QFSFileEngine::copy(const QString ©Name) +{ + Q_D(QFSFileEngine); + QSystemError error; + bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error); + if (!ret) + setError(QFile::CopyError, error.toString()); + return ret; +} -/*! \fn bool QFSFileEngine::rename(const QString &newName) +/*! \reimp */ +bool QFSFileEngine::remove() +{ + Q_D(QFSFileEngine); + QSystemError error; + bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); + d->metaData.clear(); + if (!ret) + setError(QFile::RemoveError, error.toString()); + return ret; +} - -/*! \fn bool QFSFileEngine::renameOverwrite(const QString &newName) +/*! \reimp */ - -/*! \fn bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const +bool QFSFileEngine::rename(const QString &newName) +{ + Q_D(QFSFileEngine); + QSystemError error; + bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); + if (!ret) + setError(QFile::RenameError, error.toString()); + return ret; +} +/*! \reimp */ +bool QFSFileEngine::renameOverwrite(const QString &newName) +{ + Q_D(QFSFileEngine); + QSystemError error; + bool ret = QFileSystemEngine::renameOverwriteFile(d->fileEntry, QFileSystemEntry(newName), error); + if (!ret) + setError(QFile::RenameError, error.toString()); + return ret; +} -/*! \fn QString QFSFileEngine::rootPath() - Returns the root path. +/*! + \reimp +*/ +bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const +{ + return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories); +} - \sa homePath() +/*! + \reimp */ +bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const +{ + return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories); +} -/*! \fn bool QFSFileEngine::setCurrentPath(const QString &path) + +/*! Sets the current path (e.g., for QDir), to \a path. Returns \c true if the new path exists; otherwise this function does nothing, and returns \c false. \sa currentPath() */ +bool QFSFileEngine::setCurrentPath(const QString &path) +{ + return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); +} /*! \fn bool QFSFileEngine::setPermissions(uint perms) \reimp @@ -1022,11 +1087,6 @@ bool QFSFileEngine::supportsExtension(Extension extension) const \reimp */ -/*! \fn QString QFSFileEngine::tempPath() - Returns the temporary path (i.e., a path in which it is safe - to store temporary files). -*/ - /*! \fn QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions(QAbstractFileEngine::FileFlags type) const \internal */ diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index d4983c72af..4610e9306c 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -304,54 +304,6 @@ bool QFSFileEnginePrivate::nativeIsSequential() const return isSequentialFdFh(); } -bool QFSFileEngine::remove() -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); - d->metaData.clear(); - if (!ret) { - setError(QFile::RemoveError, error.toString()); - } - return ret; -} - -bool QFSFileEngine::copy(const QString &newName) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(newName), error); - if (!ret) { - setError(QFile::CopyError, error.toString()); - } - return ret; -} - -bool QFSFileEngine::renameOverwrite(const QString &newName) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::renameOverwriteFile(d->fileEntry, QFileSystemEntry(newName), error); - - if (!ret) - setError(QFile::RenameError, error.toString()); - - return ret; -} - -bool QFSFileEngine::rename(const QString &newName) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); - - if (!ret) { - setError(QFile::RenameError, error.toString()); - } - - return ret; -} - bool QFSFileEngine::link(const QString &newName) { Q_D(QFSFileEngine); @@ -368,45 +320,16 @@ qint64 QFSFileEnginePrivate::nativeSize() const return sizeFdFh(); } -bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const -{ - return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories); -} - -bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const -{ - return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories); -} - bool QFSFileEngine::caseSensitive() const { return true; } -bool QFSFileEngine::setCurrentPath(const QString &path) -{ - return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); -} - QString QFSFileEngine::currentPath(const QString &) { return QFileSystemEngine::currentPath().filePath(); } -QString QFSFileEngine::homePath() -{ - return QFileSystemEngine::homePath(); -} - -QString QFSFileEngine::rootPath() -{ - return QFileSystemEngine::rootPath(); -} - -QString QFSFileEngine::tempPath() -{ - return QFileSystemEngine::tempPath(); -} QFileInfoList QFSFileEngine::drives() { diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp index 19cc3e6402..dd4882a2bc 100644 --- a/src/corelib/io/qfsfileengine_win.cpp +++ b/src/corelib/io/qfsfileengine_win.cpp @@ -443,66 +443,11 @@ bool QFSFileEnginePrivate::nativeIsSequential() const #endif } -bool QFSFileEngine::remove() -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::removeFile(d->fileEntry, error); - if (!ret) - setError(QFile::RemoveError, error.toString()); - return ret; -} - -bool QFSFileEngine::copy(const QString ©Name) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::copyFile(d->fileEntry, QFileSystemEntry(copyName), error); - if (!ret) - setError(QFile::CopyError, error.toString()); - return ret; -} - -bool QFSFileEngine::rename(const QString &newName) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::renameFile(d->fileEntry, QFileSystemEntry(newName), error); - if (!ret) - setError(QFile::RenameError, error.toString()); - return ret; -} - -bool QFSFileEngine::renameOverwrite(const QString &newName) -{ - Q_D(QFSFileEngine); - QSystemError error; - bool ret = QFileSystemEngine::renameOverwriteFile(d->fileEntry, QFileSystemEntry(newName), error); - if (!ret) - setError(QFile::RenameError, error.toString()); - return ret; -} - -bool QFSFileEngine::mkdir(const QString &name, bool createParentDirectories) const -{ - return QFileSystemEngine::createDirectory(QFileSystemEntry(name), createParentDirectories); -} - -bool QFSFileEngine::rmdir(const QString &name, bool recurseParentDirectories) const -{ - return QFileSystemEngine::removeDirectory(QFileSystemEntry(name), recurseParentDirectories); -} - bool QFSFileEngine::caseSensitive() const { return false; } -bool QFSFileEngine::setCurrentPath(const QString &path) -{ - return QFileSystemEngine::setCurrentPath(QFileSystemEntry(path)); -} - QString QFSFileEngine::currentPath(const QString &fileName) { #if !defined(Q_OS_WINRT) @@ -530,21 +475,6 @@ QString QFSFileEngine::currentPath(const QString &fileName) #endif // Q_OS_WINRT } -QString QFSFileEngine::homePath() -{ - return QFileSystemEngine::homePath(); -} - -QString QFSFileEngine::rootPath() -{ - return QFileSystemEngine::rootPath(); -} - -QString QFSFileEngine::tempPath() -{ - return QFileSystemEngine::tempPath(); -} - #if !defined(Q_OS_WINRT) // cf QStorageInfo::isReady static inline bool isDriveReady(const wchar_t *path) @@ -661,14 +591,14 @@ QAbstractFileEngine::FileFlags QFSFileEngine::fileFlags(QAbstractFileEngine::Fil if (type & Refresh) d->metaData.clear(); - QAbstractFileEngine::FileFlags ret = 0; + QAbstractFileEngine::FileFlags ret; if (type & FlagsMask) ret |= LocalDiskFlag; bool exists; { - QFileSystemMetaData::MetaDataFlags queryFlags = 0; + QFileSystemMetaData::MetaDataFlags queryFlags; queryFlags |= QFileSystemMetaData::MetaDataFlags(uint(type)) & QFileSystemMetaData::Permissions; diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp index e26508e631..b89cab5e3c 100644 --- a/src/corelib/io/qiodevice.cpp +++ b/src/corelib/io/qiodevice.cpp @@ -461,7 +461,7 @@ QIODevice::QIODevice(QIODevicePrivate &dd) */ QIODevice::QIODevice() - : QObject(*new QIODevicePrivate, 0) + : QObject(*new QIODevicePrivate, nullptr) { #if defined QIODEVICE_DEBUG QFile *file = qobject_cast<QFile *>(this); diff --git a/src/corelib/io/qnoncontiguousbytedevice.cpp b/src/corelib/io/qnoncontiguousbytedevice.cpp index d1806aa12b..df0197e8eb 100644 --- a/src/corelib/io/qnoncontiguousbytedevice.cpp +++ b/src/corelib/io/qnoncontiguousbytedevice.cpp @@ -127,7 +127,7 @@ QT_BEGIN_NAMESPACE \internal */ -QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)0) +QNonContiguousByteDevice::QNonContiguousByteDevice() : QObject((QObject*)nullptr) { } @@ -188,7 +188,7 @@ const char* QNonContiguousByteDeviceByteArrayImpl::readPointer(qint64 maximumLen { if (atEnd()) { len = -1; - return 0; + return nullptr; } if (maximumLength != -1) @@ -241,7 +241,7 @@ const char* QNonContiguousByteDeviceRingBufferImpl::readPointer(qint64 maximumLe { if (atEnd()) { len = -1; - return 0; + return nullptr; } const char *returnValue = ringBuffer->readPointerAtPosition(currentPosition, len); @@ -282,7 +282,7 @@ qint64 QNonContiguousByteDeviceRingBufferImpl::size() const QNonContiguousByteDeviceIoDeviceImpl::QNonContiguousByteDeviceIoDeviceImpl(QIODevice *d) : QNonContiguousByteDevice(), - currentReadBuffer(0), currentReadBufferSize(16*1024), + currentReadBuffer(nullptr), currentReadBufferSize(16*1024), currentReadBufferAmount(0), currentReadBufferPosition(0), totalAdvancements(0), eof(false) { @@ -301,10 +301,10 @@ const char* QNonContiguousByteDeviceIoDeviceImpl::readPointer(qint64 maximumLeng { if (eof == true) { len = -1; - return 0; + return nullptr; } - if (currentReadBuffer == 0) + if (currentReadBuffer == nullptr) currentReadBuffer = new QByteArray(currentReadBufferSize, '\0'); // lazy alloc if (maximumLength == -1) @@ -323,7 +323,7 @@ const char* QNonContiguousByteDeviceIoDeviceImpl::readPointer(qint64 maximumLeng // size was unknown before, emit a readProgress with the final size if (size() == -1) emit readProgress(totalAdvancements, totalAdvancements); - return 0; + return nullptr; } currentReadBufferAmount = haveRead; @@ -349,7 +349,7 @@ bool QNonContiguousByteDeviceIoDeviceImpl::advanceReadPointer(qint64 amount) if (currentReadBufferPosition > currentReadBufferAmount) { qint64 i = currentReadBufferPosition - currentReadBufferAmount; while (i > 0) { - if (device->getChar(0) == false) { + if (device->getChar(nullptr) == false) { emit readProgress(totalAdvancements - i, size()); return false; // ### FIXME handle eof } @@ -377,7 +377,7 @@ bool QNonContiguousByteDeviceIoDeviceImpl::reset() totalAdvancements = 0; //reset the progress counter if (currentReadBuffer) { delete currentReadBuffer; - currentReadBuffer = 0; + currentReadBuffer = nullptr; } currentReadBufferAmount = 0; currentReadBufferPosition = 0; @@ -405,7 +405,7 @@ qint64 QNonContiguousByteDeviceIoDeviceImpl::pos() const return device->pos(); } -QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)0) +QByteDeviceWrappingIoDevice::QByteDeviceWrappingIoDevice(QNonContiguousByteDevice *bd) : QIODevice((QObject*)nullptr) { byteDevice = bd; connect(bd, SIGNAL(readyRead()), SIGNAL(readyRead())); diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 3a77242d7c..816026a36c 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -216,7 +216,7 @@ void QProcessEnvironmentPrivate::insert(const QProcessEnvironmentPrivate &other) environment variables to be removed. */ QProcessEnvironment::QProcessEnvironment() - : d(0) + : d(nullptr) { } @@ -436,18 +436,18 @@ void QProcessPrivate::Channel::clear() case PipeSource: Q_ASSERT(process); process->stdinChannel.type = Normal; - process->stdinChannel.process = 0; + process->stdinChannel.process = nullptr; break; case PipeSink: Q_ASSERT(process); process->stdoutChannel.type = Normal; - process->stdoutChannel.process = 0; + process->stdoutChannel.process = nullptr; break; } type = Normal; file.clear(); - process = 0; + process = nullptr; } /*! @@ -869,8 +869,8 @@ QProcessPrivate::QProcessPrivate() sequenceNumber = 0; exitCode = 0; exitStatus = QProcess::NormalExit; - startupSocketNotifier = 0; - deathNotifier = 0; + startupSocketNotifier = nullptr; + deathNotifier = nullptr; childStartedPipe[0] = INVALID_Q_PIPE; childStartedPipe[1] = INVALID_Q_PIPE; forkfd = -1; @@ -924,23 +924,23 @@ void QProcessPrivate::cleanup() if (stdoutChannel.notifier) { delete stdoutChannel.notifier; - stdoutChannel.notifier = 0; + stdoutChannel.notifier = nullptr; } if (stderrChannel.notifier) { delete stderrChannel.notifier; - stderrChannel.notifier = 0; + stderrChannel.notifier = nullptr; } if (stdinChannel.notifier) { delete stdinChannel.notifier; - stdinChannel.notifier = 0; + stdinChannel.notifier = nullptr; } if (startupSocketNotifier) { delete startupSocketNotifier; - startupSocketNotifier = 0; + startupSocketNotifier = nullptr; } if (deathNotifier) { delete deathNotifier; - deathNotifier = 0; + deathNotifier = nullptr; } closeChannel(&stdoutChannel); closeChannel(&stderrChannel); @@ -1229,7 +1229,7 @@ void QProcessPrivate::closeWriteChannel() #endif if (stdinChannel.notifier) { delete stdinChannel.notifier; - stdinChannel.notifier = 0; + stdinChannel.notifier = nullptr; } #ifdef Q_OS_WIN // ### Find a better fix, feeding the process little by little @@ -2615,7 +2615,7 @@ QT_END_INCLUDE_NAMESPACE QStringList QProcess::systemEnvironment() { QStringList tmp; - char *entry = 0; + char *entry = nullptr; int count = 0; while ((entry = environ[count++])) tmp << QString::fromLocal8Bit(entry); diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp index 0c80daa024..9cd3bd531b 100644 --- a/src/corelib/io/qprocess_unix.cpp +++ b/src/corelib/io/qprocess_unix.cpp @@ -246,7 +246,7 @@ bool QProcessPrivate::openChannel(Channel &channel) return false; // create the socket notifiers - if (threadData->hasEventDispatcher()) { + if (threadData.loadRelaxed()->hasEventDispatcher()) { if (&channel == &stdinChannel) { channel.notifier = new QSocketNotifier(channel.pipe[1], QSocketNotifier::Write, q); @@ -338,11 +338,11 @@ static char **_q_dupEnvironment(const QProcessEnvironmentPrivate::Map &environme { *envc = 0; if (environment.isEmpty()) - return 0; + return nullptr; char **envp = new char *[environment.count() + 2]; - envp[environment.count()] = 0; - envp[environment.count() + 1] = 0; + envp[environment.count()] = nullptr; + envp[environment.count() + 1] = nullptr; auto it = environment.constBegin(); const auto end = environment.constEnd(); @@ -377,7 +377,7 @@ void QProcessPrivate::startProcess() return; } - if (threadData->hasEventDispatcher()) { + if (threadData.loadRelaxed()->hasEventDispatcher()) { startupSocketNotifier = new QSocketNotifier(childStartedPipe[0], QSocketNotifier::Read, q); QObject::connect(startupSocketNotifier, SIGNAL(activated(int)), @@ -390,7 +390,7 @@ void QProcessPrivate::startProcess() // Create argument list with right number of elements, and set the final // one to 0. char **argv = new char *[arguments.count() + 2]; - argv[arguments.count() + 1] = 0; + argv[arguments.count() + 1] = nullptr; // Encode the program name. QByteArray encodedProgramName = QFile::encodeName(program); @@ -437,13 +437,13 @@ void QProcessPrivate::startProcess() // Duplicate the environment. int envc = 0; - char **envp = 0; + char **envp = nullptr; if (environment.d.constData()) { envp = _q_dupEnvironment(environment.d.constData()->vars, &envc); } // Encode the working directory if it's non-empty, otherwise just pass 0. - const char *workingDirPtr = 0; + const char *workingDirPtr = nullptr; QByteArray encodedWorkingDirectory; if (!workingDirectory.isEmpty()) { encodedWorkingDirectory = QFile::encodeName(workingDirectory); @@ -517,7 +517,7 @@ void QProcessPrivate::startProcess() if (stderrChannel.pipe[0] != -1) ::fcntl(stderrChannel.pipe[0], F_SETFL, ::fcntl(stderrChannel.pipe[0], F_GETFL) | O_NONBLOCK); - if (threadData->eventDispatcher.loadAcquire()) { + if (threadData.loadRelaxed()->eventDispatcher.loadAcquire()) { deathNotifier = new QSocketNotifier(forkfd, QSocketNotifier::Read, q); QObject::connect(deathNotifier, SIGNAL(activated(int)), q, SLOT(_q_processDied())); @@ -596,7 +596,7 @@ bool QProcessPrivate::processStarted(QString *errorMessage) if (startupSocketNotifier) { startupSocketNotifier->setEnabled(false); startupSocketNotifier->deleteLater(); - startupSocketNotifier = 0; + startupSocketNotifier = nullptr; } qt_safe_close(childStartedPipe[0]); childStartedPipe[0] = -1; @@ -889,7 +889,7 @@ bool QProcessPrivate::waitForDeadChild() crashed = info.code != CLD_EXITED; delete deathNotifier; - deathNotifier = 0; + deathNotifier = nullptr; EINTR_LOOP(ret, forkfd_close(forkfd)); forkfd = -1; // Child is dead, don't try to kill it anymore @@ -935,7 +935,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - ::sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, nullptr); ::setsid(); @@ -964,7 +964,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) char **argv = new char *[arguments.size() + 2]; for (int i = 0; i < arguments.size(); ++i) argv[i + 1] = ::strdup(QFile::encodeName(arguments.at(i)).constData()); - argv[arguments.size() + 1] = 0; + argv[arguments.size() + 1] = nullptr; // Duplicate the environment. int envc = 0; @@ -991,7 +991,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - ::sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, nullptr); // '\1' means execv failed char c = '\1'; @@ -1002,7 +1002,7 @@ bool QProcessPrivate::startDetached(qint64 *pid) struct sigaction noaction; memset(&noaction, 0, sizeof(noaction)); noaction.sa_handler = SIG_IGN; - ::sigaction(SIGPIPE, &noaction, 0); + ::sigaction(SIGPIPE, &noaction, nullptr); // '\2' means internal error char c = '\2'; diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp index 3ba86063e3..05af5a5aee 100644 --- a/src/corelib/io/qprocess_win.cpp +++ b/src/corelib/io/qprocess_win.cpp @@ -590,7 +590,7 @@ void QProcessPrivate::startProcess() if (!pid) return; - if (threadData->hasEventDispatcher()) { + if (threadData.loadRelaxed()->hasEventDispatcher()) { processFinishedNotifier = new QWinEventNotifier(pid->hProcess, q); QObject::connect(processFinishedNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_processDied())); processFinishedNotifier->setEnabled(true); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 22c22ce711..3664a63050 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1492,7 +1492,7 @@ bool QResourceFileEngine::isSequential() const QAbstractFileEngine::FileFlags QResourceFileEngine::fileFlags(QAbstractFileEngine::FileFlags type) const { Q_D(const QResourceFileEngine); - QAbstractFileEngine::FileFlags ret = 0; + QAbstractFileEngine::FileFlags ret; if(!d->resource.isValid()) return ret; @@ -1584,7 +1584,7 @@ QAbstractFileEngine::Iterator *QResourceFileEngine::beginEntryList(QDir::Filters */ QAbstractFileEngine::Iterator *QResourceFileEngine::endEntryList() { - return 0; + return nullptr; } bool QResourceFileEngine::extension(Extension extension, const ExtensionOption *option, ExtensionReturn *output) @@ -1594,7 +1594,7 @@ bool QResourceFileEngine::extension(Extension extension, const ExtensionOption * const MapExtensionOption *options = (const MapExtensionOption*)(option); MapExtensionReturn *returnValue = static_cast<MapExtensionReturn*>(output); returnValue->address = d->map(options->offset, options->size, options->flags); - return (returnValue->address != 0); + return (returnValue->address != nullptr); } if (extension == UnMapExtension) { const UnMapExtensionOption *options = (const UnMapExtensionOption*)option; @@ -1623,7 +1623,7 @@ uchar *QResourceFileEnginePrivate::map(qint64 offset, qint64 size, QFile::Memory if (offset < 0 || size <= 0 || !resource.isValid() || add_overflow(offset, size, &end) || end > max) { q->setError(QFile::UnspecifiedError, QString()); - return 0; + return nullptr; } const uchar *address = resource.data(); diff --git a/src/corelib/io/qsavefile.cpp b/src/corelib/io/qsavefile.cpp index 0a884a7df9..067ccda3df 100644 --- a/src/corelib/io/qsavefile.cpp +++ b/src/corelib/io/qsavefile.cpp @@ -116,7 +116,7 @@ QSaveFile::QSaveFile(const QString &name) Constructs a new file object to represent the file with the given \a name. */ QSaveFile::QSaveFile(const QString &name) - : QFileDevice(*new QSaveFilePrivate, 0) + : QFileDevice(*new QSaveFilePrivate, nullptr) { Q_D(QSaveFile); d->fileName = name; diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index fc7122d904..9fc45e307d 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -76,10 +76,6 @@ # include <ioLib.h> #endif -#ifdef Q_OS_WASM -#include <emscripten.h> -#endif - #include <algorithm> #include <stdlib.h> @@ -210,7 +206,7 @@ QConfFile *QConfFile::fromName(const QString &fileName, bool _userPerms) ConfFileHash *usedHash = usedHashFunc(); ConfFileCache *unusedCache = unusedCacheFunc(); - QConfFile *confFile = 0; + QConfFile *confFile = nullptr; const auto locker = qt_scoped_lock(settingsGlobalMutex); if (!(confFile = usedHash->value(absPath))) { @@ -234,7 +230,7 @@ void QConfFile::clearCache() // QSettingsPrivate QSettingsPrivate::QSettingsPrivate(QSettings::Format format) - : format(format), scope(QSettings::UserScope /* nothing better to put */), iniCodec(0), fallbacks(true), + : format(format), scope(QSettings::UserScope /* nothing better to put */), iniCodec(nullptr), fallbacks(true), pendingChanges(false), status(QSettings::NoError) { } @@ -242,7 +238,7 @@ QSettingsPrivate::QSettingsPrivate(QSettings::Format format) QSettingsPrivate::QSettingsPrivate(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application) : format(format), scope(scope), organizationName(organization), applicationName(application), - iniCodec(0), fallbacks(true), pendingChanges(false), status(QSettings::NoError) + iniCodec(nullptr), fallbacks(true), pendingChanges(false), status(QSettings::NoError) { } @@ -295,7 +291,7 @@ after_loop: // see also qsettings_win.cpp, qsettings_winrt.cpp and qsettings_mac.cpp -#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) +#if !defined(Q_OS_WIN) && !defined(Q_OS_MAC) && !defined(Q_OS_WASM) QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, QSettings::Scope scope, const QString &organization, const QString &application) { @@ -928,8 +924,8 @@ QStringList QSettingsPrivate::splitArgs(const QString &s, int idx) void QConfFileSettingsPrivate::initFormat() { extension = (format == QSettings::NativeFormat) ? QLatin1String(".conf") : QLatin1String(".ini"); - readFunc = 0; - writeFunc = 0; + readFunc = nullptr; + writeFunc = nullptr; #if defined(Q_OS_MAC) caseSensitivity = (format == QSettings::NativeFormat) ? Qt::CaseSensitive : IniCaseSensitivity; #else @@ -1185,7 +1181,9 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, confFiles.append(QConfFile::fromName(systemPath.path + orgFile, false)); } +#ifndef Q_OS_WASM // wasm needs to delay access until after file sync initAccess(); +#endif } QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName, @@ -1548,13 +1546,6 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile) perms |= QFile::ReadGroup | QFile::ReadOther; QFile(confFile->name).setPermissions(perms); } -#ifdef Q_OS_WASM - EM_ASM( - // Sync sandbox filesystem to persistent database filesystem. See QTBUG-70002 - FS.syncfs(false, function(err) { - }); - ); -#endif } else { setStatus(QSettings::AccessError); } @@ -3347,7 +3338,7 @@ bool QSettings::contains(const QString &key) const { Q_D(const QSettings); QString k = d->actualKey(key); - return d->get(k, 0); + return d->get(k, nullptr); } /*! diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h index d18c96a06c..c30f099a72 100644 --- a/src/corelib/io/qsettings_p.h +++ b/src/corelib/io/qsettings_p.h @@ -57,6 +57,10 @@ #include "QtCore/qiodevice.h" #include "QtCore/qstack.h" #include "QtCore/qstringlist.h" + +#include <QtCore/qvariant.h> +#include "qsettings.h" + #ifndef QT_NO_QOBJECT #include "private/qobject_p.h" #endif @@ -253,6 +257,10 @@ protected: mutable QSettings::Status status; }; +#ifdef Q_OS_WASM +class QWasmSettingsPrivate; +#endif + class QConfFileSettingsPrivate : public QSettingsPrivate { public: @@ -281,7 +289,7 @@ public: private: void initFormat(); - void initAccess(); + virtual void initAccess(); void syncConfFile(QConfFile *confFile); bool writeIniFile(QIODevice &device, const ParsedSettingsMap &map); #ifdef Q_OS_MAC @@ -297,6 +305,9 @@ private: QString extension; Qt::CaseSensitivity caseSensitivity; int nextPosition; +#ifdef Q_OS_WASM + friend class QWasmSettingsPrivate; +#endif }; QT_END_NAMESPACE diff --git a/src/corelib/io/qsettings_wasm.cpp b/src/corelib/io/qsettings_wasm.cpp new file mode 100644 index 0000000000..8d8f4b505c --- /dev/null +++ b/src/corelib/io/qsettings_wasm.cpp @@ -0,0 +1,259 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtCore module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsettings.h" +#ifndef QT_NO_SETTINGS + +#include "qsettings_p.h" +#ifndef QT_NO_QOBJECT +#include "qcoreapplication.h" +#include <QFile> +#endif // QT_NO_QOBJECT +#include <QDebug> + +#include <QFileInfo> +#include <QDir> +#include <emscripten.h> + +QT_BEGIN_NAMESPACE + +static bool isReadReady = false; + +class QWasmSettingsPrivate : public QConfFileSettingsPrivate +{ +public: + QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization, + const QString &application); + ~QWasmSettingsPrivate(); + + bool get(const QString &key, QVariant *value) const override; + QStringList children(const QString &prefix, ChildSpec spec) const override; + void clear() override; + void sync() override; + void flush() override; + bool isWritable() const override; + + void syncToLocal(const char *data, int size); + void loadLocal(const QByteArray &filename); + void setReady(); + void initAccess() override; + +private: + QString databaseName; + QString id; +}; + +static void QWasmSettingsPrivate_onLoad(void *userData, void *dataPtr, int size) +{ + QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData); + + QFile file(wasm->fileName()); + QFileInfo fileInfo(wasm->fileName()); + QDir dir(fileInfo.path()); + if (!dir.exists()) + dir.mkpath(fileInfo.path()); + + if (file.open(QFile::WriteOnly)) { + file.write(reinterpret_cast<char *>(dataPtr), size); + file.close(); + wasm->setReady(); + } +} + +static void QWasmSettingsPrivate_onError(void *userData) +{ + QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData); + if (wasm) + wasm->setStatus(QSettings::AccessError); +} + +static void QWasmSettingsPrivate_onStore(void *userData) +{ + QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData); + if (wasm) + wasm->setStatus(QSettings::NoError); +} + +static void QWasmSettingsPrivate_onCheck(void *userData, int exists) +{ + QWasmSettingsPrivate *wasm = reinterpret_cast<QWasmSettingsPrivate *>(userData); + if (wasm) { + if (exists) + wasm->loadLocal(wasm->fileName().toLocal8Bit()); + else + wasm->setReady(); + } +} + +QSettingsPrivate *QSettingsPrivate::create(QSettings::Format format, + QSettings::Scope scope, + const QString &organization, + const QString &application) +{ + Q_UNUSED(format) + if (organization == QLatin1String("Qt")) + { + QString organizationDomain = QCoreApplication::organizationDomain(); + QString applicationName = QCoreApplication::applicationName(); + + QSettingsPrivate *newSettings; + newSettings = new QWasmSettingsPrivate(scope, organizationDomain, applicationName); + + newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(organization))); + if (!application.isEmpty()) + newSettings->beginGroupOrArray(QSettingsGroup(normalizedKey(application))); + + return newSettings; + } + return new QWasmSettingsPrivate(scope, organization, application); +} + +QWasmSettingsPrivate::QWasmSettingsPrivate(QSettings::Scope scope, const QString &organization, + const QString &application) + : QConfFileSettingsPrivate(QSettings::NativeFormat, scope, organization, application) +{ + setStatus(QSettings::AccessError); // access error until sandbox gets loaded + databaseName = organization; + id = application; + + emscripten_idb_async_exists("/home/web_user", + fileName().toLocal8Bit(), + reinterpret_cast<void*>(this), + QWasmSettingsPrivate_onCheck, + QWasmSettingsPrivate_onError); +} + +QWasmSettingsPrivate::~QWasmSettingsPrivate() +{ +} + + void QWasmSettingsPrivate::initAccess() +{ + if (isReadReady) + QConfFileSettingsPrivate::initAccess(); +} + +bool QWasmSettingsPrivate::get(const QString &key, QVariant *value) const +{ + if (isReadReady) + return QConfFileSettingsPrivate::get(key, value); + + return false; +} + +QStringList QWasmSettingsPrivate::children(const QString &prefix, ChildSpec spec) const +{ + return QConfFileSettingsPrivate::children(prefix, spec); +} + +void QWasmSettingsPrivate::clear() +{ + QConfFileSettingsPrivate::clear(); + emscripten_idb_async_delete("/home/web_user", + fileName().toLocal8Bit(), + reinterpret_cast<void*>(this), + QWasmSettingsPrivate_onStore, + QWasmSettingsPrivate_onError); +} + +void QWasmSettingsPrivate::sync() +{ + QConfFileSettingsPrivate::sync(); + + QFile file(fileName()); + if (file.open(QFile::ReadOnly)) { + QByteArray dataPointer = file.readAll(); + + emscripten_idb_async_store("/home/web_user", + fileName().toLocal8Bit(), + reinterpret_cast<void *>(dataPointer.data()), + dataPointer.length(), + reinterpret_cast<void*>(this), + QWasmSettingsPrivate_onStore, + QWasmSettingsPrivate_onError); + } +} + +void QWasmSettingsPrivate::flush() +{ + sync(); +} + +bool QWasmSettingsPrivate::isWritable() const +{ + return isReadReady && QConfFileSettingsPrivate::isWritable(); +} + +void QWasmSettingsPrivate::syncToLocal(const char *data, int size) +{ + QFile file(fileName()); + + if (file.open(QFile::WriteOnly)) { + file.write(data, size + 1); + QByteArray data = file.readAll(); + + emscripten_idb_async_store("/home/web_user", + fileName().toLocal8Bit(), + reinterpret_cast<void *>(data.data()), + data.length(), + reinterpret_cast<void*>(this), + QWasmSettingsPrivate_onStore, + QWasmSettingsPrivate_onError); + setReady(); + } +} + +void QWasmSettingsPrivate::loadLocal(const QByteArray &filename) +{ + emscripten_idb_async_load("/home/web_user", + filename.data(), + reinterpret_cast<void*>(this), + QWasmSettingsPrivate_onLoad, + QWasmSettingsPrivate_onError); +} + +void QWasmSettingsPrivate::setReady() +{ + isReadReady = true; + setStatus(QSettings::NoError); + QConfFileSettingsPrivate::initAccess(); +} + +QT_END_NAMESPACE +#endif // QT_NO_SETTINGS diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp index 878e007fb0..659552b72f 100644 --- a/src/corelib/io/qurl.cpp +++ b/src/corelib/io/qurl.cpp @@ -823,7 +823,7 @@ recodeFromUser(const QString &input, const ushort *actions, int from, int to) QString output; const QChar *begin = input.constData() + from; const QChar *end = input.constData() + to; - if (qt_urlRecode(output, begin, end, nullptr, actions)) + if (qt_urlRecode(output, begin, end, {}, actions)) return output; return input.mid(from, to - from); |