diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/arch/qatomic_armv6.h | 2 | ||||
-rw-r--r-- | src/corelib/codecs/qtextcodec.cpp | 9 | ||||
-rw-r--r-- | src/corelib/global/qglobal.h | 37 | ||||
-rw-r--r-- | src/corelib/io/qdir.cpp | 48 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 6 | ||||
-rw-r--r-- | src/corelib/io/qfilesystemengine_win.cpp | 7 | ||||
-rw-r--r-- | src/corelib/io/qtemporaryfile.cpp | 261 | ||||
-rw-r--r-- | src/corelib/tools/qbytearray.cpp | 4 | ||||
-rw-r--r-- | src/corelib/tools/qdatetime.cpp | 5 | ||||
-rw-r--r-- | src/corelib/tools/qline.cpp | 5 |
10 files changed, 247 insertions, 137 deletions
diff --git a/src/corelib/arch/qatomic_armv6.h b/src/corelib/arch/qatomic_armv6.h index 96b561e..dd465db 100644 --- a/src/corelib/arch/qatomic_armv6.h +++ b/src/corelib/arch/qatomic_armv6.h @@ -152,6 +152,7 @@ inline bool QBasicAtomicInt::testAndSetRelaxed(int expectedValue, int newValue) asm volatile("0:\n" "ldrex %[result], [%[_q_value]]\n" "eors %[result], %[result], %[expectedValue]\n" + "itt eq\n" "strexeq %[result], %[newValue], [%[_q_value]]\n" "teqeq %[result], #1\n" "beq 0b\n" @@ -210,6 +211,7 @@ Q_INLINE_TEMPLATE bool QBasicAtomicPointer<T>::testAndSetRelaxed(T *expectedValu asm volatile("0:\n" "ldrex %[result], [%[_q_value]]\n" "eors %[result], %[result], %[expectedValue]\n" + "itt eq\n" "strexeq %[result], %[newValue], [%[_q_value]]\n" "teqeq %[result], #1\n" "beq 0b\n" diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 985f515..dd06a2a 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -213,12 +213,13 @@ QTextCodecCleanup::~QTextCodecCleanup() destroying_is_ok = true; #endif - for (QList<QTextCodec *>::const_iterator it = all->constBegin() - ; it != all->constEnd(); ++it) { + QList<QTextCodec *> *myAll = all; + all = 0; // Otherwise the d'tor destroys the iterator + for (QList<QTextCodec *>::const_iterator it = myAll->constBegin() + ; it != myAll->constEnd(); ++it) { delete *it; } - delete all; - all = 0; + delete myAll; localeMapper = 0; #ifdef Q_DEBUG_TEXTCODEC diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index 9c7f1c6..cfe5eea 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1924,50 +1924,51 @@ public: } }; +#define Q_GLOBAL_STATIC_INIT(TYPE, NAME) \ + static QGlobalStatic<TYPE > this_ ## NAME \ + = { Q_BASIC_ATOMIC_INITIALIZER(0), false } + #define Q_GLOBAL_STATIC(TYPE, NAME) \ static TYPE *NAME() \ { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \ + Q_GLOBAL_STATIC_INIT(TYPE, _StaticVar_); \ + if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) { \ TYPE *x = new TYPE; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ + if (!this__StaticVar_.pointer.testAndSetOrdered(0, x)) \ delete x; \ else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ + static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \ } \ - return thisGlobalStatic.pointer; \ + return this__StaticVar_.pointer; \ } #define Q_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ static TYPE *NAME() \ { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \ + Q_GLOBAL_STATIC_INIT(TYPE, _StaticVar_); \ + if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) { \ TYPE *x = new TYPE ARGS; \ - if (!thisGlobalStatic.pointer.testAndSetOrdered(0, x)) \ + if (!this__StaticVar_.pointer.testAndSetOrdered(0, x)) \ delete x; \ else \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ + static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \ } \ - return thisGlobalStatic.pointer; \ + return this__StaticVar_.pointer; \ } #define Q_GLOBAL_STATIC_WITH_INITIALIZER(TYPE, NAME, INITIALIZER) \ static TYPE *NAME() \ { \ - static QGlobalStatic<TYPE > thisGlobalStatic \ - = { Q_BASIC_ATOMIC_INITIALIZER(0), false }; \ - if (!thisGlobalStatic.pointer && !thisGlobalStatic.destroyed) { \ + Q_GLOBAL_STATIC_INIT(TYPE, _StaticVar_); \ + if (!this__StaticVar_.pointer && !this__StaticVar_.destroyed) { \ QScopedPointer<TYPE > x(new TYPE); \ INITIALIZER; \ - if (thisGlobalStatic.pointer.testAndSetOrdered(0, x.data())) { \ - static QGlobalStaticDeleter<TYPE > cleanup(thisGlobalStatic); \ + if (this__StaticVar_.pointer.testAndSetOrdered(0, x.data())) { \ + static QGlobalStaticDeleter<TYPE > cleanup(this__StaticVar_); \ x.take(); \ } \ } \ - return thisGlobalStatic.pointer; \ + return this__StaticVar_.pointer; \ } #endif diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index b31cf69..c0c62e1 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -802,14 +802,23 @@ QString QDir::convertSeparators(const QString &pathName) */ QString QDir::toNativeSeparators(const QString &pathName) { - QString n(pathName); #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) - for (int i = 0; i < (int)n.length(); ++i) { - if (n[i] == QLatin1Char('/')) - n[i] = QLatin1Char('\\'); + int i = pathName.indexOf(QLatin1Char('/')); + if (i != -1) { + QString n(pathName); + + QChar * const data = n.data(); + data[i++] = QLatin1Char('\\'); + + for (; i < n.length(); ++i) { + if (data[i] == QLatin1Char('/')) + data[i] = QLatin1Char('\\'); + } + + return n; } #endif - return n; + return pathName; } /*! @@ -826,14 +835,23 @@ QString QDir::toNativeSeparators(const QString &pathName) */ QString QDir::fromNativeSeparators(const QString &pathName) { - QString n(pathName); #if defined(Q_FS_FAT) || defined(Q_OS_OS2EMX) || defined(Q_OS_SYMBIAN) - for (int i = 0; i < (int)n.length(); ++i) { - if (n[i] == QLatin1Char('\\')) - n[i] = QLatin1Char('/'); + int i = pathName.indexOf(QLatin1Char('\\')); + if (i != -1) { + QString n(pathName); + + QChar * const data = n.data(); + data[i++] = QLatin1Char('/'); + + for (; i < n.length(); ++i) { + if (data[i] == QLatin1Char('\\')) + data[i] = QLatin1Char('/'); + } + + return n; } #endif - return n; + return pathName; } /*! @@ -1615,9 +1633,13 @@ bool QDir::operator==(const QDir &dir) const if (d->filters == other->filters && d->sort == other->sort && d->nameFilters == other->nameFilters) { - d->resolveAbsoluteEntry(); - other->resolveAbsoluteEntry(); - return d->absoluteDirEntry.filePath().compare(other->absoluteDirEntry.filePath(), sensitive) == 0; + + // Assume directories are the same if path is the same + if (d->dirEntry.filePath() == other->dirEntry.filePath()) + return true; + + // Fallback to expensive canonical path computation + return canonicalPath().compare(dir.canonicalPath(), sensitive) == 0; } return false; } diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index ca42c87..ff328da 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -391,6 +391,11 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const return true; if (d->isDefaultConstructed || fileinfo.d_ptr->isDefaultConstructed) return false; + + // Assume files are the same if path is the same + if (d->fileEntry.filePath() == fileinfo.d_ptr->fileEntry.filePath()) + return true; + Qt::CaseSensitivity sensitive; if (d->fileEngine == 0 || fileinfo.d_ptr->fileEngine == 0) { if (d->fileEngine != fileinfo.d_ptr->fileEngine) // one is native, the other is a custom file-engine @@ -406,6 +411,7 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const if (fileinfo.size() != size()) //if the size isn't the same... return false; + // Fallback to expensive canonical path computation return canonicalFilePath().compare(fileinfo.canonicalFilePath(), sensitive) == 0; } diff --git a/src/corelib/io/qfilesystemengine_win.cpp b/src/corelib/io/qfilesystemengine_win.cpp index f704fc3..764ee6d 100644 --- a/src/corelib/io/qfilesystemengine_win.cpp +++ b/src/corelib/io/qfilesystemengine_win.cpp @@ -536,7 +536,7 @@ QFileSystemEntry QFileSystemEngine::absoluteName(const QFileSystemEntry &entry) // Force uppercase drive letters. ret[0] = ret.at(0).toUpper(); } - return QFileSystemEntry(ret); + return QFileSystemEntry(ret, QFileSystemEntry::FromInternalPath()); } //static @@ -1052,11 +1052,12 @@ QString QFileSystemEngine::tempPath() } if (ret.isEmpty()) { #if !defined(Q_OS_WINCE) - ret = QLatin1String("c:/tmp"); + ret = QLatin1String("C:/tmp"); #else ret = QLatin1String("/Temp"); #endif - } + } else if (ret.length() >= 2 && ret[1] == QLatin1Char(':')) + ret[0] = ret.at(0).toUpper(); // Force uppercase drive letters. return ret; } diff --git a/src/corelib/io/qtemporaryfile.cpp b/src/corelib/io/qtemporaryfile.cpp index 0855d93..e80a8b6 100644 --- a/src/corelib/io/qtemporaryfile.cpp +++ b/src/corelib/io/qtemporaryfile.cpp @@ -44,21 +44,18 @@ #ifndef QT_NO_TEMPORARYFILE #include "qplatformdefs.h" -#include "qabstractfileengine.h" #include "private/qfile_p.h" -#include "private/qabstractfileengine_p.h" #include "private/qfsfileengine_p.h" +#include "private/qsystemerror_p.h" +#include "private/qfilesystemengine_p.h" -#if !defined(Q_OS_WINCE) -# include <errno.h> +#if defined(Q_OS_SYMBIAN) +#include "private/qcore_symbian_p.h" #endif -#include <stdlib.h> -#include <time.h> -#include <ctype.h> - -#if defined(Q_OS_UNIX) -# include "private/qcore_unix_p.h" // overrides QT_OPEN +#if !defined(Q_OS_WIN) && !defined(Q_OS_SYMBIAN) +#include "private/qcore_unix_p.h" // overrides QT_OPEN +#include <errno.h> #endif #if defined(QT_BUILD_CORE_LIB) @@ -67,6 +64,30 @@ QT_BEGIN_NAMESPACE +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) +typedef ushort Char; + +static inline Char Latin1Char(char ch) +{ + return ushort(uchar(ch)); +} + +# ifdef Q_OS_WIN +typedef HANDLE NativeFileHandle; +# else // Q_OS_SYMBIAN +# ifdef SYMBIAN_ENABLE_64_BIT_FILE_SERVER_API +typedef RFile64 NativeFileHandle; +# else +typedef RFile NativeFileHandle; +# endif +# endif + +#else // POSIX +typedef char Char; +typedef char Latin1Char; +typedef int NativeFileHandle; +#endif + /* * Copyright (c) 1987, 1993 * The Regents of the University of California. All rights reserved. @@ -100,27 +121,33 @@ QT_BEGIN_NAMESPACE \internal Generates a unique file path and returns a native handle to the open file. - \a path is used as a template when generating unique paths, - \a placeholderStart and \a placeholderEnd delimit the sub-string that will - be randomized. + \a path is used as a template when generating unique paths, \a pos + identifies the position of the first character that will be replaced in the + template and \a length the number of characters that may be substituted. Returns an open handle to the newly created file if successful, an invalid handle otherwise. In both cases, the string in \a path will be changed and contain the generated path name. */ -static int createFileFromTemplate(char *const path, - char *const placeholderStart, char *const placeholderEnd) +static bool createFileFromTemplate(NativeFileHandle &file, + QFileSystemEntry::NativePath &path, size_t pos, size_t length, + QSystemError &error) { - Q_ASSERT(placeholderEnd > placeholderStart); + Q_ASSERT(length != 0); + Q_ASSERT(pos < size_t(path.length())); + Q_ASSERT(length <= size_t(path.length()) - pos); + + Char *const placeholderStart = (Char *)path.data() + pos; + Char *const placeholderEnd = placeholderStart + length; // Initialize placeholder with random chars + PID. { - char *rIter = placeholderEnd; + Char *rIter = placeholderEnd; #if defined(QT_BUILD_CORE_LIB) - qint64 pid = QCoreApplication::applicationPid(); + quint64 pid = quint64(QCoreApplication::applicationPid()); do { - *--rIter = (pid % 10) + '0'; + *--rIter = Latin1Char((pid % 10) + '0'); pid /= 10; } while (rIter != placeholderStart && pid != 0); #endif @@ -128,48 +155,93 @@ static int createFileFromTemplate(char *const path, while (rIter != placeholderStart) { char ch = char((qrand() & 0xffff) % (26 + 26)); if (ch < 26) - *--rIter = ch + 'A'; + *--rIter = Latin1Char(ch + 'A'); else - *--rIter = ch - 26 + 'a'; + *--rIter = Latin1Char(ch - 26 + 'a'); } } +#ifdef Q_OS_SYMBIAN + RFs& fs = qt_s60GetRFs(); +#endif + for (;;) { // Atomically create file and obtain handle -#ifndef Q_OS_WIN - { - int fd = QT_OPEN(path, QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, 0600); - if (fd != -1) - return fd; - if (errno != EEXIST) - return -1; +#if defined(Q_OS_WIN) + file = CreateFile((const wchar_t *)path.constData(), + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_NEW, + FILE_ATTRIBUTE_NORMAL, NULL); + + if (file != INVALID_HANDLE_VALUE) + return true; + + DWORD err = GetLastError(); + if (err != ERROR_FILE_EXISTS) { + error = QSystemError(err, QSystemError::NativeError); + return false; + } +#elif defined(Q_OS_SYMBIAN) + TInt err = file.Create(fs, qt_QString2TPtrC(path), + EFileRead | EFileWrite | EFileShareReadersOrWriters); + + if (err == KErrNone) + return true; + + if (err != KErrAlreadyExists) { + error = QSystemError(err, QSystemError::NativeError); + return false; + } +#else // POSIX + file = QT_OPEN(path.constData(), + QT_OPEN_CREAT | O_EXCL | QT_OPEN_RDWR | QT_OPEN_LARGEFILE, + 0600); + + if (file != -1) + return true; + + int err = errno; + if (err != EEXIST) { + error = QSystemError(err, QSystemError::NativeError); + return false; } -#else - if (!QFileInfo(QLatin1String(path)).exists()) - return 1; #endif /* tricky little algorwwithm for backward compatibility */ - for (char *iter = placeholderStart;;) { + for (Char *iter = placeholderStart;;) { // Character progression: [0-9] => 'a' ... 'z' => 'A' .. 'Z' // String progression: "ZZaiC" => "aabiC" - if (*iter == 'Z') { - *iter++ = 'a'; - if (iter == placeholderEnd) - return -1; - } else { - if (isdigit(*iter)) - *iter = 'a'; - else if (*iter == 'z') /* inc from z to A */ - *iter = 'A'; - else { + switch (char(*iter)) { + case 'Z': + // Rollover, advance next character + *iter = Latin1Char('a'); + if (++iter == placeholderEnd) { + // Out of alternatives. Return file exists error, previously set. + error = QSystemError(err, QSystemError::NativeError); + return false; + } + + continue; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + *iter = Latin1Char('a'); + break; + + case 'z': + // increment 'z' to 'A' + *iter = Latin1Char('A'); + break; + + default: ++*iter; - } - break; + break; } + break; } } - /*NOTREACHED*/ + + Q_ASSERT(false); } //************* QTemporaryFileEngine @@ -250,7 +322,7 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) QString qfilename = d->fileEntry.filePath(); - // Find placeholder string. + // Ensure there is a placeholder mask uint phPos = qfilename.length(); uint phLength = 0; @@ -262,70 +334,73 @@ bool QTemporaryFileEngine::open(QIODevice::OpenMode openMode) continue; } - if (qfilename[phPos] == QLatin1Char('/') - || phLength >= 6) { + if (phLength >= 6 + || qfilename[phPos] == QLatin1Char('/')) { ++phPos; break; } + // start over phLength = 0; } - QStringRef prefix, suffix; - if (phLength < 6) { - qfilename += QLatin1Char('.'); - prefix = QStringRef(&qfilename); - phLength = 6; - } else { - prefix = qfilename.leftRef(phPos); - suffix = qfilename.midRef(phPos + phLength); - } + if (phLength < 6) + qfilename.append(QLatin1String(".XXXXXX")); - QByteArray filename = prefix.toLocal8Bit(); + // "Nativify" :-) + QFileSystemEntry::NativePath filename = QFileSystemEngine::absoluteName( + QFileSystemEntry(qfilename, QFileSystemEntry::FromInternalPath())) + .nativeFilePath(); + + // Find mask in native path phPos = filename.length(); - if (suffix.isEmpty()) - filename.resize(phPos + phLength); - else - filename.insert(phPos + phLength, suffix.toLocal8Bit()); - - char *path = filename.data(); - -#ifndef Q_OS_WIN - int fd = createFileFromTemplate(path, path + phPos, path + phPos + phLength); - if (fd != -1) { - // First open the fd as an external file descriptor to - // initialize the engine properly. - if (QFSFileEngine::open(openMode, fd)) { - - // Allow the engine to close the handle even if it's "external". - d->closeFileHandle = true; - - // Restore the file names (open() resets them). - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(path, filename.length())); //note that filename is NOT a native path - filePathIsTemplate = false; - return true; + phLength = 0; + while (phPos != 0) { + --phPos; + + if (filename[phPos] == Latin1Char('X')) { + ++phLength; + continue; } - QT_CLOSE(fd); - } - setError(errno == EMFILE ? QFile::ResourceError : QFile::OpenError, qt_error_string(errno)); - return false; -#else - if (createFileFromTemplate(path, path + phPos, path + phPos + phLength) == -1) { - return false; + if (phLength >= 6) { + ++phPos; + break; + } + + // start over + phLength = 0; } - QString template_ = d->fileEntry.filePath(); - d->fileEntry = QFileSystemEntry(QString::fromLocal8Bit(path, filename.length())); + Q_ASSERT(phLength >= 6); - if (QFSFileEngine::open(openMode)) { - filePathIsTemplate = false; - return true; + QSystemError error; +#if defined(Q_OS_WIN) + NativeFileHandle &file = d->fileHandle; +#elif defined(Q_OS_SYMBIAN) + NativeFileHandle &file = d->symbianFile; +#else // POSIX + NativeFileHandle &file = d->fd; +#endif + + if (!createFileFromTemplate(file, filename, phPos, phLength, error)) { + setError(QFile::OpenError, error.toString()); + return false; } - d->fileEntry = QFileSystemEntry(template_); - return false; + d->fileEntry = QFileSystemEntry(filename, QFileSystemEntry::FromNativePath()); + +#if !defined(Q_OS_WIN) + d->closeFileHandle = true; #endif + + filePathIsTemplate = false; + + d->openMode = openMode; + d->lastFlushFailed = false; + d->tried_stat = 0; + + return true; } bool QTemporaryFileEngine::remove() diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 767b713..a8edea4 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -541,7 +541,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) forever { ulong alloc = len; - if (len >= (1 << 31) - sizeof(QByteArray::Data)) { + if (len >= ulong(1 << 31) - sizeof(QByteArray::Data)) { //QByteArray does not support that huge size anyway. qWarning("qUncompress: Input data is corrupted"); return QByteArray(); @@ -561,7 +561,7 @@ QByteArray qUncompress(const uchar* data, int nbytes) switch (res) { case Z_OK: if (len != alloc) { - if (len >= (1 << 31) - sizeof(QByteArray::Data)) { + if (len >= ulong(1 << 31) - sizeof(QByteArray::Data)) { //QByteArray does not support that huge size anyway. qWarning("qUncompress: Input data is corrupted"); return QByteArray(); diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 085103c..8e4fb32 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -4040,8 +4040,11 @@ static QDateTimePrivate::Spec utcToLocal(QDate &date, QTime &time) RTz tz; User::LeaveIfError(tz.Connect()); CleanupClosePushL(tz); - res.tm_isdst = tz.IsDaylightSavingOnL(*tz.GetTimeZoneIdL(),utcTTime); + CTzId *tzId = tz.GetTimeZoneIdL(); + CleanupStack::PushL(tzId); + res.tm_isdst = tz.IsDaylightSavingOnL(*tzId,utcTTime); User::LeaveIfError(tz.ConvertToLocalTime(utcTTime)); + CleanupStack::PopAndDestroy(tzId); CleanupStack::PopAndDestroy(&tz)); if (KErrNone == err) { TDateTime localDateTime = utcTTime.DateTime(); diff --git a/src/corelib/tools/qline.cpp b/src/corelib/tools/qline.cpp index 0f67652..af3b7d5 100644 --- a/src/corelib/tools/qline.cpp +++ b/src/corelib/tools/qline.cpp @@ -564,9 +564,8 @@ qreal QLineF::length() const Returns the angle of the line in degrees. - The return value will be in the range of values from 0.0 up to but not - including 360.0. The angles are measured counter-clockwise from a point - on the x-axis to the right of the origin (x > 0). + Positive values for the angles mean counter-clockwise while negative values + mean the clockwise direction. Zero degrees is at the 3 o'clock position. \sa setAngle() */ |