summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@nokia.com>2010-03-01 13:03:22 (GMT)
committerPaul Olav Tvete <paul.tvete@nokia.com>2010-03-01 13:17:53 (GMT)
commit19095f432ef7ef424ea8dc89b19e43ed9f031b3e (patch)
tree159654fbd2066eaea6d6fe78efc9726b5959eb3d /src/corelib
parent196e1484c22f6347061fa433987a86d90e178a55 (diff)
parent236c3ad7bacf165069b834b62fede6b147cfaf03 (diff)
downloadQt-19095f432ef7ef424ea8dc89b19e43ed9f031b3e.zip
Qt-19095f432ef7ef424ea8dc89b19e43ed9f031b3e.tar.gz
Qt-19095f432ef7ef424ea8dc89b19e43ed9f031b3e.tar.bz2
Merge remote branch 'qt/4.7' into lighthouse-4.7
Conflicts: configure src/gui/egl/qegl.cpp src/gui/kernel/qdnd_p.h
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/animation/qabstractanimation.cpp9
-rw-r--r--src/corelib/animation/qabstractanimation_p.h62
-rw-r--r--src/corelib/animation/qpropertyanimation.cpp6
-rw-r--r--src/corelib/animation/qvariantanimation.cpp4
-rw-r--r--src/corelib/arch/qatomic_s390.h16
-rw-r--r--src/corelib/arch/qatomic_symbian.h2
-rw-r--r--src/corelib/arch/sparc/arch.pri2
-rw-r--r--src/corelib/codecs/qsimplecodec.cpp2
-rw-r--r--src/corelib/codecs/qtextcodec.cpp147
-rw-r--r--src/corelib/codecs/qtextcodec.h16
-rw-r--r--src/corelib/concurrent/qfuture.h2
-rw-r--r--src/corelib/concurrent/qfuturewatcher.cpp7
-rw-r--r--src/corelib/corelib.pro38
-rw-r--r--src/corelib/global/qglobal.cpp2
-rw-r--r--src/corelib/global/qglobal.h23
-rw-r--r--src/corelib/global/qlibraryinfo.cpp8
-rw-r--r--src/corelib/global/qlibraryinfo.h3
-rw-r--r--src/corelib/global/qmalloc.cpp1
-rw-r--r--src/corelib/global/qnamespace.h8
-rw-r--r--src/corelib/global/qnamespace.qdoc16
-rw-r--r--src/corelib/io/io.pri2
-rw-r--r--src/corelib/io/qdatastream.cpp238
-rw-r--r--src/corelib/io/qdatastream.h7
-rw-r--r--src/corelib/io/qdataurl.cpp101
-rw-r--r--src/corelib/io/qdataurl_p.h67
-rw-r--r--src/corelib/io/qdir.cpp382
-rw-r--r--src/corelib/io/qdir.h5
-rw-r--r--src/corelib/io/qfileinfo.cpp303
-rw-r--r--src/corelib/io/qfileinfo_p.h21
-rw-r--r--src/corelib/io/qfilesystemwatcher.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_dnotify.cpp13
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.cpp21
-rw-r--r--src/corelib/io/qfilesystemwatcher_inotify.cpp2
-rw-r--r--src/corelib/io/qfilesystemwatcher_kqueue.cpp20
-rw-r--r--src/corelib/io/qfsfileengine.cpp27
-rw-r--r--src/corelib/io/qfsfileengine_iterator_unix.cpp20
-rw-r--r--src/corelib/io/qfsfileengine_unix.cpp2
-rw-r--r--src/corelib/io/qfsfileengine_win.cpp22
-rw-r--r--src/corelib/io/qiodevice.cpp4
-rw-r--r--src/corelib/io/qprocess_symbian.cpp2
-rw-r--r--src/corelib/io/qresource.cpp9
-rw-r--r--src/corelib/io/qurl.cpp34
-rw-r--r--src/corelib/io/qurl.h7
-rw-r--r--src/corelib/kernel/qabstractitemmodel.cpp2
-rw-r--r--src/corelib/kernel/qcoreapplication_win.cpp12
-rw-r--r--src/corelib/kernel/qcoreevent.cpp3
-rw-r--r--src/corelib/kernel/qcoreevent.h1
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp40
-rw-r--r--src/corelib/kernel/qmetaobject.cpp105
-rw-r--r--src/corelib/kernel/qmetaobject_p.h27
-rw-r--r--src/corelib/kernel/qmetatype.cpp280
-rw-r--r--src/corelib/kernel/qmetatype.h28
-rw-r--r--src/corelib/kernel/qobject.cpp48
-rw-r--r--src/corelib/kernel/qobject_p.h4
-rw-r--r--src/corelib/kernel/qvariant.cpp57
-rw-r--r--src/corelib/kernel/qvariant.h12
-rw-r--r--src/corelib/plugin/qlibrary.cpp16
-rw-r--r--src/corelib/thread/qmutex.cpp7
-rw-r--r--src/corelib/thread/qorderedmutexlocker_p.h8
-rw-r--r--src/corelib/tools/qbytearray.cpp20
-rw-r--r--src/corelib/tools/qbytearray.h2
-rw-r--r--src/corelib/tools/qcontiguouscache.h37
-rw-r--r--src/corelib/tools/qeasingcurve.cpp69
-rw-r--r--src/corelib/tools/qeasingcurve.h11
-rw-r--r--src/corelib/tools/qhash.cpp17
-rw-r--r--src/corelib/tools/qhash.h10
-rw-r--r--src/corelib/tools/qlinkedlist.cpp5
-rw-r--r--src/corelib/tools/qlinkedlist.h7
-rw-r--r--src/corelib/tools/qlist.cpp135
-rw-r--r--src/corelib/tools/qlist.h225
-rw-r--r--src/corelib/tools/qlocale.cpp23
-rw-r--r--src/corelib/tools/qlocale_symbian.cpp6
-rw-r--r--src/corelib/tools/qmap.cpp5
-rw-r--r--src/corelib/tools/qmap.h10
-rw-r--r--src/corelib/tools/qpoint.cpp2
-rw-r--r--src/corelib/tools/qregexp.cpp11
-rw-r--r--src/corelib/tools/qscopedpointer.cpp55
-rw-r--r--src/corelib/tools/qset.h8
-rw-r--r--src/corelib/tools/qsharedpointer_impl.h54
-rw-r--r--src/corelib/tools/qsimd.cpp246
-rw-r--r--src/corelib/tools/qsimd_p.h126
-rw-r--r--src/corelib/tools/qstring.cpp243
-rw-r--r--src/corelib/tools/qstring.h16
-rw-r--r--src/corelib/tools/qstringbuilder.h40
-rw-r--r--src/corelib/tools/qstringlist.cpp10
-rw-r--r--src/corelib/tools/qvector.cpp5
-rw-r--r--src/corelib/tools/qvector.h11
-rw-r--r--src/corelib/tools/tools.pri2
-rw-r--r--src/corelib/xml/qxmlstream.cpp7
-rw-r--r--src/corelib/xml/qxmlstream_p.h2
90 files changed, 2675 insertions, 1080 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp
index cedb43f..f834a80 100644
--- a/src/corelib/animation/qabstractanimation.cpp
+++ b/src/corelib/animation/qabstractanimation.cpp
@@ -161,7 +161,9 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_THREAD
Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
+#endif
QUnifiedTimer::QUnifiedTimer() :
QObject(), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
@@ -173,12 +175,17 @@ QUnifiedTimer::QUnifiedTimer() :
QUnifiedTimer *QUnifiedTimer::instance()
{
QUnifiedTimer *inst;
+#ifndef QT_NO_THREAD
if (!unifiedTimer()->hasLocalData()) {
inst = new QUnifiedTimer;
unifiedTimer()->setLocalData(inst);
} else {
inst = unifiedTimer()->localData();
}
+#else
+ static QUnifiedTimer unifiedTimer;
+ inst = &unifiedTimer;
+#endif
return inst;
}
@@ -242,7 +249,7 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event)
animationTimer.stop();
isPauseTimerActive = false;
// invalidate the start reference time
- time = QTime();
+ time.invalidate();
} else {
restartAnimationTimer();
if (!time.isValid()) {
diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h
index ad35d89..8bc3224 100644
--- a/src/corelib/animation/qabstractanimation_p.h
+++ b/src/corelib/animation/qabstractanimation_p.h
@@ -58,6 +58,10 @@
#include <QtCore/qtimer.h>
#include <private/qobject_p.h>
+#ifdef Q_OS_WIN
+#include <qt_windows.h>
+#endif
+
#ifndef QT_NO_ANIMATION
QT_BEGIN_NAMESPACE
@@ -109,6 +113,61 @@ private:
Q_DECLARE_PUBLIC(QAbstractAnimation)
};
+class ElapsedTimer
+{
+public:
+ ElapsedTimer() {
+ invalidate();
+ }
+
+ void invalidate() {
+ m_started = -1;
+ }
+
+ bool isValid() const {
+ return m_started >= 0;
+ }
+
+ void start() {
+ m_started = getTickCount_sys();
+ }
+
+ qint64 elapsed() const {
+ qint64 current = getTickCount_sys();
+ qint64 delta = current - m_started;
+ if (delta < 0)
+ delta += getPeriod_sys(); //we wrapped around
+ return delta;
+ }
+
+private:
+ enum {
+ MSECS_PER_HOUR = 3600000,
+ MSECS_PER_MIN = 60000
+ };
+
+ qint64 m_started;
+
+ quint64 getPeriod_sys() const {
+#ifdef Q_OS_WIN
+ return Q_UINT64_C(0x100000000);
+#else
+ // fallback
+ return 86400 * 1000;
+#endif
+ }
+
+ qint64 getTickCount_sys() const {
+#ifdef Q_OS_WIN
+ return ::GetTickCount();
+#else
+ // fallback
+ const QTime t = QTime::currentTime();
+ return MSECS_PER_HOUR * t.hour() + MSECS_PER_MIN * t.minute() + 1000 * t.second() + t.msec();
+#endif
+ }
+};
+
class QUnifiedTimer : public QObject
{
@@ -162,7 +221,8 @@ private:
// timer used to delay the check if we should start/stop the animation timer
QBasicTimer startStopAnimationTimer;
- QTime time;
+ ElapsedTimer time;
+
int lastTick;
int timingInterval;
int currentAnimationIdx;
diff --git a/src/corelib/animation/qpropertyanimation.cpp b/src/corelib/animation/qpropertyanimation.cpp
index cfd7cc2..37b79ba 100644
--- a/src/corelib/animation/qpropertyanimation.cpp
+++ b/src/corelib/animation/qpropertyanimation.cpp
@@ -118,7 +118,9 @@ void QPropertyAnimationPrivate::updateMetaProperty()
propertyType = QVariant::Invalid;
if (!targetValue->dynamicPropertyNames().contains(propertyName))
qWarning("QPropertyAnimation: you're trying to animate a non-existing property %s of your QObject", propertyName.constData());
- }
+ } else if (!targetValue->metaObject()->property(propertyIndex).isWritable()) {
+ qWarning("QPropertyAnimation: you're trying to animate the non-writable property %s of your QObject", propertyName.constData());
+ }
}
void QPropertyAnimationPrivate::updateProperty(const QVariant &newValue)
@@ -265,7 +267,9 @@ void QPropertyAnimation::updateState(QAbstractAnimation::State newState,
QPropertyAnimation *animToStop = 0;
{
+#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet(&staticMetaObject));
+#endif
typedef QPair<QObject *, QByteArray> QPropertyAnimationPair;
typedef QHash<QPropertyAnimationPair, QPropertyAnimation*> QPropertyAnimationHash;
static QPropertyAnimationHash hash;
diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp
index 115edbe..173802d 100644
--- a/src/corelib/animation/qvariantanimation.cpp
+++ b/src/corelib/animation/qvariantanimation.cpp
@@ -431,7 +431,9 @@ void QVariantAnimation::registerInterpolator(QVariantAnimation::Interpolator fun
{
// will override any existing interpolators
QInterpolatorVector *interpolators = registeredInterpolators();
+#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
+#endif
if (int(interpolationType) >= interpolators->count())
interpolators->resize(int(interpolationType) + 1);
interpolators->replace(interpolationType, func);
@@ -446,7 +448,9 @@ template<typename T> static inline QVariantAnimation::Interpolator castToInterpo
QVariantAnimation::Interpolator QVariantAnimationPrivate::getInterpolator(int interpolationType)
{
QInterpolatorVector *interpolators = registeredInterpolators();
+#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet(interpolators));
+#endif
QVariantAnimation::Interpolator ret = 0;
if (interpolationType < interpolators->count()) {
ret = interpolators->at(interpolationType);
diff --git a/src/corelib/arch/qatomic_s390.h b/src/corelib/arch/qatomic_s390.h
index 21f5037..273c17b 100644
--- a/src/corelib/arch/qatomic_s390.h
+++ b/src/corelib/arch/qatomic_s390.h
@@ -366,11 +366,9 @@ template <typename T>
Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelaxed(T *newValue)
{
#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
- "", "bcr 15,0\n");
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "");
#else
- return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
- "", "bcr 15,0\n");
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "");
#endif
}
@@ -378,9 +376,9 @@ template <typename T>
Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreAcquire(T *newValue)
{
#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr", "", "");
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "", "bcr 15,0 \n");
#else
- return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr", "", "");
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "", "bcr 15,0 \n");
#endif
}
@@ -388,11 +386,9 @@ template <typename T>
Q_INLINE_TEMPLATE T* QBasicAtomicPointer<T>::fetchAndStoreRelease(T *newValue)
{
#ifndef __s390x__
- return (T*)__CS_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (int)newValue, "lr",
- "bcr 15,0 \n", "");
+ return (T*)__CS_OLD_LOOP(&_q_value, (int)newValue, "lr", "bcr 15,0 \n", "");
#else
- return (T*)__CSG_OLD_LOOP(reinterpret_cast<volatile long*>(_q_value), (long)newValue, "lgr",
- "bcr 15,0\n", "");
+ return (T*)__CSG_OLD_LOOP(&_q_value, (long)newValue, "lgr", "bcr 15,0\n", "");
#endif
}
diff --git a/src/corelib/arch/qatomic_symbian.h b/src/corelib/arch/qatomic_symbian.h
index f1d332f..fa4e4a9 100644
--- a/src/corelib/arch/qatomic_symbian.h
+++ b/src/corelib/arch/qatomic_symbian.h
@@ -42,7 +42,7 @@
#ifndef QATOMIC_SYMBIAN_H
#define QATOMIC_SYMBIAN_H
-#include <qglobal.h>
+#include <QtCore/qglobal.h>
#include <e32std.h>
QT_BEGIN_HEADER
diff --git a/src/corelib/arch/sparc/arch.pri b/src/corelib/arch/sparc/arch.pri
index 3113dd3..9bb3a88 100644
--- a/src/corelib/arch/sparc/arch.pri
+++ b/src/corelib/arch/sparc/arch.pri
@@ -1,7 +1,7 @@
#
# SPARC architecture
#
-*-64 {
+*-64* {
SOURCES += $$QT_ARCH_CPP/qatomic64.s
}
else {
diff --git a/src/corelib/codecs/qsimplecodec.cpp b/src/corelib/codecs/qsimplecodec.cpp
index 445565a..4cc7912 100644
--- a/src/corelib/codecs/qsimplecodec.cpp
+++ b/src/corelib/codecs/qsimplecodec.cpp
@@ -681,7 +681,7 @@ QByteArray QSimpleTextCodec::convertFromUnicode(const QChar *in, int length, Con
int u;
const QChar* ucp = in;
unsigned char* rp = (unsigned char *)r.data();
- const unsigned char* rmp = (const unsigned char *)reverseMap->data();
+ const unsigned char* rmp = (const unsigned char *)reverseMap->constData();
int rmsize = (int) reverseMap->size();
while(i--)
{
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index b63a82e..ca5e658 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -79,7 +79,8 @@
# endif
#endif // QT_NO_CODECS
#include "qlocale.h"
-#include "private/qmutexpool_p.h"
+#include "qmutex.h"
+#include "qhash.h"
#include <stdlib.h>
#include <ctype.h>
@@ -172,6 +173,7 @@ static QTextCodec *createForMib(int mib)
}
static QList<QTextCodec*> *all = 0;
+static int clearCaches = 0; // flags specifying if caches should be invalided: 0x1 codecForName, 0x2 codecForMib
#ifdef Q_DEBUG_TEXTCODEC
static bool destroying_is_ok = false;
#endif
@@ -659,13 +661,13 @@ static void setupLocaleMapper()
#endif
}
-
-static void setup()
-{
#ifndef QT_NO_THREAD
- QMutexLocker locker(QMutexPool::globalInstanceGet(&all));
+Q_GLOBAL_STATIC_WITH_ARGS(QMutex, textCodecsMutex, (QMutex::Recursive));
#endif
+// textCodecsMutex need to be locked to enter this function
+static void setup()
+{
if (all)
return;
@@ -903,8 +905,6 @@ QTextCodec::ConverterState::~ConverterState()
*/
/*!
- \nonreentrant
-
Constructs a QTextCodec, and gives it the highest precedence. The
QTextCodec should always be constructed on the heap (i.e. with \c
new). Qt takes ownership and will delete it when the application
@@ -912,6 +912,9 @@ QTextCodec::ConverterState::~ConverterState()
*/
QTextCodec::QTextCodec()
{
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
all->prepend(this);
}
@@ -929,8 +932,13 @@ QTextCodec::~QTextCodec()
if (!destroying_is_ok)
qWarning("QTextCodec::~QTextCodec: Called by application");
#endif
- if (all)
+ if (all) {
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
all->removeAll(this);
+ clearCaches = 0x1 | 0x2;
+ }
}
/*!
@@ -951,19 +959,38 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
if (name.isEmpty())
return 0;
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
+ static QHash <QByteArray, QTextCodec *> cache;
+ if (clearCaches & 0x1) {
+ cache.clear();
+ clearCaches &= ~0x1;
+ }
+ QTextCodec *codec = cache.value(name);
+ if (codec)
+ return codec;
+
for (int i = 0; i < all->size(); ++i) {
QTextCodec *cursor = all->at(i);
- if (nameMatch(cursor->name(), name))
+ if (nameMatch(cursor->name(), name)) {
+ cache.insert(name, cursor);
return cursor;
+ }
QList<QByteArray> aliases = cursor->aliases();
for (int y = 0; y < aliases.size(); ++y)
- if (nameMatch(aliases.at(y), name))
+ if (nameMatch(aliases.at(y), name)) {
+ cache.insert(name, cursor);
return cursor;
+ }
}
- return createForName(name);
+ codec = createForName(name);
+ if (codec)
+ cache.insert(name, codec);
+ return codec;
}
@@ -973,21 +1000,39 @@ QTextCodec *QTextCodec::codecForName(const QByteArray &name)
*/
QTextCodec* QTextCodec::codecForMib(int mib)
{
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
- // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map
- // this correctly for compatibility.
- if (mib == 1000)
- mib = 1015;
+ static QHash <int, QTextCodec *> cache;
+ if (clearCaches & 0x2) {
+ cache.clear();
+ clearCaches &= ~0x2;
+ }
+ QTextCodec *codec = cache.value(mib);
+ if (codec)
+ return codec;
QList<QTextCodec*>::ConstIterator i;
for (int i = 0; i < all->size(); ++i) {
QTextCodec *cursor = all->at(i);
- if (cursor->mibEnum() == mib)
+ if (cursor->mibEnum() == mib) {
+ cache.insert(mib, cursor);
return cursor;
+ }
}
- return createForMib(mib);
+ codec = createForMib(mib);
+
+ // Qt 3 used 1000 (mib for UCS2) as its identifier for the utf16 codec. Map
+ // this correctly for compatibility.
+ if (!codec && mib == 1000)
+ return codecForMib(1015);
+
+ if (codec)
+ cache.insert(mib, codec);
+ return codec;
}
/*!
@@ -1001,6 +1046,9 @@ QTextCodec* QTextCodec::codecForMib(int mib)
*/
QList<QByteArray> QTextCodec::availableCodecs()
{
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
QList<QByteArray> codecs;
@@ -1008,6 +1056,11 @@ QList<QByteArray> QTextCodec::availableCodecs()
codecs += all->at(i)->name();
codecs += all->at(i)->aliases();
}
+
+#ifndef QT_NO_THREAD
+ locker.unlock();
+#endif
+
#ifndef QT_NO_TEXTCODECPLUGIN
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -1031,11 +1084,19 @@ QList<QByteArray> QTextCodec::availableCodecs()
*/
QList<int> QTextCodec::availableMibs()
{
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
QList<int> codecs;
for (int i = 0; i < all->size(); ++i)
codecs += all->at(i)->mibEnum();
+
+#ifndef QT_NO_THREAD
+ locker.unlock();
+#endif
+
#ifndef QT_NO_TEXTCODECPLUGIN
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -1082,6 +1143,9 @@ QTextCodec* QTextCodec::codecForLocale()
if (localeMapper)
return localeMapper;
+#ifndef QT_NO_THREAD
+ QMutexLocker locker(textCodecsMutex());
+#endif
setup();
return localeMapper;
@@ -1163,6 +1227,19 @@ QTextDecoder* QTextCodec::makeDecoder() const
return new QTextDecoder(this);
}
+/*!
+ Creates a QTextDecoder with a specified \a flags to decode chunks
+ of \c{char *} data to create chunks of Unicode data.
+
+ The caller is responsible for deleting the returned object.
+
+ \since 4.7
+*/
+QTextDecoder* QTextCodec::makeDecoder(QTextCodec::ConversionFlags flags) const
+{
+ return new QTextDecoder(this, flags);
+}
+
/*!
Creates a QTextEncoder which stores enough state to encode chunks
@@ -1176,6 +1253,19 @@ QTextEncoder* QTextCodec::makeEncoder() const
}
/*!
+ Creates a QTextEncoder with a specified \a flags to encode chunks
+ of Unicode data as \c{char *} data.
+
+ The caller is responsible for deleting the returned object.
+
+ \since 4.7
+*/
+QTextEncoder* QTextCodec::makeEncoder(QTextCodec::ConversionFlags flags) const
+{
+ return new QTextEncoder(this, flags);
+}
+
+/*!
\fn QByteArray QTextCodec::fromUnicode(const QChar *input, int number,
ConverterState *state) const
@@ -1316,6 +1406,17 @@ QString QTextCodec::toUnicode(const char *chars) const
*/
/*!
+ Constructs a text encoder for the given \a codec and conversion \a flags.
+
+ \since 4.7
+*/
+QTextEncoder::QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags)
+ : c(codec), state()
+{
+ state.flags = flags;
+}
+
+/*!
Destroys the encoder.
*/
QTextEncoder::~QTextEncoder()
@@ -1392,6 +1493,18 @@ QByteArray QTextEncoder::fromUnicode(const QString& uc, int& lenInOut)
*/
/*!
+ Constructs a text decoder for the given \a codec and conversion \a flags.
+
+ \since 4.7
+*/
+
+QTextDecoder::QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags)
+ : c(codec), state()
+{
+ state.flags = flags;
+}
+
+/*!
Destroys the decoder.
*/
QTextDecoder::~QTextDecoder()
diff --git a/src/corelib/codecs/qtextcodec.h b/src/corelib/codecs/qtextcodec.h
index a099dd9..e37527d 100644
--- a/src/corelib/codecs/qtextcodec.h
+++ b/src/corelib/codecs/qtextcodec.h
@@ -85,9 +85,6 @@ public:
static QTextCodec *codecForUtfText(const QByteArray &ba);
static QTextCodec *codecForUtfText(const QByteArray &ba, QTextCodec *defaultCodec);
- QTextDecoder* makeDecoder() const;
- QTextEncoder* makeEncoder() const;
-
bool canEncode(QChar) const;
bool canEncode(const QString&) const;
@@ -120,6 +117,12 @@ public:
QByteArray fromUnicode(const QChar *in, int length, ConverterState *state = 0) const
{ return convertFromUnicode(in, length, state); }
+ // ### Qt 5: merge these functions.
+ QTextDecoder* makeDecoder() const;
+ QTextDecoder* makeDecoder(ConversionFlags flags) const;
+ QTextEncoder* makeEncoder() const;
+ QTextEncoder* makeEncoder(ConversionFlags flags) const;
+
virtual QByteArray name() const = 0;
virtual QList<QByteArray> aliases() const;
virtual int mibEnum() const = 0;
@@ -157,6 +160,7 @@ class Q_CORE_EXPORT QTextEncoder {
Q_DISABLE_COPY(QTextEncoder)
public:
explicit QTextEncoder(const QTextCodec *codec) : c(codec), state() {}
+ QTextEncoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags);
~QTextEncoder();
QByteArray fromUnicode(const QString& str);
QByteArray fromUnicode(const QChar *uc, int len);
@@ -167,17 +171,13 @@ public:
private:
const QTextCodec *c;
QTextCodec::ConverterState state;
-
- friend class QXmlStreamWriter;
- friend class QXmlStreamWriterPrivate;
- friend class QCoreXmlStreamWriter;
- friend class QCoreXmlStreamWriterPrivate;
};
class Q_CORE_EXPORT QTextDecoder {
Q_DISABLE_COPY(QTextDecoder)
public:
explicit QTextDecoder(const QTextCodec *codec) : c(codec), state() {}
+ QTextDecoder(const QTextCodec *codec, QTextCodec::ConversionFlags flags);
~QTextDecoder();
QString toUnicode(const char* chars, int len);
QString toUnicode(const QByteArray &ba);
diff --git a/src/corelib/concurrent/qfuture.h b/src/corelib/concurrent/qfuture.h
index e402335..02ae40a 100644
--- a/src/corelib/concurrent/qfuture.h
+++ b/src/corelib/concurrent/qfuture.h
@@ -111,7 +111,7 @@ public:
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
diff --git a/src/corelib/concurrent/qfuturewatcher.cpp b/src/corelib/concurrent/qfuturewatcher.cpp
index 3065205..3b808b8 100644
--- a/src/corelib/concurrent/qfuturewatcher.cpp
+++ b/src/corelib/concurrent/qfuturewatcher.cpp
@@ -499,6 +499,13 @@ void QFutureWatcherBasePrivate::sendCallOutEvent(QFutureCallOutEvent *event)
/*! \fn void QFutureWatcher::setFuture(const QFuture<T> &future)
Starts watching the given \a future.
+
+ One of the signals might be emitted for the current state of the
+ \a future. For example, if the future is already stopped, the
+ finished signal will be emitted.
+
+ To avoid a race condition, it is important to call this function
+ \i after doing the connections.
*/
/*! \fn QFuture<T> QFutureWatcher::future() const
diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro
index 9a15bf1..df9a463 100644
--- a/src/corelib/corelib.pro
+++ b/src/corelib/corelib.pro
@@ -35,4 +35,42 @@ symbian: {
# Workaroud for problems with paging this dll
MMP_RULES -= PAGED
MMP_RULES *= UNPAGED
+
+ # Partial upgrade SIS file
+ vendorinfo = \
+ "&EN" \
+ "; Localised Vendor name" \
+ "%{\"Nokia, Qt\"}" \
+ " " \
+ "; Unique Vendor name" \
+ ":\"Nokia, Qt\"" \
+ " "
+ pu_header = "; Partial upgrade package for testing QtCore changes without reinstalling everything" \
+ "$${LITERAL_HASH}{\"Qt corelib\"}, (0x2001E61C), $${QT_MAJOR_VERSION},$${QT_MINOR_VERSION},$${QT_PATCH_VERSION}, TYPE=PU"
+ partial_upgrade.pkg_prerules = pu_header vendorinfo
+ partial_upgrade.sources = qtcore.dll
+ partial_upgrade.path = c:/sys/bin
+ DEPLOYMENT = partial_upgrade $$DEPLOYMENT
+}
+
+mmx {
+ DEFINES += QT_HAVE_MMX
+}
+3dnow {
+ DEFINES += QT_HAVE_3DNOW
+}
+sse {
+ DEFINES += QT_HAVE_SSE
+ DEFINES += QT_HAVE_MMXEXT
}
+sse2 {
+ DEFINES += QT_HAVE_SSE2
+}
+iwmmxt {
+ DEFINES += QT_HAVE_IWMMXT
+}
+neon {
+ DEFINES += QT_HAVE_NEON
+ QMAKE_CXXFLAGS *= -mfpu=neon
+}
+
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index 9af9cce..74d39bd 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -2003,7 +2003,6 @@ void qt_check_pointer(const char *n, int l)
qWarning("In file %s, line %d: Out of memory", n, l);
}
-#ifndef QT_NO_EXCEPTIONS
/* \internal
Allows you to throw an exception without including <new>
Called internally from Q_CHECK_PTR on certain OS combinations
@@ -2012,7 +2011,6 @@ void qBadAlloc()
{
QT_THROW(std::bad_alloc());
}
-#endif
/*
The Q_ASSERT macro calls this function when the test fails.
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 471a66e..e9ed0e6 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -44,11 +44,11 @@
#include <stddef.h>
-#define QT_VERSION_STR "4.6.2"
+#define QT_VERSION_STR "4.7.0"
/*
QT_VERSION is (major << 16) + (minor << 8) + patch.
*/
-#define QT_VERSION 0x040602
+#define QT_VERSION 0x040700
/*
can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0))
*/
@@ -275,7 +275,7 @@ namespace QT_NAMESPACE {}
# endif
#endif
-#ifdef AUTODETECT_COCOA
+#ifdef QT_AUTODETECT_COCOA
# ifdef Q_OS_MAC64
# define QT_MAC_USE_COCOA 1
# define QT_BUILD_KEY QT_BUILD_KEY_COCOA
@@ -672,8 +672,9 @@ namespace QT_NAMESPACE {}
# define Q_ALIGNOF(type) __alignof__(type)
# define Q_TYPEOF(expr) __typeof__(expr)
# define Q_DECL_ALIGN(n) __attribute__((__aligned__(n)))
-// using CC 5.9: Warning: attribute visibility is unsupported and will be skipped..
-//# define Q_DECL_EXPORT __attribute__((__visibility__("default")))
+# endif
+# if __SUNPRO_CC >= 0x550
+# define Q_DECL_EXPORT __global
# endif
# if __SUNPRO_CC < 0x5a0
# define Q_NO_TEMPLATE_FRIENDS
@@ -813,7 +814,7 @@ namespace QT_NAMESPACE {}
# define Q_WS_MAC32
# endif
# elif defined(Q_OS_SYMBIAN)
-# if (defined(__SERIES60_31__) || defined(__S60_32__) || defined(__S60_50__)) && !defined(QT_NO_S60)
+# if !defined(QT_NO_S60)
# define Q_WS_S60
# endif
# elif !defined(Q_WS_QWS) && !defined(Q_WS_LITE)
@@ -863,6 +864,9 @@ typedef quint64 qulonglong;
# endif
#endif
+#define Q_INIT_RESOURCE_EXTERN(name) \
+ extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) ();
+
#define Q_INIT_RESOURCE(name) \
do { extern int QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); \
QT_MANGLE_NAMESPACE(qInitResources_ ## name) (); } while (0)
@@ -1540,6 +1544,7 @@ inline QT3_SUPPORT bool qt_winUnicode() { return true; }
inline QT3_SUPPORT int qWinVersion() { return QSysInfo::WindowsVersion; }
#endif
+// ### Qt 5: remove Win9x support macros QT_WA and QT_WA_INLINE.
#define QT_WA(unicode, ansi) unicode
#define QT_WA_INLINE(unicode, ansi) (unicode)
@@ -1674,10 +1679,7 @@ Q_CORE_EXPORT void qt_assert_x(const char *where, const char *what, const char *
#endif
Q_CORE_EXPORT void qt_check_pointer(const char *, int);
-
-#ifndef QT_NO_EXCEPTIONS
Q_CORE_EXPORT void qBadAlloc();
-#endif
#ifdef QT_NO_EXCEPTIONS
# if defined(QT_NO_DEBUG)
@@ -2412,10 +2414,11 @@ QT3_SUPPORT Q_CORE_EXPORT const char *qInstallPathSysconf();
#if defined(Q_OS_SYMBIAN)
-#ifdef SYMBIAN_GRAPHICS_USE_GCE
+#ifdef SYMBIAN_BUILD_GCE
//RWsPointerCursor is fixed, so don't use low performance sprites
#define Q_SYMBIAN_FIXED_POINTER_CURSORS
#define Q_SYMBIAN_HAS_EXTENDED_BITMAP_TYPE
+#define Q_SYMBIAN_WINDOW_SIZE_CACHE
//enabling new graphics resources
#define QT_SYMBIAN_SUPPORTS_SGIMAGE
#define QT_SYMBIAN_SUPPORTS_ADVANCED_POINTER
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index a9ea44a..9490225 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -266,6 +266,11 @@ QLibraryInfo::location(LibraryLocation loc)
path = QT_CONFIGURE_PLUGINS_PATH;
break;
#endif
+#ifdef QT_CONFIGURE_IMPORTS_PATH
+ case ImportsPath:
+ path = QT_CONFIGURE_IMPORTS_PATH;
+ break;
+#endif
#ifdef QT_CONFIGURE_DATA_PATH
case DataPath:
path = QT_CONFIGURE_DATA_PATH;
@@ -439,7 +444,7 @@ QLibraryInfo::location(LibraryLocation loc)
QCFType<CFURLRef> urlRef = CFBundleCopyBundleURL(bundleRef);
if (urlRef) {
QCFString path = CFURLCopyFileSystemPath(urlRef, kCFURLPOSIXPathStyle);
- return QDir::cleanPath(path + QLatin1String("/Contents/") + ret);
+ return QDir::cleanPath(QString(path) + QLatin1String("/Contents/") + ret);
}
}
#endif
@@ -470,6 +475,7 @@ QLibraryInfo::location(LibraryLocation loc)
\value LibrariesPath The location of installed librarires.
\value BinariesPath The location of installed Qt binaries (tools and applications).
\value PluginsPath The location of installed Qt plugins.
+ \value ImportsPath The location of installed QML extensions to import.
\value DataPath The location of general Qt data.
\value TranslationsPath The location of translation information for Qt strings.
\value SettingsPath The location for Qt settings.
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index e64b760..4a7ba06 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -76,7 +76,8 @@ public:
TranslationsPath,
SettingsPath,
DemosPath,
- ExamplesPath
+ ExamplesPath,
+ ImportsPath
};
static QString location(LibraryLocation); // ### Qt 5: consider renaming it to path()
diff --git a/src/corelib/global/qmalloc.cpp b/src/corelib/global/qmalloc.cpp
index 43e89e3..090998c 100644
--- a/src/corelib/global/qmalloc.cpp
+++ b/src/corelib/global/qmalloc.cpp
@@ -124,3 +124,4 @@ void qFreeAligned(void *ptr)
}
QT_END_NAMESPACE
+
diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h
index a9e7934..6f2bd3f 100644
--- a/src/corelib/global/qnamespace.h
+++ b/src/corelib/global/qnamespace.h
@@ -1235,7 +1235,10 @@ public:
BusyCursor,
OpenHandCursor,
ClosedHandCursor,
- LastCursor = ClosedHandCursor,
+ DragCopyCursor,
+ DragMoveCursor,
+ DragLinkCursor,
+ LastCursor = DragLinkCursor,
BitmapCursor = 24,
CustomCursor = 25
@@ -1722,7 +1725,8 @@ public:
enum GestureFlag
{
DontStartGestureOnChildren = 0x01,
- ReceivePartialGestures = 0x02
+ ReceivePartialGestures = 0x02,
+ IgnoredGesturesPropagateToParent = 0x04
};
Q_DECLARE_FLAGS(GestureFlags, GestureFlag)
diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc
index 6627c76..db910ce 100644
--- a/src/corelib/global/qnamespace.qdoc
+++ b/src/corelib/global/qnamespace.qdoc
@@ -42,6 +42,7 @@
/*!
\namespace Qt
\inmodule QtCore
+ \target Qt Namespace
\brief The Qt namespace contains miscellaneous identifiers
used throughout the Qt library.
@@ -157,7 +158,7 @@
\value AA_MacDontSwapCtrlAndMeta On Mac OS X by default, Qt swaps the
Control and Meta (Command) keys (i.e., whenever Control is pressed, Qt
- sends Meta and whenever Meta is pressed Control is sent. When this
+ sends Meta, and whenever Meta is pressed Control is sent). When this
attribute is true, Qt will not do the flip. QKeySequence::StandardShortcuts
will also flip accordingly (i.e., QKeySequence::Copy will be
Command+C on the keyboard regardless of the value set, though what is output for
@@ -493,7 +494,7 @@
\omitvalue WordBreak
\omitvalue TextForceLeftToRight
\omitvalue TextForceRightToLeft
- \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string
+ \omitvalue TextLongestVariant Always use the longest variant when computing the size of a multi-variant string.
You can use as many modifier flags as you want, except that
Qt::TextSingleLine and Qt::TextWordWrap cannot be combined.
@@ -2115,7 +2116,7 @@
On some platforms this implies Qt::WindowSystemMenuHint for it to work.
\value MacWindowToolBarButtonHint On Mac OS X adds a tool bar button (i.e.,
- the oblong button that is on the top right of windows that have toolbars.
+ the oblong button that is on the top right of windows that have toolbars).
\value BypassGraphicsProxyWidget Prevents the window and its children from
automatically embedding themselves into a QGraphicsProxyWidget if the
@@ -2508,6 +2509,15 @@
operations that allow the user to interact with
the application while they are performed in the
background.
+ \value DragMoveCursor
+ A cursor that is usually used when dragging an item.
+ \value DragCopyCursor
+ A cursor that is usually used when dragging an item
+ to copy it.
+ \value DragLinkCursor
+ A cursor that is usually used when dragging an item
+ to make a link to it.
+
\value BitmapCursor
\omitvalue LastCursor
\omitvalue CustomCursor
diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri
index 02a1586..2ed0e46 100644
--- a/src/corelib/io/io.pri
+++ b/src/corelib/io/io.pri
@@ -6,6 +6,7 @@ HEADERS += \
io/qbuffer.h \
io/qdatastream.h \
io/qdatastream_p.h \
+ io/qdataurl_p.h \
io/qdebug.h \
io/qdir.h \
io/qdiriterator.h \
@@ -34,6 +35,7 @@ SOURCES += \
io/qabstractfileengine.cpp \
io/qbuffer.cpp \
io/qdatastream.cpp \
+ io/qdataurl.cpp \
io/qdebug.cpp \
io/qdir.cpp \
io/qdiriterator.cpp \
diff --git a/src/corelib/io/qdatastream.cpp b/src/corelib/io/qdatastream.cpp
index 82d3b79..2731ae1 100644
--- a/src/corelib/io/qdatastream.cpp
+++ b/src/corelib/io/qdatastream.cpp
@@ -48,6 +48,7 @@
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
+#include "qendian.h"
QT_BEGIN_NAMESPACE
@@ -156,6 +157,12 @@ QT_BEGIN_NAMESPACE
data, followed by the data. Note that any encoding/decoding of
the data (apart from the length quint32) must be done by you.
+ \section1 Reading and writing Qt collection classes
+
+ The Qt container classes can also be serialized to a QDataStream.
+ These include QList, QLinkedList, QVector, QSet, QHash, and QMap.
+ The stream operators are declared as non-members of the classes.
+
\target Serializing Qt Classes
\section1 Reading and writing other Qt classes.
@@ -570,6 +577,7 @@ void QDataStream::setByteOrder(ByteOrder bo)
\value Qt_4_4 Version 10 (Qt 4.4)
\value Qt_4_5 Version 11 (Qt 4.5)
\value Qt_4_6 Version 12 (Qt 4.6)
+ \value Qt_4_7 Same as Qt_4_6.
\sa setVersion(), version()
*/
@@ -672,24 +680,12 @@ QDataStream &QDataStream::operator>>(qint16 &i)
{
i = 0;
CHECK_STREAM_PRECOND(*this)
- if (noswap) {
- if (dev->read((char *)&i, 2) != 2) {
- i = 0;
- setStatus(ReadPastEnd);
- }
+ if (dev->read((char *)&i, 2) != 2) {
+ i = 0;
+ setStatus(ReadPastEnd);
} else {
- union {
- qint16 val1;
- char val2[2];
- } x;
- char *p = x.val2;
- char b[2];
- if (dev->read(b, 2) == 2) {
- *p++ = b[1];
- *p = b[0];
- i = x.val1;
- } else {
- setStatus(ReadPastEnd);
+ if (!noswap) {
+ i = qbswap(i);
}
}
return *this;
@@ -715,26 +711,12 @@ QDataStream &QDataStream::operator>>(qint32 &i)
{
i = 0;
CHECK_STREAM_PRECOND(*this)
- if (noswap) {
- if (dev->read((char *)&i, 4) != 4) {
- i = 0;
- setStatus(ReadPastEnd);
- }
- } else { // swap bytes
- union {
- qint32 val1;
- char val2[4];
- } x;
- char *p = x.val2;
- char b[4];
- if (dev->read(b, 4) == 4) {
- *p++ = b[3];
- *p++ = b[2];
- *p++ = b[1];
- *p = b[0];
- i = x.val1;
- } else {
- setStatus(ReadPastEnd);
+ if (dev->read((char *)&i, 4) != 4) {
+ i = 0;
+ setStatus(ReadPastEnd);
+ } else {
+ if (!noswap) {
+ i = qbswap(i);
}
}
return *this;
@@ -763,31 +745,14 @@ QDataStream &QDataStream::operator>>(qint64 &i)
quint32 i1, i2;
*this >> i2 >> i1;
i = ((quint64)i1 << 32) + i2;
- } else if (noswap) { // no conversion needed
+ } else {
if (dev->read((char *)&i, 8) != 8) {
i = qint64(0);
setStatus(ReadPastEnd);
- }
- } else { // swap bytes
- union {
- qint64 val1;
- char val2[8];
- } x;
-
- char *p = x.val2;
- char b[8];
- if (dev->read(b, 8) == 8) {
- *p++ = b[7];
- *p++ = b[6];
- *p++ = b[5];
- *p++ = b[4];
- *p++ = b[3];
- *p++ = b[2];
- *p++ = b[1];
- *p = b[0];
- i = x.val1;
} else {
- setStatus(ReadPastEnd);
+ if (!noswap) {
+ i = qbswap(i);
+ }
}
}
return *this;
@@ -827,27 +792,17 @@ QDataStream &QDataStream::operator>>(float &f)
f = 0.0f;
CHECK_STREAM_PRECOND(*this)
- if (noswap) {
- if (dev->read((char *)&f, 4) != 4) {
- f = 0.0f;
- setStatus(ReadPastEnd);
- }
- } else { // swap bytes
- union {
- float val1;
- char val2[4];
- } x;
-
- char *p = x.val2;
- char b[4];
- if (dev->read(b, 4) == 4) {
- *p++ = b[3];
- *p++ = b[2];
- *p++ = b[1];
- *p = b[0];
+ if (dev->read((char *)&f, 4) != 4) {
+ f = 0.0f;
+ setStatus(ReadPastEnd);
+ } else {
+ if (!noswap) {
+ union {
+ float val1;
+ quint32 val2;
+ } x;
+ x.val2 = qbswap(*reinterpret_cast<quint32 *>(&f));
f = x.val1;
- } else {
- setStatus(ReadPastEnd);
}
}
return *this;
@@ -880,30 +835,17 @@ QDataStream &QDataStream::operator>>(double &f)
f = 0.0;
CHECK_STREAM_PRECOND(*this)
#ifndef Q_DOUBLE_FORMAT
- if (noswap) {
- if (dev->read((char *)&f, 8) != 8) {
- f = 0.0;
- setStatus(ReadPastEnd);
- }
- } else { // swap bytes
- union {
- double val1;
- char val2[8];
- } x;
- char *p = x.val2;
- char b[8];
- if (dev->read(b, 8) == 8) {
- *p++ = b[7];
- *p++ = b[6];
- *p++ = b[5];
- *p++ = b[4];
- *p++ = b[3];
- *p++ = b[2];
- *p++ = b[1];
- *p = b[0];
+ if (dev->read((char *)&f, 8) != 8) {
+ f = 0.0;
+ setStatus(ReadPastEnd);
+ } else {
+ if (!noswap) {
+ union {
+ double val1;
+ quint64 val2;
+ } x;
+ x.val2 = qbswap(*reinterpret_cast<quint64 *>(&f));
f = x.val1;
- } else {
- setStatus(ReadPastEnd);
}
}
#else
@@ -1075,20 +1017,10 @@ QDataStream &QDataStream::operator<<(qint8 i)
QDataStream &QDataStream::operator<<(qint16 i)
{
CHECK_STREAM_PRECOND(*this)
- if (noswap) {
- dev->write((char *)&i, sizeof(qint16));
- } else { // swap bytes
- union {
- qint16 val1;
- char val2[2];
- } x;
- x.val1 = i;
- char *p = x.val2;
- char b[2];
- b[1] = *p++;
- b[0] = *p;
- dev->write(b, 2);
+ if (!noswap) {
+ i = qbswap(i);
}
+ dev->write((char *)&i, sizeof(qint16));
return *this;
}
@@ -1102,22 +1034,10 @@ QDataStream &QDataStream::operator<<(qint16 i)
QDataStream &QDataStream::operator<<(qint32 i)
{
CHECK_STREAM_PRECOND(*this)
- if (noswap) {
- dev->write((char *)&i, sizeof(qint32));
- } else { // swap bytes
- union {
- qint32 val1;
- char val2[4];
- } x;
- x.val1 = i;
- char *p = x.val2;
- char b[4];
- b[3] = *p++;
- b[2] = *p++;
- b[1] = *p++;
- b[0] = *p;
- dev->write(b, 4);
+ if (!noswap) {
+ i = qbswap(i);
}
+ dev->write((char *)&i, sizeof(qint32));
return *this;
}
@@ -1143,25 +1063,11 @@ QDataStream &QDataStream::operator<<(qint64 i)
quint32 i1 = i & 0xffffffff;
quint32 i2 = i >> 32;
*this << i2 << i1;
- } else if (noswap) { // no conversion needed
+ } else {
+ if (!noswap) {
+ i = qbswap(i);
+ }
dev->write((char *)&i, sizeof(qint64));
- } else { // swap bytes
- union {
- qint64 val1;
- char val2[8];
- } x;
- x.val1 = i;
- char *p = x.val2;
- char b[8];
- b[7] = *p++;
- b[6] = *p++;
- b[5] = *p++;
- b[4] = *p++;
- b[3] = *p++;
- b[2] = *p++;
- b[1] = *p++;
- b[0] = *p;
- dev->write(b, 8);
}
return *this;
}
@@ -1205,22 +1111,16 @@ QDataStream &QDataStream::operator<<(float f)
CHECK_STREAM_PRECOND(*this)
float g = f; // fixes float-on-stack problem
- if (noswap) { // no conversion needed
- dev->write((char *)&g, sizeof(float));
- } else { // swap bytes
+ if (!noswap) {
union {
float val1;
- char val2[4];
+ quint32 val2;
} x;
- x.val1 = f;
- char *p = x.val2;
- char b[4];
- b[3] = *p++;
- b[2] = *p++;
- b[1] = *p++;
- b[0] = *p;
- dev->write(b, 4);
+ x.val1 = g;
+ x.val2 = qbswap(x.val2);
+ g = x.val1;
}
+ dev->write((char *)&g, sizeof(float));
return *this;
}
@@ -1244,26 +1144,16 @@ QDataStream &QDataStream::operator<<(double f)
CHECK_STREAM_PRECOND(*this)
#ifndef Q_DOUBLE_FORMAT
- if (noswap) {
- dev->write((char *)&f, sizeof(double));
- } else {
+ if (!noswap) {
union {
double val1;
- char val2[8];
+ quint64 val2;
} x;
x.val1 = f;
- char *p = x.val2;
- char b[8];
- b[7] = *p++;
- b[6] = *p++;
- b[5] = *p++;
- b[4] = *p++;
- b[3] = *p++;
- b[2] = *p++;
- b[1] = *p++;
- b[0] = *p;
- dev->write(b, 8);
+ x.val2 = qbswap(x.val2);
+ f = x.val1;
}
+ dev->write((char *)&f, sizeof(double));
#else
union {
double val1;
diff --git a/src/corelib/io/qdatastream.h b/src/corelib/io/qdatastream.h
index afc16bc..ec4ba2f 100644
--- a/src/corelib/io/qdatastream.h
+++ b/src/corelib/io/qdatastream.h
@@ -84,10 +84,11 @@ public:
Qt_4_3 = 9,
Qt_4_4 = 10,
Qt_4_5 = 11,
- Qt_4_6 = 12
-#if QT_VERSION >= 0x040700
-#error Add the datastream version for this Qt version
+ Qt_4_6 = 12,
Qt_4_7 = Qt_4_6
+#if QT_VERSION >= 0x040800
+#error Add the datastream version for this Qt version
+ Qt_4_8 = Qt_4_7
#endif
};
diff --git a/src/corelib/io/qdataurl.cpp b/src/corelib/io/qdataurl.cpp
new file mode 100644
index 0000000..4e2dec2
--- /dev/null
+++ b/src/corelib/io/qdataurl.cpp
@@ -0,0 +1,101 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qplatformdefs.h"
+#include "qurl.h"
+#include "private/qdataurl_p.h"
+
+QT_BEGIN_NAMESPACE
+
+/*!
+ \internal
+
+ Decode a data: URL into its mimetype and payload. Returns a null string if
+ the URL could not be decoded.
+*/
+Q_CORE_EXPORT QPair<QString, QByteArray> qDecodeDataUrl(const QUrl &uri)
+{
+ QString mimeType;
+ QByteArray payload;
+
+ if (uri.scheme() == QLatin1String("data") && uri.host().isEmpty()) {
+ mimeType = QLatin1String("text/plain;charset=US-ASCII");
+
+ // the following would have been the correct thing, but
+ // reality often differs from the specification. People have
+ // data: URIs with ? and #
+ //QByteArray data = QByteArray::fromPercentEncoding(uri.encodedPath());
+ QByteArray data = QByteArray::fromPercentEncoding(uri.toEncoded());
+
+ // remove the data: scheme
+ data.remove(0, 5);
+
+ // parse it:
+ int pos = data.indexOf(',');
+ if (pos != -1) {
+ payload = data.mid(pos + 1);
+ data.truncate(pos);
+ data = data.trimmed();
+
+ // find out if the payload is encoded in Base64
+ if (data.endsWith(";base64")) {
+ payload = QByteArray::fromBase64(payload);
+ data.chop(7);
+ }
+
+ if (data.toLower().startsWith("charset")) {
+ int i = 7; // strlen("charset")
+ while (data.at(i) == ' ')
+ ++i;
+ if (data.at(i) == '=')
+ data.prepend("text/plain;");
+ }
+
+ if (!data.isEmpty())
+ mimeType = QLatin1String(data.trimmed());
+
+ }
+ }
+
+ return QPair<QString,QByteArray>(mimeType,payload);
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/io/qdataurl_p.h b/src/corelib/io/qdataurl_p.h
new file mode 100644
index 0000000..57cfd75
--- /dev/null
+++ b/src/corelib/io/qdataurl_p.h
@@ -0,0 +1,67 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QDATAURL_P_H
+#define QDATAURL_P_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists for the convenience
+// of qDecodeDataUrl. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include "QtCore/qurl.h"
+#include "QtCore/qbytearray.h"
+#include "QtCore/qstring.h"
+#include "QtCore/qpair.h"
+
+QT_BEGIN_NAMESPACE
+
+Q_CORE_EXPORT QPair<QString, QByteArray> qDecodeDataUrl(const QUrl &url);
+
+QT_END_NAMESPACE
+
+#endif // QDATAURL_P_H
diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp
index dc7f17e..505889e 100644
--- a/src/corelib/io/qdir.cpp
+++ b/src/corelib/io/qdir.cpp
@@ -52,13 +52,13 @@
#include "qregexp.h"
#include "qvector.h"
#include "qalgorithms.h"
+#include "qvarlengtharray.h"
+
#ifdef QT_BUILD_CORE_LIB
-# include "qresource.h"
+# include "qresource.h"
+# include "private/qcoreglobaldata_p.h"
#endif
-#include "qvarlengtharray.h"
-
-#include "private/qcoreglobaldata_p.h"
#include <stdlib.h>
QT_BEGIN_NAMESPACE
@@ -83,20 +83,15 @@ static QString driveSpec(const QString &path)
//************* QDirPrivate
class QDirPrivate
{
- QDir *q_ptr;
- Q_DECLARE_PUBLIC(QDir)
-
friend struct QScopedPointerDeleter<QDirPrivate>;
-protected:
- QDirPrivate(QDir*, const QDir *copy=0);
- ~QDirPrivate();
- QString initFileEngine(const QString &file);
+public:
+ QDirPrivate(const QDir *copy = 0);
+ ~QDirPrivate();
void updateFileLists() const;
void sortFileList(QDir::SortFlags, QFileInfoList &, QStringList *, QFileInfoList *) const;
-private:
#ifdef QT3_SUPPORT
QChar filterSepChar;
bool matchAllDirs;
@@ -109,28 +104,30 @@ private:
sep = QChar(QLatin1Char(' '));
return sep;
}
- static inline QStringList splitFilters(const QString &nameFilter, QChar sep=0) {
- if(sep == 0)
+ static inline QStringList splitFilters(const QString &nameFilter, QChar sep = 0) {
+ if (sep == 0)
sep = getFilterSepChar(nameFilter);
QStringList ret = nameFilter.split(sep);
- for(int i = 0; i < ret.count(); i++)
+ for (int i = 0; i < ret.count(); ++i)
ret[i] = ret[i].trimmed();
return ret;
}
struct Data {
inline Data()
- : ref(1), fileEngine(0)
- { clear(); }
+ : ref(1), fileEngine(0), listsDirty(1)
+ {}
inline Data(const Data &copy)
: ref(1), path(copy.path), nameFilters(copy.nameFilters), sort(copy.sort),
- filters(copy.filters), fileEngine(0)
- { clear(); }
+ filters(copy.filters), fileEngine(0), listsDirty(1)
+ {}
inline ~Data()
{ delete fileEngine; }
inline void clear() {
listsDirty = 1;
+ files.clear();
+ fileInfos.clear();
}
mutable QAtomicInt ref;
@@ -156,9 +153,10 @@ private:
#endif
path.truncate(path.length() - 1);
}
- if(!data->fileEngine || !QDir::isRelativePath(path))
- path = initFileEngine(path);
- data->fileEngine->setFileName(path);
+
+ delete data->fileEngine;
+ data->fileEngine = QAbstractFileEngine::create(path);
+
// set the path to be the qt friendly version so then we can operate on it using just /
data->path = data->fileEngine->fileName(QAbstractFileEngine::DefaultName);
data->clear();
@@ -170,18 +168,16 @@ private:
void detach(bool createFileEngine = true);
};
-QDirPrivate::QDirPrivate(QDir *qq, const QDir *copy) : q_ptr(qq)
+QDirPrivate::QDirPrivate(const QDir *copy)
#ifdef QT3_SUPPORT
- , filterSepChar(0)
- , matchAllDirs(false)
+ : filterSepChar(0), matchAllDirs(false)
#endif
{
- if(copy) {
+ if (copy) {
copy->d_func()->data->ref.ref();
data = copy->d_func()->data;
} else {
data = new QDirPrivate::Data;
- data->clear();
}
}
@@ -190,18 +186,19 @@ QDirPrivate::~QDirPrivate()
if (!data->ref.deref())
delete data;
data = 0;
- q_ptr = 0;
}
/* For sorting */
-struct QDirSortItem {
+struct QDirSortItem
+{
mutable QString filename_cache;
mutable QString suffix_cache;
QFileInfo item;
};
-class QDirSortItemComparator {
+class QDirSortItemComparator
+{
int qt_cmp_si_sort_flags;
public:
QDirSortItemComparator(int flags) : qt_cmp_si_sort_flags(flags) {}
@@ -240,7 +237,7 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
f2->suffix_cache = ic ? f2->item.suffix().toLower()
: f2->item.suffix();
- r = qt_cmp_si_sort_flags & QDir::LocaleAware
+ r = qt_cmp_si_sort_flags & QDir::LocaleAware
? f1->suffix_cache.localeAwareCompare(f2->suffix_cache)
: f1->suffix_cache.compare(f2->suffix_cache);
}
@@ -260,7 +257,7 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
f2->filename_cache = ic ? f2->item.fileName().toLower()
: f2->item.fileName();
- r = qt_cmp_si_sort_flags & QDir::LocaleAware
+ r = qt_cmp_si_sort_flags & QDir::LocaleAware
? f1->filename_cache.localeAwareCompare(f2->filename_cache)
: f1->filename_cache.compare(f2->filename_cache);
}
@@ -274,16 +271,13 @@ bool QDirSortItemComparator::operator()(const QDirSortItem &n1, const QDirSortIt
inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
QStringList *names, QFileInfoList *infos) const
{
- if(names)
- names->clear();
- if(infos)
- infos->clear();
+ // names and infos are always empty lists or 0 here
int n = l.size();
- if(n > 0) {
+ if (n > 0) {
if (n == 1 || (sort & QDir::SortByMask) == QDir::Unsorted) {
- if(infos)
+ if (infos)
*infos = l;
- if(names) {
+ if (names) {
for (int i = 0; i < n; ++i)
names->append(l.at(i).fileName());
}
@@ -291,13 +285,13 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
QScopedArrayPointer<QDirSortItem> si(new QDirSortItem[n]);
for (int i = 0; i < n; ++i)
si[i].item = l.at(i);
- qSort(si.data(), si.data()+n, QDirSortItemComparator(sort));
+ qSort(si.data(), si.data() + n, QDirSortItemComparator(sort));
// put them back in the list(s)
- if(infos) {
+ if (infos) {
for (int i = 0; i < n; ++i)
infos->append(si[i].item);
}
- if(names) {
+ if (names) {
for (int i = 0; i < n; ++i)
names->append(si[i].item.fileName());
}
@@ -307,7 +301,7 @@ inline void QDirPrivate::sortFileList(QDir::SortFlags sort, QFileInfoList &l,
inline void QDirPrivate::updateFileLists() const
{
- if(data->listsDirty) {
+ if (data->listsDirty) {
QFileInfoList l;
QDirIterator it(data->path, data->nameFilters, data->filters);
while (it.hasNext()) {
@@ -319,16 +313,6 @@ inline void QDirPrivate::updateFileLists() const
}
}
-QString QDirPrivate::initFileEngine(const QString &path)
-{
- detach(false);
- delete data->fileEngine;
- data->fileEngine = 0;
- data->clear();
- data->fileEngine = QAbstractFileEngine::create(path);
- return data->fileEngine->fileName(QAbstractFileEngine::DefaultName);
-}
-
void QDirPrivate::detach(bool createFileEngine)
{
qAtomicDetach(data);
@@ -520,8 +504,7 @@ void QDirPrivate::detach(bool createFileEngine)
\sa currentPath()
*/
-
-QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(this))
+QDir::QDir(const QString &path) : d_ptr(new QDirPrivate)
{
Q_D(QDir);
d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
@@ -548,18 +531,17 @@ QDir::QDir(const QString &path) : d_ptr(new QDirPrivate(this))
\sa exists(), setPath(), setNameFilter(), setFilter(), setSorting()
*/
-
QDir::QDir(const QString &path, const QString &nameFilter,
- SortFlags sort, Filters filters) : d_ptr(new QDirPrivate(this))
+ SortFlags sort, Filters filters) : d_ptr(new QDirPrivate)
{
Q_D(QDir);
d->setPath(path.isEmpty() ? QString::fromLatin1(".") : path);
d->data->nameFilters = QDir::nameFiltersFromString(nameFilter);
bool empty = d->data->nameFilters.isEmpty();
- if(!empty) {
+ if (!empty) {
empty = true;
- for(int i = 0; i < d->data->nameFilters.size(); ++i) {
- if(!d->data->nameFilters.at(i).isEmpty()) {
+ for (int i = 0; i < d->data->nameFilters.size(); ++i) {
+ if (!d->data->nameFilters.at(i).isEmpty()) {
empty = false;
break;
}
@@ -577,8 +559,7 @@ QDir::QDir(const QString &path, const QString &nameFilter,
\sa operator=()
*/
-
-QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(this, &dir))
+QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(&dir))
{
}
@@ -586,7 +567,6 @@ QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(this, &dir))
Destroys the QDir object frees up its resources. This has no
effect on the underlying directory in the file system.
*/
-
QDir::~QDir()
{
}
@@ -607,7 +587,6 @@ QDir::~QDir()
\sa path(), absolutePath(), exists(), cleanPath(), dirName(),
absoluteFilePath(), isRelative(), makeAbsolute()
*/
-
void QDir::setPath(const QString &path)
{
Q_D(QDir);
@@ -624,7 +603,6 @@ void QDir::setPath(const QString &path)
\sa setPath(), absolutePath(), exists(), cleanPath(), dirName(),
absoluteFilePath(), toNativeSeparators(), makeAbsolute()
*/
-
QString QDir::path() const
{
Q_D(const QDir);
@@ -639,7 +617,6 @@ QString QDir::path() const
\sa setPath(), canonicalPath(), exists(), cleanPath(),
dirName(), absoluteFilePath()
*/
-
QString QDir::absolutePath() const
{
Q_D(const QDir);
@@ -649,7 +626,6 @@ QString QDir::absolutePath() const
return cleanPath(ret);
}
-
/*!
Returns the canonical path, i.e. a path without symbolic links or
redundant "." or ".." elements.
@@ -666,12 +642,11 @@ QString QDir::absolutePath() const
\sa path(), absolutePath(), exists(), cleanPath(), dirName(),
absoluteFilePath()
*/
-
QString QDir::canonicalPath() const
{
Q_D(const QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return cleanPath(d->data->fileEngine->fileName(QAbstractFileEngine::CanonicalName));
}
@@ -687,7 +662,6 @@ QString QDir::canonicalPath() const
\sa path(), filePath(), absolutePath(), absoluteFilePath()
*/
-
QString QDir::dirName() const
{
Q_D(const QDir);
@@ -706,7 +680,6 @@ QString QDir::dirName() const
\sa dirName() absoluteFilePath(), isRelative(), canonicalPath()
*/
-
QString QDir::filePath(const QString &fileName) const
{
Q_D(const QDir);
@@ -714,7 +687,7 @@ QString QDir::filePath(const QString &fileName) const
return QString(fileName);
QString ret = d->data->path;
- if(!fileName.isEmpty()) {
+ if (!fileName.isEmpty()) {
if (!ret.isEmpty() && ret[(int)ret.length()-1] != QLatin1Char('/') && fileName[0] != QLatin1Char('/'))
ret += QLatin1Char('/');
ret += fileName;
@@ -730,13 +703,12 @@ QString QDir::filePath(const QString &fileName) const
\sa relativeFilePath() filePath() canonicalPath()
*/
-
QString QDir::absoluteFilePath(const QString &fileName) const
{
Q_D(const QDir);
if (isAbsolutePath(fileName))
return fileName;
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return fileName;
QString ret;
@@ -744,7 +716,7 @@ QString QDir::absoluteFilePath(const QString &fileName) const
if (isRelativePath(d->data->path)) //get pwd
ret = QFSFileEngine::currentPath(fileName);
#endif
- if(!d->data->path.isEmpty() && d->data->path != QLatin1String(".")) {
+ if (!d->data->path.isEmpty() && d->data->path != QLatin1String(".")) {
if (!ret.isEmpty() && !ret.endsWith(QLatin1Char('/')))
ret += QLatin1Char('/');
ret += d->data->path;
@@ -764,7 +736,6 @@ QString QDir::absoluteFilePath(const QString &fileName) const
\sa absoluteFilePath() filePath() canonicalPath()
*/
-
QString QDir::relativeFilePath(const QString &fileName) const
{
QString dir = absolutePath();
@@ -851,7 +822,7 @@ 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++) {
+ for (int i = 0; i < (int)n.length(); ++i) {
if (n[i] == QLatin1Char('/'))
n[i] = QLatin1Char('\\');
}
@@ -875,7 +846,7 @@ 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++) {
+ for (int i = 0; i < (int)n.length(); ++i) {
if (n[i] == QLatin1Char('\\'))
n[i] = QLatin1Char('/');
}
@@ -894,7 +865,6 @@ QString QDir::fromNativeSeparators(const QString &pathName)
\sa cdUp(), isReadable(), exists(), path()
*/
-
bool QDir::cd(const QString &dirName)
{
Q_D(QDir);
@@ -930,14 +900,13 @@ bool QDir::cd(const QString &dirName)
}
}
}
- {
- QFileInfo fi(newPath);
- if (!(fi.exists() && fi.isDir()))
- return false;
- }
- d->setPath(newPath);
- refresh();
+ QDir dir(*this);
+ dir.setPath(newPath);
+ if (!dir.exists())
+ return false;
+
+ *this = dir;
return true;
}
@@ -951,7 +920,6 @@ bool QDir::cd(const QString &dirName)
\sa cd(), isReadable(), exists(), path()
*/
-
bool QDir::cdUp()
{
return cd(QString::fromLatin1(".."));
@@ -960,7 +928,6 @@ bool QDir::cdUp()
/*!
Returns the string list set by setNameFilters()
*/
-
QStringList QDir::nameFilters() const
{
Q_D(const QDir);
@@ -983,25 +950,25 @@ QStringList QDir::nameFilters() const
\sa nameFilters(), setFilter()
*/
-
void QDir::setNameFilters(const QStringList &nameFilters)
{
Q_D(QDir);
- d->detach();
+
+ d->reset();
d->data->nameFilters = nameFilters;
}
/*!
\obsolete
+
+ Use QDir::addSearchPath() with a prefix instead.
+
Adds \a path to the search paths searched in to find resources
that are not specified with an absolute path. The default search
path is to search only in the root (\c{:/}).
- Use QDir::addSearchPath() with a prefix instead.
-
- \sa {The Qt Resource System}, QResource::addSearchPath()
+ \sa {The Qt Resource System}
*/
-
void QDir::addResourceSearchPath(const QString &path)
{
#ifdef QT_BUILD_CORE_LIB
@@ -1039,7 +1006,7 @@ void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths)
return;
}
- for (int i = 0; i < prefix.count(); i++) {
+ for (int i = 0; i < prefix.count(); ++i) {
if (!prefix.at(i).isLetterOrNumber()) {
qWarning("QDir::setSearchPaths: Prefix can only contain letters or numbers");
return;
@@ -1089,7 +1056,6 @@ QStringList QDir::searchPaths(const QString &prefix)
/*!
Returns the value set by setFilter()
*/
-
QDir::Filters QDir::filter() const
{
Q_D(const QDir);
@@ -1171,12 +1137,11 @@ QDir::Filters QDir::filter() const
\sa filter(), setNameFilters()
*/
-
void QDir::setFilter(Filters filters)
{
Q_D(QDir);
- d->detach();
+ d->reset();
d->data->filters = filters;
}
@@ -1185,7 +1150,6 @@ void QDir::setFilter(Filters filters)
\sa setSorting() SortFlag
*/
-
QDir::SortFlags QDir::sorting() const
{
Q_D(const QDir);
@@ -1231,16 +1195,14 @@ QDir::SortFlags QDir::sorting() const
\sa sorting() SortFlag
*/
-
void QDir::setSorting(SortFlags sort)
{
Q_D(QDir);
- d->detach();
+ d->reset();
d->data->sort = sort;
}
-
/*!
Returns the total number of directories and files in the directory.
@@ -1248,7 +1210,6 @@ void QDir::setSorting(SortFlags sort)
\sa operator[](), entryList()
*/
-
uint QDir::count() const
{
Q_D(const QDir);
@@ -1260,13 +1221,10 @@ uint QDir::count() const
/*!
Returns the file name at position \a pos in the list of file
names. Equivalent to entryList().at(index).
-
- Returns an empty string if \a pos is out of range or if the
- entryList() function failed.
+ \a pos must be a valid index position in the list (i.e., 0 <= pos < count()).
\sa count(), entryList()
*/
-
QString QDir::operator[](int pos) const
{
Q_D(const QDir);
@@ -1294,7 +1252,6 @@ QString QDir::operator[](int pos) const
\sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
*/
-
QStringList QDir::entryList(Filters filters, SortFlags sort) const
{
Q_D(const QDir);
@@ -1342,7 +1299,6 @@ QFileInfoList QDir::entryInfoList(Filters filters, SortFlags sort) const
\sa entryInfoList(), setNameFilters(), setSorting(), setFilter()
*/
-
QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
SortFlags sort) const
{
@@ -1356,10 +1312,12 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
#endif
if (sort == NoSort)
sort = d->data->sort;
- if (filters == NoFilter && sort == NoSort && nameFilters == d->data->nameFilters) {
+
+ if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) {
d->updateFileLists();
return d->data->files;
}
+
QFileInfoList l;
QDirIterator it(d->data->path, nameFilters, filters);
while (it.hasNext()) {
@@ -1387,7 +1345,6 @@ QStringList QDir::entryList(const QStringList &nameFilters, Filters filters,
\sa entryList(), setNameFilters(), setSorting(), setFilter(), isReadable(), exists()
*/
-
QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filters,
SortFlags sort) const
{
@@ -1401,10 +1358,12 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter
#endif
if (sort == NoSort)
sort = d->data->sort;
- if (filters == NoFilter && sort == NoSort && nameFilters == d->data->nameFilters) {
+
+ if (filters == d->data->filters && sort == d->data->sort && nameFilters == d->data->nameFilters) {
d->updateFileLists();
return d->data->fileInfos;
}
+
QFileInfoList l;
QDirIterator it(d->data->path, nameFilters, filters);
while (it.hasNext()) {
@@ -1423,7 +1382,6 @@ QFileInfoList QDir::entryInfoList(const QStringList &nameFilters, Filters filter
\sa rmdir()
*/
-
bool QDir::mkdir(const QString &dirName) const
{
Q_D(const QDir);
@@ -1432,7 +1390,7 @@ bool QDir::mkdir(const QString &dirName) const
qWarning("QDir::mkdir: Empty or null file name(s)");
return false;
}
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QString fn = filePath(dirName);
@@ -1448,7 +1406,6 @@ bool QDir::mkdir(const QString &dirName) const
\sa mkdir()
*/
-
bool QDir::rmdir(const QString &dirName) const
{
Q_D(const QDir);
@@ -1457,7 +1414,7 @@ bool QDir::rmdir(const QString &dirName) const
qWarning("QDir::rmdir: Empty or null file name(s)");
return false;
}
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QString fn = filePath(dirName);
@@ -1474,7 +1431,6 @@ bool QDir::rmdir(const QString &dirName) const
\sa rmpath()
*/
-
bool QDir::mkpath(const QString &dirPath) const
{
Q_D(const QDir);
@@ -1483,7 +1439,7 @@ bool QDir::mkpath(const QString &dirPath) const
qWarning("QDir::mkpath: Empty or null file name(s)");
return false;
}
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QString fn = filePath(dirPath);
@@ -1509,7 +1465,7 @@ bool QDir::rmpath(const QString &dirPath) const
qWarning("QDir::rmpath: Empty or null file name(s)");
return false;
}
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QString fn = filePath(dirPath);
@@ -1525,17 +1481,16 @@ bool QDir::rmpath(const QString &dirPath) const
\sa QFileInfo::isReadable()
*/
-
-
bool QDir::isReadable() const
{
Q_D(const QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
- const QAbstractFileEngine::FileFlags info = d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
- |QAbstractFileEngine::PermsMask);
- if(!(info & QAbstractFileEngine::DirectoryType))
+ const QAbstractFileEngine::FileFlags info =
+ d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
+ | QAbstractFileEngine::PermsMask);
+ if (!(info & QAbstractFileEngine::DirectoryType))
return false;
return info & QAbstractFileEngine::ReadUserPerm;
}
@@ -1551,19 +1506,17 @@ bool QDir::isReadable() const
\sa QFileInfo::exists(), QFile::exists()
*/
-
bool QDir::exists() const
{
Q_D(const QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
const QAbstractFileEngine::FileFlags info =
- d->data->fileEngine->fileFlags(
- QAbstractFileEngine::DirectoryType
- | QAbstractFileEngine::ExistsFlag
- | QAbstractFileEngine::Refresh);
- if(!(info & QAbstractFileEngine::DirectoryType))
+ d->data->fileEngine->fileFlags(QAbstractFileEngine::DirectoryType
+ | QAbstractFileEngine::ExistsFlag
+ | QAbstractFileEngine::Refresh);
+ if (!(info & QAbstractFileEngine::DirectoryType))
return false;
return info & QAbstractFileEngine::ExistsFlag;
}
@@ -1580,12 +1533,11 @@ bool QDir::exists() const
\sa root(), rootPath()
*/
-
bool QDir::isRoot() const
{
Q_D(const QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return true;
return d->data->fileEngine->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::RootFlag;
}
@@ -1615,12 +1567,11 @@ bool QDir::isRoot() const
\sa makeAbsolute() isAbsolute() isAbsolutePath() cleanPath()
*/
-
bool QDir::isRelative() const
{
Q_D(const QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->data->fileEngine->isRelativePath();
}
@@ -1633,20 +1584,19 @@ bool QDir::isRelative() const
\sa isAbsolute() isAbsolutePath() isRelative() cleanPath()
*/
-
bool QDir::makeAbsolute() // ### What do the return values signify?
{
Q_D(QDir);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QString absolutePath = d->data->fileEngine->fileName(QAbstractFileEngine::AbsoluteName);
- if(QDir::isRelativePath(absolutePath))
+ if (QDir::isRelativePath(absolutePath))
return false;
d->detach();
d->data->path = absolutePath;
d->data->fileEngine->setFileName(absolutePath);
- if(!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType))
+ if (!(d->data->fileEngine->fileFlags(QAbstractFileEngine::TypesMask) & QAbstractFileEngine::DirectoryType))
return false;
return true;
}
@@ -1660,22 +1610,21 @@ bool QDir::makeAbsolute() // ### What do the return values signify?
\snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 10
*/
-
bool QDir::operator==(const QDir &dir) const
{
const QDirPrivate *d = d_func();
const QDirPrivate *other = dir.d_func();
- if(d->data == other->data)
+ if (d->data == other->data)
return true;
Q_ASSERT(d->data->fileEngine && other->data->fileEngine);
- if(d->data->fileEngine->caseSensitive() != other->data->fileEngine->caseSensitive())
+ if (d->data->fileEngine->caseSensitive() != other->data->fileEngine->caseSensitive())
return false;
- if(d->data->filters == other->data->filters
+ if (d->data->filters == other->data->filters
&& d->data->sort == other->data->sort
&& d->data->nameFilters == other->data->nameFilters) {
QString dir1 = absolutePath(), dir2 = dir.absolutePath();
- if(!other->data->fileEngine->caseSensitive())
+ if (!other->data->fileEngine->caseSensitive())
return (dir1.toLower() == dir2.toLower());
return (dir1 == dir2);
@@ -1688,7 +1637,6 @@ bool QDir::operator==(const QDir &dir) const
Makes a copy of the \a dir object and assigns it to this QDir
object.
*/
-
QDir &QDir::operator=(const QDir &dir)
{
if (this == &dir)
@@ -1707,7 +1655,6 @@ QDir &QDir::operator=(const QDir &dir)
Use setPath() instead.
*/
-
QDir &QDir::operator=(const QString &path)
{
Q_D(QDir);
@@ -1728,22 +1675,19 @@ QDir &QDir::operator=(const QString &path)
\snippet doc/src/snippets/code/src_corelib_io_qdir.cpp 11
*/
-
/*!
Removes the file, \a fileName.
Returns true if the file is removed successfully; otherwise
returns false.
*/
-
bool QDir::remove(const QString &fileName)
{
if (fileName.isEmpty()) {
qWarning("QDir::remove: Empty or null file name");
return false;
}
- QString p = filePath(fileName);
- return QFile::remove(p);
+ return QFile::remove(filePath(fileName));
}
/*!
@@ -1757,7 +1701,6 @@ bool QDir::remove(const QString &fileName)
fail. For example, on at least one file system rename() fails if
\a newName points to an open file.
*/
-
bool QDir::rename(const QString &oldName, const QString &newName)
{
Q_D(QDir);
@@ -1766,11 +1709,11 @@ bool QDir::rename(const QString &oldName, const QString &newName)
qWarning("QDir::rename: Empty or null file name(s)");
return false;
}
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
QFile file(filePath(oldName));
- if(!file.exists())
+ if (!file.exists())
return false;
return file.rename(filePath(newName));
}
@@ -1785,15 +1728,13 @@ bool QDir::rename(const QString &oldName, const QString &newName)
\sa QFileInfo::exists(), QFile::exists()
*/
-
bool QDir::exists(const QString &name) const
{
if (name.isEmpty()) {
qWarning("QDir::exists: Empty or null file name");
return false;
}
- QString tmp = filePath(name);
- return QFile::exists(tmp);
+ return QFile::exists(filePath(name));
}
/*!
@@ -1805,7 +1746,6 @@ bool QDir::exists(const QString &name) const
\sa root(), rootPath()
*/
-
QFileInfoList QDir::drives()
{
#ifdef QT_NO_FSFILEENGINE
@@ -1825,7 +1765,6 @@ QFileInfoList QDir::drives()
user using their operating system's separator use
toNativeSeparators().
*/
-
QChar QDir::separator()
{
#if defined (Q_FS_FAT) || defined(Q_WS_WIN) || defined(Q_OS_SYMBIAN)
@@ -1844,9 +1783,8 @@ QChar QDir::separator()
Returns true if the directory was successfully changed; otherwise
returns false.
- \sa current() currentPath() home() root() temp()
+ \sa current(), currentPath(), home(), root(), temp()
*/
-
bool QDir::setCurrent(const QString &path)
{
#ifdef QT_NO_FSFILEENGINE
@@ -1865,13 +1803,13 @@ bool QDir::setCurrent(const QString &path)
The directory is constructed using the absolute path of the current directory,
ensuring that its path() will be the same as its absolutePath().
- \sa currentPath(), home(), root(), temp()
+ \sa currentPath(), setCurrent(), home(), root(), temp()
*/
/*!
Returns the absolute path of the application's current directory.
- \sa current(), homePath(), rootPath(), tempPath()
+ \sa current(), setCurrent(), homePath(), rootPath(), tempPath()
*/
QString QDir::currentPath()
{
@@ -1888,7 +1826,7 @@ QString QDir::currentPath()
Use currentPath() instead.
- \sa currentPath()
+ \sa currentPath(), setCurrent()
*/
/*!
@@ -1945,14 +1883,14 @@ QString QDir::homePath()
}
/*!
- \fn QString QDir::homeDirPath()
+ \fn QString QDir::homeDirPath()
- Returns the absolute path of the user's home directory.
+ Returns the absolute path of the user's home directory.
- Use homePath() instead.
+ Use homePath() instead.
- \sa homePath()
- */
+ \sa homePath()
+*/
/*!
\fn QDir QDir::temp()
@@ -2018,13 +1956,13 @@ QString QDir::rootPath()
}
/*!
- \fn QString QDir::rootDirPath()
+ \fn QString QDir::rootDirPath()
- Returns the absolute path of the root directory.
+ Returns the absolute path of the root directory.
- Use rootPath() instead.
+ Use rootPath() instead.
- \sa rootPath()
+ \sa rootPath()
*/
#ifndef QT_NO_REGEXP
@@ -2037,11 +1975,9 @@ QString QDir::rootPath()
\sa {QRegExp wildcard matching}, QRegExp::exactMatch() entryList() entryInfoList()
*/
-
-
bool QDir::match(const QStringList &filters, const QString &fileName)
{
- for(QStringList::ConstIterator sit = filters.begin(); sit != filters.end(); ++sit) {
+ for (QStringList::ConstIterator sit = filters.constBegin(); sit != filters.constEnd(); ++sit) {
QRegExp rx(*sit, Qt::CaseInsensitive, QRegExp::Wildcard);
if (rx.exactMatch(fileName))
return true;
@@ -2057,12 +1993,11 @@ bool QDir::match(const QStringList &filters, const QString &fileName)
\sa {QRegExp wildcard matching}, QRegExp::exactMatch() entryList() entryInfoList()
*/
-
bool QDir::match(const QString &filter, const QString &fileName)
{
return match(nameFiltersFromString(filter), fileName);
}
-#endif
+#endif // QT_NO_REGEXP
/*!
Removes all multiple directory separators "/" and resolves any
@@ -2075,15 +2010,14 @@ bool QDir::match(const QString &filter, const QString &fileName)
\sa absolutePath() canonicalPath()
*/
-
QString QDir::cleanPath(const QString &path)
{
if (path.isEmpty())
return path;
QString name = path;
QChar dir_separator = separator();
- if(dir_separator != QLatin1Char('/'))
- name.replace(dir_separator, QLatin1Char('/'));
+ if (dir_separator != QLatin1Char('/'))
+ name.replace(dir_separator, QLatin1Char('/'));
int used = 0, levels = 0;
const int len = name.length();
@@ -2091,27 +2025,27 @@ QString QDir::cleanPath(const QString &path)
QChar *out = outVector.data();
const QChar *p = name.unicode();
- for(int i = 0, last = -1, iwrite = 0; i < len; i++) {
- if(p[i] == QLatin1Char('/')) {
- while(i < len-1 && p[i+1] == QLatin1Char('/')) {
+ for (int i = 0, last = -1, iwrite = 0; i < len; ++i) {
+ if (p[i] == QLatin1Char('/')) {
+ while (i < len-1 && p[i+1] == QLatin1Char('/')) {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) //allow unc paths
- if(!i)
+ if (!i)
break;
#endif
i++;
}
bool eaten = false;
- if(i < len - 1 && p[i+1] == QLatin1Char('.')) {
+ if (i < len - 1 && p[i+1] == QLatin1Char('.')) {
int dotcount = 1;
- if(i < len - 2 && p[i+2] == QLatin1Char('.'))
+ if (i < len - 2 && p[i+2] == QLatin1Char('.'))
dotcount++;
- if(i == len - dotcount - 1) {
- if(dotcount == 1) {
+ if (i == len - dotcount - 1) {
+ if (dotcount == 1) {
break;
- } else if(levels) {
- if(last == -1) {
- for(int i2 = iwrite-1; i2 >= 0; i2--) {
- if(out[i2] == QLatin1Char('/')) {
+ } else if (levels) {
+ if (last == -1) {
+ for (int i2 = iwrite-1; i2 >= 0; i2--) {
+ if (out[i2] == QLatin1Char('/')) {
last = i2;
break;
}
@@ -2120,11 +2054,11 @@ QString QDir::cleanPath(const QString &path)
used -= iwrite - last - 1;
break;
}
- } else if(p[i+dotcount+1] == QLatin1Char('/')) {
- if(dotcount == 2 && levels) {
- if(last == -1 || iwrite - last == 1) {
- for(int i2 = (last == -1) ? (iwrite-1) : (last-1); i2 >= 0; i2--) {
- if(out[i2] == QLatin1Char('/')) {
+ } else if (p[i+dotcount+1] == QLatin1Char('/')) {
+ if (dotcount == 2 && levels) {
+ if (last == -1 || iwrite - last == 1) {
+ for (int i2 = (last == -1) ? (iwrite-1) : (last-1); i2 >= 0; i2--) {
+ if (out[i2] == QLatin1Char('/')) {
eaten = true;
last = i2;
break;
@@ -2133,7 +2067,7 @@ QString QDir::cleanPath(const QString &path)
} else {
eaten = true;
}
- if(eaten) {
+ if (eaten) {
levels--;
used -= iwrite - last;
iwrite = last;
@@ -2145,38 +2079,38 @@ QString QDir::cleanPath(const QString &path)
iwrite = qMax(0, last);
last = -1;
++i;
- } else if(dotcount == 1) {
+ } else if (dotcount == 1) {
eaten = true;
}
- if(eaten)
+ if (eaten)
i += dotcount;
} else {
levels++;
}
- } else if(last != -1 && iwrite - last == 1) {
+ } else if (last != -1 && iwrite - last == 1) {
#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN)
eaten = (iwrite > 2);
#else
eaten = true;
#endif
last = -1;
- } else if(last != -1 && i == len-1) {
+ } else if (last != -1 && i == len-1) {
eaten = true;
} else {
levels++;
}
- if(!eaten)
+ if (!eaten)
last = i - (i - iwrite);
else
continue;
- } else if(!i && p[i] == QLatin1Char('.')) {
+ } else if (!i && p[i] == QLatin1Char('.')) {
int dotcount = 1;
- if(len >= 1 && p[1] == QLatin1Char('.'))
+ if (len >= 1 && p[1] == QLatin1Char('.'))
dotcount++;
- if(len >= dotcount && p[dotcount] == QLatin1Char('/')) {
- if(dotcount == 1) {
+ if (len >= dotcount && p[dotcount] == QLatin1Char('/')) {
+ if (dotcount == 1) {
i++;
- while(i+1 < len-1 && p[i+1] == QLatin1Char('/'))
+ while (i+1 < len-1 && p[i+1] == QLatin1Char('/'))
i++;
continue;
}
@@ -2185,16 +2119,15 @@ QString QDir::cleanPath(const QString &path)
out[iwrite++] = p[i];
used++;
}
- QString ret;
- if(used == len)
- ret = name;
- else
- ret = QString(out, used);
+ QString ret = (used == len ? name : QString(out, used));
// Strip away last slash except for root directories
- if (ret.endsWith(QLatin1Char('/'))
- && !(ret.size() == 1 || (ret.size() == 3 && ret.at(1) == QLatin1Char(':'))))
- ret = ret.left(ret.length() - 1);
+ if (ret.length() > 1 && ret.endsWith(QLatin1Char('/'))) {
+#ifdef Q_OS_WIN
+ if (!(ret.length() == 3 && ret.at(1) == QLatin1Char(':')))
+#endif
+ ret.chop(1);
+ }
return ret;
}
@@ -2205,7 +2138,6 @@ QString QDir::cleanPath(const QString &path)
\sa isRelative() isAbsolutePath() makeAbsolute()
*/
-
bool QDir::isRelativePath(const QString &path)
{
return QFileInfo(path).isRelative();
@@ -2214,12 +2146,11 @@ bool QDir::isRelativePath(const QString &path)
/*!
Refreshes the directory information.
*/
-
void QDir::refresh() const
{
Q_D(const QDir);
- d->data->clear();
+ const_cast<QDirPrivate *>(d)->reset();
}
/*!
@@ -2229,7 +2160,6 @@ void QDir::refresh() const
there is more than one filter, each pair of filters is separated
by a space or by a semicolon.)
*/
-
QStringList QDir::nameFiltersFromString(const QString &nameFilter)
{
return QDirPrivate::splitFilters(nameFilter);
@@ -2309,6 +2239,8 @@ bool QDir::matchAllDirs() const
void QDir::setMatchAllDirs(bool on)
{
Q_D(QDir);
+
+ d->reset();
d->matchAllDirs = on;
}
@@ -2421,7 +2353,8 @@ void QDir::setNameFilter(const QString &nameFilter)
Use QDir::SortFlags instead.
*/
-#endif
+#endif // QT3_SUPPORT
+
#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, QDir::Filters filters)
{
@@ -2484,9 +2417,6 @@ QDebug operator<<(QDebug debug, const QDir &dir)
<< ')';
return debug.space();
}
-
-
-
-#endif
+#endif // QT_NO_DEBUG_STREAM
QT_END_NAMESPACE
diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h
index 6be4922..186dd2f 100644
--- a/src/corelib/io/qdir.h
+++ b/src/corelib/io/qdir.h
@@ -83,7 +83,7 @@ public:
Modified = 0x080,
Hidden = 0x100,
System = 0x200,
-
+
AccessMask = 0x3F0,
AllDirs = 0x400,
@@ -215,6 +215,7 @@ public:
static bool match(const QStringList &filters, const QString &fileName);
static bool match(const QString &filter, const QString &fileName);
#endif
+
static QString cleanPath(const QString &path);
void refresh() const;
@@ -246,7 +247,7 @@ public:
inline QT3_SUPPORT static QString homeDirPath() { return homePath(); }
inline QT3_SUPPORT static QString rootDirPath() { return rootPath(); }
inline QT3_SUPPORT static QString cleanDirPath(const QString &name) { return cleanPath(name); }
-#endif
+#endif // QT3_SUPPORT
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QDir::Filters)
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index e90529e..625098e 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -41,12 +41,8 @@
#include "qplatformdefs.h"
#include "qfileinfo.h"
-#include "qdatetime.h"
-#include "qabstractfileengine.h"
#include "qfsfileengine_p.h"
#include "qglobal.h"
-#include "qatomic.h"
-#include "qhash.h"
#include "qdir.h"
#include "qfileinfo_p.h"
@@ -54,7 +50,7 @@ QT_BEGIN_NAMESPACE
QFileInfoPrivate::QFileInfoPrivate(const QFileInfo *copy)
{
- if(copy) {
+ if (copy) {
copy->d_func()->data->ref.ref();
data = copy->d_func()->data;
} else {
@@ -81,7 +77,8 @@ void QFileInfoPrivate::initFileEngine(const QString &file)
bool QFileInfoPrivate::hasAccess(Access access) const
{
- if (!(getFileFlags(QAbstractFileEngine::FileInfoAll) & QAbstractFileEngine::LocalDiskFlag)) {
+ if (!(getFileFlags(QAbstractFileEngine::PermsMask
+ | QAbstractFileEngine::LocalDiskFlag) & QAbstractFileEngine::LocalDiskFlag)) {
switch (access) {
case ReadAccess:
return getFileFlags(QAbstractFileEngine::ReadUserPerm);
@@ -129,86 +126,104 @@ void QFileInfoPrivate::detach()
QString QFileInfoPrivate::getFileName(QAbstractFileEngine::FileName name) const
{
- if(data->cache_enabled && !data->fileNames[(int)name].isNull())
+ if (data->cache_enabled && !data->fileNames[(int)name].isNull())
return data->fileNames[(int)name];
QString ret = data->fileEngine->fileName(name);
- if(data->cache_enabled)
+ if (ret.isNull())
+ ret = QLatin1String("");
+ if (data->cache_enabled)
data->fileNames[(int)name] = ret;
return ret;
}
+QString QFileInfoPrivate::getFileOwner(QAbstractFileEngine::FileOwner own) const
+{
+ if (data->cache_enabled && !data->fileOwners[(int)own].isNull())
+ return data->fileOwners[(int)own];
+ QString ret = data->fileEngine->owner(own);
+ if (ret.isNull())
+ ret = QLatin1String("");
+ if (data->cache_enabled)
+ data->fileOwners[(int)own] = ret;
+ return ret;
+}
+
uint QFileInfoPrivate::getFileFlags(QAbstractFileEngine::FileFlags request) const
{
- // We split the testing into tests for for LinkType, BundleType and the rest.
+ // We split the testing into tests for for LinkType, BundleType, PermsMask
+ // and the rest.
+ // Tests for file permissions on Windows can be slow, expecially on network
+ // paths and NTFS drives.
// In order to determine if a file is a symlink or not, we have to lstat().
// If we're not interested in that information, we might as well avoid one
// extra syscall. Bundle detecton on Mac can be slow, expecially on network
// paths, so we separate out that as well.
- QAbstractFileEngine::FileFlags flags;
- if (!data->getCachedFlag(CachedFileFlags)) {
- QAbstractFileEngine::FileFlags req = QAbstractFileEngine::FileInfoAll;
- req &= (~QAbstractFileEngine::LinkType);
- req &= (~QAbstractFileEngine::BundleType);
+ QAbstractFileEngine::FileFlags req = 0;
+ uint cachedFlags = 0;
- flags = data->fileEngine->fileFlags(req);
- data->setCachedFlag(CachedFileFlags);
- data->fileFlags |= uint(flags);
- } else {
- flags = QAbstractFileEngine::FileFlags(data->fileFlags & request);
- }
+ if (request & (QAbstractFileEngine::FlagsMask | QAbstractFileEngine::TypesMask)) {
+ if (!data->getCachedFlag(CachedFileFlags)) {
+ req |= QAbstractFileEngine::FlagsMask;
+ req |= QAbstractFileEngine::TypesMask;
+ req &= (~QAbstractFileEngine::LinkType);
+ req &= (~QAbstractFileEngine::BundleType);
- if (request & QAbstractFileEngine::LinkType) {
- if (!data->getCachedFlag(CachedLinkTypeFlag)) {
- QAbstractFileEngine::FileFlags linkflag;
- linkflag = data->fileEngine->fileFlags(QAbstractFileEngine::LinkType);
+ cachedFlags |= CachedFileFlags;
+ }
- data->setCachedFlag(CachedLinkTypeFlag);
- data->fileFlags |= uint(linkflag);
- flags |= linkflag;
+ if (request & QAbstractFileEngine::LinkType) {
+ if (!data->getCachedFlag(CachedLinkTypeFlag)) {
+ req |= QAbstractFileEngine::LinkType;
+ cachedFlags |= CachedLinkTypeFlag;
+ }
}
- }
- if (request & QAbstractFileEngine::BundleType) {
- if (!data->getCachedFlag(CachedBundleTypeFlag)) {
- QAbstractFileEngine::FileFlags bundleflag;
- bundleflag = data->fileEngine->fileFlags(QAbstractFileEngine::BundleType);
+ if (request & QAbstractFileEngine::BundleType) {
+ if (!data->getCachedFlag(CachedBundleTypeFlag)) {
+ req |= QAbstractFileEngine::BundleType;
+ cachedFlags |= CachedBundleTypeFlag;
+ }
+ }
+ }
- data->setCachedFlag(CachedBundleTypeFlag);
- data->fileFlags |= uint(bundleflag);
- flags |= bundleflag;
+ if (request & QAbstractFileEngine::PermsMask) {
+ if (!data->getCachedFlag(CachedPerms)) {
+ req |= QAbstractFileEngine::PermsMask;
+ cachedFlags |= CachedPerms;
}
}
- // no else branch
- // if we had it cached, it was caught in the previous else branch
+ if (req) {
+ if (data->cache_enabled)
+ req &= (~QAbstractFileEngine::Refresh);
+ else
+ req |= QAbstractFileEngine::Refresh;
- return flags & request;
+ QAbstractFileEngine::FileFlags flags = data->fileEngine->fileFlags(req);
+ data->fileFlags |= uint(flags);
+ data->setCachedFlag(cachedFlags);
+ }
+
+ return data->fileFlags & request;
}
QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request) const
{
if (!data->cache_enabled)
data->clearFlags();
- if(request == QAbstractFileEngine::CreationTime) {
- if(data->getCachedFlag(CachedCTime))
- return data->fileTimes[request];
- data->setCachedFlag(CachedCTime);
- return (data->fileTimes[request] = data->fileEngine->fileTime(request));
+ uint cf;
+ if (request == QAbstractFileEngine::CreationTime)
+ cf = CachedCTime;
+ else if (request == QAbstractFileEngine::ModificationTime)
+ cf = CachedMTime;
+ else
+ cf = CachedATime;
+ if (!data->getCachedFlag(cf)) {
+ data->fileTimes[request] = data->fileEngine->fileTime(request);
+ data->setCachedFlag(cf);
}
- if(request == QAbstractFileEngine::ModificationTime) {
- if(data->getCachedFlag(CachedMTime))
- return data->fileTimes[request];
- data->setCachedFlag(CachedMTime);
- return (data->fileTimes[request] = data->fileEngine->fileTime(request));
- }
- if(request == QAbstractFileEngine::AccessTime) {
- if(data->getCachedFlag(CachedATime))
- return data->fileTimes[request];
- data->setCachedFlag(CachedATime);
- return (data->fileTimes[request] = data->fileEngine->fileTime(request));
- }
- return data->fileTimes[0]; //cannot really happen
+ return data->fileTimes[request];
}
//************* QFileInfo
@@ -305,7 +320,6 @@ QDateTime &QFileInfoPrivate::getFileTime(QAbstractFileEngine::FileTime request)
\sa setFile()
*/
-
QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate())
{
}
@@ -316,7 +330,6 @@ QFileInfo::QFileInfo() : d_ptr(new QFileInfoPrivate())
\sa setFile(), isRelative(), QDir::setCurrent(), QDir::isRelativePath()
*/
-
QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate())
{
d_ptr->initFileEngine(file);
@@ -331,7 +344,6 @@ QFileInfo::QFileInfo(const QString &file) : d_ptr(new QFileInfoPrivate())
\sa isRelative()
*/
-
QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate())
{
d_ptr->initFileEngine(file.fileName());
@@ -349,7 +361,6 @@ QFileInfo::QFileInfo(const QFile &file) : d_ptr(new QFileInfoPrivate())
\sa isRelative()
*/
-
QFileInfo::QFileInfo(const QDir &dir, const QString &file) : d_ptr(new QFileInfoPrivate())
{
d_ptr->initFileEngine(dir.filePath(file));
@@ -358,7 +369,6 @@ QFileInfo::QFileInfo(const QDir &dir, const QString &file) : d_ptr(new QFileInfo
/*!
Constructs a new QFileInfo that is a copy of the given \a fileinfo.
*/
-
QFileInfo::QFileInfo(const QFileInfo &fileinfo) : d_ptr(new QFileInfoPrivate(&fileinfo))
{
@@ -368,7 +378,6 @@ QFileInfo::QFileInfo(const QFileInfo &fileinfo) : d_ptr(new QFileInfoPrivate(&fi
Destroys the QFileInfo and frees its resources.
*/
-
QFileInfo::~QFileInfo()
{
}
@@ -395,19 +404,19 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo) const
Q_D(const QFileInfo);
// ### Qt 5: understand long and short file names on Windows
// ### (GetFullPathName()).
- if(fileinfo.d_func()->data == d->data)
+ if (fileinfo.d_func()->data == d->data)
return true;
- if(!d->data->fileEngine || !fileinfo.d_func()->data->fileEngine)
+ if (!d->data->fileEngine || !fileinfo.d_func()->data->fileEngine)
return false;
- if(d->data->fileEngine->caseSensitive() != fileinfo.d_func()->data->fileEngine->caseSensitive())
+ if (d->data->fileEngine->caseSensitive() != fileinfo.d_func()->data->fileEngine->caseSensitive())
return false;
- if(fileinfo.size() == size()) { //if the size isn't the same...
+ if (fileinfo.size() == size()) { //if the size isn't the same...
QString file1 = canonicalFilePath(),
file2 = fileinfo.canonicalFilePath();
- if(file1.length() == file2.length()) {
- if(!fileinfo.d_func()->data->fileEngine->caseSensitive()) {
- for(int i = 0; i < file1.length(); i++) {
- if(file1.at(i).toLower() != file2.at(i).toLower())
+ if (file1.length() == file2.length()) {
+ if (!fileinfo.d_func()->data->fileEngine->caseSensitive()) {
+ for (int i = 0; i < file1.length(); i++) {
+ if (file1.at(i).toLower() != file2.at(i).toLower())
return false;
}
return true;
@@ -441,7 +450,6 @@ bool QFileInfo::operator==(const QFileInfo &fileinfo)
/*!
Makes a copy of the given \a fileinfo and assigns it to this QFileInfo.
*/
-
QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo)
{
Q_D(QFileInfo);
@@ -464,7 +472,6 @@ QFileInfo &QFileInfo::operator=(const QFileInfo &fileinfo)
\sa isRelative(), QDir::setCurrent(), QDir::isRelativePath()
*/
-
void QFileInfo::setFile(const QString &file)
{
*this = QFileInfo(file);
@@ -481,7 +488,6 @@ void QFileInfo::setFile(const QString &file)
\sa isRelative()
*/
-
void QFileInfo::setFile(const QFile &file)
{
*this = QFileInfo(file.fileName());
@@ -498,7 +504,6 @@ void QFileInfo::setFile(const QFile &file)
\sa isRelative()
*/
-
void QFileInfo::setFile(const QDir &dir, const QString &file)
{
*this = QFileInfo(dir.filePath(file));
@@ -528,25 +533,24 @@ void QFileInfo::setFile(const QDir &dir, const QString &file)
QString QFileInfo::absoluteFilePath() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::AbsoluteName);
}
/*!
- Returns the canonical path including the file name, i.e. an absolute
- path without symbolic links or redundant "." or ".." elements.
+ Returns the canonical path including the file name, i.e. an absolute
+ path without symbolic links or redundant "." or ".." elements.
- If the file does not exist, canonicalFilePath() returns an empty
- string.
+ If the file does not exist, canonicalFilePath() returns an empty
+ string.
- \sa filePath(), absoluteFilePath(), dir()
+ \sa filePath(), absoluteFilePath(), dir()
*/
-
QString QFileInfo::canonicalFilePath() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::CanonicalName);
}
@@ -569,7 +573,6 @@ QString QFileInfo::canonicalFilePath() const
\sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
*/
-
QString QFileInfo::absolutePath() const
{
Q_D(const QFileInfo);
@@ -591,16 +594,14 @@ QString QFileInfo::absolutePath() const
\sa path(), absolutePath()
*/
-
QString QFileInfo::canonicalPath() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::CanonicalPathName);
}
-
/*!
Returns the file's path. This doesn't include the file name.
@@ -610,11 +611,10 @@ QString QFileInfo::canonicalPath() const
\sa filePath(), absolutePath(), canonicalPath(), dir(), fileName(), isRelative()
*/
-
QString QFileInfo::path() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::PathName);
}
@@ -635,16 +635,14 @@ QString QFileInfo::path() const
\sa isAbsolute()
*/
-
bool QFileInfo::isRelative() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return true;
return d->data->fileEngine->isRelativePath();
}
-
/*!
Converts the file's path to an absolute path if it is not already in that form.
Returns true to indicate that the path was converted; otherwise returns false
@@ -652,11 +650,10 @@ bool QFileInfo::isRelative() const
\sa filePath(), isRelative()
*/
-
bool QFileInfo::makeAbsolute()
{
Q_D(QFileInfo);
- if(!d->data->fileEngine || !d->data->fileEngine->isRelativePath())
+ if (!d->data->fileEngine || !d->data->fileEngine->isRelativePath())
return false;
QString absFileName = d->getFileName(QAbstractFileEngine::AbsoluteName);
d->initFileEngine(absFileName);
@@ -669,11 +666,10 @@ bool QFileInfo::makeAbsolute()
\note If the file is a symlink that points to a non existing
file, false is returned.
*/
-
bool QFileInfo::exists() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::ExistsFlag);
}
@@ -685,7 +681,6 @@ bool QFileInfo::exists() const
\note On Windows CE, there might be a delay for the file system driver
to detect changes on the file.
*/
-
void QFileInfo::refresh()
{
Q_D(QFileInfo);
@@ -698,11 +693,10 @@ void QFileInfo::refresh()
\sa absoluteFilePath(), canonicalFilePath(), isRelative()
*/
-
QString QFileInfo::filePath() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::DefaultName);
}
@@ -718,11 +712,10 @@ QString QFileInfo::filePath() const
\sa isRelative(), filePath(), baseName(), extension()
*/
-
QString QFileInfo::fileName() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::BaseName);
}
@@ -739,11 +732,10 @@ QString QFileInfo::fileName() const
\sa isBundle(), filePath(), baseName(), extension()
*/
-
QString QFileInfo::bundleName() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::BundleName);
}
@@ -764,11 +756,10 @@ QString QFileInfo::bundleName() const
\sa fileName(), suffix(), completeSuffix(), completeBaseName()
*/
-
QString QFileInfo::baseName() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::BaseName).section(QLatin1Char('.'), 0, 0);
}
@@ -784,11 +775,10 @@ QString QFileInfo::baseName() const
\sa fileName(), suffix(), completeSuffix(), baseName()
*/
-
QString QFileInfo::completeBaseName() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
QString name = d->getFileName(QAbstractFileEngine::BaseName);
int index = name.lastIndexOf(QLatin1Char('.'));
@@ -806,11 +796,10 @@ QString QFileInfo::completeBaseName() const
\sa fileName(), suffix(), baseName(), completeBaseName()
*/
-
QString QFileInfo::completeSuffix() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
QString fileName = d->getFileName(QAbstractFileEngine::BaseName);
int firstDot = fileName.indexOf(QLatin1Char('.'));
@@ -834,11 +823,10 @@ QString QFileInfo::completeSuffix() const
\sa fileName(), completeSuffix(), baseName(), completeBaseName()
*/
-
QString QFileInfo::suffix() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
QString fileName = d->getFileName(QAbstractFileEngine::BaseName);
int lastDot = fileName.lastIndexOf(QLatin1Char('.'));
@@ -849,24 +837,23 @@ QString QFileInfo::suffix() const
/*!
- Returns the path of the object's parent directory as a QDir object.
+ Returns the path of the object's parent directory as a QDir object.
- \bold{Note:} The QDir returned always corresponds to the object's
- parent directory, even if the QFileInfo represents a directory.
+ \bold{Note:} The QDir returned always corresponds to the object's
+ parent directory, even if the QFileInfo represents a directory.
- For each of the follwing, dir() returns a QDir for
- \c{"~/examples/191697"}.
+ For each of the follwing, dir() returns a QDir for
+ \c{"~/examples/191697"}.
- \snippet doc/src/snippets/fileinfo/main.cpp 0
+ \snippet doc/src/snippets/fileinfo/main.cpp 0
- For each of the follwing, dir() returns a QDir for
- \c{"."}.
+ For each of the follwing, dir() returns a QDir for
+ \c{"."}.
- \snippet doc/src/snippets/fileinfo/main.cpp 1
+ \snippet doc/src/snippets/fileinfo/main.cpp 1
- \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir()
+ \sa absolutePath(), filePath(), fileName(), isRelative(), absoluteDir()
*/
-
QDir QFileInfo::dir() const
{
// ### Qt5: Maybe rename this to parentDirectory(), considering what it actually do?
@@ -878,7 +865,6 @@ QDir QFileInfo::dir() const
\sa dir(), filePath(), fileName(), isRelative()
*/
-
QDir QFileInfo::absoluteDir() const
{
return QDir(absolutePath());
@@ -891,7 +877,7 @@ QDir QFileInfo::absoluteDir() const
*/
QDir QFileInfo::dir(bool absPath) const
{
- if(absPath)
+ if (absPath)
return absoluteDir();
return dir();
}
@@ -902,11 +888,10 @@ QDir QFileInfo::dir(bool absPath) const
\sa isWritable(), isExecutable(), permission()
*/
-
bool QFileInfo::isReadable() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->hasAccess(QFileInfoPrivate::ReadAccess);
}
@@ -916,11 +901,10 @@ bool QFileInfo::isReadable() const
\sa isReadable(), isExecutable(), permission()
*/
-
bool QFileInfo::isWritable() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->hasAccess(QFileInfoPrivate::WriteAccess);
}
@@ -930,11 +914,10 @@ bool QFileInfo::isWritable() const
\sa isReadable(), isWritable(), permission()
*/
-
bool QFileInfo::isExecutable() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->hasAccess(QFileInfoPrivate::ExecuteAccess);
}
@@ -948,7 +931,7 @@ bool QFileInfo::isExecutable() const
bool QFileInfo::isHidden() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::HiddenFlag);
}
@@ -960,11 +943,10 @@ bool QFileInfo::isHidden() const
\sa isDir(), isSymLink(), isBundle()
*/
-
bool QFileInfo::isFile() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::FileType);
}
@@ -975,11 +957,10 @@ bool QFileInfo::isFile() const
\sa isFile(), isSymLink(), isBundle()
*/
-
bool QFileInfo::isDir() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::DirectoryType);
}
@@ -992,11 +973,10 @@ bool QFileInfo::isDir() const
\sa isDir(), isSymLink(), isFile()
*/
-
bool QFileInfo::isBundle() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::BundleType);
}
@@ -1018,21 +998,19 @@ bool QFileInfo::isBundle() const
\sa isFile(), isDir(), symLinkTarget()
*/
-
bool QFileInfo::isSymLink() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::LinkType);
}
/*!
- Returns true if the object points to a directory or to a symbolic
- link to a directory, and that directory is the root directory; otherwise
- returns false.
+ Returns true if the object points to a directory or to a symbolic
+ link to a directory, and that directory is the root directory; otherwise
+ returns false.
*/
-
bool QFileInfo::isRoot() const
{
Q_D(const QFileInfo);
@@ -1064,7 +1042,7 @@ bool QFileInfo::isRoot() const
QString QFileInfo::readLink() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
return d->getFileName(QAbstractFileEngine::LinkName);
}
@@ -1079,13 +1057,12 @@ QString QFileInfo::readLink() const
\sa ownerId(), group(), groupId()
*/
-
QString QFileInfo::owner() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
- return d->data->fileEngine->owner(QAbstractFileEngine::OwnerUser);
+ return d->getFileOwner(QAbstractFileEngine::OwnerUser);
}
/*!
@@ -1096,11 +1073,10 @@ QString QFileInfo::owner() const
\sa owner(), group(), groupId()
*/
-
uint QFileInfo::ownerId() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return 0;
return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerUser);
}
@@ -1115,13 +1091,12 @@ uint QFileInfo::ownerId() const
\sa groupId(), owner(), ownerId()
*/
-
QString QFileInfo::group() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QLatin1String("");
- return d->data->fileEngine->owner(QAbstractFileEngine::OwnerGroup);
+ return d->getFileOwner(QAbstractFileEngine::OwnerGroup);
}
/*!
@@ -1132,11 +1107,10 @@ QString QFileInfo::group() const
\sa group(), owner(), ownerId()
*/
-
uint QFileInfo::groupId() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return 0;
return d->data->fileEngine->ownerId(QAbstractFileEngine::OwnerGroup);
}
@@ -1154,11 +1128,10 @@ uint QFileInfo::groupId() const
\sa isReadable(), isWritable(), isExecutable()
*/
-
bool QFileInfo::permission(QFile::Permissions permissions) const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return false;
return d->getFileFlags(QAbstractFileEngine::FileFlags((int)permissions)) == (uint)permissions;
}
@@ -1167,11 +1140,10 @@ bool QFileInfo::permission(QFile::Permissions permissions) const
Returns the complete OR-ed together combination of
QFile::Permissions for the file.
*/
-
QFile::Permissions QFileInfo::permissions() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return 0;
return QFile::Permissions(d->getFileFlags(QAbstractFileEngine::PermsMask) & QAbstractFileEngine::PermsMask);
}
@@ -1183,13 +1155,12 @@ QFile::Permissions QFileInfo::permissions() const
\sa exists()
*/
-
qint64 QFileInfo::size() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return 0;
- if(!d->data->getCachedFlag(QFileInfoPrivate::CachedSize)) {
+ if (!d->data->getCachedFlag(QFileInfoPrivate::CachedSize)) {
d->data->setCachedFlag(QFileInfoPrivate::CachedSize);
d->data->fileSize = d->data->fileEngine->size();
}
@@ -1209,11 +1180,10 @@ qint64 QFileInfo::size() const
\sa lastModified() lastRead()
*/
-
QDateTime QFileInfo::created() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QDateTime();
return d->getFileTime(QAbstractFileEngine::CreationTime);
}
@@ -1223,11 +1193,10 @@ QDateTime QFileInfo::created() const
\sa created() lastRead()
*/
-
QDateTime QFileInfo::lastModified() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QDateTime();
return d->getFileTime(QAbstractFileEngine::ModificationTime);
}
@@ -1240,11 +1209,10 @@ QDateTime QFileInfo::lastModified() const
\sa created() lastModified()
*/
-
QDateTime QFileInfo::lastRead() const
{
Q_D(const QFileInfo);
- if(!d->data->fileEngine)
+ if (!d->data->fileEngine)
return QDateTime();
return d->getFileTime(QAbstractFileEngine::AccessTime);
}
@@ -1252,7 +1220,6 @@ QDateTime QFileInfo::lastRead() const
/*! \internal
Detaches all internal data.
*/
-
void QFileInfo::detach()
{
Q_D(QFileInfo);
@@ -1264,7 +1231,6 @@ void QFileInfo::detach()
\sa setCaching(), refresh()
*/
-
bool QFileInfo::caching() const
{
Q_D(const QFileInfo);
@@ -1283,7 +1249,6 @@ bool QFileInfo::caching() const
\sa refresh(), caching()
*/
-
void QFileInfo::setCaching(bool enable)
{
Q_D(QFileInfo);
diff --git a/src/corelib/io/qfileinfo_p.h b/src/corelib/io/qfileinfo_p.h
index 065f860..d97a0cf 100644
--- a/src/corelib/io/qfileinfo_p.h
+++ b/src/corelib/io/qfileinfo_p.h
@@ -54,6 +54,9 @@
//
#include "qfileinfo.h"
+#include "qabstractfileengine.h"
+#include "qdatetime.h"
+#include "qatomic.h"
QT_BEGIN_NAMESPACE
@@ -75,35 +78,41 @@ public:
uint getFileFlags(QAbstractFileEngine::FileFlags) const;
QDateTime &getFileTime(QAbstractFileEngine::FileTime) const;
QString getFileName(QAbstractFileEngine::FileName) const;
+ QString getFileOwner(QAbstractFileEngine::FileOwner own) const;
enum { CachedFileFlags=0x01, CachedLinkTypeFlag=0x02, CachedBundleTypeFlag=0x04,
CachedMTime=0x10, CachedCTime=0x20, CachedATime=0x40,
- CachedSize =0x08 };
+ CachedSize =0x08, CachedPerms=0x80 };
struct Data {
inline Data()
- : ref(1), fileEngine(0), cache_enabled(1), fileSize(0)
- { clear(); }
+ : ref(1), fileEngine(0),
+ cachedFlags(0), cache_enabled(1), fileFlags(0), fileSize(0)
+ {}
inline Data(const Data &copy)
: ref(1), fileEngine(QAbstractFileEngine::create(copy.fileName)),
- fileName(copy.fileName), cache_enabled(copy.cache_enabled), fileSize(copy.fileSize)
- { clear(); }
+ fileName(copy.fileName),
+ cachedFlags(0), cache_enabled(copy.cache_enabled), fileFlags(0), fileSize(0)
+ {}
inline ~Data() { delete fileEngine; }
inline void clearFlags() {
fileFlags = 0;
cachedFlags = 0;
if (fileEngine)
- (void)fileEngine->fileFlags(QFSFileEngine::Refresh);
+ (void)fileEngine->fileFlags(QAbstractFileEngine::Refresh);
}
inline void clear() {
clearFlags();
for (int i = QAbstractFileEngine::NFileNames - 1 ; i >= 0 ; --i)
fileNames[i].clear();
+ fileOwners[1].clear();
+ fileOwners[0].clear();
}
mutable QAtomicInt ref;
QAbstractFileEngine *fileEngine;
mutable QString fileName;
mutable QString fileNames[QAbstractFileEngine::NFileNames];
+ mutable QString fileOwners[2];
mutable uint cachedFlags : 31;
mutable uint cache_enabled : 1;
diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp
index 451fbd4..7223e49 100644
--- a/src/corelib/io/qfilesystemwatcher.cpp
+++ b/src/corelib/io/qfilesystemwatcher.cpp
@@ -248,7 +248,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine()
eng = QDnotifyFileSystemWatcherEngine::create();
return eng;
#elif defined(Q_OS_FREEBSD) || defined(Q_OS_MAC)
-# if 0 && (defined Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
+# if defined(Q_OS_MAC) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5)
if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5)
return QFSEventsFileSystemWatcherEngine::create();
else
diff --git a/src/corelib/io/qfilesystemwatcher_dnotify.cpp b/src/corelib/io/qfilesystemwatcher_dnotify.cpp
index 1a218c7..82470c8 100644
--- a/src/corelib/io/qfilesystemwatcher_dnotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_dnotify.cpp
@@ -39,6 +39,7 @@
**
****************************************************************************/
+#include "qplatformdefs.h"
#include "qfilesystemwatcher.h"
#include "qfilesystemwatcher_dnotify_p.h"
@@ -255,16 +256,16 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
if(fd == 0) {
- DIR *d = ::opendir(path.toUtf8().constData());
+ QT_DIR *d = QT_OPENDIR(path.toUtf8().constData());
if(!d) continue; // Could not open directory
- DIR *parent = 0;
+ QT_DIR *parent = 0;
QDir parentDir(path);
if(!parentDir.isRoot()) {
parentDir.cdUp();
- parent = ::opendir(parentDir.path().toUtf8().constData());
+ parent = QT_OPENDIR(parentDir.path().toUtf8().constData());
if(!parent) {
- ::closedir(d);
+ QT_CLOSEDIR(d);
continue;
}
}
@@ -272,8 +273,8 @@ QStringList QDnotifyFileSystemWatcherEngine::addPaths(const QStringList &paths,
fd = qt_safe_dup(::dirfd(d));
int parentFd = parent ? qt_safe_dup(::dirfd(parent)) : 0;
- ::closedir(d);
- if(parent) ::closedir(parent);
+ QT_CLOSEDIR(d);
+ if(parent) QT_CLOSEDIR(parent);
Q_ASSERT(fd);
if(::fcntl(fd, F_SETSIG, SIGIO) ||
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.cpp b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
index 046377e..efbc290 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.cpp
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.cpp
@@ -94,7 +94,7 @@ static void addPathToHash(PathHash &pathHash, const QString &key, const QFileInf
{
PathInfoList &list = pathHash[key];
list.push_back(PathInfo(path,
- fileInfo.absoluteFilePath().normalized(QString::NormalizationForm_D).toUtf8()));
+ fileInfo.canonicalFilePath().normalized(QString::NormalizationForm_D).toUtf8()));
pathHash.insert(key, list);
}
@@ -206,7 +206,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
} else {
directories->append(path);
// Full file path for dirs.
- QCFString cfpath(createFSStreamPath(fileInfo.absoluteFilePath()));
+ QCFString cfpath(createFSStreamPath(fileInfo.canonicalFilePath()));
addPathToHash(dirPathInfoHash, cfpath, fileInfo, path);
CFArrayAppendValue(tmpArray, cfpath);
}
@@ -216,7 +216,7 @@ QStringList QFSEventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
continue;
} else {
// Just the absolute path (minus it's filename) for files.
- QCFString cfpath(createFSStreamPath(fileInfo.absolutePath()));
+ QCFString cfpath(createFSStreamPath(fileInfo.canonicalPath()));
files->append(path);
addPathToHash(filePathInfoHash, cfpath, fileInfo, path);
CFArrayAppendValue(tmpArray, cfpath);
@@ -293,7 +293,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
itemCount = CFArrayGetCount(tmpArray);
const QString &path = paths.at(i);
QFileInfo fi(path);
- QCFString cfpath(createFSStreamPath(fi.absolutePath()));
+ QCFString cfpath(createFSStreamPath(fi.canonicalPath()));
CFIndex index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfpath);
if (index != -1) {
@@ -302,7 +302,7 @@ QStringList QFSEventsFileSystemWatcherEngine::removePaths(const QStringList &pat
removePathFromHash(filePathInfoHash, cfpath, path);
} else {
// Could be a directory we are watching instead.
- QCFString cfdirpath(createFSStreamPath(fi.absoluteFilePath()));
+ QCFString cfdirpath(createFSStreamPath(fi.canonicalFilePath()));
index = CFArrayGetFirstIndexOfValue(tmpArray, CFRangeMake(0, itemCount), cfdirpath);
if (index != -1) {
CFArrayRemoveValueAtIndex(tmpArray, index);
@@ -445,7 +445,16 @@ void QFSEventsFileSystemWatcherEngine::updateFiles()
updateHash(dirPathInfoHash);
if (filePathInfoHash.isEmpty() && dirPathInfoHash.isEmpty()) {
// Everything disappeared before we got to start, don't bother.
- stop();
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ // Code duplicated from stop(), with the exception that we
+ // don't wait on waitForStop here. Doing this will lead to
+ // a deadlock since this function is called from the worker
+ // thread. (waitForStop.wakeAll() is only called from the
+ // end of run()).
+ stopFSStream(fsStream);
+ if (threadsRunLoop)
+ CFRunLoopStop(threadsRunLoop);
+#endif
cleanupFSStream(fsStream);
}
waitCondition.wakeAll();
diff --git a/src/corelib/io/qfilesystemwatcher_inotify.cpp b/src/corelib/io/qfilesystemwatcher_inotify.cpp
index a7dc8fa..4740a89 100644
--- a/src/corelib/io/qfilesystemwatcher_inotify.cpp
+++ b/src/corelib/io/qfilesystemwatcher_inotify.cpp
@@ -235,7 +235,7 @@ QInotifyFileSystemWatcherEngine::QInotifyFileSystemWatcherEngine(int fd)
QInotifyFileSystemWatcherEngine::~QInotifyFileSystemWatcherEngine()
{
- foreach (int id, pathToID.values())
+ foreach (int id, pathToID)
inotify_rm_watch(inotifyFd, id < 0 ? -id : id);
::close(inotifyFd);
diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
index f088ded..99c165e 100644
--- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp
+++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp
@@ -109,7 +109,7 @@ QKqueueFileSystemWatcherEngine::~QKqueueFileSystemWatcherEngine()
close(kqpipe[0]);
close(kqpipe[1]);
- foreach (int id, pathToID.values())
+ foreach (int id, pathToID)
::close(id < 0 ? -id : id);
}
@@ -260,12 +260,22 @@ void QKqueueFileSystemWatcherEngine::run()
DEBUG() << "QKqueueFileSystemWatcherEngine: processing kevent" << kev.ident << kev.filter;
if (fd == kqpipe[0]) {
- char c;
- if (read(kqpipe[0], &c, 1) != 1) {
+ // read all pending data from the pipe
+ QByteArray ba;
+ ba.resize(kev.data);
+ if (read(kqpipe[0], ba.data(), ba.size()) != ba.size()) {
perror("QKqueueFileSystemWatcherEngine: error reading from pipe");
return;
}
- switch (c) {
+ // read the command from the buffer (but break and return on 'q')
+ char cmd = 0;
+ for (int i = 0; i < ba.size(); ++i) {
+ cmd = ba.constData()[i];
+ if (cmd == 'q')
+ break;
+ }
+ // handle the command
+ switch (cmd) {
case 'q':
DEBUG() << "QKqueueFileSystemWatcherEngine: thread received 'q', exiting...";
return;
@@ -273,7 +283,7 @@ void QKqueueFileSystemWatcherEngine::run()
DEBUG() << "QKqueueFileSystemWatcherEngine: thread received '@', continuing...";
break;
default:
- DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << c;
+ DEBUG() << "QKqueueFileSystemWatcherEngine: thread received unknow message" << cmd;
break;
}
} else {
diff --git a/src/corelib/io/qfsfileengine.cpp b/src/corelib/io/qfsfileengine.cpp
index c842e49..1672dfc 100644
--- a/src/corelib/io/qfsfileengine.cpp
+++ b/src/corelib/io/qfsfileengine.cpp
@@ -56,6 +56,9 @@
#endif
#include <stdio.h>
#include <stdlib.h>
+#if defined(Q_OS_MAC)
+# include <private/qcore_mac_p.h>
+#endif
QT_BEGIN_NAMESPACE
@@ -143,9 +146,27 @@ QString QFSFileEnginePrivate::canonicalized(const QString &path)
if (path.size() == 1 && path.at(0) == QLatin1Char('/'))
return path;
#endif
- // Mac OS X 10.5.x doesn't support the realpath(X,0) extenstion we use here.
-#if defined(Q_OS_LINUX) || defined(Q_OS_SYMBIAN)
- char *ret = realpath(path.toLocal8Bit().constData(), (char*)0);
+#if defined(Q_OS_LINUX) || defined(Q_OS_SYMBIAN) || defined(Q_OS_MAC)
+ char *ret = 0;
+#if defined(Q_OS_MAC)
+ // Mac OS X 10.5.x doesn't support the realpath(X,0) extension we use here.
+ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_6) {
+ ret = realpath(path.toLocal8Bit().constData(), (char*)0);
+ } else {
+ // on 10.5 we can use FSRef to resolve the file path.
+ FSRef fsref;
+ if (FSPathMakeRef((const UInt8 *)QDir::cleanPath(path).toUtf8().data(), &fsref, 0) == noErr) {
+ CFURLRef urlref = CFURLCreateFromFSRef(NULL, &fsref);
+ CFStringRef canonicalPath = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle);
+ QString ret = QCFString::toQString(canonicalPath);
+ CFRelease(canonicalPath);
+ CFRelease(urlref);
+ return ret;
+ }
+ }
+#else
+ ret = realpath(path.toLocal8Bit().constData(), (char*)0);
+#endif
if (ret) {
QString canonicalPath = QDir::cleanPath(QString::fromLocal8Bit(ret));
free(ret);
diff --git a/src/corelib/io/qfsfileengine_iterator_unix.cpp b/src/corelib/io/qfsfileengine_iterator_unix.cpp
index b68b1a1..bfdb03e 100644
--- a/src/corelib/io/qfsfileengine_iterator_unix.cpp
+++ b/src/corelib/io/qfsfileengine_iterator_unix.cpp
@@ -58,13 +58,13 @@ public:
#endif
{}
- DIR *dir;
- dirent *dirEntry;
+ QT_DIR *dir;
+ QT_DIRENT *dirEntry;
bool done;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN)
// for readdir_r
- dirent *mt_file;
+ QT_DIRENT *mt_file;
#endif
};
@@ -76,14 +76,14 @@ void QFSFileEngineIterator::advance()
return;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN)
- if (::readdir_r(platform->dir, platform->mt_file, &platform->dirEntry) != 0)
+ if (QT_READDIR_R(platform->dir, platform->mt_file, &platform->dirEntry) != 0)
platform->done = true;
#else
// ### add local lock to prevent breaking reentrancy
- platform->dirEntry = ::readdir(platform->dir);
+ platform->dirEntry = QT_READDIR(platform->dir);
#endif // _POSIX_THREAD_SAFE_FUNCTIONS
if (!platform->dirEntry) {
- ::closedir(platform->dir);
+ QT_CLOSEDIR(platform->dir);
platform->dir = 0;
platform->done = true;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN)
@@ -101,7 +101,7 @@ void QFSFileEngineIterator::newPlatformSpecifics()
void QFSFileEngineIterator::deletePlatformSpecifics()
{
if (platform->dir) {
- ::closedir(platform->dir);
+ QT_CLOSEDIR(platform->dir);
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN)
delete [] platform->mt_file;
platform->mt_file = 0;
@@ -115,18 +115,18 @@ bool QFSFileEngineIterator::hasNext() const
{
if (!platform->done && !platform->dir) {
QFSFileEngineIterator *that = const_cast<QFSFileEngineIterator *>(this);
- if ((that->platform->dir = ::opendir(QFile::encodeName(path()).data())) == 0) {
+ if ((that->platform->dir = QT_OPENDIR(QFile::encodeName(path()).data())) == 0) {
that->platform->done = true;
} else {
// ### Race condition; we should use fpathconf and dirfd().
long maxPathName = ::pathconf(QFile::encodeName(path()).data(), _PC_NAME_MAX);
if ((int) maxPathName == -1)
maxPathName = FILENAME_MAX;
- maxPathName += sizeof(dirent) + 1;
+ maxPathName += sizeof(QT_DIRENT) + 1;
#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) && !defined(Q_OS_CYGWIN) && !defined(Q_OS_SYMBIAN)
if (that->platform->mt_file)
delete [] that->platform->mt_file;
- that->platform->mt_file = (dirent *)new char[maxPathName];
+ that->platform->mt_file = (QT_DIRENT *)new char[maxPathName];
#endif
that->advance();
diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp
index 9179485..d2fa744 100644
--- a/src/corelib/io/qfsfileengine_unix.cpp
+++ b/src/corelib/io/qfsfileengine_unix.cpp
@@ -1270,7 +1270,7 @@ uchar *QFSFileEnginePrivate::map(qint64 offset, qint64 size, QFile::MemoryMapFla
int pageSize = getpagesize();
int extra = offset % pageSize;
- if (size + extra > (size_t)-1) {
+ if (quint64(size + extra) > quint64((size_t)-1)) {
q->setError(QFile::UnspecifiedError, qt_error_string(int(EINVAL)));
return 0;
}
diff --git a/src/corelib/io/qfsfileengine_win.cpp b/src/corelib/io/qfsfileengine_win.cpp
index bec0075..d8b1c03 100644
--- a/src/corelib/io/qfsfileengine_win.cpp
+++ b/src/corelib/io/qfsfileengine_win.cpp
@@ -66,10 +66,6 @@
#include <ctype.h>
#include <limits.h>
#define SECURITY_WIN32
-#ifdef Q_CC_MINGW
-// A workaround for a certain version of MinGW, the define UNICODE_STRING.
-#include <subauth.h>
-#endif
#include <security.h>
#ifndef _INTPTR_T_DEFINED
@@ -181,7 +177,7 @@ void QFSFileEnginePrivate::resolveLibs()
triedResolve = true;
#if !defined(Q_OS_WINCE)
- HINSTANCE advapiHnd = LoadLibraryW(L"advapi32");
+ HINSTANCE advapiHnd = LoadLibrary(L"advapi32");
if (advapiHnd) {
ptrGetNamedSecurityInfoW = (PtrGetNamedSecurityInfoW)GetProcAddress(advapiHnd, "GetNamedSecurityInfoW");
ptrLookupAccountSidW = (PtrLookupAccountSidW)GetProcAddress(advapiHnd, "LookupAccountSidW");
@@ -213,7 +209,7 @@ void QFSFileEnginePrivate::resolveLibs()
ptrFreeSid(pWorld);
}
}
- HINSTANCE userenvHnd = LoadLibraryW(L"userenv");
+ HINSTANCE userenvHnd = LoadLibrary(L"userenv");
if (userenvHnd)
ptrGetUserProfileDirectoryW = (PtrGetUserProfileDirectoryW)GetProcAddress(userenvHnd, "GetUserProfileDirectoryW");
#endif
@@ -221,7 +217,6 @@ void QFSFileEnginePrivate::resolveLibs()
}
#endif // QT_NO_LIBRARY
-// UNC functions NT
typedef DWORD (WINAPI *PtrNetShareEnum)(LPWSTR, DWORD, LPBYTE*, DWORD, LPDWORD, LPDWORD, LPDWORD);
static PtrNetShareEnum ptrNetShareEnum = 0;
typedef DWORD (WINAPI *PtrNetApiBufferFree)(LPVOID);
@@ -245,7 +240,7 @@ bool QFSFileEnginePrivate::resolveUNCLibs()
#endif
triedResolve = true;
#if !defined(Q_OS_WINCE)
- HINSTANCE hLib = LoadLibraryW(L"Netapi32");
+ HINSTANCE hLib = LoadLibrary(L"netapi32");
if (hLib) {
ptrNetShareEnum = (PtrNetShareEnum)GetProcAddress(hLib, "NetShareEnum");
if (ptrNetShareEnum)
@@ -1042,11 +1037,11 @@ QString QFSFileEngine::homePath()
if (ok) {
DWORD dwBufferSize = 0;
// First call, to determine size of the strings (with '\0').
- ok = ::ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize);
+ ok = ptrGetUserProfileDirectoryW(token, NULL, &dwBufferSize);
if (!ok && dwBufferSize != 0) { // We got the required buffer size
wchar_t *userDirectory = new wchar_t[dwBufferSize];
// Second call, now we can fill the allocated buffer.
- ok = ::ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize);
+ ok = ptrGetUserProfileDirectoryW(token, userDirectory, &dwBufferSize);
if (ok)
ret = QString::fromWCharArray(userDirectory);
@@ -1418,7 +1413,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
QAbstractFileEngine::FileFlags ret = 0;
#if !defined(QT_NO_LIBRARY)
- if((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) {
+ if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
resolveLibs();
if(ptrGetNamedSecurityInfoW && ptrBuildTrusteeWithSidW && ptrGetEffectiveRightsFromAclW) {
enum { ReadMask = 0x00000001, WriteMask = 0x00000002, ExecMask = 0x00000020 };
@@ -1484,7 +1479,7 @@ QAbstractFileEngine::FileFlags QFSFileEnginePrivate::getPermissions() const
{
//### what to do with permissions if we don't use NTFS
// for now just add all permissions and what about exe missions ??
- // also qt_ntfs_permission_lookup is now not set by defualt ... should it ?
+ // also qt_ntfs_permission_lookup is now not set by default ... should it ?
ret |= QAbstractFileEngine::ReadOtherPerm | QAbstractFileEngine::ReadGroupPerm
| QAbstractFileEngine::ReadOwnerPerm | QAbstractFileEngine::ReadUserPerm
| QAbstractFileEngine::WriteUserPerm | QAbstractFileEngine::WriteOwnerPerm
@@ -1721,8 +1716,7 @@ QString QFSFileEngine::owner(FileOwner own) const
QString name;
#if !defined(QT_NO_LIBRARY)
Q_D(const QFSFileEngine);
-
- if ((qt_ntfs_permission_lookup > 0) && ((QSysInfo::WindowsVersion&QSysInfo::WV_NT_based) > QSysInfo::WV_NT)) {
+ if((qt_ntfs_permission_lookup > 0) && (QSysInfo::WindowsVersion & QSysInfo::WV_NT_based)) {
QFSFileEnginePrivate::resolveLibs();
if (ptrGetNamedSecurityInfoW && ptrLookupAccountSidW) {
PSID pOwner = 0;
diff --git a/src/corelib/io/qiodevice.cpp b/src/corelib/io/qiodevice.cpp
index 4e14ba8..662100a 100644
--- a/src/corelib/io/qiodevice.cpp
+++ b/src/corelib/io/qiodevice.cpp
@@ -1003,8 +1003,8 @@ QByteArray QIODevice::readAll()
to a maximum of \a maxSize - 1 bytes, stores the characters in \a
data, and returns the number of bytes read. If a line could not be
read but no error ocurred, this function returns 0. If an error
- occurs, this function returns what it could the length of what
- could be read, or -1 if nothing was read.
+ occurs, this function returns the length of what could be read, or
+ -1 if nothing was read.
A terminating '\0' byte is always appended to \a data, so \a
maxSize must be larger than 1.
diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp
index 75cde51..07d10ad 100644
--- a/src/corelib/io/qprocess_symbian.cpp
+++ b/src/corelib/io/qprocess_symbian.cpp
@@ -1002,7 +1002,7 @@ bool QProcessPrivate::waitForDeadChild()
TExitCategoryName catName = symbianProcess->ExitCategory();
qDebug() << "QProcessPrivate::waitForDeadChild() dead with exitCode"
<< exitCode << ", crashed:" << crashed
- << ", category:" << QString::fromUtf16(catName.Ptr());
+ << ", category:" << QString((const QChar *)catName.Ptr());
#endif
} else {
QPROCESS_DEBUG_PRINT("QProcessPrivate::waitForDeadChild() not dead!");
diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp
index adfbb15..6d33c8b 100644
--- a/src/corelib/io/qresource.cpp
+++ b/src/corelib/io/qresource.cpp
@@ -555,16 +555,15 @@ QStringList QResource::children() const
/*!
\obsolete
+ Use QDir::addSearchPath() with a prefix instead.
+
Adds \a path to the search paths searched in to find resources that are
not specified with an absolute path. The \a path must be an absolute
path (start with \c{/}).
The default search path is to search only in the root (\c{:/}). The last
path added will be consulted first upon next QResource creation.
-
- Use QDir::addSearchPath() with a prefix instead.
*/
-
void
QResource::addSearchPath(const QString &path)
{
@@ -578,6 +577,10 @@ QResource::addSearchPath(const QString &path)
}
/*!
+ \obsolete
+
+ Use QDir::searchPaths() instead.
+
Returns the current search path list. This list is consulted when
creating a relative resource.
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index 076cc33..626bd3f 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -167,6 +167,13 @@
regardless of the Qt::FormattingOptions used.
*/
+/*!
+ \fn uint qHash(const QUrl &url)
+ \since 4.7
+ \relates QUrl
+
+ Computes a hash key from the normalized version of \a url.
+ */
#include "qplatformdefs.h"
#include "qurl.h"
#include "private/qunicodetables_p.h"
@@ -437,17 +444,19 @@ static bool QT_FASTCALL _unreserved(const char **ptr)
}
// scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-static void QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
+static bool QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
{
bool first = true;
+ bool isSchemeValid = true;
parseData->scheme = *ptr;
for (;;) {
char ch = **ptr;
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')) {
;
- } else if (!first && ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.')) {
- ;
+ } else if ((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '.') {
+ if (first)
+ isSchemeValid = false;
} else {
break;
}
@@ -457,11 +466,14 @@ static void QT_FASTCALL _scheme(const char **ptr, QUrlParseData *parseData)
}
if (**ptr != ':') {
+ isSchemeValid = true;
*ptr = parseData->scheme;
} else {
parseData->schemeLength = *ptr - parseData->scheme;
++(*ptr); // skip ':'
}
+
+ return isSchemeValid;
}
// IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" )
@@ -3743,7 +3755,19 @@ void QUrlPrivate::parse(ParseOptions parseOptions) const
#endif
// optional scheme
- _scheme(ptr, &parseData);
+ bool isSchemeValid = _scheme(ptr, &parseData);
+
+ if (isSchemeValid == false) {
+ that->isValid = false;
+ char ch = *((*ptr)++);
+ that->errorInfo.setParams(*ptr, QT_TRANSLATE_NOOP(QUrl, "unexpected URL scheme"),
+ 0, ch);
+ QURL_SETFLAG(that->stateFlags, Validated | Parsed);
+#if defined (QURL_DEBUG)
+ qDebug("QUrlPrivate::parse(), unrecognized: %c%s", ch, *ptr);
+#endif
+ return;
+ }
// hierpart
_hierPart(ptr, &parseData);
@@ -6348,7 +6372,7 @@ QUrl QUrl::fromUserInput(const QString &userInput)
return QUrl::fromLocalFile(trimmedString);
QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
- QUrl urlPrepended = QUrl::fromEncoded((QLatin1String("http://") + trimmedString).toUtf8(), QUrl::TolerantMode);
+ QUrl urlPrepended = QUrl::fromEncoded("http://" + trimmedString.toUtf8(), QUrl::TolerantMode);
// Check the most common case of a valid url with scheme and host
// We check if the port would be valid by adding the scheme to handle the case host:port
diff --git a/src/corelib/io/qurl.h b/src/corelib/io/qurl.h
index 0aa534a..6f8331a 100644
--- a/src/corelib/io/qurl.h
+++ b/src/corelib/io/qurl.h
@@ -46,6 +46,7 @@
#include <QtCore/qobjectdefs.h>
#include <QtCore/qpair.h>
#include <QtCore/qstring.h>
+#include <QtCore/qhash.h>
QT_BEGIN_HEADER
@@ -75,6 +76,7 @@ public:
RemovePath = 0x20,
RemoveQuery = 0x40,
RemoveFragment = 0x80,
+ // 0x100: private: normalized
StripTrailingSlash = 0x10000
};
@@ -268,6 +270,11 @@ public:
inline DataPtr &data_ptr() { return d; }
};
+inline uint qHash(const QUrl &url)
+{
+ return qHash(url.toEncoded(QUrl::FormattingOption(0x100)));
+}
+
Q_DECLARE_TYPEINFO(QUrl, Q_MOVABLE_TYPE);
Q_DECLARE_SHARED(QUrl)
Q_DECLARE_OPERATORS_FOR_FLAGS(QUrl::FormattingOptions)
diff --git a/src/corelib/kernel/qabstractitemmodel.cpp b/src/corelib/kernel/qabstractitemmodel.cpp
index 36e4af9..b0503be 100644
--- a/src/corelib/kernel/qabstractitemmodel.cpp
+++ b/src/corelib/kernel/qabstractitemmodel.cpp
@@ -1248,7 +1248,7 @@ void QAbstractItemModelPrivate::columnsRemoved(const QModelIndex &parent,
/*!
\fn QModelIndex QAbstractItemModel::parent(const QModelIndex &index) const = 0
- Returns the parent of the model item with the given \a index. If the model
+ Returns the parent of the model item with the given \a index. If the item
has no parent, an invalid QModelIndex is returned.
A common convention used in models that expose tree data structures is that
diff --git a/src/corelib/kernel/qcoreapplication_win.cpp b/src/corelib/kernel/qcoreapplication_win.cpp
index 5990f86..566626d 100644
--- a/src/corelib/kernel/qcoreapplication_win.cpp
+++ b/src/corelib/kernel/qcoreapplication_win.cpp
@@ -1021,14 +1021,14 @@ QString decodeMSG(const MSG& msg)
LPWINDOWPOS winPos = (LPWINDOWPOS)lParam;
if (!winPos)
break;
- QString hwndAfter = valueCheck((uint)winPos->hwndInsertAfter,
- FLAG_STRING((uint)HWND_BOTTOM, "HWND_BOTTOM"),
- FLAG_STRING((int)HWND_NOTOPMOST, "HWND_NOTOPMOST"),
- FLAG_STRING((uint)HWND_TOP, "HWND_TOP"),
- FLAG_STRING((int)HWND_TOPMOST, "HWND_TOPMOST"),
+ QString hwndAfter = valueCheck(quint64(winPos->hwndInsertAfter),
+ FLAG_STRING((quintptr)HWND_BOTTOM, "HWND_BOTTOM"),
+ FLAG_STRING((quintptr)HWND_NOTOPMOST, "HWND_NOTOPMOST"),
+ FLAG_STRING((quintptr)HWND_TOP, "HWND_TOP"),
+ FLAG_STRING((quintptr)HWND_TOPMOST, "HWND_TOPMOST"),
FLAG_STRING());
if (hwndAfter.size() == 0)
- hwndAfter = QString::number((uint)winPos->hwndInsertAfter, 16);
+ hwndAfter = QString::number((quintptr)winPos->hwndInsertAfter, 16);
QString flags = flagCheck(winPos->flags,
FLGSTR(SWP_DRAWFRAME),
FLGSTR(SWP_FRAMECHANGED),
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index 3500b63..d23ea4c 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -272,7 +272,6 @@ QT_BEGIN_NAMESPACE
\omitvalue MacGLClearDrawable
\omitvalue NetworkReplyUpdated
\omitvalue FutureCallOut
- \omitvalue CocoaRequestModal
\omitvalue UpdateSoftKeys
\omitvalue NativeGesture
*/
@@ -331,7 +330,7 @@ QEvent::~QEvent()
equivalent of calling setAccepted(false).
Clearing the accept parameter indicates that the event receiver
- does not want the event. Unwanted events might be propgated to the
+ does not want the event. Unwanted events might be propagated to the
parent widget.
\sa accept()
diff --git a/src/corelib/kernel/qcoreevent.h b/src/corelib/kernel/qcoreevent.h
index c76e81b..a20d171 100644
--- a/src/corelib/kernel/qcoreevent.h
+++ b/src/corelib/kernel/qcoreevent.h
@@ -266,7 +266,6 @@ public:
UngrabMouse = 187,
GrabKeyboard = 188,
UngrabKeyboard = 189,
- CocoaRequestModal = 190, // Internal for requesting an application modal Cocoa Window
MacGLClearDrawable = 191, // Internal Cocoa, the window has changed, so we must clear
StateMachineSignal = 192,
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index cbc87f3..4755540 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -68,6 +68,14 @@ extern uint qGlobalPostedEventsCount();
# define QS_RAWINPUT 0x0400
#endif
+#ifndef WM_TOUCH
+# define WM_TOUCH 0x0240
+#endif
+#ifndef WM_GESTURE
+# define WM_GESTURE 0x0119
+# define WM_GESTURENOTIFY 0x011A
+#endif
+
enum {
WM_QT_SOCKETNOTIFIER = WM_USER,
WM_QT_SENDPOSTEDEVENTS = WM_USER + 1,
@@ -341,6 +349,9 @@ public:
// for controlling when to send posted events
QAtomicInt serialNumber;
int lastSerialNumber;
+#ifndef Q_OS_WINCE
+ int lastMessageTime;
+#endif
QAtomicInt wakeUps;
// timers
@@ -364,7 +375,12 @@ public:
};
QEventDispatcherWin32Private::QEventDispatcherWin32Private()
- : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0), serialNumber(0), lastSerialNumber(0), wakeUps(0)
+ : threadId(GetCurrentThreadId()), interrupt(false), internalHwnd(0), getMessageHook(0),
+ serialNumber(0), lastSerialNumber(0),
+#ifndef Q_OS_WINCE
+ lastMessageTime(0),
+#endif
+ wakeUps(0)
{
resolveTimerAPI();
}
@@ -479,6 +495,9 @@ LRESULT CALLBACK qt_internal_proc(HWND hwnd, UINT message, WPARAM wp, LPARAM lp)
int localSerialNumber = d->serialNumber;
if (localSerialNumber != d->lastSerialNumber) {
d->lastSerialNumber = localSerialNumber;
+#ifndef Q_OS_WINCE
+ d->lastMessageTime = GetMessageTime();
+#endif
QCoreApplicationPrivate::sendPostedEvents(0, 0, d->threadData);
}
return 0;
@@ -495,15 +514,19 @@ LRESULT CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
if (q) {
QEventDispatcherWin32Private *d = q->d_func();
int localSerialNumber = d->serialNumber;
- if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0) {
- // no more input or timer events in the message queue, we can allow posted events to be
- // sent now
+ if (HIWORD(GetQueueStatus(QS_INPUT | QS_RAWINPUT | QS_TIMER)) == 0
+#ifndef Q_OS_WINCE
+ || GetMessageTime() - d->lastMessageTime >= 10
+#endif
+ ) {
+ // no more input or timer events in the message queue or more than 10ms has elapsed since
+ // we send posted events, we can allow posted events to be sent now
(void) d->wakeUps.fetchAndStoreRelease(0);
MSG *msg = (MSG *) lp;
if (localSerialNumber != d->lastSerialNumber
// if this message IS the one that triggers sendPostedEvents(), no need to post it again
- && msg->hwnd != d->internalHwnd
- && msg->message != WM_QT_SENDPOSTEDEVENTS) {
+ && (msg->hwnd != d->internalHwnd
+ || msg->message != WM_QT_SENDPOSTEDEVENTS)) {
PostMessage(d->internalHwnd, WM_QT_SENDPOSTEDEVENTS, 0, 0);
}
}
@@ -714,6 +737,9 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
&& msg.message <= WM_MOUSELAST)
|| msg.message == WM_MOUSEWHEEL
|| msg.message == WM_MOUSEHWHEEL
+ || msg.message == WM_TOUCH
+ || msg.message == WM_GESTURE
+ || msg.message == WM_GESTURENOTIFY
|| msg.message == WM_CLOSE)) {
// queue user input events for later processing
haveMessage = false;
@@ -744,6 +770,8 @@ bool QEventDispatcherWin32::processEvents(QEventLoop::ProcessEventsFlags flags)
if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {
if (seenWM_QT_SENDPOSTEDEVENTS) {
+ // when calling processEvents() "manually", we only want to send posted
+ // events once
needWM_QT_SENDPOSTEDEVENTS = true;
continue;
}
diff --git a/src/corelib/kernel/qmetaobject.cpp b/src/corelib/kernel/qmetaobject.cpp
index cd7418a..be1b2ae 100644
--- a/src/corelib/kernel/qmetaobject.cpp
+++ b/src/corelib/kernel/qmetaobject.cpp
@@ -482,6 +482,46 @@ int QMetaObject::classInfoCount() const
return n;
}
+/** \internal
+* helper class for indexOf{Method,Slot,Signal}, returns the relative index of the method within
+* the baseObject
+* \a MethodType might be MethodSignal or MethodSlot, or 0 to match everything.
+*/
+template<int MethodType>
+static inline int indexOfMethodRelative(const QMetaObject **baseObject,
+ const char *method,
+ bool normalizeStringData)
+{
+ const QMetaObject *m;
+ for (m = *baseObject; m; m = *baseObject = m->d.superdata) {
+ const QMetaObject *const m = *baseObject;
+ int i = (MethodType == MethodSignal && priv(m->d.data)->revision >= 4)
+ ? (priv(m->d.data)->signalCount - 1) : (priv(m->d.data)->methodCount - 1);
+ if (i < 0)
+ continue;
+
+ const int end = (MethodType == MethodSlot && priv(m->d.data)->revision >= 4)
+ ? (priv(m->d.data)->signalCount) : 0;
+ if (!normalizeStringData) {
+ for (; i >= end; --i) {
+ if ((MethodType == 0 || (m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodType)
+ && strcmp(method, m->d.stringdata + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0)
+ return i;
+ }
+ } else if (priv(m->d.data)->revision < 5) {
+ const char *stringdata = (m->d.stringdata + m->d.data[priv(m->d.data)->methodData + 5 * i]);
+ const QByteArray normalizedSignature = QMetaObject::normalizedSignature(stringdata);
+ for (; i >= end; --i) {
+ if ((MethodType == 0|| (m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodType)
+ && normalizedSignature == method)
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+
+
/*!
\since 4.5
@@ -515,17 +555,14 @@ int QMetaObject::indexOfConstructor(const char *constructor) const
*/
int QMetaObject::indexOfMethod(const char *method) const
{
- int i = -1;
const QMetaObject *m = this;
- while (m && i < 0) {
- for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
- if (strcmp(method, m->d.stringdata
- + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
- i += m->methodOffset();
- break;
- }
- m = m->d.superdata;
+ int i = indexOfMethodRelative<0>(&m, method, false);
+ if (i < 0) {
+ m = this;
+ i = indexOfMethodRelative<0>(&m, method, true);
}
+ if (i >= 0)
+ i += m->methodOffset();
return i;
}
@@ -543,7 +580,11 @@ int QMetaObject::indexOfMethod(const char *method) const
int QMetaObject::indexOfSignal(const char *signal) const
{
const QMetaObject *m = this;
- int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal);
+ int i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, false);
+ if (i < 0) {
+ m = this;
+ i = QMetaObjectPrivate::indexOfSignalRelative(&m, signal, true);
+ }
if (i >= 0)
i += m->methodOffset();
return i;
@@ -554,21 +595,11 @@ int QMetaObject::indexOfSignal(const char *signal) const
\a baseObject will be adjusted to the enclosing QMetaObject, or 0 if the signal is not found
*/
-int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, const char *signal)
+int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject,
+ const char *signal,
+ bool normalizeStringData)
{
- int i = -1;
- while (*baseObject) {
- const QMetaObject *const m = *baseObject;
- for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
- if ((m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodSignal
- && strcmp(signal, m->d.stringdata
- + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
- break;
- }
- if (i >= 0)
- break;
- *baseObject = m->d.superdata;
- }
+ int i = indexOfMethodRelative<MethodSignal>(baseObject, signal, normalizeStringData);
#ifndef QT_NO_DEBUG
const QMetaObject *m = *baseObject;
if (i >= 0 && m && m->d.superdata) {
@@ -581,7 +612,6 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co
return i;
}
-
/*!
Finds \a slot and returns its index; otherwise returns -1.
@@ -592,18 +622,19 @@ int QMetaObjectPrivate::indexOfSignalRelative(const QMetaObject **baseObject, co
*/
int QMetaObject::indexOfSlot(const char *slot) const
{
- int i = -1;
- const QMetaObject *m = this;
- while (m && i < 0) {
- for (i = priv(m->d.data)->methodCount-1; i >= 0; --i)
- if ((m->d.data[priv(m->d.data)->methodData + 5*i + 4] & MethodTypeMask) == MethodSlot
- && strcmp(slot, m->d.stringdata
- + m->d.data[priv(m->d.data)->methodData + 5*i]) == 0) {
- i += m->methodOffset();
- break;
- }
- m = m->d.superdata;
- }
+ int i = QMetaObjectPrivate::indexOfSlot(this, slot, false);
+ if (i < 0)
+ i = QMetaObjectPrivate::indexOfSlot(this, slot, true);
+ return i;
+}
+
+int QMetaObjectPrivate::indexOfSlot(const QMetaObject *m,
+ const char *slot,
+ bool normalizeStringData)
+{
+ int i = indexOfMethodRelative<MethodSlot>(&m, slot, normalizeStringData);
+ if (i >= 0)
+ i += m->methodOffset();
return i;
}
diff --git a/src/corelib/kernel/qmetaobject_p.h b/src/corelib/kernel/qmetaobject_p.h
index 3bbb050..a176149 100644
--- a/src/corelib/kernel/qmetaobject_p.h
+++ b/src/corelib/kernel/qmetaobject_p.h
@@ -115,11 +115,17 @@ struct QMetaObjectPrivate
int constructorCount, constructorData; //since revision 2
int flags; //since revision 3
int signalCount; //since revision 4
+ // revision 5 introduces changes in normalized signatures, no new members
static inline const QMetaObjectPrivate *get(const QMetaObject *metaobject)
{ return reinterpret_cast<const QMetaObjectPrivate*>(metaobject->d.data); }
- static int indexOfSignalRelative(const QMetaObject **baseObject, const char* name);
+ static int indexOfSignalRelative(const QMetaObject **baseObject,
+ const char* name,
+ bool normalizeStringData);
+ static int indexOfSlot(const QMetaObject *m,
+ const char *slot,
+ bool normalizeStringData);
static int originalClone(const QMetaObject *obj, int local_method_index);
#ifndef QT_NO_QOBJECT
@@ -247,6 +253,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc
} while (optional[++i].keyword != 0);
}
+ bool star = false;
while (t != e) {
char c = *t++;
if (fixScope && c == ':' && *t == ':' ) {
@@ -257,6 +264,7 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc
--i;
result.resize(i + 1);
}
+ star = star || c == '*';
result += c;
if (c == '<') {
//template recursion
@@ -277,6 +285,23 @@ static QByteArray normalizeTypeInternal(const char *t, const char *e, bool fixSc
}
}
}
+
+ // cv qualifers can appear after the type as well
+ if (t != e && (e - t >= 5 && strncmp("const", t, 5) == 0)) {
+ t += 5;
+ while (t != e && is_space(*t))
+ ++t;
+ if (adjustConst && t != e && *t == '&') {
+ // treat const ref as value
+ ++t;
+ } else if (!star) {
+ // move const to the front (but not if const comes after a *)
+ result.prepend("const ");
+ } else {
+ // keep const after a *
+ result += "const";
+ }
+ }
}
return result;
diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp
index e304290..779b69b 100644
--- a/src/corelib/kernel/qmetatype.cpp
+++ b/src/corelib/kernel/qmetatype.cpp
@@ -48,6 +48,7 @@
#include "qstringlist.h"
#include "qvector.h"
#include "qlocale.h"
+#include "qeasingcurve.h"
#ifdef QT_BOOTSTRAPPED
# ifndef QT_NO_GEOM_VARIANT
@@ -176,6 +177,7 @@ QT_BEGIN_NAMESPACE
\value QVector3D QVector3D
\value QVector4D QVector4D
\value QQuaternion QQuaternion
+ \value QEasingCurve QEasingCurve
\value User Base value for user types
@@ -223,100 +225,104 @@ QT_BEGIN_NAMESPACE
\sa Q_DECLARE_METATYPE(), QVariant::setValue(), QVariant::value(), QVariant::fromValue()
*/
+#define QT_ADD_STATIC_METATYPE(STR, TP) \
+ { STR, sizeof(STR) - 1, TP }
+
/* Note: these MUST be in the order of the enums */
-static const struct { const char * typeName; int type; } types[] = {
+static const struct { const char * typeName; int typeNameLength; int type; } types[] = {
/* All Core types */
- {"void", QMetaType::Void},
- {"bool", QMetaType::Bool},
- {"int", QMetaType::Int},
- {"uint", QMetaType::UInt},
- {"qlonglong", QMetaType::LongLong},
- {"qulonglong", QMetaType::ULongLong},
- {"double", QMetaType::Double},
- {"QChar", QMetaType::QChar},
- {"QVariantMap", QMetaType::QVariantMap},
- {"QVariantList", QMetaType::QVariantList},
- {"QString", QMetaType::QString},
- {"QStringList", QMetaType::QStringList},
- {"QByteArray", QMetaType::QByteArray},
- {"QBitArray", QMetaType::QBitArray},
- {"QDate", QMetaType::QDate},
- {"QTime", QMetaType::QTime},
- {"QDateTime", QMetaType::QDateTime},
- {"QUrl", QMetaType::QUrl},
- {"QLocale", QMetaType::QLocale},
- {"QRect", QMetaType::QRect},
- {"QRectF", QMetaType::QRectF},
- {"QSize", QMetaType::QSize},
- {"QSizeF", QMetaType::QSizeF},
- {"QLine", QMetaType::QLine},
- {"QLineF", QMetaType::QLineF},
- {"QPoint", QMetaType::QPoint},
- {"QPointF", QMetaType::QPointF},
- {"QRegExp", QMetaType::QRegExp},
- {"QVariantHash", QMetaType::QVariantHash},
+ QT_ADD_STATIC_METATYPE("void", QMetaType::Void),
+ QT_ADD_STATIC_METATYPE("bool", QMetaType::Bool),
+ QT_ADD_STATIC_METATYPE("int", QMetaType::Int),
+ QT_ADD_STATIC_METATYPE("uint", QMetaType::UInt),
+ QT_ADD_STATIC_METATYPE("qlonglong", QMetaType::LongLong),
+ QT_ADD_STATIC_METATYPE("qulonglong", QMetaType::ULongLong),
+ QT_ADD_STATIC_METATYPE("double", QMetaType::Double),
+ QT_ADD_STATIC_METATYPE("QChar", QMetaType::QChar),
+ QT_ADD_STATIC_METATYPE("QVariantMap", QMetaType::QVariantMap),
+ QT_ADD_STATIC_METATYPE("QVariantList", QMetaType::QVariantList),
+ QT_ADD_STATIC_METATYPE("QString", QMetaType::QString),
+ QT_ADD_STATIC_METATYPE("QStringList", QMetaType::QStringList),
+ QT_ADD_STATIC_METATYPE("QByteArray", QMetaType::QByteArray),
+ QT_ADD_STATIC_METATYPE("QBitArray", QMetaType::QBitArray),
+ QT_ADD_STATIC_METATYPE("QDate", QMetaType::QDate),
+ QT_ADD_STATIC_METATYPE("QTime", QMetaType::QTime),
+ QT_ADD_STATIC_METATYPE("QDateTime", QMetaType::QDateTime),
+ QT_ADD_STATIC_METATYPE("QUrl", QMetaType::QUrl),
+ QT_ADD_STATIC_METATYPE("QLocale", QMetaType::QLocale),
+ QT_ADD_STATIC_METATYPE("QRect", QMetaType::QRect),
+ QT_ADD_STATIC_METATYPE("QRectF", QMetaType::QRectF),
+ QT_ADD_STATIC_METATYPE("QSize", QMetaType::QSize),
+ QT_ADD_STATIC_METATYPE("QSizeF", QMetaType::QSizeF),
+ QT_ADD_STATIC_METATYPE("QLine", QMetaType::QLine),
+ QT_ADD_STATIC_METATYPE("QLineF", QMetaType::QLineF),
+ QT_ADD_STATIC_METATYPE("QPoint", QMetaType::QPoint),
+ QT_ADD_STATIC_METATYPE("QPointF", QMetaType::QPointF),
+ QT_ADD_STATIC_METATYPE("QRegExp", QMetaType::QRegExp),
+ QT_ADD_STATIC_METATYPE("QVariantHash", QMetaType::QVariantHash),
+ QT_ADD_STATIC_METATYPE("QEasingCurve", QMetaType::QEasingCurve),
/* All GUI types */
- {"QColorGroup", 63},
- {"QFont", QMetaType::QFont},
- {"QPixmap", QMetaType::QPixmap},
- {"QBrush", QMetaType::QBrush},
- {"QColor", QMetaType::QColor},
- {"QPalette", QMetaType::QPalette},
- {"QIcon", QMetaType::QIcon},
- {"QImage", QMetaType::QImage},
- {"QPolygon", QMetaType::QPolygon},
- {"QRegion", QMetaType::QRegion},
- {"QBitmap", QMetaType::QBitmap},
- {"QCursor", QMetaType::QCursor},
- {"QSizePolicy", QMetaType::QSizePolicy},
- {"QKeySequence", QMetaType::QKeySequence},
- {"QPen", QMetaType::QPen},
- {"QTextLength", QMetaType::QTextLength},
- {"QTextFormat", QMetaType::QTextFormat},
- {"QMatrix", QMetaType::QMatrix},
- {"QTransform", QMetaType::QTransform},
- {"QMatrix4x4", QMetaType::QMatrix4x4},
- {"QVector2D", QMetaType::QVector2D},
- {"QVector3D", QMetaType::QVector3D},
- {"QVector4D", QMetaType::QVector4D},
- {"QQuaternion", QMetaType::QQuaternion},
+ QT_ADD_STATIC_METATYPE("QColorGroup", 63),
+ QT_ADD_STATIC_METATYPE("QFont", QMetaType::QFont),
+ QT_ADD_STATIC_METATYPE("QPixmap", QMetaType::QPixmap),
+ QT_ADD_STATIC_METATYPE("QBrush", QMetaType::QBrush),
+ QT_ADD_STATIC_METATYPE("QColor", QMetaType::QColor),
+ QT_ADD_STATIC_METATYPE("QPalette", QMetaType::QPalette),
+ QT_ADD_STATIC_METATYPE("QIcon", QMetaType::QIcon),
+ QT_ADD_STATIC_METATYPE("QImage", QMetaType::QImage),
+ QT_ADD_STATIC_METATYPE("QPolygon", QMetaType::QPolygon),
+ QT_ADD_STATIC_METATYPE("QRegion", QMetaType::QRegion),
+ QT_ADD_STATIC_METATYPE("QBitmap", QMetaType::QBitmap),
+ QT_ADD_STATIC_METATYPE("QCursor", QMetaType::QCursor),
+ QT_ADD_STATIC_METATYPE("QSizePolicy", QMetaType::QSizePolicy),
+ QT_ADD_STATIC_METATYPE("QKeySequence", QMetaType::QKeySequence),
+ QT_ADD_STATIC_METATYPE("QPen", QMetaType::QPen),
+ QT_ADD_STATIC_METATYPE("QTextLength", QMetaType::QTextLength),
+ QT_ADD_STATIC_METATYPE("QTextFormat", QMetaType::QTextFormat),
+ QT_ADD_STATIC_METATYPE("QMatrix", QMetaType::QMatrix),
+ QT_ADD_STATIC_METATYPE("QTransform", QMetaType::QTransform),
+ QT_ADD_STATIC_METATYPE("QMatrix4x4", QMetaType::QMatrix4x4),
+ QT_ADD_STATIC_METATYPE("QVector2D", QMetaType::QVector2D),
+ QT_ADD_STATIC_METATYPE("QVector3D", QMetaType::QVector3D),
+ QT_ADD_STATIC_METATYPE("QVector4D", QMetaType::QVector4D),
+ QT_ADD_STATIC_METATYPE("QQuaternion", QMetaType::QQuaternion),
/* All Metatype builtins */
- {"void*", QMetaType::VoidStar},
- {"long", QMetaType::Long},
- {"short", QMetaType::Short},
- {"char", QMetaType::Char},
- {"ulong", QMetaType::ULong},
- {"ushort", QMetaType::UShort},
- {"uchar", QMetaType::UChar},
- {"float", QMetaType::Float},
- {"QObject*", QMetaType::QObjectStar},
- {"QWidget*", QMetaType::QWidgetStar},
+ QT_ADD_STATIC_METATYPE("void*", QMetaType::VoidStar),
+ QT_ADD_STATIC_METATYPE("long", QMetaType::Long),
+ QT_ADD_STATIC_METATYPE("short", QMetaType::Short),
+ QT_ADD_STATIC_METATYPE("char", QMetaType::Char),
+ QT_ADD_STATIC_METATYPE("ulong", QMetaType::ULong),
+ QT_ADD_STATIC_METATYPE("ushort", QMetaType::UShort),
+ QT_ADD_STATIC_METATYPE("uchar", QMetaType::UChar),
+ QT_ADD_STATIC_METATYPE("float", QMetaType::Float),
+ QT_ADD_STATIC_METATYPE("QObject*", QMetaType::QObjectStar),
+ QT_ADD_STATIC_METATYPE("QWidget*", QMetaType::QWidgetStar),
/* Type aliases - order doesn't matter */
- {"unsigned long", QMetaType::ULong},
- {"unsigned int", QMetaType::UInt},
- {"unsigned short", QMetaType::UShort},
- {"unsigned char", QMetaType::UChar},
- {"long long", QMetaType::LongLong},
- {"unsigned long long", QMetaType::ULongLong},
- {"qint8", QMetaType::Char},
- {"quint8", QMetaType::UChar},
- {"qint16", QMetaType::Short},
- {"quint16", QMetaType::UShort},
- {"qint32", QMetaType::Int},
- {"quint32", QMetaType::UInt},
- {"qint64", QMetaType::LongLong},
- {"quint64", QMetaType::ULongLong},
- {"QList<QVariant>", QMetaType::QVariantList},
- {"QMap<QString,QVariant>", QMetaType::QVariantMap},
- {"QHash<QString,QVariant>", QMetaType::QVariantHash},
+ QT_ADD_STATIC_METATYPE("unsigned long", QMetaType::ULong),
+ QT_ADD_STATIC_METATYPE("unsigned int", QMetaType::UInt),
+ QT_ADD_STATIC_METATYPE("unsigned short", QMetaType::UShort),
+ QT_ADD_STATIC_METATYPE("unsigned char", QMetaType::UChar),
+ QT_ADD_STATIC_METATYPE("long long", QMetaType::LongLong),
+ QT_ADD_STATIC_METATYPE("unsigned long long", QMetaType::ULongLong),
+ QT_ADD_STATIC_METATYPE("qint8", QMetaType::Char),
+ QT_ADD_STATIC_METATYPE("quint8", QMetaType::UChar),
+ QT_ADD_STATIC_METATYPE("qint16", QMetaType::Short),
+ QT_ADD_STATIC_METATYPE("quint16", QMetaType::UShort),
+ QT_ADD_STATIC_METATYPE("qint32", QMetaType::Int),
+ QT_ADD_STATIC_METATYPE("quint32", QMetaType::UInt),
+ QT_ADD_STATIC_METATYPE("qint64", QMetaType::LongLong),
+ QT_ADD_STATIC_METATYPE("quint64", QMetaType::ULongLong),
+ QT_ADD_STATIC_METATYPE("QList<QVariant>", QMetaType::QVariantList),
+ QT_ADD_STATIC_METATYPE("QMap<QString,QVariant>", QMetaType::QVariantMap),
+ QT_ADD_STATIC_METATYPE("QHash<QString,QVariant>", QMetaType::QVariantHash),
// let QMetaTypeId2 figure out the type at compile time
- {"qreal", QMetaTypeId2<qreal>::MetaType},
+ QT_ADD_STATIC_METATYPE("qreal", QMetaTypeId2<qreal>::MetaType),
- {0, QMetaType::Void}
+ {0, 0, QMetaType::Void}
};
struct QMetaTypeGuiHelper
@@ -361,7 +367,14 @@ void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveO
int idx = type(typeName);
if (!idx)
return;
+ registerStreamOperators(idx, saveOp, loadOp);
+}
+/*! \internal
+*/
+void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp,
+ LoadOperator loadOp)
+{
QVector<QCustomTypeInfo> *ct = customTypes();
if (!ct)
return;
@@ -400,24 +413,35 @@ const char *QMetaType::typeName(int type)
}
/*! \internal
- Same as QMetaType::type(), but doesn't lock the mutex.
+ Similar to QMetaType::type(), but only looks in the static set of types.
*/
-static int qMetaTypeType_unlocked(const QByteArray &typeName)
+static inline int qMetaTypeStaticType(const char *typeName, int length)
{
int i = 0;
- while (types[i].typeName && strcmp(typeName.constData(), types[i].typeName))
+ while (types[i].typeName && ((length != types[i].typeNameLength)
+ || strcmp(typeName, types[i].typeName))) {
++i;
- if (!types[i].type) {
- const QVector<QCustomTypeInfo> * const ct = customTypes();
- if (!ct)
- return 0;
+ }
+ return types[i].type;
+}
- for (int v = 0; v < ct->count(); ++v) {
- if (ct->at(v).typeName == typeName)
- return v + QMetaType::User;
+/*! \internal
+ Similar to QMetaType::type(), but only looks in the custom set of
+ types, and doesn't lock the mutex.
+*/
+static int qMetaTypeCustomType_unlocked(const char *typeName, int length)
+{
+ const QVector<QCustomTypeInfo> * const ct = customTypes();
+ if (!ct)
+ return 0;
+
+ for (int v = 0; v < ct->count(); ++v) {
+ if ((length == ct->at(v).typeName.size())
+ && !strcmp(typeName, ct->at(v).typeName.constData())) {
+ return v + QMetaType::User;
}
}
- return types[i].type;
+ return 0;
}
/*! \internal
@@ -439,16 +463,21 @@ int QMetaType::registerType(const char *typeName, Destructor destructor,
NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
#endif
- QWriteLocker locker(customTypesLock());
- int idx = qMetaTypeType_unlocked(normalizedTypeName);
+ int idx = qMetaTypeStaticType(normalizedTypeName.constData(),
+ normalizedTypeName.size());
if (!idx) {
- QCustomTypeInfo inf;
- inf.typeName = normalizedTypeName;
- inf.constr = constructor;
- inf.destr = destructor;
- idx = ct->size() + User;
- ct->append(inf);
+ QWriteLocker locker(customTypesLock());
+ idx = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
+ normalizedTypeName.size());
+ if (!idx) {
+ QCustomTypeInfo inf;
+ inf.typeName = normalizedTypeName;
+ inf.constr = constructor;
+ inf.destr = destructor;
+ idx = ct->size() + User;
+ ct->append(inf);
+ }
}
return idx;
}
@@ -507,14 +536,24 @@ bool QMetaType::isRegistered(int type)
*/
int QMetaType::type(const char *typeName)
{
-#ifdef QT_NO_QOBJECT
- const NS(QByteArray) normalizedTypeName = typeName;
-#else
- const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
+ int length = qstrlen(typeName);
+ int type = qMetaTypeStaticType(typeName, length);
+ if (!type) {
+ QReadLocker locker(customTypesLock());
+ type = qMetaTypeCustomType_unlocked(typeName, length);
+#ifndef QT_NO_QOBJECT
+ if (!type) {
+ const NS(QByteArray) normalizedTypeName = QMetaObject::normalizedType(typeName);
+ type = qMetaTypeStaticType(normalizedTypeName.constData(),
+ normalizedTypeName.size());
+ if (!type) {
+ type = qMetaTypeCustomType_unlocked(normalizedTypeName.constData(),
+ normalizedTypeName.size());
+ }
+ }
#endif
-
- QReadLocker locker(customTypesLock());
- return qMetaTypeType_unlocked(normalizedTypeName);
+ }
+ return type;
}
#ifndef QT_NO_DATASTREAM
@@ -659,6 +698,11 @@ bool QMetaType::save(QDataStream &stream, int type, const void *data)
stream << *static_cast<const NS(QRegExp)*>(data);
break;
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QEasingCurve:
+ stream << *static_cast<const NS(QEasingCurve)*>(data);
+ break;
+#endif
#ifdef QT3_SUPPORT
case QMetaType::QColorGroup:
#endif
@@ -856,6 +900,11 @@ bool QMetaType::load(QDataStream &stream, int type, void *data)
stream >> *static_cast< NS(QRegExp)*>(data);
break;
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QEasingCurve:
+ stream >> *static_cast< NS(QEasingCurve)*>(data);
+ break;
+#endif
#ifdef QT3_SUPPORT
case QMetaType::QColorGroup:
#endif
@@ -1000,6 +1049,10 @@ void *QMetaType::construct(int type, const void *copy)
case QMetaType::QRegExp:
return new NS(QRegExp)(*static_cast<const NS(QRegExp)*>(copy));
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QEasingCurve:
+ return new NS(QEasingCurve)(*static_cast<const NS(QEasingCurve)*>(copy));
+#endif
case QMetaType::Void:
return 0;
default:
@@ -1091,6 +1144,10 @@ void *QMetaType::construct(int type, const void *copy)
case QMetaType::QRegExp:
return new NS(QRegExp);
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QEasingCurve:
+ return new NS(QEasingCurve);
+#endif
case QMetaType::Void:
return 0;
default:
@@ -1246,6 +1303,11 @@ void QMetaType::destroy(int type, void *data)
delete static_cast< NS(QRegExp)* >(data);
break;
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QMetaType::QEasingCurve:
+ delete static_cast< NS(QEasingCurve)* >(data);
+ break;
+#endif
case QMetaType::Void:
break;
default: {
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index c0dd288..33126e8 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -69,7 +69,7 @@ public:
QBitArray = 13, QDate = 14, QTime = 15, QDateTime = 16, QUrl = 17,
QLocale = 18, QRect = 19, QRectF = 20, QSize = 21, QSizeF = 22,
QLine = 23, QLineF = 24, QPoint = 25, QPointF = 26, QRegExp = 27,
- QVariantHash = 28, LastCoreType = 28 /* QVariantHash */,
+ QVariantHash = 28, QEasingCurve = 29, LastCoreType = QEasingCurve,
FirstGuiType = 63 /* QColorGroup */,
#ifdef QT3_SUPPORT
@@ -81,12 +81,12 @@ public:
QTextLength = 78, QTextFormat = 79, QMatrix = 80, QTransform = 81,
QMatrix4x4 = 82, QVector2D = 83, QVector3D = 84, QVector4D = 85,
QQuaternion = 86,
- LastGuiType = 86 /* QQuaternion */,
+ LastGuiType = QQuaternion,
FirstCoreExtType = 128 /* VoidStar */,
VoidStar = 128, Long = 129, Short = 130, Char = 131, ULong = 132,
UShort = 133, UChar = 134, Float = 135, QObjectStar = 136, QWidgetStar = 137,
- LastCoreExtType = 137 /* QWidgetStar */,
+ LastCoreExtType = QWidgetStar,
// This logic must match the one in qglobal.h
#if defined(QT_COORD_TYPE)
@@ -108,6 +108,8 @@ public:
typedef void (*LoadOperator)(QDataStream &, void *);
static void registerStreamOperators(const char *typeName, SaveOperator saveOp,
LoadOperator loadOp);
+ static void registerStreamOperators(int type, SaveOperator saveOp,
+ LoadOperator loadOp);
#endif
static int registerType(const char *typeName, Destructor destructor,
Constructor constructor);
@@ -224,6 +226,24 @@ inline int qRegisterMetaType(
#endif
}
+#ifndef QT_NO_DATASTREAM
+template <typename T>
+inline int qRegisterMetaTypeStreamOperators()
+{
+ typedef void(*SavePtr)(QDataStream &, const T *);
+ typedef void(*LoadPtr)(QDataStream &, T *);
+ SavePtr sptr = qMetaTypeSaveHelper<T>;
+ LoadPtr lptr = qMetaTypeLoadHelper<T>;
+
+ register int id = qMetaTypeId<T>();
+ QMetaType::registerStreamOperators(id,
+ reinterpret_cast<QMetaType::SaveOperator>(sptr),
+ reinterpret_cast<QMetaType::LoadOperator>(lptr));
+
+ return id;
+}
+#endif
+
#define Q_DECLARE_METATYPE(TYPE) \
QT_BEGIN_NAMESPACE \
template <> \
@@ -270,6 +290,7 @@ class QPointF;
#ifndef QT_NO_REGEXP
class QRegExp;
#endif
+class QEasingCurve;
class QWidget;
class QObject;
@@ -339,6 +360,7 @@ Q_DECLARE_BUILTIN_METATYPE(QPointF, QPointF)
#ifndef QT_NO_REGEXP
Q_DECLARE_BUILTIN_METATYPE(QRegExp, QRegExp)
#endif
+Q_DECLARE_BUILTIN_METATYPE(QEasingCurve, QEasingCurve)
#ifdef QT3_SUPPORT
Q_DECLARE_BUILTIN_METATYPE(QColorGroup, QColorGroup)
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 5298fff..761b31f 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -871,7 +871,7 @@ QObject::~QObject()
// all the signal/slots connections are still in place - if we don't
// quit now, we will crash pretty soon.
qWarning("Detected an unexpected exception in ~QObject while emitting destroyed().");
-#if defined(Q_AUTOTEST_EXPORT) && !defined(QT_NO_EXCEPTIONS)
+#if defined(Q_BUILD_INTERNAL) && !defined(QT_NO_EXCEPTIONS)
struct AutotestException : public std::exception
{
const char *what() const throw() { return "autotest swallow"; }
@@ -903,7 +903,8 @@ QObject::~QObject()
// disconnect all receivers
if (d->connectionLists) {
++d->connectionLists->inUse;
- for (int signal = -1; signal < d->connectionLists->count(); ++signal) {
+ int connectionListsCount = d->connectionLists->count();
+ for (int signal = -1; signal < connectionListsCount; ++signal) {
QObjectPrivate::ConnectionList &connectionList =
(*d->connectionLists)[signal];
@@ -940,16 +941,17 @@ QObject::~QObject()
// disconnect all senders
QObjectPrivate::Connection *node = d->senders;
while (node) {
- QMutex *m = signalSlotLock(node->sender);
+ QObject *sender = node->sender;
+ QMutex *m = signalSlotLock(sender);
node->prev = &node;
bool needToUnlock = QOrderedMutexLocker::relock(locker.mutex(), m);
//the node has maybe been removed while the mutex was unlocked in relock?
- if (!node || signalSlotLock(node->sender) != m) {
+ if (!node || node->sender != sender) {
m->unlock();
continue;
}
node->receiver = 0;
- QObjectConnectionListVector *senderLists = node->sender->d_func()->connectionLists;
+ QObjectConnectionListVector *senderLists = sender->d_func()->connectionLists;
if (senderLists)
senderLists->dirty = true;
@@ -2510,20 +2512,25 @@ bool QObject::connect(const QObject *sender, const char *signal,
const QMetaObject *smeta = sender->metaObject();
const char *signal_arg = signal;
++signal; //skip code
- int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ int signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
if (signal_index < 0) {
// check for normalized signatures
tmp_signal_name = QMetaObject::normalizedSignature(signal - 1);
signal = tmp_signal_name.constData() + 1;
smeta = sender->metaObject();
- signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
+ }
+ if (signal_index < 0) {
+ // re-use tmp_signal_name and signal from above
- if (signal_index < 0) {
- err_method_notfound(sender, signal_arg, "connect");
- err_info_about_objects("connect", sender, receiver);
- return false;
- }
+ smeta = sender->metaObject();
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
+ }
+ if (signal_index < 0) {
+ err_method_notfound(sender, signal_arg, "connect");
+ err_info_about_objects("connect", sender, receiver);
+ return false;
}
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
int signalOffset, methodOffset;
@@ -2543,16 +2550,21 @@ bool QObject::connect(const QObject *sender, const char *signal,
int method_index = -1;
switch (membcode) {
case QSLOT_CODE:
- method_index = rmeta->indexOfSlot(method);
+ method_index = QMetaObjectPrivate::indexOfSlot(rmeta, method, false);
break;
case QSIGNAL_CODE:
- method_index = rmeta->indexOfSignal(method);
+ method_index = QMetaObjectPrivate::indexOfSignalRelative(&rmeta, method, false);
+ if (method_index >= 0)
+ method_index += rmeta->methodOffset();
break;
}
if (method_index < 0) {
// check for normalized methods
tmp_method_name = QMetaObject::normalizedSignature(method);
method = tmp_method_name.constData();
+
+ // rmeta may have been modified above
+ rmeta = receiver->metaObject();
switch (membcode) {
case QSLOT_CODE:
method_index = rmeta->indexOfSlot(method);
@@ -2740,7 +2752,9 @@ bool QObject::disconnect(const QObject *sender, const char *signal,
do {
int signal_index = -1;
if (signal) {
- signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal);
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, false);
+ if (signal_index < 0)
+ signal_index = QMetaObjectPrivate::indexOfSignalRelative(&smeta, signal, true);
if (signal_index < 0)
break;
signal_index = QMetaObjectPrivate::originalClone(smeta, signal_index);
@@ -3360,7 +3374,9 @@ int QObjectPrivate::signalIndex(const char *signalName) const
{
Q_Q(const QObject);
const QMetaObject *base = q->metaObject();
- int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName);
+ int relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, false);
+ if (relative_index < 0)
+ relative_index = QMetaObjectPrivate::indexOfSignalRelative(&base, signalName, true);
if (relative_index < 0)
return relative_index;
relative_index = QMetaObjectPrivate::originalClone(base, relative_index);
diff --git a/src/corelib/kernel/qobject_p.h b/src/corelib/kernel/qobject_p.h
index 27ab105..cc5bf97 100644
--- a/src/corelib/kernel/qobject_p.h
+++ b/src/corelib/kernel/qobject_p.h
@@ -189,8 +189,8 @@ public:
QList<QObject *> pendingChildInsertedEvents;
#else
// preserve binary compatibility with code compiled without Qt 3 support
- // ### why?
- QList<QObject *> unused;
+ // keeping the binary layout stable helps the Qt Creator debugger
+ void *unused;
#endif
QList<QPointer<QObject> > eventFilters;
diff --git a/src/corelib/kernel/qvariant.cpp b/src/corelib/kernel/qvariant.cpp
index e1b5825..227a60d 100644
--- a/src/corelib/kernel/qvariant.cpp
+++ b/src/corelib/kernel/qvariant.cpp
@@ -46,6 +46,7 @@
#include "qdebug.h"
#include "qmap.h"
#include "qdatetime.h"
+#include "qeasingcurve.h"
#include "qlist.h"
#include "qstring.h"
#include "qstringlist.h"
@@ -146,6 +147,11 @@ static void construct(QVariant::Private *x, const void *copy)
v_construct<QRegExp>(x, copy);
break;
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::EasingCurve:
+ v_construct<QEasingCurve>(x, copy);
+ break;
+#endif
case QVariant::Int:
x->data.i = copy ? *static_cast<const int *>(copy) : 0;
break;
@@ -259,6 +265,11 @@ static void clear(QVariant::Private *d)
v_clear<QRegExp>(d);
break;
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::EasingCurve:
+ v_clear<QEasingCurve>(d);
+ break;
+#endif
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Double:
@@ -317,6 +328,9 @@ static bool isNull(const QVariant::Private *d)
case QVariant::PointF:
return v_cast<QPointF>(d)->isNull();
#endif
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::EasingCurve:
+#endif
case QVariant::Url:
case QVariant::Locale:
case QVariant::RegExp:
@@ -435,6 +449,10 @@ static bool compare(const QVariant::Private *a, const QVariant::Private *b)
return *v_cast<QTime>(a) == *v_cast<QTime>(b);
case QVariant::DateTime:
return *v_cast<QDateTime>(a) == *v_cast<QDateTime>(b);
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::EasingCurve:
+ return *v_cast<QEasingCurve>(a) == *v_cast<QEasingCurve>(b);
+#endif
case QVariant::ByteArray:
return *v_cast<QByteArray>(a) == *v_cast<QByteArray>(b);
case QVariant::BitArray:
@@ -1097,6 +1115,11 @@ static void streamDebug(QDebug dbg, const QVariant &v)
case QVariant::DateTime:
dbg.nospace() << v.toDateTime();
break;
+#ifndef QT_BOOTSTRAPPED
+ case QVariant::EasingCurve:
+ dbg.nospace() << v.toEasingCurve();
+ break;
+#endif
case QVariant::ByteArray:
dbg.nospace() << v.toByteArray();
break;
@@ -1265,6 +1288,7 @@ const QVariant::Handler *QVariant::handler = &qt_kernel_variant_handler;
\value Date a QDate
\value DateTime a QDateTime
\value Double a double
+ \value EasingCurve a QEasingCurve
\value Font a QFont
\value Hash a QVariantHash
\value Icon a QIcon
@@ -1483,6 +1507,12 @@ QVariant::QVariant(const char *val)
*/
/*!
+ \fn QVariant::QVariant(const QEasingCurve &val)
+
+ Constructs a new variant with an easing curve value, \a val.
+*/
+
+/*!
\fn QVariant::QVariant(const QByteArray &val)
Constructs a new variant with a bytearray value, \a val.
@@ -1681,6 +1711,10 @@ QVariant::QVariant(const QTime &val)
{ d.is_null = false; d.type = Time; v_construct<QTime>(&d, val); }
QVariant::QVariant(const QDateTime &val)
{ d.is_null = false; d.type = DateTime; v_construct<QDateTime>(&d, val); }
+#ifndef QT_BOOTSTRAPPED
+QVariant::QVariant(const QEasingCurve &val)
+{ d.is_null = false; d.type = EasingCurve; v_construct<QEasingCurve>(&d, val); }
+#endif
QVariant::QVariant(const QList<QVariant> &list)
{ d.is_null = false; d.type = List; v_construct<QVariantList>(&d, list); }
QVariant::QVariant(const QMap<QString, QVariant> &map)
@@ -1870,7 +1904,7 @@ QVariant::Type QVariant::nameToType(const char *name)
}
#ifndef QT_NO_DATASTREAM
-enum { MapFromThreeCount = 35 };
+enum { MapFromThreeCount = 36 };
static const ushort map_from_three[MapFromThreeCount] =
{
QVariant::Invalid,
@@ -1907,7 +1941,8 @@ static const ushort map_from_three[MapFromThreeCount] =
QVariant::KeySequence,
QVariant::Pen,
QVariant::LongLong,
- QVariant::ULongLong
+ QVariant::ULongLong,
+ QVariant::EasingCurve
};
/*!
@@ -2165,6 +2200,21 @@ QDateTime QVariant::toDateTime() const
}
/*!
+ \fn QEasingCurve QVariant::toEasingCurve() const
+
+ Returns the variant as a QEasingCurve if the variant has type() \l
+ EasingCurve; otherwise returns a default easing curve.
+
+ \sa canConvert(), convert()
+*/
+#ifndef QT_BOOTSTRAPPED
+QEasingCurve QVariant::toEasingCurve() const
+{
+ return qVariantToHelper<QEasingCurve>(d, EasingCurve, handler);
+}
+#endif
+
+/*!
\fn QByteArray QVariant::toByteArray() const
Returns the variant as a QByteArray if the variant has type() \l
@@ -2605,8 +2655,9 @@ static const quint32 qCanConvertMatrix[QVariant::LastCoreType + 1] =
/*QRegExp*/ 0,
-/*QHash*/ 0
+/*QHash*/ 0,
+/*QEasingCurve*/ 0
};
/*!
diff --git a/src/corelib/kernel/qvariant.h b/src/corelib/kernel/qvariant.h
index 1a9e43a..9628dbf 100644
--- a/src/corelib/kernel/qvariant.h
+++ b/src/corelib/kernel/qvariant.h
@@ -60,6 +60,7 @@ class QBitArray;
class QDataStream;
class QDate;
class QDateTime;
+class QEasingCurve;
class QLine;
class QLineF;
class QLocale;
@@ -128,9 +129,10 @@ class Q_CORE_EXPORT QVariant
LineF = 24,
Point = 25,
PointF = 26,
- RegExp = 27,
+ RegExp = 27,
Hash = 28,
- LastCoreType = Hash,
+ EasingCurve = 29,
+ LastCoreType = EasingCurve,
// value 62 is internally reserved
#ifdef QT3_SUPPORT
@@ -219,6 +221,9 @@ class Q_CORE_EXPORT QVariant
#ifndef QT_NO_REGEXP
QVariant(const QRegExp &regExp);
#endif
+#ifndef QT_BOOTSTRAPPED
+ QVariant(const QEasingCurve &easing);
+#endif
QVariant(Qt::GlobalColor color);
QVariant& operator=(const QVariant &other);
@@ -280,6 +285,9 @@ class Q_CORE_EXPORT QVariant
#ifndef QT_NO_REGEXP
QRegExp toRegExp() const;
#endif
+#ifndef QT_BOOTSTRAPPED
+ QEasingCurve toEasingCurve() const;
+#endif
#ifdef QT3_SUPPORT
inline QT3_SUPPORT int &asInt();
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index f2c2384..a2c575a 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -630,6 +630,22 @@ bool QLibraryPrivate::isPlugin(QSettings *settings)
.arg((QT_VERSION & 0xff00) >> 8)
.arg(QLIBRARY_AS_DEBUG ? QLatin1String("debug") : QLatin1String("false"))
.arg(fileName);
+#ifdef Q_WS_MAC
+ // On Mac, add the application arch to the reg key in order to
+ // cache plugin information separately for each arch. This prevents
+ // Qt from wrongly caching plugin load failures when the archs
+ // don't match.
+#if defined(__x86_64__)
+ regkey += QLatin1String("-x86_64");
+#elif defined(__i386__)
+ regkey += QLatin1String("-i386");
+#elif defined(__ppc64__)
+ regkey += QLatin1String("-ppc64");
+#elif defined(__ppc__)
+ regkey += QLatin1String("-ppc");
+#endif
+#endif // Q_WS_MAC
+
QStringList reg;
#ifndef QT_NO_SETTINGS
if (!settings) {
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index ec50ac8..43df13a 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -41,6 +41,7 @@
#include "qplatformdefs.h"
#include "qmutex.h"
+#include <qdebug.h>
#ifndef QT_NO_THREAD
#include "qatomic.h"
@@ -159,8 +160,7 @@ void QMutex::lock()
if (!isLocked) {
#ifndef QT_NO_DEBUG
if (d->owner == self)
- qWarning("QMutex::lock: Deadlock detected in thread %ld",
- long(d->owner));
+ qWarning() << "QMutex::lock: Deadlock detected in thread" << d->owner;
#endif
// didn't get the lock, wait for it
@@ -197,8 +197,7 @@ void QMutex::lock()
if (!isLocked) {
#ifndef QT_NO_DEBUG
if (d->owner == self)
- qWarning("QMutex::lock: Deadlock detected in thread %ld",
- long(d->owner));
+ qWarning() << "QMutex::lock: Deadlock detected in thread" << d->owner;
#endif
// didn't get the lock, wait for it
diff --git a/src/corelib/thread/qorderedmutexlocker_p.h b/src/corelib/thread/qorderedmutexlocker_p.h
index 7d52a29..702125c 100644
--- a/src/corelib/thread/qorderedmutexlocker_p.h
+++ b/src/corelib/thread/qorderedmutexlocker_p.h
@@ -103,9 +103,11 @@ public:
mtx2->lock();
return true;
}
- mtx1->unlock();
- mtx2->lock();
- mtx1->lock();
+ if (!mtx2->tryLock()) {
+ mtx1->unlock();
+ mtx2->lock();
+ mtx1->lock();
+ }
return true;
}
diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp
index 556093f..3324796 100644
--- a/src/corelib/tools/qbytearray.cpp
+++ b/src/corelib/tools/qbytearray.cpp
@@ -1061,6 +1061,11 @@ QByteArray &QByteArray::operator=(const char *str)
\internal
*/
+/*! \fn bool QByteArray::isSharedWith(const QByteArray &other) const
+
+ \internal
+*/
+
/*! \fn char QByteArray::at(int i) const
Returns the character at index position \a i in the byte array.
@@ -1799,7 +1804,20 @@ QByteArray &QByteArray::replace(int pos, int len, const QByteArray &after)
*/
QByteArray &QByteArray::replace(int pos, int len, const char *after)
{
- int alen = qstrlen(after);
+ return replace(pos,len,after,qstrlen(after));
+}
+
+/*! \fn QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
+
+ \overload
+
+ Replaces \a len bytes from index position \a pos with \a alen bytes
+ from the string \a after. \a after is allowed to have '\0' characters.
+
+ \since 4.7
+*/
+QByteArray &QByteArray::replace(int pos, int len, const char *after, int alen)
+{
if (len == alen && (pos + len <= d->size)) {
detach();
memcpy(d->data + pos, after, len*sizeof(char));
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index ef97716..0b77512 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -164,6 +164,7 @@ public:
inline const char *constData() const;
inline void detach();
bool isDetached() const;
+ inline bool isSharedWith(const QByteArray &other) const { return d == other.d; }
void clear();
#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
@@ -236,6 +237,7 @@ public:
QByteArray &insert(int i, const QByteArray &a);
QByteArray &remove(int index, int len);
QByteArray &replace(int index, int len, const char *s);
+ QByteArray &replace(int index, int len, const char *s, int alen);
QByteArray &replace(int index, int len, const QByteArray &s);
QByteArray &replace(char before, const char *after);
QByteArray &replace(char before, const QByteArray &after);
diff --git a/src/corelib/tools/qcontiguouscache.h b/src/corelib/tools/qcontiguouscache.h
index 1f7fdb2..f767962 100644
--- a/src/corelib/tools/qcontiguouscache.h
+++ b/src/corelib/tools/qcontiguouscache.h
@@ -97,7 +97,7 @@ public:
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef int size_type;
explicit QContiguousCache(int capacity = 0);
@@ -221,22 +221,29 @@ void QContiguousCache<T>::setCapacity(int asize)
x.d->alloc = asize;
x.d->count = qMin(d->count, asize);
x.d->offset = d->offset + d->count - x.d->count;
- x.d->start = x.d->offset % x.d->alloc;
- T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
- T *src = p->array + (d->start + d->count-1) % d->alloc;
+ if(asize)
+ x.d->start = x.d->offset % x.d->alloc;
+ else
+ x.d->start = 0;
+
int oldcount = x.d->count;
- while (oldcount--) {
- if (QTypeInfo<T>::isComplex) {
- new (dest) T(*src);
- } else {
- *dest = *src;
+ if(oldcount)
+ {
+ T *dest = x.p->array + (x.d->start + x.d->count-1) % x.d->alloc;
+ T *src = p->array + (d->start + d->count-1) % d->alloc;
+ while (oldcount--) {
+ if (QTypeInfo<T>::isComplex) {
+ new (dest) T(*src);
+ } else {
+ *dest = *src;
+ }
+ if (dest == x.p->array)
+ dest = x.p->array + x.d->alloc;
+ dest--;
+ if (src == p->array)
+ src = p->array + d->alloc;
+ src--;
}
- if (dest == x.p->array)
- dest = x.p->array + x.d->alloc;
- dest--;
- if (src == p->array)
- src = p->array + d->alloc;
- src--;
}
/* free old */
free(p);
diff --git a/src/corelib/tools/qeasingcurve.cpp b/src/corelib/tools/qeasingcurve.cpp
index b6a2df4..d4b2c27 100644
--- a/src/corelib/tools/qeasingcurve.cpp
+++ b/src/corelib/tools/qeasingcurve.cpp
@@ -600,11 +600,11 @@ QEasingCurve::QEasingCurve(Type type)
Construct a copy of \a other.
*/
QEasingCurve::QEasingCurve(const QEasingCurve &other)
-: d_ptr(new QEasingCurvePrivate)
+ : d_ptr(new QEasingCurvePrivate)
{
// ### non-atomic, requires malloc on shallow copy
*d_ptr = *other.d_ptr;
- if(other.d_ptr->config)
+ if (other.d_ptr->config)
d_ptr->config = other.d_ptr->config->copy();
}
@@ -629,7 +629,7 @@ QEasingCurve &QEasingCurve::operator=(const QEasingCurve &other)
}
*d_ptr = *other.d_ptr;
- if(other.d_ptr->config)
+ if (other.d_ptr->config)
d_ptr->config = other.d_ptr->config->copy();
return *this;
@@ -845,6 +845,67 @@ QDebug operator<<(QDebug debug, const QEasingCurve &item)
}
return debug;
}
-#endif
+#endif // QT_NO_DEBUG_STREAM
+
+#ifndef QT_NO_DATASTREAM
+/*!
+ \fn QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)
+ \relates QEasingCurve
+
+ Writes the given \a easing curve to the given \a stream and returns a
+ reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator<<(QDataStream &stream, const QEasingCurve &easing)
+{
+ stream << quint8(easing.d_ptr->type);
+ stream << quint64(quintptr(easing.d_ptr->func));
+
+ bool hasConfig = easing.d_ptr->config;
+ stream << hasConfig;
+ if (hasConfig) {
+ stream << easing.d_ptr->config->_p;
+ stream << easing.d_ptr->config->_a;
+ stream << easing.d_ptr->config->_o;
+ }
+ return stream;
+}
+
+/*!
+ \fn QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)
+ \relates QQuaternion
+
+ Reads an easing curve from the given \a stream into the given \a quaternion
+ and returns a reference to the stream.
+
+ \sa {Format of the QDataStream Operators}
+*/
+
+QDataStream &operator>>(QDataStream &stream, QEasingCurve &easing)
+{
+ QEasingCurve::Type type;
+ quint8 int_type;
+ stream >> int_type;
+ type = static_cast<QEasingCurve::Type>(int_type);
+ easing.setType(type);
+
+ quint64 ptr_func;
+ stream >> ptr_func;
+ easing.d_ptr->func = QEasingCurve::EasingFunction(quintptr(ptr_func));
+
+ bool hasConfig;
+ stream >> hasConfig;
+ if (hasConfig) {
+ QEasingCurveFunction *config = curveToFunctionObject(type);
+ stream >> config->_p;
+ stream >> config->_a;
+ stream >> config->_o;
+ easing.d_ptr->config = config;
+ }
+ return stream;
+}
+#endif // QT_NO_DATASTREAM
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qeasingcurve.h b/src/corelib/tools/qeasingcurve.h
index ae8822e..173fba4 100644
--- a/src/corelib/tools/qeasingcurve.h
+++ b/src/corelib/tools/qeasingcurve.h
@@ -100,13 +100,24 @@ public:
qreal valueForProgress(qreal progress) const;
private:
QEasingCurvePrivate *d_ptr;
+#ifndef QT_NO_DEBUG_STREAM
friend Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item);
+#endif
+#ifndef QT_NO_DATASTREAM
+ friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QEasingCurve&);
+ friend Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QEasingCurve &);
+#endif
};
#ifndef QT_NO_DEBUG_STREAM
Q_CORE_EXPORT QDebug operator<<(QDebug debug, const QEasingCurve &item);
#endif
+#ifndef QT_NO_DATASTREAM
+Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QEasingCurve&);
+Q_CORE_EXPORT QDataStream &operator>>(QDataStream &, QEasingCurve &);
+#endif
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp
index 6231471..85a8b63 100644
--- a/src/corelib/tools/qhash.cpp
+++ b/src/corelib/tools/qhash.cpp
@@ -64,13 +64,11 @@ QT_BEGIN_NAMESPACE
static uint hash(const uchar *p, int n)
{
uint h = 0;
- uint g;
while (n--) {
h = (h << 4) + *p++;
- g = h & 0xf0000000;
- h ^= g >> 23;
- h &= ~g;
+ h ^= (h & 0xf0000000) >> 23;
+ h &= 0x0fffffff;
}
return h;
}
@@ -78,13 +76,11 @@ static uint hash(const uchar *p, int n)
static uint hash(const QChar *p, int n)
{
uint h = 0;
- uint g;
while (n--) {
h = (h << 4) + (*p++).unicode();
- g = h & 0xf0000000;
- h ^= g >> 23;
- h &= ~g;
+ h ^= (h & 0xf0000000) >> 23;
+ h &= 0x0fffffff;
}
return h;
}
@@ -847,6 +843,11 @@ void QHashData::checkSanity()
\internal
*/
+/*! \fn bool QHash::isSharedWith(const QHash<Key, T> &other) const
+
+ \internal
+*/
+
/*! \fn void QHash::clear()
Removes all items from the hash.
diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h
index 5e93523..3374c80 100644
--- a/src/corelib/tools/qhash.h
+++ b/src/corelib/tools/qhash.h
@@ -299,6 +299,7 @@ public:
inline void detach() { if (d->ref != 1) detach_helper(); }
inline bool isDetached() const { return d->ref == 1; }
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline bool isSharedWith(const QHash<Key, T> &other) const { return d == other.d; }
void clear();
@@ -329,7 +330,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
@@ -394,7 +395,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -478,7 +479,7 @@ public:
// STL compatibility
typedef T mapped_type;
typedef Key key_type;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef int size_type;
inline bool empty() const { return isEmpty(); }
@@ -624,6 +625,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::uniqueKeys() const
{
QList<Key> res;
+ res.reserve(size()); // May be too much, but assume short lifetime
const_iterator i = begin();
if (i != end()) {
for (;;) {
@@ -643,6 +645,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<Key> QHash<Key, T>::keys() const
{
QList<Key> res;
+ res.reserve(size());
const_iterator i = begin();
while (i != end()) {
res.append(i.key());
@@ -687,6 +690,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<T> QHash<Key, T>::values() const
{
QList<T> res;
+ res.reserve(size());
const_iterator i = begin();
while (i != end()) {
res.append(i.value());
diff --git a/src/corelib/tools/qlinkedlist.cpp b/src/corelib/tools/qlinkedlist.cpp
index 5a53c32..909d940 100644
--- a/src/corelib/tools/qlinkedlist.cpp
+++ b/src/corelib/tools/qlinkedlist.cpp
@@ -197,6 +197,11 @@ QLinkedListData QLinkedListData::shared_null = {
\internal
*/
+/*! \fn bool QLinkedList::isSharedWith(const QLinkedList<T> &other) const
+
+ \internal
+*/
+
/*! \fn bool QLinkedList::isEmpty() const
Returns true if the list contains no items; otherwise returns
diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h
index f6de966..d145fe3 100644
--- a/src/corelib/tools/qlinkedlist.h
+++ b/src/corelib/tools/qlinkedlist.h
@@ -93,6 +93,7 @@ public:
{ if (d->ref != 1) detach_helper(); }
inline bool isDetached() const { return d->ref == 1; }
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline bool isSharedWith(const QLinkedList<T> &other) const { return d == other.d; }
inline bool isEmpty() const { return d->size == 0; }
@@ -113,7 +114,7 @@ public:
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
@@ -146,7 +147,7 @@ public:
{
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -212,7 +213,7 @@ public:
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
#ifndef QT_NO_STL
static inline QLinkedList<T> fromStdList(const std::list<T> &list)
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index c302857..6f5bb9b 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -66,6 +66,53 @@ static int grow(int size)
return x;
}
+/*!
+ * Detaches the QListData by allocating new memory for a list which will be bigger
+ * than the copied one and is expected to grow further.
+ * *idx is the desired insertion point and is clamped to the actual size of the list.
+ * num is the number of new elements to insert at the insertion point.
+ * Returns the old (shared) data, it is up to the caller to deref() and free().
+ * For the new data node_copy needs to be called.
+ *
+ * \internal
+ */
+QListData::Data *QListData::detach_grow(int *idx, int num)
+{
+ Data *x = d;
+ int l = x->end - x->begin;
+ int nl = l + num;
+ int alloc = grow(nl);
+ Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *)));
+ Q_CHECK_PTR(t);
+
+ t->ref = 1;
+ t->sharable = true;
+ t->alloc = alloc;
+ // The space reservation algorithm's optimization is biased towards appending:
+ // Something which looks like an append will put the data at the beginning,
+ // while something which looks like a prepend will put it in the middle
+ // instead of at the end. That's based on the assumption that prepending
+ // is uncommon and even an initial prepend will eventually be followed by
+ // at least some appends.
+ int bg;
+ if (*idx < 0) {
+ *idx = 0;
+ bg = (alloc - nl) >> 1;
+ } else if (*idx > l) {
+ *idx = l;
+ bg = 0;
+ } else if (*idx < (l >> 1)) {
+ bg = (alloc - nl) >> 1;
+ } else {
+ bg = 0;
+ }
+ t->begin = bg;
+ t->end = bg + nl;
+ d = t;
+
+ return x;
+}
+
#if QT_VERSION >= 0x050000
# error "Remove QListData::detach(), it is only required for binary compatibility for 4.0.x to 4.2.x"
#endif
@@ -125,22 +172,23 @@ QListData::Data *QListData::detach2()
}
/*!
- * Detaches the QListData by reallocating new memory.
+ * Detaches the QListData by allocating new memory for a list which possibly
+ * has a different size than the copied one.
* Returns the old (shared) data, it is up to the caller to deref() and free()
* For the new data node_copy needs to be called.
*
* \internal
*/
-QListData::Data *QListData::detach3()
+QListData::Data *QListData::detach(int alloc)
{
Data *x = d;
- Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *)));
+ Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + alloc * sizeof(void *)));
Q_CHECK_PTR(t);
t->ref = 1;
t->sharable = true;
- t->alloc = x->alloc;
- if (!t->alloc) {
+ t->alloc = alloc;
+ if (!alloc) {
t->begin = 0;
t->end = 0;
} else {
@@ -152,6 +200,21 @@ QListData::Data *QListData::detach3()
return x;
}
+/*!
+ * Detaches the QListData by reallocating new memory.
+ * Returns the old (shared) data, it is up to the caller to deref() and free()
+ * For the new data node_copy needs to be called.
+ *
+ * \internal
+ */
+#if QT_VERSION >= 0x050000
+# error "Remove QListData::detach3(), it is only required for binary compatibility for 4.5.x to 4.6.x"
+#endif
+QListData::Data *QListData::detach3()
+{
+ return detach(d->alloc);
+}
+
void QListData::realloc(int alloc)
{
Q_ASSERT(d->ref == 1);
@@ -164,22 +227,30 @@ void QListData::realloc(int alloc)
d->begin = d->end = 0;
}
-// ensures that enough space is available to append one element
-void **QListData::append()
+// ensures that enough space is available to append n elements
+void **QListData::append(int n)
{
Q_ASSERT(d->ref == 1);
- if (d->end == d->alloc) {
- int n = d->end - d->begin;
- if (d->begin > 2 * d->alloc / 3) {
+ int e = d->end;
+ if (e + n > d->alloc) {
+ int b = d->begin;
+ if (b - n >= 2 * d->alloc / 3) {
// we have enough space. Just not at the end -> move it.
- ::memcpy(d->array + n, d->array + d->begin, n * sizeof(void *));
- d->begin = n;
- d->end = n * 2;
+ e -= b;
+ ::memcpy(d->array, d->array + b, e * sizeof(void *));
+ d->begin = 0;
} else {
- realloc(grow(d->alloc + 1));
+ realloc(grow(d->alloc + n));
}
}
- return d->array + d->end++;
+ d->end = e + n;
+ return d->array + e;
+}
+
+// ensures that enough space is available to append one element
+void **QListData::append()
+{
+ return append(1);
}
// ensures that enough space is available to append the list
@@ -193,7 +264,7 @@ void **QListData::append(const QListData& l)
int n = l.d->end - l.d->begin;
if (n) {
if (e + n > d->alloc)
- realloc(grow(e + l.d->end - l.d->begin));
+ realloc(grow(e + n));
::memcpy(d->array + d->end, l.d->array + l.d->begin, n*sizeof(void*));
d->end += n;
}
@@ -203,15 +274,7 @@ void **QListData::append(const QListData& l)
// ensures that enough space is available to append the list
void **QListData::append2(const QListData& l)
{
- Q_ASSERT(d->ref == 1);
- int e = d->end;
- int n = l.d->end - l.d->begin;
- if (n) {
- if (e + n > d->alloc)
- realloc(grow(e + n));
- d->end += n;
- }
- return d->array + e;
+ return append(l.d->end - l.d->begin);
}
void **QListData::prepend()
@@ -237,11 +300,11 @@ void **QListData::insert(int i)
Q_ASSERT(d->ref == 1);
if (i <= 0)
return prepend();
- if (i >= d->end - d->begin)
+ int size = d->end - d->begin;
+ if (i >= size)
return append();
bool leftward = false;
- int size = d->end - d->begin;
if (d->begin == 0) {
if (d->end == d->alloc) {
@@ -599,6 +662,11 @@ void **QListData::erase(void **xi)
\internal
*/
+/*! \fn bool QList::isSharedWith(const QList<T> &other) const
+
+ \internal
+*/
+
/*! \fn bool QList::isEmpty() const
Returns true if the list contains no items; otherwise returns
@@ -642,6 +710,19 @@ void **QListData::erase(void **xi)
Same as at().
*/
+/*! \fn QList::reserve(int alloc)
+
+ Reserve space for \a alloc elements.
+
+ If \a alloc is smaller than the current size of the list, nothing will happen.
+
+ Use this function to avoid repetetive reallocation of QList's internal
+ data if you can predict how many elements will be appended.
+ Note that the reservation applies only to the internal pointer array.
+
+ \since 4.7
+*/
+
/*! \fn void QList::append(const T &value)
Inserts \a value at the end of the list.
diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h
index 120442d..c6dd106 100644
--- a/src/corelib/tools/qlist.h
+++ b/src/corelib/tools/qlist.h
@@ -52,6 +52,7 @@
#endif
#include <new>
+#include <limits.h>
#include <string.h>
QT_BEGIN_HEADER
@@ -72,13 +73,16 @@ struct Q_CORE_EXPORT QListData {
};
enum { DataHeaderSize = sizeof(Data) - sizeof(void *) };
+ Data *detach(int alloc);
+ Data *detach_grow(int *i, int n);
Data *detach(); // remove in 5.0
Data *detach2(); // remove in 5.0
- Data *detach3();
+ Data *detach3(); // remove in 5.0
void realloc(int alloc);
static Data shared_null;
Data *d;
void **erase(void **xi);
+ void **append(int n);
void **append();
void **append(const QListData &l);
void **append2(const QListData &l); // remove in 5.0
@@ -94,6 +98,25 @@ struct Q_CORE_EXPORT QListData {
inline void **end() const { return d->array + d->end; }
};
+//////////////////////////////////////////////////////////////////////////////////
+//
+// QtPodForSize and QtPodForType are internal and may change or go away any time.
+// We mean it.
+//
+//////////////////////////////////////////////////////////////////////////////////
+template <int N> struct QtPodForSize {
+ // This base type is rather obviously broken and cannot be made
+ // working due to alignment constraints.
+ // This doesn't matter as far as QList is concerned, as we are
+ // using this type only for QTypeInfo<T>::isLarge == false.
+ typedef struct { } Type;
+};
+template <> struct QtPodForSize<1> { typedef quint8 Type; };
+template <> struct QtPodForSize<2> { typedef quint16 Type; };
+template <> struct QtPodForSize<4> { typedef quint32 Type; };
+template <> struct QtPodForSize<8> { typedef quint64 Type; };
+template <class T> struct QtPodForType : QtPodForSize<sizeof(T)> { };
+
template <typename T>
class QList
{
@@ -130,6 +153,7 @@ public:
inline bool isDetached() const { return d->ref == 1; }
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline bool isSharedWith(const QList<T> &other) const { return d == other.d; }
inline bool isEmpty() const { return p.isEmpty(); }
@@ -139,6 +163,7 @@ public:
const T &operator[](int i) const;
T &operator[](int i);
+ void reserve(int size);
void append(const T &t);
void append(const QList<T> &t);
void prepend(const T &t);
@@ -163,7 +188,7 @@ public:
public:
Node *i;
typedef std::random_access_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
@@ -210,7 +235,7 @@ public:
public:
Node *i;
typedef std::random_access_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -289,7 +314,7 @@ public:
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
#ifdef QT3_SUPPORT
inline QT3_SUPPORT iterator remove(iterator pos) { return erase(pos); }
@@ -330,6 +355,8 @@ public:
#endif
private:
+ Node *detach_helper_grow(int i, int n);
+ void detach_helper(int alloc);
void detach_helper();
void free(QListData::Data *d);
@@ -463,11 +490,21 @@ inline T QList<T>::takeLast()
{ T t = last(); removeLast(); return t; }
template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::reserve(int alloc)
+{
+ if (d->alloc < alloc) {
+ if (d->ref != 1)
+ detach_helper(alloc);
+ else
+ p.realloc(alloc);
+ }
+}
+
+template <typename T>
Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
{
- detach();
- if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
- Node *n = reinterpret_cast<Node *>(p.append());
+ if (d->ref != 1) {
+ Node *n = detach_helper_grow(INT_MAX, 1);
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -475,13 +512,25 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
QT_RETHROW;
}
} else {
- const T cpy(t);
- Node *n = reinterpret_cast<Node *>(p.append());
- QT_TRY {
- node_construct(n, cpy);
- } QT_CATCH(...) {
- --d->end;
- QT_RETHROW;
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ Node *n = reinterpret_cast<Node *>(p.append());
+ QT_TRY {
+ node_construct(n, t);
+ } QT_CATCH(...) {
+ --d->end;
+ QT_RETHROW;
+ }
+ } else {
+ typedef typename QtPodForType<T>::Type PodNode;
+ PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
+ Node *n = reinterpret_cast<Node *>(p.append());
+ QT_TRY {
+ void *ptr = &cpy;
+ node_construct(n, *reinterpret_cast<T *>(ptr));
+ } QT_CATCH(...) {
+ --d->end;
+ QT_RETHROW;
+ }
}
}
}
@@ -489,9 +538,8 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t)
template <typename T>
inline void QList<T>::prepend(const T &t)
{
- detach();
- if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
- Node *n = reinterpret_cast<Node *>(p.prepend());
+ if (d->ref != 1) {
+ Node *n = detach_helper_grow(0, 1);
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -499,13 +547,25 @@ inline void QList<T>::prepend(const T &t)
QT_RETHROW;
}
} else {
- const T cpy(t);
- Node *n = reinterpret_cast<Node *>(p.prepend());
- QT_TRY {
- node_construct(n, cpy);
- } QT_CATCH(...) {
- ++d->begin;
- QT_RETHROW;
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ Node *n = reinterpret_cast<Node *>(p.prepend());
+ QT_TRY {
+ node_construct(n, t);
+ } QT_CATCH(...) {
+ ++d->begin;
+ QT_RETHROW;
+ }
+ } else {
+ typedef typename QtPodForType<T>::Type PodNode;
+ PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
+ Node *n = reinterpret_cast<Node *>(p.prepend());
+ QT_TRY {
+ void *ptr = &cpy;
+ node_construct(n, *reinterpret_cast<T *>(ptr));
+ } QT_CATCH(...) {
+ ++d->begin;
+ QT_RETHROW;
+ }
}
}
}
@@ -513,9 +573,8 @@ inline void QList<T>::prepend(const T &t)
template <typename T>
inline void QList<T>::insert(int i, const T &t)
{
- detach();
- if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
- Node *n = reinterpret_cast<Node *>(p.insert(i));
+ if (d->ref != 1) {
+ Node *n = detach_helper_grow(i, 1);
QT_TRY {
node_construct(n, t);
} QT_CATCH(...) {
@@ -523,13 +582,25 @@ inline void QList<T>::insert(int i, const T &t)
QT_RETHROW;
}
} else {
- const T cpy(t);
- Node *n = reinterpret_cast<Node *>(p.insert(i));
- QT_TRY {
- node_construct(n, cpy);
- } QT_CATCH(...) {
- p.remove(i);
- QT_RETHROW;
+ if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
+ Node *n = reinterpret_cast<Node *>(p.insert(i));
+ QT_TRY {
+ node_construct(n, t);
+ } QT_CATCH(...) {
+ p.remove(i);
+ QT_RETHROW;
+ }
+ } else {
+ typedef typename QtPodForType<T>::Type PodNode;
+ PodNode cpy = *reinterpret_cast<const PodNode *>(&t);
+ Node *n = reinterpret_cast<Node *>(p.insert(i));
+ QT_TRY {
+ void *ptr = &cpy;
+ node_construct(n, *reinterpret_cast<T *>(ptr));
+ } QT_CATCH(...) {
+ p.remove(i);
+ QT_RETHROW;
+ }
}
}
}
@@ -539,12 +610,7 @@ inline void QList<T>::replace(int i, const T &t)
{
Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::replace", "index out of range");
detach();
- if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) {
- reinterpret_cast<Node *>(p.at(i))->t() = t;
- } else {
- const T cpy(t);
- reinterpret_cast<Node *>(p.at(i))->t() = cpy;
- }
+ reinterpret_cast<Node *>(p.at(i))->t() = t;
}
template <typename T>
@@ -574,11 +640,20 @@ Q_OUTOFLINE_TEMPLATE QList<T> QList<T>::mid(int pos, int alength) const
alength = size() - pos;
if (pos == 0 && alength == size())
return *this;
- QList<T> cpy;
if (pos + alength > size())
alength = size() - pos;
- for (int i = pos; i < pos + alength; ++i)
- cpy += at(i);
+ QList<T> cpy;
+ cpy.reserve(alength);
+ cpy.d->end = alength;
+ QT_TRY {
+ cpy.node_copy(reinterpret_cast<Node *>(cpy.p.begin()),
+ reinterpret_cast<Node *>(cpy.p.end()),
+ reinterpret_cast<Node *>(p.begin() + pos));
+ } QT_CATCH(...) {
+ // restore the old end
+ cpy.d->end = 0;
+ QT_RETHROW;
+ }
return cpy;
}
@@ -598,10 +673,40 @@ Q_OUTOFLINE_TEMPLATE T QList<T>::value(int i, const T& defaultValue) const
}
template <typename T>
-Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
+Q_OUTOFLINE_TEMPLATE typename QList<T>::Node *QList<T>::detach_helper_grow(int i, int c)
{
Node *n = reinterpret_cast<Node *>(p.begin());
- QListData::Data *x = p.detach3();
+ QListData::Data *x = p.detach_grow(&i, c);
+ QT_TRY {
+ node_copy(reinterpret_cast<Node *>(p.begin()),
+ reinterpret_cast<Node *>(p.begin() + i), n);
+ } QT_CATCH(...) {
+ qFree(d);
+ d = x;
+ QT_RETHROW;
+ }
+ QT_TRY {
+ node_copy(reinterpret_cast<Node *>(p.begin() + i + c),
+ reinterpret_cast<Node *>(p.end()), n + i);
+ } QT_CATCH(...) {
+ node_destruct(reinterpret_cast<Node *>(p.begin()),
+ reinterpret_cast<Node *>(p.begin() + i));
+ qFree(d);
+ d = x;
+ QT_RETHROW;
+ }
+
+ if (!x->ref.deref())
+ free(x);
+
+ return reinterpret_cast<Node *>(p.begin() + i);
+}
+
+template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper(int alloc)
+{
+ Node *n = reinterpret_cast<Node *>(p.begin());
+ QListData::Data *x = p.detach(alloc);
QT_TRY {
node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n);
} QT_CATCH(...) {
@@ -615,6 +720,12 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
}
template <typename T>
+Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper()
+{
+ detach_helper(d->alloc);
+}
+
+template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T>::~QList()
{
if (d && !d->ref.deref())
@@ -700,14 +811,22 @@ Q_OUTOFLINE_TEMPLATE typename QList<T>::iterator QList<T>::erase(typename QList<
template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T> &QList<T>::operator+=(const QList<T> &l)
{
- detach();
- Node *n = reinterpret_cast<Node *>(p.append2(l.p));
- QT_TRY{
- node_copy(n, reinterpret_cast<Node *>(p.end()), reinterpret_cast<Node *>(l.p.begin()));
- } QT_CATCH(...) {
- // restore the old end
- d->end -= int(reinterpret_cast<Node *>(p.end()) - n);
- QT_RETHROW;
+ if (!l.isEmpty()) {
+ if (isEmpty()) {
+ *this = l;
+ } else {
+ Node *n = (d->ref != 1)
+ ? detach_helper_grow(INT_MAX, l.size())
+ : reinterpret_cast<Node *>(p.append2(l.p));
+ QT_TRY {
+ node_copy(n, reinterpret_cast<Node *>(p.end()),
+ reinterpret_cast<Node *>(l.p.begin()));
+ } QT_CATCH(...) {
+ // restore the old end
+ d->end -= int(reinterpret_cast<Node *>(p.end()) - n);
+ QT_RETHROW;
+ }
+ }
}
return *this;
}
diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp
index 8d79cb3..84bc154 100644
--- a/src/corelib/tools/qlocale.cpp
+++ b/src/corelib/tools/qlocale.cpp
@@ -465,7 +465,7 @@ static QString winToQtFormat(const QString &sys_fmt)
if (text == QLatin1String("'"))
result += QLatin1String("''");
else
- result += QLatin1Char('\'') + text + QLatin1Char('\'');
+ result += QString(QLatin1Char('\'') + text + QLatin1Char('\''));
continue;
}
@@ -681,8 +681,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
case DateTimeFormatLong:
case DateTimeFormatShort:
- return query(type == DateTimeFormatLong ? DateFormatLong : DateFormatShort).toString()
- + QLatin1Char(' ') + query(type == DateTimeFormatLong ? TimeFormatLong : TimeFormatShort).toString();
+ return QString(query(type == DateTimeFormatLong ? DateFormatLong : DateFormatShort).toString()
+ + QLatin1Char(' ') + query(type == DateTimeFormatLong ? TimeFormatLong : TimeFormatShort).toString());
case DayNameLong:
case DayNameShort:
return winDayName(in.toInt(), (type == DayNameShort));
@@ -698,8 +698,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
case DateTimeToStringShort:
case DateTimeToStringLong: {
const QDateTime dt = in.toDateTime();
- return winDateToString(dt.date(), type == DateTimeToStringShort ? DATE_SHORTDATE : DATE_LONGDATE)
- + QLatin1Char(' ') + winTimeToString(dt.time()); }
+ return QString(winDateToString(dt.date(), type == DateTimeToStringShort ? DATE_SHORTDATE : DATE_LONGDATE)
+ + QLatin1Char(' ') + winTimeToString(dt.time())); }
case ZeroDigit:
locale_info = LOCALE_SNATIVEDIGITS;
@@ -2917,7 +2917,7 @@ QDate QLocale::toDate(const QString &string, FormatType format) const
#ifndef QT_NO_DATESTRING
QDateTime QLocale::toDateTime(const QString &string, FormatType format) const
{
- return toDateTime(string, dateFormat(format));
+ return toDateTime(string, dateTimeFormat(format));
}
#endif
@@ -4293,6 +4293,7 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
const bool scientific = numMode == DoubleScientificMode;
bool lastWasE = false;
+ bool lastWasDigit = false;
int eCnt = 0;
int decPointCnt = 0;
bool dec = false;
@@ -4307,6 +4308,7 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
if (dec && decDigits != -1 && decDigits < ++decDigitCnt)
return false;
}
+ lastWasDigit = true;
} else {
switch (c) {
case '.':
@@ -4344,7 +4346,10 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
break;
case ',':
- return false;
+ //it can only be placed after a digit which is before the decimal point
+ if (!lastWasDigit || decPointCnt > 0)
+ return false;
+ break;
case 'e':
if (scientific) {
@@ -4362,10 +4367,12 @@ bool QLocalePrivate::validateChars(const QString &str, NumberMode numMode, QByte
// If it's not a valid digit, it shall be Invalid.
return false;
}
+ lastWasDigit = false;
}
lastWasE = c == 'e';
- buff->append(c);
+ if (c != ',')
+ buff->append(c);
}
return true;
diff --git a/src/corelib/tools/qlocale_symbian.cpp b/src/corelib/tools/qlocale_symbian.cpp
index b1a7caa..58e3ba8 100644
--- a/src/corelib/tools/qlocale_symbian.cpp
+++ b/src/corelib/tools/qlocale_symbian.cpp
@@ -841,7 +841,7 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
return symbianTimeFormat();
case DateTimeFormatLong:
case DateTimeFormatShort:
- return symbianDateFormat( (type == DateTimeFormatShort) ) + QLatin1Char(' ') + symbianTimeFormat();
+ return QString(symbianDateFormat( (type == DateTimeFormatShort) ) + QLatin1Char(' ') + symbianTimeFormat());
case DateToStringShort:
case DateToStringLong:
return symbianDateToString(in.toDate(), (type == DateToStringShort) );
@@ -851,8 +851,8 @@ QVariant QSystemLocale::query(QueryType type, QVariant in = QVariant()) const
case DateTimeToStringShort:
case DateTimeToStringLong: {
const QDateTime dt = in.toDateTime();
- return symbianDateToString(dt.date(), (type == DateTimeToStringShort) )
- + QLatin1Char(' ') + symbianTimeToString(dt.time());
+ return QString(symbianDateToString(dt.date(), (type == DateTimeToStringShort) )
+ + QLatin1Char(' ') + symbianTimeToString(dt.time()));
}
case MeasurementSystem:
return static_cast<int>(symbianMeasurementSystem());
diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp
index 82cbe78..3143ee4 100644
--- a/src/corelib/tools/qmap.cpp
+++ b/src/corelib/tools/qmap.cpp
@@ -473,6 +473,11 @@ void QMapData::dump()
\internal
*/
+/*! \fn bool QMap::isSharedWith(const QMap<Key, T> &other) const
+
+ \internal
+*/
+
/*! \fn void QMap::setInsertInOrder(bool sharable)
\internal
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index e71064c..df0ae46 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -182,6 +182,7 @@ public:
inline void detach() { if (d->ref != 1) detach_helper(); }
inline bool isDetached() const { return d->ref == 1; }
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline bool isSharedWith(const QMap<Key, T> &other) const { return d == other.d; }
inline void setInsertInOrder(bool ordered) { d->insertInOrder = ordered; }
void clear();
@@ -213,7 +214,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
@@ -281,7 +282,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -384,7 +385,7 @@ public:
// STL compatibility
typedef Key key_type;
typedef T mapped_type;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef int size_type;
inline bool empty() const { return isEmpty(); }
@@ -772,6 +773,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::uniqueKeys() const
{
QList<Key> res;
+ res.reserve(size()); // May be too much, but assume short lifetime
const_iterator i = begin();
if (i != end()) {
for (;;) {
@@ -791,6 +793,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<Key> QMap<Key, T>::keys() const
{
QList<Key> res;
+ res.reserve(size());
const_iterator i = begin();
while (i != end()) {
res.append(i.key());
@@ -835,6 +838,7 @@ template <class Key, class T>
Q_OUTOFLINE_TEMPLATE QList<T> QMap<Key, T>::values() const
{
QList<T> res;
+ res.reserve(size());
const_iterator i = begin();
while (i != end()) {
res.append(i.value());
diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp
index d60087f..9850ee7 100644
--- a/src/corelib/tools/qpoint.cpp
+++ b/src/corelib/tools/qpoint.cpp
@@ -374,7 +374,7 @@ QDebug operator<<(QDebug dbg, const QPoint &p) {
QDebug operator<<(QDebug d, const QPointF &p)
{
d.nospace() << "QPointF(" << p.x() << ", " << p.y() << ')';
- return d;
+ return d.space();
}
#endif
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index 25255f9..20ad444 100644
--- a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -1466,9 +1466,14 @@ void QRegExpMatchState::match(const QChar *str0, int len0, int pos0,
#ifndef QT_NO_REGEXP_CAPTURE
for (int i = 0; i < numCaptures; ++i) {
int j = eng->captureForOfficialCapture.at(i);
- int len = capEnd[j] - capBegin[j];
- *c++ = (len > 0) ? pos + capBegin[j] : 0;
- *c++ = len;
+ if (capBegin[j] != EmptyCapture) {
+ int len = capEnd[j] - capBegin[j];
+ *c++ = (len > 0) ? pos + capBegin[j] : 0;
+ *c++ = len;
+ } else {
+ *c++ = -1;
+ *c++ = -1;
+ }
}
#endif
} else {
diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp
index 12badf0..e7dd769 100644
--- a/src/corelib/tools/qscopedpointer.cpp
+++ b/src/corelib/tools/qscopedpointer.cpp
@@ -225,4 +225,59 @@ QT_BEGIN_NAMESPACE
Swap this pointer with \a other.
*/
+/*!
+ \class QScopedArrayPointer
+
+ \brief The QScopedArrayPointer class stores a pointer to a
+ dynamically allocated array of objects, and deletes it upon
+ destruction.
+
+ \since 4.6
+ \reentrant
+ \ingroup misc
+
+ A QScopedArrayPointer is a QScopedPointer that defaults to
+ deleting the object it is pointing to with the delete[] operator. It
+ also features operator[] for convenience, so we can write:
+
+ \code
+ void foo()
+ {
+ QScopedArrayPointer<int> i(new int[10]);
+ i[2] = 42;
+ ...
+ return; // our integer array is now deleted using delete[]
+ }
+ \endcode
+*/
+
+/*!
+ \fn QScopedArrayPointer::QScopedArrayPointer(T *p = 0)
+
+ Constructs this QScopedArrayPointer instance and sets its pointer
+ to \a p.
+*/
+
+/*!
+ \fn T *QScopedArrayPointer::operator[](int i)
+
+ Provides access to entry \a i of the scoped pointer's array of
+ objects.
+
+ If the contained pointer is \c null, behavior is undefined.
+
+ \sa isNull()
+*/
+
+/*!
+ \fn T *QScopedArrayPointer::operator[](int i) const
+
+ Provides access to entry \a i of the scoped pointer's array of
+ objects.
+
+ If the contained pointer is \c null, behavior is undefined.
+
+ \sa isNull()
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qset.h b/src/corelib/tools/qset.h
index 6525880..fe50d4d 100644
--- a/src/corelib/tools/qset.h
+++ b/src/corelib/tools/qset.h
@@ -97,7 +97,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -132,7 +132,7 @@ public:
public:
typedef std::bidirectional_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -188,11 +188,10 @@ public:
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef int size_type;
inline bool empty() const { return isEmpty(); }
-
// comfort
inline QSet<T> &operator<<(const T &value) { insert(value); return *this; }
inline QSet<T> &operator|=(const QSet<T> &other) { unite(other); return *this; }
@@ -292,6 +291,7 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QSet<T>::toList() const
{
QList<T> result;
+ result.reserve(size());
typename QSet<T>::const_iterator i = constBegin();
while (i != constEnd()) {
result.append(*i);
diff --git a/src/corelib/tools/qsharedpointer_impl.h b/src/corelib/tools/qsharedpointer_impl.h
index 8fbfcda..bfc65bc 100644
--- a/src/corelib/tools/qsharedpointer_impl.h
+++ b/src/corelib/tools/qsharedpointer_impl.h
@@ -132,7 +132,7 @@ namespace QtSharedPointer {
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
inline T *data() const { return value; }
inline bool isNull() const { return !data(); }
@@ -209,6 +209,7 @@ namespace QtSharedPointer {
inline bool destroy() { destroyer(this); return true; }
inline void operator delete(void *ptr) { ::operator delete(ptr); }
+ inline void operator delete(void *, void *) { }
};
// sizeof(ExternalRefCountWithDestroyFn) = 16 (32-bit) / 24 (64-bit)
@@ -541,7 +542,7 @@ public:
typedef const value_type *const_pointer;
typedef value_type &reference;
typedef const value_type &const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
inline bool isNull() const { return d == 0 || d->strongref == 0 || value == 0; }
#ifndef Q_CC_NOKIAX86
@@ -653,6 +654,9 @@ public:
T *value;
};
+//
+// operator== and operator!=
+//
template <class T, class X>
bool operator==(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
{
@@ -674,7 +678,6 @@ bool operator==(const T *ptr1, const QSharedPointer<X> &ptr2)
{
return ptr1 == ptr2.data();
}
-
template <class T, class X>
bool operator!=(const QSharedPointer<T> &ptr1, const X *ptr2)
{
@@ -697,11 +700,54 @@ bool operator!=(const QSharedPointer<T> &ptr1, const QWeakPointer<X> &ptr2)
return ptr2 != ptr1;
}
+//
+// operator-
+//
template <class T, class X>
-Q_INLINE_TEMPLATE typename T::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
{
return ptr1.data() - ptr2.data();
}
+template <class T, class X>
+Q_INLINE_TEMPLATE typename QSharedPointer<T>::difference_type operator-(const QSharedPointer<T> &ptr1, X *ptr2)
+{
+ return ptr1.data() - ptr2;
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE typename QSharedPointer<X>::difference_type operator-(T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 - ptr2.data();
+}
+
+//
+// operator<
+//
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1.data() < ptr2.data();
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(const QSharedPointer<T> &ptr1, X *ptr2)
+{
+ return ptr1.data() < ptr2;
+}
+template <class T, class X>
+Q_INLINE_TEMPLATE bool operator<(T *ptr1, const QSharedPointer<X> &ptr2)
+{
+ return ptr1 < ptr2.data();
+}
+
+//
+// qHash
+//
+template <class T> inline uint qHash(const T *key); // defined in qhash.h
+template <class T>
+Q_INLINE_TEMPLATE uint qHash(const QSharedPointer<T> &ptr)
+{
+ return QT_PREPEND_NAMESPACE(qHash)<T>(ptr.data());
+}
+
template <class T>
Q_INLINE_TEMPLATE QWeakPointer<T> QSharedPointer<T>::toWeakRef() const
diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp
new file mode 100644
index 0000000..52d2cea
--- /dev/null
+++ b/src/corelib/tools/qsimd.cpp
@@ -0,0 +1,246 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qsimd_p.h"
+#include <QByteArray>
+
+QT_BEGIN_NAMESPACE
+
+uint qDetectCPUFeatures()
+{
+ static uint features = 0xffffffff;
+ if (features != 0xffffffff)
+ return features;
+
+#if defined (Q_OS_WINCE)
+#if defined (ARM)
+ if (IsProcessorFeaturePresent(PF_ARM_INTEL_WMMX)) {
+ features = IWMMXT;
+ return features;
+ }
+#elif defined(_X86_)
+ features = 0;
+#if defined QT_HAVE_MMX
+ if (IsProcessorFeaturePresent(PF_MMX_INSTRUCTIONS_AVAILABLE))
+ features |= MMX;
+#endif
+#if defined QT_HAVE_3DNOW
+ if (IsProcessorFeaturePresent(PF_3DNOW_INSTRUCTIONS_AVAILABLE))
+ features |= MMX3DNOW;
+#endif
+ return features;
+#endif
+ features = 0;
+ return features;
+#elif defined(QT_HAVE_IWMMXT)
+ // runtime detection only available when running as a previlegied process
+ static const bool doIWMMXT = !qgetenv("QT_NO_IWMMXT").toInt();
+ features = doIWMMXT ? IWMMXT : 0;
+ return features;
+#elif defined(QT_HAVE_NEON)
+ static const bool doNEON = !qgetenv("QT_NO_NEON").toInt();
+ features = doNEON ? NEON : 0;
+ return features;
+#else
+ features = 0;
+#if defined(__x86_64__) || defined(Q_OS_WIN64)
+ features = MMX|SSE|SSE2|CMOV;
+#elif defined(__ia64__)
+ features = MMX|SSE|SSE2;
+#elif defined(__i386__) || defined(_M_IX86)
+ unsigned int extended_result = 0;
+ uint result = 0;
+ /* see p. 118 of amd64 instruction set manual Vol3 */
+#if defined(Q_CC_GNU)
+ asm ("push %%ebx\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "mov %%eax, %%ebx\n"
+ "xor $0x00200000, %%eax\n"
+ "push %%eax\n"
+ "popf\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "xor %%edx, %%edx\n"
+ "xor %%ebx, %%eax\n"
+ "jz 1f\n"
+
+ "mov $0x00000001, %%eax\n"
+ "cpuid\n"
+ "1:\n"
+ "pop %%ebx\n"
+ "mov %%edx, %0\n"
+ : "=r" (result)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+
+ asm ("push %%ebx\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "mov %%eax, %%ebx\n"
+ "xor $0x00200000, %%eax\n"
+ "push %%eax\n"
+ "popf\n"
+ "pushf\n"
+ "pop %%eax\n"
+ "xor %%edx, %%edx\n"
+ "xor %%ebx, %%eax\n"
+ "jz 2f\n"
+
+ "mov $0x80000000, %%eax\n"
+ "cpuid\n"
+ "cmp $0x80000000, %%eax\n"
+ "jbe 2f\n"
+ "mov $0x80000001, %%eax\n"
+ "cpuid\n"
+ "2:\n"
+ "pop %%ebx\n"
+ "mov %%edx, %0\n"
+ : "=r" (extended_result)
+ :
+ : "%eax", "%ecx", "%edx"
+ );
+#elif defined (Q_OS_WIN)
+ _asm {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ pushfd
+ pop eax
+ mov ebx, eax
+ xor eax, 00200000h
+ push eax
+ popfd
+ pushfd
+ pop eax
+ mov edx, 0
+ xor eax, ebx
+ jz skip
+
+ mov eax, 1
+ cpuid
+ mov result, edx
+ skip:
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+
+ _asm {
+ push eax
+ push ebx
+ push ecx
+ push edx
+ pushfd
+ pop eax
+ mov ebx, eax
+ xor eax, 00200000h
+ push eax
+ popfd
+ pushfd
+ pop eax
+ mov edx, 0
+ xor eax, ebx
+ jz skip2
+
+ mov eax, 80000000h
+ cpuid
+ cmp eax, 80000000h
+ jbe skip2
+ mov eax, 80000001h
+ cpuid
+ mov extended_result, edx
+ skip2:
+ pop edx
+ pop ecx
+ pop ebx
+ pop eax
+ }
+#endif
+
+ // result now contains the standard feature bits
+ if (result & (1u << 15))
+ features |= CMOV;
+ if (result & (1u << 23))
+ features |= MMX;
+ if (extended_result & (1u << 22))
+ features |= MMXEXT;
+ if (extended_result & (1u << 31))
+ features |= MMX3DNOW;
+ if (extended_result & (1u << 30))
+ features |= MMX3DNOWEXT;
+ if (result & (1u << 25))
+ features |= SSE;
+ if (result & (1u << 26))
+ features |= SSE2;
+#endif // i386
+
+#if defined(QT_HAVE_MMX)
+ if (qgetenv("QT_NO_MMX").toInt())
+ features ^= MMX;
+#endif
+ if (qgetenv("QT_NO_MMXEXT").toInt())
+ features ^= MMXEXT;
+
+#if defined(QT_HAVE_3DNOW)
+ if (qgetenv("QT_NO_3DNOW").toInt())
+ features ^= MMX3DNOW;
+#endif
+ if (qgetenv("QT_NO_3DNOWEXT").toInt())
+ features ^= MMX3DNOWEXT;
+
+#if defined(QT_HAVE_SSE)
+ if (qgetenv("QT_NO_SSE").toInt())
+ features ^= SSE;
+#endif
+#if defined(QT_HAVE_SSE2)
+ if (qgetenv("QT_NO_SSE2").toInt())
+ features ^= SSE2;
+#endif
+
+ return features;
+#endif
+}
+
+QT_END_NAMESPACE
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
new file mode 100644
index 0000000..44c1798
--- /dev/null
+++ b/src/corelib/tools/qsimd_p.h
@@ -0,0 +1,126 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QSIMD_P_H
+#define QSIMD_P_H
+
+#include <qglobal.h>
+
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+#if defined(QT_NO_MAC_XARCH) || (defined(Q_OS_DARWIN) && (defined(__ppc__) || defined(__ppc64__)))
+// Disable MMX and SSE on Mac/PPC builds, or if the compiler
+// does not support -Xarch argument passing
+#undef QT_HAVE_SSE2
+#undef QT_HAVE_SSE
+#undef QT_HAVE_3DNOW
+#undef QT_HAVE_MMX
+#endif
+
+// SSE intrinsics
+#if defined(__SSE2__) && defined(QT_HAVE_SSE2) && !defined(QT_BOOTSTRAPPED)
+#if defined(QT_LINUXBASE)
+/// this is an evil hack - the posix_memalign declaration in LSB
+/// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431
+# define posix_memalign _lsb_hack_posix_memalign
+# include <emmintrin.h>
+# undef posix_memalign
+#else
+# include <emmintrin.h>
+#endif
+
+#define QT_ALWAYS_HAVE_SSE2
+#endif
+
+// NEON intrinsics
+#if defined(QT_HAVE_NEON)
+#include <arm_neon.h>
+#endif
+
+
+// IWMMXT intrinsics
+#if defined(QT_HAVE_IWMMXT)
+#include <mmintrin.h>
+#if defined(Q_OS_WINCE)
+# include "qplatformdefs.h"
+#endif
+#endif
+
+#if defined(QT_HAVE_IWMMXT)
+#if !defined(__IWMMXT__) && !defined(Q_OS_WINCE)
+# include <xmmintrin.h>
+#elif defined(Q_OS_WINCE_STD) && defined(_X86_)
+# pragma warning(disable: 4391)
+# include <xmmintrin.h>
+#endif
+#endif
+
+// 3D now intrinsics
+#if defined(QT_HAVE_3DNOW)
+#include <mm3dnow.h>
+#endif
+
+enum CPUFeatures {
+ None = 0,
+ MMX = 0x1,
+ MMXEXT = 0x2,
+ MMX3DNOW = 0x4,
+ MMX3DNOWEXT = 0x8,
+ SSE = 0x10,
+ SSE2 = 0x20,
+ CMOV = 0x40,
+ IWMMXT = 0x80,
+ NEON = 0x100
+};
+
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+Q_CORE_EXPORT uint qDetectCPUFeatures();
+
+#endif // QSIMD_P_H
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 3ef0e66..e9b7b9a 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -46,6 +46,7 @@
#include <qtextcodec.h>
#endif
#include <private/qutfcodec_p.h>
+#include "qsimd_p.h"
#include <qdatastream.h>
#include <qlist.h>
#include "qlocale.h"
@@ -55,6 +56,7 @@
#include "qtools_p.h"
#include "qhash.h"
#include "qdebug.h"
+#include "qendian.h"
#ifdef Q_OS_MAC
#include <private/qcore_mac_p.h>
@@ -988,6 +990,40 @@ QString::QString(const QChar *unicode, int size)
}
}
+/*!
+ \since 4.7
+
+ Constructs a string initialized with the characters of the QChar array
+ \a unicode, which must be terminated with a 0.
+
+ QString makes a deep copy of the string data. The unicode data is copied as
+ is and the Byte Order Mark is preserved if present.
+*/
+QString::QString(const QChar *unicode)
+{
+ if (!unicode) {
+ d = &shared_null;
+ d->ref.ref();
+ } else {
+ int size = 0;
+ while (unicode[size] != 0)
+ ++size;
+ if (!size) {
+ d = &shared_empty;
+ d->ref.ref();
+ } else {
+ d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ Q_CHECK_PTR(d);
+ d->ref = 1;
+ d->alloc = d->size = size;
+ d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
+ d->data = d->array;
+ memcpy(d->array, unicode, size * sizeof(QChar));
+ d->array[size] = '\0';
+ }
+ }
+}
+
/*!
Constructs a string of the given \a size with every character set
@@ -1091,7 +1127,12 @@ QString::QString(QChar ch)
\internal
*/
-/*! \fn void QString::isDetached() const
+/*! \fn bool QString::isDetached() const
+
+ \internal
+*/
+
+/*! \fn bool QString::isSharedWith(const QString &other) const
\internal
*/
@@ -1760,13 +1801,14 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
}
QT_TRY {
- detach();
if (blen == alen) {
// replace in place
+ detach();
for (int i = 0; i < nIndices; ++i)
memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar));
} else if (alen < blen) {
// replace from front
+ detach();
uint to = indices[0];
if (alen)
memcpy(d->data+to, after, alen*sizeof(QChar));
@@ -3438,12 +3480,82 @@ static QByteArray toLatin1_helper(const QChar *data, int length)
QByteArray ba;
if (length) {
ba.resize(length);
- const ushort *i = reinterpret_cast<const ushort *>(data);
- const ushort *e = i + length;
- uchar *s = (uchar*) ba.data();
- while (i != e) {
- *s++ = (*i>0xff) ? '?' : (uchar) *i;
- ++i;
+ const ushort *src = reinterpret_cast<const ushort *>(data);
+ uchar *dst = (uchar*) ba.data();
+#if defined(QT_ALWAYS_HAVE_SSE2)
+ if (length >= 16) {
+ const int chunkCount = length >> 4; // divided by 16
+ const __m128i questionMark = _mm_set1_epi16('?');
+ // SSE has no compare instruction for unsigned comparison.
+ // The variables must be shiffted + 0x8000 to be compared
+ const __m128i signedBitOffset = _mm_set1_epi16(0x8000);
+ const __m128i thresholdMask = _mm_set1_epi16(0xff + 0x8000);
+ for (int i = 0; i < chunkCount; ++i) {
+ __m128i chunk1 = _mm_loadu_si128((__m128i*)src); // load
+ src += 8;
+ {
+ // each 16 bit is equal to 0xFF if the source is outside latin 1 (>0xff)
+ const __m128i signedChunk = _mm_add_epi16(chunk1, signedBitOffset);
+ const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
+
+ // offLimitQuestionMark contains '?' for each 16 bits that was off-limit
+ // the 16 bits that were correct contains zeros
+ const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
+
+ // correctBytes contains the bytes that were in limit
+ // the 16 bits that were off limits contains zeros
+ const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk1);
+
+ // merge offLimitQuestionMark and correctBytes to have the result
+ chunk1 = _mm_or_si128(correctBytes, offLimitQuestionMark);
+ }
+
+ __m128i chunk2 = _mm_loadu_si128((__m128i*)src); // load
+ src += 8;
+ {
+ // exactly the same operations as for the previous chunk of data
+ const __m128i signedChunk = _mm_add_epi16(chunk2, signedBitOffset);
+ const __m128i offLimitMask = _mm_cmpgt_epi16(signedChunk, thresholdMask);
+ const __m128i offLimitQuestionMark = _mm_and_si128(offLimitMask, questionMark);
+ const __m128i correctBytes = _mm_andnot_si128(offLimitMask, chunk2);
+ chunk2 = _mm_or_si128(correctBytes, offLimitQuestionMark);
+ }
+
+ // pack the two vector to 16 x 8bits elements
+ const __m128i result = _mm_packus_epi16(chunk1, chunk2);
+
+ _mm_storeu_si128((__m128i*)dst, result); // store
+ dst += 16;
+ }
+ length = length % 16;
+ }
+#elif QT_HAVE_NEON
+ // Refer to the documentation of the SSE2 implementation
+ // this use eactly the same method as for SSE except:
+ // 1) neon has unsigned comparison
+ // 2) packing is done to 64 bits (8 x 8bits component).
+ if (length >= 16) {
+ const int chunkCount = length >> 3; // divided by 8
+ const uint16x8_t questionMark = vdupq_n_u16('?'); // set
+ const uint16x8_t thresholdMask = vdupq_n_u16(0xff); // set
+ for (int i = 0; i < chunkCount; ++i) {
+ uint16x8_t chunk = vld1q_u16((uint16_t *)src); // load
+ src += 8;
+
+ const uint16x8_t offLimitMask = vcgtq_u16(chunk, thresholdMask); // chunk > thresholdMask
+ const uint16x8_t offLimitQuestionMark = vandq_u16(offLimitMask, questionMark); // offLimitMask & questionMark
+ const uint16x8_t correctBytes = vbicq_u16(chunk, offLimitMask); // !offLimitMask & chunk
+ chunk = vorrq_u16(correctBytes, offLimitQuestionMark); // correctBytes | offLimitQuestionMark
+ const uint8x8_t result = vmovn_u16(chunk); // narrowing move->packing
+ vst1_u8(dst, result); // store
+ dst += 8;
+ }
+ length = length % 8;
+ }
+#endif
+ while (length--) {
+ *dst++ = (*src>0xff) ? '?' : (uchar) *src;
+ ++src;
}
}
return ba;
@@ -3606,10 +3718,35 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
d->alloc = d->size = size;
d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0;
d->data = d->array;
- ushort *i = d->data;
d->array[size] = '\0';
+ ushort *dst = d->data;
+ /* SIMD:
+ * Unpacking with SSE has been shown to improve performance on recent CPUs
+ * The same method gives no improvement with NEON.
+ */
+#if defined(QT_ALWAYS_HAVE_SSE2)
+ if (size >= 16) {
+ int chunkCount = size >> 4; // divided by 16
+ const __m128i nullMask = _mm_set1_epi32(0);
+ for (int i = 0; i < chunkCount; ++i) {
+ const __m128i chunk = _mm_loadu_si128((__m128i*)str); // load
+ str += 16;
+
+ // unpack the first 8 bytes, padding with zeros
+ const __m128i firstHalf = _mm_unpacklo_epi8(chunk, nullMask);
+ _mm_storeu_si128((__m128i*)dst, firstHalf); // store
+ dst += 8;
+
+ // unpack the last 8 bytes, padding with zeros
+ const __m128i secondHalf = _mm_unpackhi_epi8 (chunk, nullMask);
+ _mm_storeu_si128((__m128i*)dst, secondHalf); // store
+ dst += 8;
+ }
+ size = size % 16;
+ }
+#endif
while (size--)
- *i++ = (uchar)*str++;
+ *dst++ = (uchar)*str++;
}
return d;
}
@@ -3861,7 +3998,7 @@ QString QString::fromUtf8(const char *str, int size)
host byte order is assumed.
This function is comparatively slow.
- Use QString(const ushort *, int) if possible.
+ Use QString(const ushort *, int) or QString(const ushort *) if possible.
QString makes a deep copy of the Unicode data.
@@ -3954,24 +4091,74 @@ QString QString::simplified() const
{
if (d->size == 0)
return *this;
- QString result(d->size, Qt::Uninitialized);
- const QChar *from = (const QChar*) d->data;
- const QChar *fromend = (const QChar*) from+d->size;
- int outc=0;
- QChar *to = (QChar*) result.d->data;
- for (;;) {
- while (from!=fromend && from->isSpace())
- from++;
- while (from!=fromend && !from->isSpace())
- to[outc++] = *from++;
- if (from!=fromend)
- to[outc++] = QLatin1Char(' ');
- else
+
+ const QChar * const start = reinterpret_cast<QChar *>(d->data);
+ const QChar *from = start;
+ const QChar *fromEnd = start + d->size;
+ forever {
+ QChar ch = *from;
+ if (!ch.isSpace())
break;
+ if (++from == fromEnd) {
+ // All-whitespace string
+ shared_empty.ref.ref();
+ return QString(&shared_empty, 0);
+ }
+ }
+ // This loop needs no underflow check, as we already determined that
+ // the string contains non-whitespace. If the string has exactly one
+ // non-whitespace, it will be checked twice - we can live with that.
+ while (fromEnd[-1].isSpace())
+ fromEnd--;
+ // The rest of the function depends on the fact that we already know
+ // that the last character in the source is no whitespace.
+ const QChar *copyFrom = from;
+ int copyCount;
+ forever {
+ if (++from == fromEnd) {
+ // Only leading and/or trailing whitespace, if any at all
+ return mid(copyFrom - start, from - copyFrom);
+ }
+ QChar ch = *from;
+ if (!ch.isSpace())
+ continue;
+ if (ch != QLatin1Char(' ')) {
+ copyCount = from - copyFrom;
+ break;
+ }
+ ch = *++from;
+ if (ch.isSpace()) {
+ copyCount = from - copyFrom - 1;
+ break;
+ }
+ }
+ // 'from' now points at the non-trailing whitespace which made the
+ // string not simplified in the first place. 'copyCount' is the number
+ // of already simplified characters - at least one, obviously -
+ // without a trailing space.
+ QString result((fromEnd - from) + copyCount, Qt::Uninitialized);
+ QChar *to = reinterpret_cast<QChar *>(result.d->data);
+ ::memcpy(to, copyFrom, copyCount * 2);
+ to += copyCount;
+ fromEnd--;
+ QChar ch;
+ forever {
+ *to++ = QLatin1Char(' ');
+ do {
+ ch = *++from;
+ } while (ch.isSpace());
+ if (from == fromEnd)
+ break;
+ do {
+ *to++ = ch;
+ ch = *++from;
+ if (from == fromEnd)
+ goto done;
+ } while (!ch.isSpace());
}
- if (outc > 0 && to[outc-1] == QLatin1Char(' '))
- outc--;
- result.truncate(outc);
+ done:
+ *to++ = ch;
+ result.truncate(to - reinterpret_cast<QChar *>(result.d->data));
return result;
}
@@ -7317,7 +7504,7 @@ QDataStream &operator>>(QDataStream &in, QString &str)
!= (QSysInfo::ByteOrder == QSysInfo::BigEndian)) {
ushort *data = reinterpret_cast<ushort *>(str.data());
while (len--) {
- *data = (*data >> 8) | (*data << 8);
+ *data = qbswap(*data);
++data;
}
}
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index c1def0f..a59c0bd 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -73,6 +73,16 @@ typedef std::basic_string<wchar_t> QStdWString;
#error qstring.h must be included before any header file that defines truncate
#endif
+#if defined(Q_CC_GNU) && (__GNUC__ == 4 && __GNUC_MINOR__ == 0)
+//There is a bug in GCC 4.0 that tries to instantiate template of annonymous enum
+# ifdef QT_USE_FAST_OPERATOR_PLUS
+# undef QT_USE_FAST_OPERATOR_PLUS
+# endif
+# ifdef QT_USE_FAST_CONCATENATION
+# undef QT_USE_FAST_CONCATENATION
+# endif
+#endif
+
QT_BEGIN_HEADER
QT_BEGIN_NAMESPACE
@@ -91,7 +101,8 @@ class Q_CORE_EXPORT QString
{
public:
inline QString();
- QString(const QChar *unicode, int size);
+ QString(const QChar *unicode, int size); // Qt5: don't cap size < 0
+ explicit QString(const QChar *unicode); // Qt5: merge with the above
QString(QChar c);
QString(int size, QChar c);
inline QString(const QLatin1String &latin1);
@@ -122,6 +133,7 @@ public:
inline void detach();
inline bool isDetached() const;
+ inline bool isSharedWith(const QString &other) const { return d == other.d; }
void clear();
inline const QChar at(int i) const;
@@ -594,7 +606,7 @@ private:
struct Data {
QBasicAtomicInt ref;
int alloc, size;
- ushort *data;
+ ushort *data; // QT5: put that after the bit field to fill alignment gap; don't use sizeof any more then
ushort clean : 1;
ushort simpletext : 1;
ushort righttoleft : 1;
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 74661c2..0c3ba06 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -100,14 +100,18 @@ public:
operator QString() const
{
- QString s(QConcatenable< QStringBuilder<A, B> >::size(*this),
- Qt::Uninitialized);
+ const uint size = QConcatenable< QStringBuilder<A, B> >::size(*this);
+ QString s(size, Qt::Uninitialized);
QChar *d = s.data();
+ const QChar * const start = d;
QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d);
- // this resize is necessary since we allocate a bit too much
- // when dealing with variable sized 8-bit encodings
- s.resize(d - s.data());
+
+ if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(size) != d - start) {
+ // this resize is necessary since we allocate a bit too much
+ // when dealing with variable sized 8-bit encodings
+ s.resize(d - start);
+ }
return s;
}
QByteArray toLatin1() const { return QString(*this).toLatin1(); }
@@ -116,10 +120,24 @@ public:
const B &b;
};
+template <>
+class QStringBuilder <QString, QString>
+{
+ public:
+ QStringBuilder(const QString &a_, const QString &b_) : a(a_), b(b_) {}
+
+ operator QString() const
+ { QString r(a); r += b; return r; }
+ QByteArray toLatin1() const { return QString(*this).toLatin1(); }
+
+ const QString &a;
+ const QString &b;
+};
template <> struct QConcatenable<char> : private QAbstractConcatenable
{
typedef char type;
+ enum { ExactSize = true };
static int size(const char) { return 1; }
static inline void appendTo(const char c, QChar *&out)
{
@@ -130,6 +148,7 @@ template <> struct QConcatenable<char> : private QAbstractConcatenable
template <> struct QConcatenable<QLatin1Char>
{
typedef QLatin1Char type;
+ enum { ExactSize = true };
static int size(const QLatin1Char) { return 1; }
static inline void appendTo(const QLatin1Char c, QChar *&out)
{
@@ -140,6 +159,7 @@ template <> struct QConcatenable<QLatin1Char>
template <> struct QConcatenable<QChar>
{
typedef QChar type;
+ enum { ExactSize = true };
static int size(const QChar) { return 1; }
static inline void appendTo(const QChar c, QChar *&out)
{
@@ -150,6 +170,7 @@ template <> struct QConcatenable<QChar>
template <> struct QConcatenable<QCharRef>
{
typedef QCharRef type;
+ enum { ExactSize = true };
static int size(const QCharRef &) { return 1; }
static inline void appendTo(const QCharRef &c, QChar *&out)
{
@@ -160,6 +181,7 @@ template <> struct QConcatenable<QCharRef>
template <> struct QConcatenable<QLatin1String>
{
typedef QLatin1String type;
+ enum { ExactSize = true };
static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
static inline void appendTo(const QLatin1String &a, QChar *&out)
{
@@ -172,6 +194,7 @@ template <> struct QConcatenable<QLatin1String>
template <> struct QConcatenable<QLatin1Literal>
{
typedef QLatin1Literal type;
+ enum { ExactSize = true };
static int size(const QLatin1Literal &a) { return a.size(); }
static inline void appendTo(const QLatin1Literal &a, QChar *&out)
{
@@ -183,6 +206,7 @@ template <> struct QConcatenable<QLatin1Literal>
template <> struct QConcatenable<QString>
{
typedef QString type;
+ enum { ExactSize = true };
static int size(const QString &a) { return a.size(); }
static inline void appendTo(const QString &a, QChar *&out)
{
@@ -195,6 +219,7 @@ template <> struct QConcatenable<QString>
template <> struct QConcatenable<QStringRef>
{
typedef QStringRef type;
+ enum { ExactSize = true };
static int size(const QStringRef &a) { return a.size(); }
static inline void appendTo(QStringRef a, QChar *&out)
{
@@ -208,6 +233,7 @@ template <> struct QConcatenable<QStringRef>
template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
{
typedef char type[N];
+ enum { ExactSize = false };
static int size(const char[N])
{
return N - 1;
@@ -221,6 +247,7 @@ template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable
template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable
{
typedef const char type[N];
+ enum { ExactSize = false };
static int size(const char[N]) { return N - 1; }
static inline void appendTo(const char a[N], QChar *&out)
{
@@ -231,6 +258,7 @@ template <int N> struct QConcatenable<const char[N]> : private QAbstractConcaten
template <> struct QConcatenable<const char *> : private QAbstractConcatenable
{
typedef char const *type;
+ enum { ExactSize = false };
static int size(const char *a) { return qstrlen(a); }
static inline void appendTo(const char *a, QChar *&out)
{
@@ -241,6 +269,7 @@ template <> struct QConcatenable<const char *> : private QAbstractConcatenable
template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable
{
typedef QByteArray type;
+ enum { ExactSize = false };
static int size(const QByteArray &ba) { return qstrnlen(ba.constData(), ba.size()); }
static inline void appendTo(const QByteArray &ba, QChar *&out)
{
@@ -253,6 +282,7 @@ template <typename A, typename B>
struct QConcatenable< QStringBuilder<A, B> >
{
typedef QStringBuilder<A, B> type;
+ enum { ExactSize = QConcatenable<A>::ExactSize && QConcatenable<B>::ExactSize };
static int size(const type &p)
{
return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b);
diff --git a/src/corelib/tools/qstringlist.cpp b/src/corelib/tools/qstringlist.cpp
index 4b0f488..e9bdf57 100644
--- a/src/corelib/tools/qstringlist.cpp
+++ b/src/corelib/tools/qstringlist.cpp
@@ -404,7 +404,17 @@ void QtPrivate::QStringList_replaceInStrings(QStringList *that, const QRegExp &r
*/
QString QtPrivate::QStringList_join(const QStringList *that, const QString &sep)
{
+ int totalLength = 0;
+ const int size = that->size();
+
+ for (int i = 0; i < size; ++i)
+ totalLength += that->at(i).size();
+
+ if(size > 0)
+ totalLength += sep.size() * (size - 1);
+
QString res;
+ res.reserve(totalLength);
for (int i = 0; i < that->size(); ++i) {
if (i)
res += sep;
diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp
index 48b52d2..3a13540 100644
--- a/src/corelib/tools/qvector.cpp
+++ b/src/corelib/tools/qvector.cpp
@@ -392,6 +392,11 @@ int QVectorData::grow(int sizeofTypedData, int size, int sizeofT, bool excessive
\internal
*/
+/*! \fn bool QVector::isSharedWith(const QVector<T> &other) const
+
+ \internal
+*/
+
/*! \fn T *QVector::data()
Returns a pointer to the data stored in the vector. The pointer
diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h
index 90b7442..c2e2485 100644
--- a/src/corelib/tools/qvector.h
+++ b/src/corelib/tools/qvector.h
@@ -134,6 +134,7 @@ public:
inline void detach() { if (d->ref != 1) detach_helper(); }
inline bool isDetached() const { return d->ref == 1; }
inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; }
+ inline bool isSharedWith(const QVector<T> &other) const { return d == other.d; }
inline T *data() { detach(); return p->array; }
inline const T *data() const { return p->array; }
@@ -163,7 +164,7 @@ public:
public:
T *i;
typedef std::random_access_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef T *pointer;
typedef T &reference;
@@ -196,7 +197,7 @@ public:
public:
T *i;
typedef std::random_access_iterator_tag iterator_category;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef T value_type;
typedef const T *pointer;
typedef const T &reference;
@@ -260,7 +261,7 @@ public:
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
- typedef ptrdiff_t difference_type;
+ typedef qptrdiff difference_type;
typedef iterator Iterator;
typedef const_iterator ConstIterator;
typedef int size_type;
@@ -727,9 +728,10 @@ Q_OUTOFLINE_TEMPLATE QVector<T> QVector<T>::mid(int pos, int length) const
length = size() - pos;
if (pos == 0 && length == size())
return *this;
- QVector<T> copy;
if (pos + length > size())
length = size() - pos;
+ QVector<T> copy;
+ copy.reserve(length);
for (int i = pos; i < pos + length; ++i)
copy += at(i);
return copy;
@@ -739,6 +741,7 @@ template <typename T>
Q_OUTOFLINE_TEMPLATE QList<T> QVector<T>::toList() const
{
QList<T> result;
+ result.reserve(size());
for (int i = 0; i < size(); ++i)
result.append(at(i));
return result;
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 3406e41..6d64915 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -33,6 +33,7 @@ HEADERS += \
tools/qsharedpointer.h \
tools/qsharedpointer_impl.h \
tools/qset.h \
+ tools/qsimd_p.h \
tools/qsize.h \
tools/qstack.h \
tools/qstring.h \
@@ -68,6 +69,7 @@ SOURCES += \
tools/qregexp.cpp \
tools/qshareddata.cpp \
tools/qsharedpointer.cpp \
+ tools/qsimd.cpp \
tools/qsize.cpp \
tools/qstring.cpp \
tools/qstringbuilder.cpp \
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 5717ca2..1bf00b8 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -3003,8 +3003,7 @@ QXmlStreamWriterPrivate::QXmlStreamWriterPrivate(QXmlStreamWriter *q)
deleteDevice = false;
#ifndef QT_NO_TEXTCODEC
codec = QTextCodec::codecForMib(106); // utf8
- encoder = codec->makeEncoder();
- encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8
+ encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8
#endif
inStartElement = inEmptyElement = false;
wroteSomething = false;
@@ -3278,9 +3277,7 @@ void QXmlStreamWriter::setCodec(QTextCodec *codec)
if (codec) {
d->codec = codec;
delete d->encoder;
- d->encoder = codec->makeEncoder();
- if (codec->mibEnum() == 106)
- d->encoder->state.flags |= QTextCodec::IgnoreHeader; // no byte order mark for utf8
+ d->encoder = codec->makeEncoder(QTextCodec::IgnoreHeader); // no byte order mark for utf8
}
}
diff --git a/src/corelib/xml/qxmlstream_p.h b/src/corelib/xml/qxmlstream_p.h
index 6b911d2..ac421cf 100644
--- a/src/corelib/xml/qxmlstream_p.h
+++ b/src/corelib/xml/qxmlstream_p.h
@@ -54,7 +54,7 @@
#ifndef QXMLSTREAM_P_H
#define QXMLSTREAM_P_H
-#if defined(Q_OS_VXWORKS) && defined(ERROR)
+#if defined(ERROR)
# undef ERROR
#endif