diff options
Diffstat (limited to 'src')
294 files changed, 2864 insertions, 1896 deletions
diff --git a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp index 36b9282..2e3ef38 100644 --- a/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp +++ b/src/3rdparty/harfbuzz/src/harfbuzz-shaper.cpp @@ -935,7 +935,13 @@ static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Ta if (error) return 0; stream = (HB_Stream)malloc(sizeof(HB_StreamRec)); + if (!stream) + return 0; stream->base = (HB_Byte*)malloc(length); + if (!stream->base) { + free(stream); + return 0; + } error = tableFunc(font, tag, stream->base, &length); if (error) { _hb_close_stream(stream); @@ -950,6 +956,8 @@ static HB_Stream getTableStream(void *font, HB_GetFontTableFunc tableFunc, HB_Ta HB_Face HB_NewFace(void *font, HB_GetFontTableFunc tableFunc) { HB_Face face = (HB_Face )malloc(sizeof(HB_FaceRec)); + if (!face) + return 0; face->isSymbolFont = false; face->gdef = 0; diff --git a/src/3rdparty/phonon/phonon/abstractmediastream.cpp b/src/3rdparty/phonon/phonon/abstractmediastream.cpp index a661702..5b860f3 100644 --- a/src/3rdparty/phonon/phonon/abstractmediastream.cpp +++ b/src/3rdparty/phonon/phonon/abstractmediastream.cpp @@ -49,7 +49,6 @@ AbstractMediaStream::AbstractMediaStream(AbstractMediaStreamPrivate &dd, QObject AbstractMediaStream::~AbstractMediaStream() { - delete d_ptr; } qint64 AbstractMediaStream::streamSize() const diff --git a/src/3rdparty/phonon/phonon/abstractmediastream.h b/src/3rdparty/phonon/phonon/abstractmediastream.h index 0daa92a..c4cde85 100644 --- a/src/3rdparty/phonon/phonon/abstractmediastream.h +++ b/src/3rdparty/phonon/phonon/abstractmediastream.h @@ -214,7 +214,7 @@ class PHONON_EXPORT AbstractMediaStream : public QObject virtual void seekStream(qint64 offset); AbstractMediaStream(AbstractMediaStreamPrivate &dd, QObject *parent); - AbstractMediaStreamPrivate *d_ptr; + QScopedPointer<AbstractMediaStreamPrivate> d_ptr; }; } // namespace Phonon diff --git a/src/3rdparty/phonon/phonon/abstractmediastream_p.h b/src/3rdparty/phonon/phonon/abstractmediastream_p.h index a9d6489..0e87c4d 100644 --- a/src/3rdparty/phonon/phonon/abstractmediastream_p.h +++ b/src/3rdparty/phonon/phonon/abstractmediastream_p.h @@ -45,6 +45,7 @@ class PHONON_EXPORT AbstractMediaStreamPrivate : private MediaNodeDestructionHan public: void setStreamInterface(StreamInterface *); void setMediaObjectPrivate(MediaObjectPrivate *); + ~AbstractMediaStreamPrivate(); protected: AbstractMediaStreamPrivate() @@ -56,7 +57,6 @@ class PHONON_EXPORT AbstractMediaStreamPrivate : private MediaNodeDestructionHan errorType(NoError) { } - ~AbstractMediaStreamPrivate(); virtual void setStreamSize(qint64 newSize); virtual void setStreamSeekable(bool s); diff --git a/src/corelib/codecs/qisciicodec.cpp b/src/corelib/codecs/qisciicodec.cpp index dd2bc8d..5619580 100644 --- a/src/corelib/codecs/qisciicodec.cpp +++ b/src/corelib/codecs/qisciicodec.cpp @@ -38,7 +38,6 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ - #include "qisciicodec_p.h" #include "qlist.h" diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp index 6e8ffa1..cfb62c7 100644 --- a/src/corelib/codecs/qtextcodec.cpp +++ b/src/corelib/codecs/qtextcodec.cpp @@ -92,6 +92,11 @@ # define QT_NO_SETLOCALE #endif +#if 0 // ### TODO - remove me! +// enabling this is not exception safe! +#define Q_DEBUG_TEXTCODEC +#endif + QT_BEGIN_NAMESPACE #ifndef QT_NO_TEXTCODECPLUGIN @@ -165,7 +170,9 @@ static QTextCodec *createForMib(int mib) } static QList<QTextCodec*> *all = 0; +#ifdef Q_DEBUG_TEXTCODEC static bool destroying_is_ok = false; +#endif static QTextCodec *localeMapper = 0; QTextCodec *QTextCodec::cftr = 0; @@ -187,15 +194,21 @@ QTextCodecCleanup::~QTextCodecCleanup() if (!all) return; +#ifdef Q_DEBUG_TEXTCODEC destroying_is_ok = true; +#endif - while (all->size()) - delete all->takeFirst(); + for (QList<QTextCodec *>::const_iterator it = all->constBegin() + ; it != all->constEnd(); ++it) { + delete *it; + } delete all; all = 0; localeMapper = 0; +#ifdef Q_DEBUG_TEXTCODEC destroying_is_ok = false; +#endif } Q_GLOBAL_STATIC(QTextCodecCleanup, createQTextCodecCleanup) @@ -659,8 +672,10 @@ static void setup() if (all) return; +#ifdef Q_DEBUG_TEXTCODEC if (destroying_is_ok) qWarning("QTextCodec: Creating new codec during codec cleanup"); +#endif all = new QList<QTextCodec*>; // create the cleanup object to cleanup all codecs on exit (void) createQTextCodecCleanup(); @@ -915,8 +930,10 @@ QTextCodec::QTextCodec() */ QTextCodec::~QTextCodec() { +#ifdef Q_DEBUG_TEXTCODEC if (!destroying_is_ok) qWarning("QTextCodec::~QTextCodec: Called by application"); +#endif if (all) all->removeAll(this); } diff --git a/src/corelib/concurrent/qthreadpool.cpp b/src/corelib/concurrent/qthreadpool.cpp index 30edfd4..8913b56 100644 --- a/src/corelib/concurrent/qthreadpool.cpp +++ b/src/corelib/concurrent/qthreadpool.cpp @@ -246,14 +246,14 @@ bool QThreadPoolPrivate::tooManyThreadsActive() const */ void QThreadPoolPrivate::startThread(QRunnable *runnable) { - QThreadPoolThread *thread = new QThreadPoolThread(this); - allThreads.insert(thread); + QScopedPointer <QThreadPoolThread> thread(new QThreadPoolThread(this)); + allThreads.insert(thread.data()); ++activeThreads; if (runnable->autoDelete()) ++runnable->ref; thread->runnable = runnable; - thread->start(); + thread.take()->start(); } /*! \internal diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index ca243e7..484c618 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1929,6 +1929,15 @@ void qt_check_pointer(const char *n, int l) qWarning("In file %s, line %d: Out of memory", n, l); } +/* \internal + Allows you to throw an exception without including <new> + Called internally from Q_CHECK_PTR on certain OS combinations +*/ +void qBadAlloc() +{ + QT_THROW(std::bad_alloc()); +} + /* The Q_ASSERT macro calls this function when the test fails. */ @@ -2177,7 +2186,11 @@ void qt_message_output(QtMsgType msgType, const char *buf) #if defined(Q_OS_SYMBIAN) __DEBUGGER(); // on the emulator, get the debugger to kick in if there's one around - User::Invariant(); // Panic the current thread + TBuf<256> tmp; + TPtrC8 ptr(reinterpret_cast<const TUint8*>(buf)); + TInt len = Min(tmp.MaxLength(), ptr.Length()); + tmp.Copy(ptr.Left(len)); + User::Panic(tmp, 0); // Panic the current thread #elif (defined(Q_OS_UNIX) || defined(Q_CC_MINGW)) abort(); // trap; generates core dump #else @@ -2186,6 +2199,48 @@ void qt_message_output(QtMsgType msgType, const char *buf) } } +#if !defined(QT_NO_EXCEPTIONS) +/*! + \internal + Uses a local buffer to output the message. Not locale safe + cuts off + everything after character 1023, but will work in out of memory situations. +*/ +static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap) +{ + char emergency_buf[1024] = { '\0' }; + emergency_buf[1023] = '\0'; + if (msg) + qvsnprintf(emergency_buf, 1023, msg, ap); + qt_message_output(msgType, emergency_buf); +} +#endif + +/*! + \internal +*/ +static void qt_message(QtMsgType msgType, const char *msg, va_list ap) +{ +#if !defined(QT_NO_EXCEPTIONS) + if (std::uncaught_exception()) { + qEmergencyOut(msgType, msg, ap); + return; + } +#endif + QByteArray buf; + if (msg) { + QT_TRY { + buf = QString().vsprintf(msg, ap).toLocal8Bit(); + } QT_CATCH(const std::bad_alloc &) { +#if !defined(QT_NO_EXCEPTIONS) + qEmergencyOut(msgType, msg, ap); + // don't rethrow - we use qWarning and friends in destructors. + return; +#endif + } + } + qt_message_output(msgType, buf.constData()); +} + #undef qDebug /*! \relates <QtGlobal> @@ -2223,14 +2278,10 @@ void qt_message_output(QtMsgType msgType, const char *buf) */ void qDebug(const char *msg, ...) { - QString buf; va_list ap; - va_start(ap, msg); // use variable arg list - if (msg) - buf.vsprintf(msg, ap); + va_start(ap, msg); // use variable arg list + qt_message(QtDebugMsg, msg, ap); va_end(ap); - - qt_message_output(QtDebugMsg, buf.toLocal8Bit().constData()); } #undef qWarning @@ -2267,14 +2318,10 @@ void qDebug(const char *msg, ...) */ void qWarning(const char *msg, ...) { - QString buf; va_list ap; va_start(ap, msg); // use variable arg list - if (msg) - buf.vsprintf(msg, ap); + qt_message(QtWarningMsg, msg, ap); va_end(ap); - - qt_message_output(QtWarningMsg, buf.toLocal8Bit().constData()); } /*! @@ -2307,15 +2354,12 @@ void qWarning(const char *msg, ...) */ void qCritical(const char *msg, ...) { - QString buf; va_list ap; va_start(ap, msg); // use variable arg list - if (msg) - buf.vsprintf(msg, ap); + qt_message(QtCriticalMsg, msg, ap); va_end(ap); - - qt_message_output(QtCriticalMsg, buf.toLocal8Bit().constData()); } + #ifdef QT3_SUPPORT void qSystemWarning(const char *msg, int code) { qCritical("%s (%s)", msg, qt_error_string(code).toLocal8Bit().constData()); } @@ -2323,6 +2367,8 @@ void qSystemWarning(const char *msg, int code) void qErrnoWarning(const char *msg, ...) { + // qt_error_string() will allocate anyway, so we don't have + // to be careful here (like we do in plain qWarning()) QString buf; va_list ap; va_start(ap, msg); @@ -2335,6 +2381,8 @@ void qErrnoWarning(const char *msg, ...) void qErrnoWarning(int code, const char *msg, ...) { + // qt_error_string() will allocate anyway, so we don't have + // to be careful here (like we do in plain qWarning()) QString buf; va_list ap; va_start(ap, msg); @@ -2371,14 +2419,10 @@ void qErrnoWarning(int code, const char *msg, ...) */ void qFatal(const char *msg, ...) { - QString buf; va_list ap; va_start(ap, msg); // use variable arg list - if (msg) - buf.vsprintf(msg, ap); + qt_message(QtFatalMsg, msg, ap); va_end(ap); - - qt_message_output(QtFatalMsg, buf.toLocal8Bit().constData()); } // getenv is declared as deprecated in VS2005. This function @@ -3166,4 +3210,59 @@ bool QInternal::callFunction(InternalFunction func, void **args) \sa Q_DECL_EXPORT */ +#if defined(Q_OS_SYMBIAN) + +#include <typeinfo> + +const char* QSymbianLeaveException::what() const throw() +{ + static const char str[] = "Symbian leave exception %d"; + static char msg[sizeof(str)+12]; + sprintf(msg, str, error); + return msg; +} + +void qt_translateSymbianErrorToException(int error) +{ + if (error >= KErrNone) + return; // do nothing - not an exception + switch (error) { + case KErrNoMemory: + throw std::bad_alloc(); + default: + throw QSymbianLeaveException(error); + } +} + +void qt_translateExceptionToSymbianErrorL(const std::exception& aThrow) +{ + User::Leave(qt_translateExceptionToSymbianError(aThrow)); +} + +int qt_translateExceptionToSymbianError(const std::exception& aThrow) +{ + const std::type_info& atype = typeid(aThrow); + int err = KErrGeneral; + + if(atype == typeid (std::bad_alloc)) + err = KErrNoMemory; + else if(atype == typeid(QSymbianLeaveException)) + err = static_cast<const QSymbianLeaveException&>(aThrow).error; + else if(atype == typeid(std::invalid_argument)) + err = KErrArgument; + else if(atype == typeid(std::out_of_range)) + // std::out_of_range is of type logic_error which by definition means that it is + // "presumably detectable before the program executes". + // std::out_of_range is used to report an argument is not within the expected range. + // The description of KErrArgument says an argument is out of range. Hence the mapping. + err = KErrArgument; + else if(atype == typeid(std::overflow_error)) + err = KErrOverflow; + else if(atype == typeid(std::underflow_error)) + err = KErrUnderflow; + + return err; +} +#endif + QT_END_NAMESPACE diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h index b075db6..030840e 100644 --- a/src/corelib/global/qglobal.h +++ b/src/corelib/global/qglobal.h @@ -1301,6 +1301,32 @@ class QDataStream; # define Q_AUTOTEST_EXPORT #endif +inline void qt_noop() {} + +/* These wrap try/catch so we can switch off exceptions later. + + Beware - do not use more than one QT_CATCH per QT_TRY, and do not use + the exception instance in the catch block. + If you can't live with those constraints, don't use these macros. + Use the QT_NO_EXCEPTIONS macro to protect your code instead. +*/ + +#ifdef QT_BOOTSTRAPPED +# define QT_NO_EXCEPTIONS +#endif + +#ifdef QT_NO_EXCEPTIONS +# define QT_TRY if (true) +# define QT_CATCH(A) else +# define QT_THROW(A) qt_noop() +# define QT_RETHROW qt_noop() +#else +# define QT_TRY try +# define QT_CATCH(A) catch (A) +# define QT_THROW(A) throw A +# define QT_RETHROW throw +#endif + /* System information */ @@ -1554,8 +1580,6 @@ inline QNoDebug qDebug(); #endif -inline void qt_noop() {} - Q_CORE_EXPORT void qt_assert(const char *assertion, const char *file, int line); #if !defined(Q_ASSERT) @@ -1581,11 +1605,16 @@ 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); +Q_CORE_EXPORT void qBadAlloc(); -#ifndef QT_NO_DEBUG -# define Q_CHECK_PTR(p) do {if(!(p))qt_check_pointer(__FILE__,__LINE__);} while (0) +#ifdef QT_NO_EXCEPTIONS +# if defined(QT_NO_DEBUG) +# define Q_CHECK_PTR(p) qt_noop(); +# else +# define Q_CHECK_PTR(p) do {if(!(p))qt_check_pointer(__FILE__,__LINE__);} while (0) +# endif #else -# define Q_CHECK_PTR(p) +# define Q_CHECK_PTR(p) do { if (!(p)) qBadAlloc(); } while (0) #endif #if (defined(Q_CC_GNU) && !defined(Q_OS_SOLARIS)) || defined(Q_CC_HPACC) @@ -1734,12 +1763,12 @@ public: static TYPE *NAME() \ { \ if (!this_##NAME.pointer && !this_##NAME.destroyed) { \ - TYPE *x = new TYPE; \ + QScopedPointer<TYPE > x(new TYPE); \ INITIALIZER; \ - if (!this_##NAME.pointer.testAndSetOrdered(0, x)) \ - delete x; \ - else \ + if (this_##NAME.pointer.testAndSetOrdered(0, x.data())) { \ static QGlobalStaticDeleter<TYPE > cleanup(this_##NAME); \ + x.take(); \ + } \ } \ return this_##NAME.pointer; \ } @@ -2193,8 +2222,8 @@ inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase #endif #define Q_DECLARE_PRIVATE(Class) \ - inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr); } \ - inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr); } \ + inline Class##Private* d_func() { return reinterpret_cast<Class##Private *>(d_ptr.data()); } \ + inline const Class##Private* d_func() const { return reinterpret_cast<const Class##Private *>(d_ptr.data()); } \ friend class Class##Private; #define Q_DECLARE_PRIVATE_D(Dptr, Class) \ @@ -2242,7 +2271,9 @@ inline const QForeachContainer<T> *qForeachContainer(const QForeachContainerBase Class(const Class &); \ Class &operator=(const Class &); #else -# define Q_DISABLE_COPY(Class) +# define Q_DISABLE_COPY(Class) \ + Class(const Class &); \ + Class &operator=(const Class &); #endif class QByteArray; @@ -2434,6 +2465,48 @@ QT_LICENSED_MODULE(DBus) # define QT_NO_CONCURRENT_FILTER #endif +#if defined(Q_OS_SYMBIAN) + +#include <stdexcept> +class QSymbianLeaveException : public std::exception +{ +public: + QSymbianLeaveException(int err) : error(err){ } + const char* what() const throw(); +public: + int error; +}; + +Q_CORE_EXPORT void qt_translateSymbianErrorToException(int error); +Q_CORE_EXPORT void qt_translateExceptionToSymbianErrorL(const std::exception& ex); +Q_CORE_EXPORT int qt_translateExceptionToSymbianError(const std::exception& ex); + +#define QT_TRANSLATE_SYMBIAN_LEAVE_TO_EXCEPTION(f) \ + { \ + TInt error; \ + TRAP(error, f); \ + if (error) \ + qt_translateSymbianErrorToException(error); \ + } + +#define QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(err, f) \ + { \ + err = KErrNone; \ + try { \ + f; \ + } catch (const std::exception &ex) { \ + err = qt_translateExceptionToSymbianError(ex); \ + } \ + } + +#define QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(f) \ + { \ + TInt err; \ + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(err, f) \ + User::LeaveIfError(err); \ + } +#endif + QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 29e356e..5e4b9bd 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -40,11 +40,11 @@ ****************************************************************************/ #include "qdir.h" -#include "qfile.h" +#include "qfile.h" #include "qconfig.h" #include "qsettings.h" #include "qlibraryinfo.h" -#include "qpointer.h" +#include "qscopedpointer.h" #ifdef QT_BUILD_QMAKE QT_BEGIN_NAMESPACE @@ -67,8 +67,7 @@ QT_BEGIN_NAMESPACE struct QLibrarySettings { QLibrarySettings(); - ~QLibrarySettings() { delete static_cast<QSettings *>(settings); } - QSettings *settings; + QScopedPointer<QSettings> settings; }; Q_GLOBAL_STATIC(QLibrarySettings, qt_library_settings) @@ -79,32 +78,19 @@ public: static void cleanup() { QLibrarySettings *ls = qt_library_settings(); - if (ls) { - delete static_cast<QSettings *>(ls->settings); - ls->settings = 0; - } + if (ls) + ls->settings.reset(0); } static QSettings *configuration() { -#ifdef QT_NO_THREAD - // This recursion guard should be a temporary solution; the recursive - // dependency should be found and removed. - static bool initializing = false; - if (initializing) - return 0; - initializing = true; -#endif QLibrarySettings *ls = qt_library_settings(); -#ifdef QT_NO_THREAD - initializing = false; -#endif - return ls ? static_cast<QSettings *>(qt_library_settings()->settings) : (QSettings*)0; + return ls ? ls->settings.data() : 0; } }; QLibrarySettings::QLibrarySettings() + : settings(QLibraryInfoPrivate::findConfiguration()) { - settings = QLibraryInfoPrivate::findConfiguration(); #ifndef QT_BUILD_QMAKE qAddPostRoutine(QLibraryInfoPrivate::cleanup); #endif diff --git a/src/corelib/io/qabstractfileengine.cpp b/src/corelib/io/qabstractfileengine.cpp index bedc121..63d4944 100644 --- a/src/corelib/io/qabstractfileengine.cpp +++ b/src/corelib/io/qabstractfileengine.cpp @@ -352,8 +352,6 @@ QAbstractFileEngine::QAbstractFileEngine(QAbstractFileEnginePrivate &dd) : d_ptr */ QAbstractFileEngine::~QAbstractFileEngine() { - delete d_ptr; - d_ptr = 0; } /*! @@ -881,7 +879,6 @@ QAbstractFileEngineIterator::QAbstractFileEngineIterator(QDir::Filters filters, */ QAbstractFileEngineIterator::~QAbstractFileEngineIterator() { - delete d; } /*! diff --git a/src/corelib/io/qabstractfileengine.h b/src/corelib/io/qabstractfileengine.h index d742467..5b75343 100644 --- a/src/corelib/io/qabstractfileengine.h +++ b/src/corelib/io/qabstractfileengine.h @@ -193,7 +193,7 @@ protected: QAbstractFileEngine(); QAbstractFileEngine(QAbstractFileEnginePrivate &); - QAbstractFileEnginePrivate *d_ptr; + QScopedPointer<QAbstractFileEnginePrivate> d_ptr; private: Q_DECLARE_PRIVATE(QAbstractFileEngine) Q_DISABLE_COPY(QAbstractFileEngine) @@ -237,7 +237,7 @@ private: friend class QDirIterator; friend class QDirIteratorPrivate; void setPath(const QString &path); - QAbstractFileEngineIteratorPrivate *d; + QScopedPointer<QAbstractFileEngineIteratorPrivate> d; }; QT_END_NAMESPACE diff --git a/src/corelib/io/qdebug.h b/src/corelib/io/qdebug.h index 8334146..60dc688 100644 --- a/src/corelib/io/qdebug.h +++ b/src/corelib/io/qdebug.h @@ -79,8 +79,11 @@ public: inline QDebug &operator=(const QDebug &other); inline ~QDebug() { if (!--stream->ref) { - if(stream->message_output) - qt_message_output(stream->type, stream->buffer.toLocal8Bit().data()); + if(stream->message_output) { + QT_TRY { + qt_message_output(stream->type, stream->buffer.toLocal8Bit().data()); + } QT_CATCH(std::bad_alloc) { /* We're out of memory - give up. */ } + } delete stream; } } diff --git a/src/corelib/io/qdir.cpp b/src/corelib/io/qdir.cpp index 901641c..e1cc7ac 100644 --- a/src/corelib/io/qdir.cpp +++ b/src/corelib/io/qdir.cpp @@ -83,6 +83,7 @@ class QDirPrivate QDir *q_ptr; Q_DECLARE_PUBLIC(QDir) + friend class QScopedPointer<QDirPrivate>; protected: QDirPrivate(QDir*, const QDir *copy=0); ~QDirPrivate(); @@ -573,8 +574,6 @@ QDir::QDir(const QDir &dir) : d_ptr(new QDirPrivate(this, &dir)) QDir::~QDir() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/corelib/io/qdir.h b/src/corelib/io/qdir.h index c4f6b1a..ac80094 100644 --- a/src/corelib/io/qdir.h +++ b/src/corelib/io/qdir.h @@ -45,6 +45,7 @@ #include <QtCore/qstring.h> #include <QtCore/qfileinfo.h> #include <QtCore/qstringlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -57,7 +58,7 @@ class QDirPrivate; class Q_CORE_EXPORT QDir { protected: - QDirPrivate *d_ptr; + QScopedPointer<QDirPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QDir) public: diff --git a/src/corelib/io/qfile.cpp b/src/corelib/io/qfile.cpp index 551485d..1e3d5a3 100644 --- a/src/corelib/io/qfile.cpp +++ b/src/corelib/io/qfile.cpp @@ -109,6 +109,7 @@ QFilePrivate::openExternalFile(int flags, int fd) return false; #else delete fileEngine; + fileEngine = 0; QFSFileEngine *fe = new QFSFileEngine; fe->setFileName(fileName); fileEngine = fe; @@ -125,6 +126,7 @@ QFilePrivate::openExternalFile(int flags, FILE *fh) return false; #else delete fileEngine; + fileEngine = 0; QFSFileEngine *fe = new QFSFileEngine; fe->setFileName(fileName); fileEngine = fe; @@ -410,9 +412,6 @@ QFile::QFile(QFilePrivate &dd, QObject *parent) QFile::~QFile() { close(); -#ifdef QT_NO_QOBJECT - delete d_ptr; -#endif } /*! diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 96e0f82..b36fb69 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -439,8 +439,6 @@ QFileInfo::QFileInfo(const QFileInfo &fileinfo) : d_ptr(new QFileInfoPrivate(&fi QFileInfo::~QFileInfo() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 97997a3..6c01f63 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -44,6 +44,7 @@ #include <QtCore/qfile.h> #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -165,7 +166,7 @@ public: #endif protected: - QFileInfoPrivate *d_ptr; + QScopedPointer<QFileInfoPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QFileInfo) }; diff --git a/src/corelib/io/qfilesystemwatcher_symbian.cpp b/src/corelib/io/qfilesystemwatcher_symbian.cpp index b1a6188..aeb19db 100644 --- a/src/corelib/io/qfilesystemwatcher_symbian.cpp +++ b/src/corelib/io/qfilesystemwatcher_symbian.cpp @@ -80,7 +80,7 @@ void CNotifyChangeEvent::RunL() if (iStatus.Int() == KErrNone){ fsSession.NotifyChange(ENotifyAll, iStatus, watchedPath); SetActive(); - engine->emitPathChanged(this); + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(engine->emitPathChanged(this)); } else { qWarning("CNotifyChangeEvent::RunL() - Failed to order change notifications: %d", iStatus.Int()); } @@ -262,9 +262,9 @@ void QSymbianFileSystemWatcherEngine::run() void QSymbianFileSystemWatcherEngine::addNativeListener(const QString &directoryPath) { QMutexLocker locker(&mutex); - HBufC* buffer = qt_QString2HBufCNewL(QDir::toNativeSeparators(directoryPath)); - currentEvent = CNotifyChangeEvent::New(fsSession, *buffer, this); - delete buffer; + QString nativeDir(QDir::toNativeSeparators(directoryPath)); + TPtrC ptr(qt_QString2TPtrC(nativeDir)); + currentEvent = CNotifyChangeEvent::New(fsSession, ptr, this); syncCondition.wakeOne(); } diff --git a/src/corelib/io/qfsfileengine_unix.cpp b/src/corelib/io/qfsfileengine_unix.cpp index e595f15..45e547f 100644 --- a/src/corelib/io/qfsfileengine_unix.cpp +++ b/src/corelib/io/qfsfileengine_unix.cpp @@ -404,23 +404,21 @@ bool QFSFileEngine::copy(const QString &newName) TInt err = rfs.Connect(); if (err == KErrNone) { CFileMan* fm = NULL; - HBufC* oldBuf = NULL; - HBufC* newBuf = NULL; + QString oldNative(QDir::toNativeSeparators(d->filePath)); + TPtrC oldPtr(qt_QString2TPtrC(oldNative)); + QFileInfo fi(newName); + QString absoluteNewName = fi.absolutePath() + QDir::separator() + fi.fileName(); + QString newNative(QDir::toNativeSeparators(absoluteNewName)); + TPtrC newPtr(qt_QString2TPtrC(newNative)); TRAP (err, fm = CFileMan::NewL(rfs); - oldBuf = qt_QString2HBufCNewL(QDir::toNativeSeparators(d->filePath)); RFile rfile; - err = rfile.Open(rfs, *oldBuf, EFileShareReadersOrWriters); + err = rfile.Open(rfs, oldPtr, EFileShareReadersOrWriters); if (err == KErrNone) { - QFileInfo fi(newName); - QString absoluteNewName = fi.absolutePath() + QDir::separator() + fi.fileName(); - newBuf = qt_QString2HBufCNewL(QDir::toNativeSeparators(absoluteNewName)); - err = fm->Copy(rfile, *newBuf); + err = fm->Copy(rfile, newPtr); rfile.Close(); } ) // End TRAP - delete oldBuf; - delete newBuf; delete fm; rfs.Close(); } @@ -675,10 +673,10 @@ static bool _q_isSymbianHidden(const QString &path, bool isDir) if (isDir && absPath.at(absPath.size()-1) != QChar('/')) { absPath += QChar('/'); } - HBufC* buffer = qt_QString2HBufCNewL(QDir::toNativeSeparators(absPath)); + QString native(QDir::toNativeSeparators(absPath)); + TPtrC ptr(qt_QString2TPtrC(native)); TUint attributes; - err = rfs.Att(*buffer, attributes); - delete buffer; + err = rfs.Att(ptr, attributes); rfs.Close(); if (err == KErrNone && (attributes & KEntryAttHidden)) { retval = true; diff --git a/src/corelib/io/qiodevice.h b/src/corelib/io/qiodevice.h index 76d47ca..ad87125 100644 --- a/src/corelib/io/qiodevice.h +++ b/src/corelib/io/qiodevice.h @@ -46,6 +46,7 @@ #include <QtCore/qobject.h> #else #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> #endif #include <QtCore/qstring.h> @@ -160,7 +161,7 @@ protected: void setErrorString(const QString &errorString); #ifdef QT_NO_QOBJECT - QIODevicePrivate *d_ptr; + QScopedPointer<QIODevicePrivate> d_ptr; #endif private: diff --git a/src/corelib/io/qprocess_symbian.cpp b/src/corelib/io/qprocess_symbian.cpp index a59976c..26e7cdc 100644 --- a/src/corelib/io/qprocess_symbian.cpp +++ b/src/corelib/io/qprocess_symbian.cpp @@ -56,6 +56,7 @@ User::Panic(KQProcessPanic, panicReason); \ } +#include <exception> #include <e32base.h> #include <e32std.h> #include <stdio.h> diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index 1f77caa..0cbcc41 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -334,7 +334,6 @@ QResource::QResource(const QString &file, const QLocale &locale) : d_ptr(new QRe */ QResource::~QResource() { - delete d_ptr; } /*! diff --git a/src/corelib/io/qresource.h b/src/corelib/io/qresource.h index 1e9b2d5..f260b68 100644 --- a/src/corelib/io/qresource.h +++ b/src/corelib/io/qresource.h @@ -91,7 +91,7 @@ protected: QStringList children() const; protected: - QResourcePrivate *d_ptr; + QScopedPointer<QResourcePrivate> d_ptr; private: Q_DECLARE_PRIVATE(QResource) diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp index 6152518..afaaf28 100644 --- a/src/corelib/io/qsettings.cpp +++ b/src/corelib/io/qsettings.cpp @@ -1106,10 +1106,10 @@ static QString getPath(QSettings::Format format, QSettings::Scope scope) QString homePath = QDir::homePath(); QString systemPath; - globalMutex()->lock(); + QMutexLocker locker(globalMutex()); PathHash *pathHash = pathHashFunc(); bool loadSystemPath = pathHash->isEmpty(); - globalMutex()->unlock(); + locker.unlock(); if (loadSystemPath) { /* @@ -1121,7 +1121,7 @@ static QString getPath(QSettings::Format format, QSettings::Scope scope) systemPath += QLatin1Char('/'); } - QMutexLocker locker(globalMutex()); + locker.relock(); if (pathHash->isEmpty()) { /* Lazy initialization of pathHash. We initialize the @@ -1181,9 +1181,6 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, int i; initFormat(); - for (i = 0; i < NumConfFiles; ++i) - confFiles[i] = 0; - QString org = organization; if (org.isEmpty()) { setStatus(QSettings::AccessError); @@ -1196,14 +1193,14 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(QSettings::Format format, if (scope == QSettings::UserScope) { QString userPath = getPath(format, QSettings::UserScope); if (!application.isEmpty()) - confFiles[F_User | F_Application] = QConfFile::fromName(userPath + appFile, true); - confFiles[F_User | F_Organization] = QConfFile::fromName(userPath + orgFile, true); + confFiles[F_User | F_Application].reset(QConfFile::fromName(userPath + appFile, true)); + confFiles[F_User | F_Organization].reset(QConfFile::fromName(userPath + orgFile, true)); } QString systemPath = getPath(format, QSettings::SystemScope); if (!application.isEmpty()) - confFiles[F_System | F_Application] = QConfFile::fromName(systemPath + appFile, false); - confFiles[F_System | F_Organization] = QConfFile::fromName(systemPath + orgFile, false); + confFiles[F_System | F_Application].reset(QConfFile::fromName(systemPath + appFile, false)); + confFiles[F_System | F_Organization].reset(QConfFile::fromName(systemPath + orgFile, false)); for (i = 0; i < NumConfFiles; ++i) { if (confFiles[i]) { @@ -1222,9 +1219,7 @@ QConfFileSettingsPrivate::QConfFileSettingsPrivate(const QString &fileName, { initFormat(); - confFiles[0] = QConfFile::fromName(fileName, true); - for (int i = 1; i < NumConfFiles; ++i) - confFiles[i] = 0; + confFiles[0].reset(QConfFile::fromName(fileName, true)); initAccess(); } @@ -1241,19 +1236,27 @@ QConfFileSettingsPrivate::~QConfFileSettingsPrivate() usedHash->remove(confFiles[i]->name); if (confFiles[i]->size == 0) { - delete confFiles[i]; + delete confFiles[i].take(); } else if (unusedCache) { - // compute a better size? - unusedCache->insert(confFiles[i]->name, confFiles[i], + QT_TRY { + // compute a better size? + unusedCache->insert(confFiles[i]->name, confFiles[i].data(), 10 + (confFiles[i]->originalKeys.size() / 4)); + confFiles[i].take(); + } QT_CATCH(...) { + // out of memory. Do not cache the file. + delete confFiles[i].take(); + } } } + // prevent the ScopedPointer to deref it again. + confFiles[i].take(); } } void QConfFileSettingsPrivate::remove(const QString &key) { - QConfFile *confFile = confFiles[spec]; + QConfFile *confFile = confFiles[spec].data(); if (!confFile) return; @@ -1280,7 +1283,7 @@ void QConfFileSettingsPrivate::remove(const QString &key) void QConfFileSettingsPrivate::set(const QString &key, const QVariant &value) { - QConfFile *confFile = confFiles[spec]; + QConfFile *confFile = confFiles[spec].data(); if (!confFile) return; @@ -1297,7 +1300,7 @@ bool QConfFileSettingsPrivate::get(const QString &key, QVariant *value) const bool found = false; for (int i = 0; i < NumConfFiles; ++i) { - if (QConfFile *confFile = confFiles[i]) { + if (QConfFile *confFile = confFiles[i].data()) { QMutexLocker locker(&confFile->mutex); if (!confFile->addedKeys.isEmpty()) { @@ -1332,7 +1335,7 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec int startPos = prefix.size(); for (int i = 0; i < NumConfFiles; ++i) { - if (QConfFile *confFile = confFiles[i]) { + if (QConfFile *confFile = confFiles[i].data()) { QMutexLocker locker(&confFile->mutex); if (thePrefix.isEmpty()) { @@ -1365,7 +1368,7 @@ QStringList QConfFileSettingsPrivate::children(const QString &prefix, ChildSpec void QConfFileSettingsPrivate::clear() { - QConfFile *confFile = confFiles[spec]; + QConfFile *confFile = confFiles[spec].data(); if (!confFile) return; @@ -1381,7 +1384,7 @@ void QConfFileSettingsPrivate::sync() // error we just try to go on and make the best of it for (int i = 0; i < NumConfFiles; ++i) { - QConfFile *confFile = confFiles[i]; + QConfFile *confFile = confFiles[i].data(); if (confFile) { QMutexLocker locker(&confFile->mutex); syncConfFile(i); @@ -1396,7 +1399,7 @@ void QConfFileSettingsPrivate::flush() QString QConfFileSettingsPrivate::fileName() const { - QConfFile *confFile = confFiles[spec]; + QConfFile *confFile = confFiles[spec].data(); if (!confFile) return QString(); return confFile->name; @@ -1407,7 +1410,7 @@ bool QConfFileSettingsPrivate::isWritable() const if (format > QSettings::IniFormat && !writeFunc) return false; - QConfFile *confFile = confFiles[spec]; + QConfFile *confFile = confFiles[spec].data(); if (!confFile) return false; @@ -1416,7 +1419,7 @@ bool QConfFileSettingsPrivate::isWritable() const void QConfFileSettingsPrivate::syncConfFile(int confFileNo) { - QConfFile *confFile = confFiles[confFileNo]; + QConfFile *confFile = confFiles[confFileNo].data(); bool readOnly = confFile->addedKeys.isEmpty() && confFile->removedKeys.isEmpty(); bool ok; @@ -2759,11 +2762,13 @@ QSettings::QSettings(const QString &fileName, Format format) QSettings::~QSettings() { Q_D(QSettings); - if (d->pendingChanges) - d->flush(); -#ifdef QT_NO_QOBJECT - delete d; -#endif + if (d->pendingChanges) { + QT_TRY { + d->flush(); + } QT_CATCH(...) { + ; // ok. then don't flush but at least don't throw in the destructor + } + } } /*! @@ -3566,8 +3571,7 @@ void QSettings::setPath_helper(Scope scope, const QString &organization, const Q QSettingsPrivate *oldPriv = d; QSettingsPrivate *newPriv = QSettingsPrivate::create(oldPriv->format, scope, organization, application); static_cast<QObjectPrivate &>(*newPriv) = static_cast<QObjectPrivate &>(*oldPriv); // copy the QObject stuff over (hack) - delete oldPriv; - d_ptr = newPriv; + d_ptr.reset(newPriv); } /*! \fn bool QSettings::writeEntry(const QString &key, bool value) diff --git a/src/corelib/io/qsettings.h b/src/corelib/io/qsettings.h index cbb24ba..41bce89 100644 --- a/src/corelib/io/qsettings.h +++ b/src/corelib/io/qsettings.h @@ -78,7 +78,7 @@ class Q_CORE_EXPORT QSettings #ifndef QT_NO_QOBJECT Q_OBJECT #else - QSettingsPrivate *d_ptr; + QScopedPointer<QSettingsPrivate> d_ptr; #endif Q_DECLARE_PRIVATE(QSettings) diff --git a/src/corelib/io/qsettings_p.h b/src/corelib/io/qsettings_p.h index dd72fd9..1bdbf2c 100644 --- a/src/corelib/io/qsettings_p.h +++ b/src/corelib/io/qsettings_p.h @@ -300,7 +300,7 @@ private: void ensureAllSectionsParsed(QConfFile *confFile) const; void ensureSectionParsed(QConfFile *confFile, const QSettingsKey &key) const; - QConfFile *confFiles[NumConfFiles]; + QScopedSharedPointer<QConfFile> confFiles[NumConfFiles]; QSettings::ReadFunc readFunc; QSettings::WriteFunc writeFunc; QString extension; diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp index 1167671..9382fae 100644 --- a/src/corelib/io/qtextstream.cpp +++ b/src/corelib/io/qtextstream.cpp @@ -1112,9 +1112,6 @@ QTextStream::~QTextStream() #endif if (!d->writeBuffer.isEmpty()) d->flushWriteBuffer(); - - delete d; - d_ptr = 0; } /*! diff --git a/src/corelib/io/qtextstream.h b/src/corelib/io/qtextstream.h index 6302d34..cfacec6 100644 --- a/src/corelib/io/qtextstream.h +++ b/src/corelib/io/qtextstream.h @@ -46,6 +46,7 @@ #include <QtCore/qstring.h> #include <QtCore/qchar.h> #include <QtCore/qlocale.h> +#include <QtCore/qscopedpointer.h> #ifndef QT_NO_TEXTCODEC # ifdef QT3_SUPPORT @@ -256,7 +257,7 @@ private: Q_DISABLE_COPY(QTextStream) - QTextStreamPrivate *d_ptr; + QScopedPointer<QTextStreamPrivate> d_ptr; }; Q_DECLARE_OPERATORS_FOR_FLAGS(QTextStream::NumberFlags) diff --git a/src/corelib/kernel/qcore_symbian_p.cpp b/src/corelib/kernel/qcore_symbian_p.cpp index 4f18490..101ed44 100644 --- a/src/corelib/kernel/qcore_symbian_p.cpp +++ b/src/corelib/kernel/qcore_symbian_p.cpp @@ -39,9 +39,11 @@ ** ****************************************************************************/ +#include <exception> #include <e32base.h> #include <e32uid.h> #include "qcore_symbian_p.h" +#include <string> QT_BEGIN_NAMESPACE @@ -51,18 +53,17 @@ QT_BEGIN_NAMESPACE must be deleted by the caller. */ -Q_CORE_EXPORT HBufC* qt_QString2HBufCNewL(const QString& aString) +Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString) { HBufC *buffer; #ifdef QT_NO_UNICODE TPtrC8 ptr(reinterpret_cast<const TUint8*>(aString.toLocal8Bit().constData())); - buffer = HBufC8::NewL(ptr.Length()); - buffer->Des().Copy(ptr); #else - TPtrC16 ptr(reinterpret_cast<const TUint16*>(aString.utf16())); - buffer = HBufC16::NewL(ptr.Length()); - buffer->Des().Copy(ptr); + TPtrC16 ptr(qt_QString2TPtrC(aString)); #endif + buffer = HBufC::New(ptr.Length()); + Q_CHECK_PTR(buffer); + buffer->Des().Copy(ptr); return buffer; } @@ -82,7 +83,8 @@ QHBufC::QHBufC() QHBufC::QHBufC(const QHBufC &src) { - m_hBufC = src.m_hBufC->AllocL(); + m_hBufC = src.m_hBufC->Alloc(); + Q_CHECK_PTR(m_hBufC); } /*! @@ -97,7 +99,7 @@ QHBufC::QHBufC(HBufC *src) QHBufC::QHBufC(const QString &src) { - m_hBufC = qt_QString2HBufCNewL(src); + m_hBufC = qt_QString2HBufC(src); } QHBufC::~QHBufC() @@ -172,4 +174,5 @@ Q_CORE_EXPORT TLibraryFunction qt_resolveS60PluginFunc(int ordinal) return qt_s60_plugin_resolver()->resolve(ordinal); } + QT_END_NAMESPACE diff --git a/src/corelib/kernel/qcore_symbian_p.h b/src/corelib/kernel/qcore_symbian_p.h index 3b974c3..bd8f304 100644 --- a/src/corelib/kernel/qcore_symbian_p.h +++ b/src/corelib/kernel/qcore_symbian_p.h @@ -63,7 +63,7 @@ QT_BEGIN_HEADER QT_BEGIN_NAMESPACE -Q_CORE_EXPORT HBufC* qt_QString2HBufCNewL(const QString& aString); +Q_CORE_EXPORT HBufC* qt_QString2HBufC(const QString& aString); Q_CORE_EXPORT QString qt_TDesC2QStringL(const TDesC& aDescriptor); inline QString qt_TDes2QStringL(const TDes& aDescriptor) { return qt_TDesC2QStringL(aDescriptor); } @@ -91,7 +91,7 @@ static inline TRect qt_QRect2TRect(const QRect& qr) // Returned TPtrC is valid as long as the given parameter is valid and unmodified static inline TPtrC qt_QString2TPtrC( const QString& string ) { - return reinterpret_cast<const TUint16*>(string.utf16()); + return TPtrC16(static_cast<const TUint16*>(string.utf16()), string.length()); } class Q_CORE_EXPORT QHBufC diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index d99164b..5c3fd76 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -63,8 +63,10 @@ #include <private/qfactoryloader_p.h> #ifdef Q_OS_SYMBIAN +# include <exception> # include <f32file.h> # include "qeventdispatcher_symbian_p.h" +# include "private/qcore_symbian_p.h" #elif defined(Q_OS_UNIX) # if !defined(QT_NO_GLIB) # include "qeventdispatcher_glib_p.h" @@ -88,6 +90,21 @@ QT_BEGIN_NAMESPACE +class QLockedMutexUnlocker +{ +public: + inline explicit QLockedMutexUnlocker(QMutex *m) + : mtx(m) + { } + inline ~QLockedMutexUnlocker() { unlock(); } + inline void unlock() { if (mtx) mtx->unlock(); mtx = 0; } + +private: + Q_DISABLE_COPY(QLockedMutexUnlocker) + + QMutex *mtx; +}; + #if defined(Q_WS_WIN) || defined(Q_WS_MAC) extern QString qAppFileName(); #endif @@ -159,7 +176,14 @@ void qRemovePostRoutine(QtCleanUpFunction p) void Q_CORE_EXPORT qt_call_post_routines() { - QVFuncList *list = postRList(); + QVFuncList *list = 0; + QT_TRY { + list = postRList(); + } QT_CATCH(const std::bad_alloc &) { + // ignore - if we can't allocate a post routine list, + // there's a high probability that there's no post + // routine to be executed :) + } if (!list) return; while (!list->isEmpty()) @@ -248,24 +272,26 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv) QCoreApplicationPrivate::~QCoreApplicationPrivate() { + if (threadData) { #ifndef QT_NO_THREAD - void *data = &threadData->tls; - QThreadStorageData::finish((void **)data); + void *data = &threadData->tls; + QThreadStorageData::finish((void **)data); #endif - // need to clear the state of the mainData, just in case a new QCoreApplication comes along. - QMutexLocker locker(&threadData->postEventList.mutex); - for (int i = 0; i < threadData->postEventList.size(); ++i) { - const QPostEvent &pe = threadData->postEventList.at(i); - if (pe.event) { - --pe.receiver->d_func()->postedEvents; - pe.event->posted = false; - delete pe.event; + // need to clear the state of the mainData, just in case a new QCoreApplication comes along. + QMutexLocker locker(&threadData->postEventList.mutex); + for (int i = 0; i < threadData->postEventList.size(); ++i) { + const QPostEvent &pe = threadData->postEventList.at(i); + if (pe.event) { + --pe.receiver->d_func()->postedEvents; + pe.event->posted = false; + delete pe.event; + } } + threadData->postEventList.clear(); + threadData->postEventList.recursion = 0; + threadData->quitNow = false; } - threadData->postEventList.clear(); - threadData->postEventList.recursion = 0; - threadData->quitNow = false; } void QCoreApplicationPrivate::createEventDispatcher() @@ -544,7 +570,14 @@ QCoreApplication::~QCoreApplication() #if !defined(QT_NO_THREAD) #if !defined(QT_NO_CONCURRENT) // Synchronize and stop the global thread pool threads. - QThreadPool::globalInstance()->waitForDone(); + QThreadPool *globalThreadPool = 0; + QT_TRY { + globalThreadPool = QThreadPool::globalInstance(); + } QT_CATCH (...) { + // swallow the exception, since destructors shouldn't throw + } + if (globalThreadPool) + globalThreadPool->waitForDone(); #endif QThread::cleanup(); #endif @@ -626,26 +659,13 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event) d->inEventHandler = true; #endif -#if defined(Q_OS_SYMBIAN) -// __UHEAP_MARK; - TInt error; - bool returnValue = false; - TRAP(error, returnValue = notify(receiver, event)); - if (error != KErrNone) { - qWarning(QString("Symbian OS error: %1").arg(error).toAscii().constData()); - } -// __UHEAP_MARKEND; -#elif defined(QT_NO_EXCEPTIONS) - bool returnValue = notify(receiver, event); -#else bool returnValue; - try { + QT_TRY { returnValue = notify(receiver, event); - } catch(...) { + } QT_CATCH (...) { --threadData->loopLevel; - throw; + QT_RETHROW; } -#endif #ifdef QT_JAMBI_BUILD // Restore the previous state if the object was not deleted.. @@ -1066,15 +1086,14 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) data->postEventList.mutex.lock(); } + QLockedMutexUnlocker locker(&data->postEventList.mutex); + // if this is one of the compressible events, do compression if (receiver->d_func()->postedEvents && self && self->compressEvent(event, receiver, &data->postEventList)) { - data->postEventList.mutex.unlock(); return; } - event->posted = true; - ++receiver->d_func()->postedEvents; if (event->type() == QEvent::DeferredDelete && data == QThreadData::current()) { // remember the current running eventloop for DeferredDelete // events posted in the receiver's thread @@ -1095,8 +1114,10 @@ void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority) QPostEventList::iterator at = qUpperBound(begin, end, priority); data->postEventList.insert(at, QPostEvent(receiver, event, priority)); } + event->posted = true; + ++receiver->d_func()->postedEvents; data->canWait = false; - data->postEventList.mutex.unlock(); + locker.unlock(); if (data->eventDispatcher) data->eventDispatcher->wakeUp(); diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h index 65733ac..095d501 100644 --- a/src/corelib/kernel/qcoreapplication.h +++ b/src/corelib/kernel/qcoreapplication.h @@ -195,6 +195,8 @@ private: void init(); static QCoreApplication *self; + + Q_DISABLE_COPY(QCoreApplication) friend class QEventDispatcherUNIXPrivate; friend class QApplication; diff --git a/src/corelib/kernel/qeventdispatcher_symbian.cpp b/src/corelib/kernel/qeventdispatcher_symbian.cpp index c5d91c2..423fbaa 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian.cpp +++ b/src/corelib/kernel/qeventdispatcher_symbian.cpp @@ -193,7 +193,7 @@ void QWakeUpActiveObject::RunL() { iStatus = KRequestPending; SetActive(); - m_dispatcher->wakeUpWasCalled(); + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->wakeUpWasCalled()); } QTimerActiveObject::QTimerActiveObject(QEventDispatcherSymbian *dispatcher, SymbianTimerInfo *timerInfo) @@ -222,9 +222,15 @@ void QTimerActiveObject::DoCancel() void QTimerActiveObject::RunL() { - if (!okToRun()) - return; + int error; + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_ERROR(error, Run()); + if (error < 0) { + CActiveScheduler::Current()->Error(error); // stop and report here, as this timer will be deleted on scope exit + } +} +void QTimerActiveObject::Run() +{ if (m_timerInfo->interval > 0) { // Start a new timer immediately so that we don't lose time. iStatus = KRequestPending; @@ -240,7 +246,7 @@ void QTimerActiveObject::RunL() SymbianTimerInfoPtr timerInfoPtr(m_timerInfo); m_timerInfo->dispatcher->timerFired(m_timerInfo->timerId); - + iStatus = KRequestPending; SetActive(); TRequestStatus *status = &iStatus; @@ -304,7 +310,7 @@ void QCompleteDeferredAOs::RunL() iStatus = KRequestPending; SetActive(); - m_dispatcher->reactivateDeferredActiveObjects(); + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->reactivateDeferredActiveObjects()); } QSelectThread::QSelectThread() @@ -577,7 +583,7 @@ void QSocketActiveObject::RunL() if (!okToRun()) return; - m_dispatcher->socketFired(this); + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(m_dispatcher->socketFired(this)); } void QSocketActiveObject::deleteLater() @@ -633,101 +639,108 @@ void QEventDispatcherSymbian::closingDown() bool QEventDispatcherSymbian::processEvents ( QEventLoop::ProcessEventsFlags flags ) { - Q_D(QAbstractEventDispatcher); + bool handledAnyEvent = false; + QT_TRY { + Q_D(QAbstractEventDispatcher); + // It is safe if this counter overflows. The main importance is that each // iteration count is different from the last. m_iterationCount++; - RThread &thread = d->threadData->symbian_thread_handle; - - bool block; - if (flags & QEventLoop::WaitForMoreEvents) { - block = true; - emit aboutToBlock(); - } else { - block = false; - } - - bool handledAnyEvent = false; - - bool oldNoSocketEventsValue = m_noSocketEvents; - if (flags & QEventLoop::ExcludeSocketNotifiers) { - m_noSocketEvents = true; - } else { - m_noSocketEvents = false; - handledAnyEvent = sendDeferredSocketEvents(); - } - - bool handledSymbianEvent = false; - m_interrupt = false; - - /* - * This QTime variable is used to measure the time it takes to finish - * the event loop. If we take too long in the loop, other processes - * may be starved and killed. After the first event has completed, we - * take the current time, and if the remaining events take longer than - * a preset time, we temporarily lower the priority to force a context - * switch. For applications that do not take unecessarily long in the - * event loop, the priority will not be altered. - */ - QTime time; - enum { - FirstRun, - SubsequentRun, - TimeStarted - } timeState = FirstRun; - - TProcessPriority priority; - - while (1) { - if (block) { - // This is where Qt will spend most of its time. - CActiveScheduler::Current()->WaitForAnyRequest(); + RThread &thread = d->threadData->symbian_thread_handle; + + bool block; + if (flags & QEventLoop::WaitForMoreEvents) { + block = true; + emit aboutToBlock(); } else { - if (thread.RequestCount() == 0) { - break; - } - // This one should return without delay. - CActiveScheduler::Current()->WaitForAnyRequest(); - } - - if (timeState == SubsequentRun) { - time.start(); - timeState = TimeStarted; - } - - TInt error; - handledSymbianEvent = CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); - if (error) { - qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error); - CActiveScheduler::Current()->Error(error); + block = false; } - if (!handledSymbianEvent) { - qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal"); - } - handledAnyEvent = true; - if (m_interrupt) { - break; + + bool oldNoSocketEventsValue = m_noSocketEvents; + if (flags & QEventLoop::ExcludeSocketNotifiers) { + m_noSocketEvents = true; + } else { + m_noSocketEvents = false; + handledAnyEvent = sendDeferredSocketEvents(); } - block = false; + + bool handledSymbianEvent = false; + m_interrupt = false; + + /* + * This QTime variable is used to measure the time it takes to finish + * the event loop. If we take too long in the loop, other processes + * may be starved and killed. After the first event has completed, we + * take the current time, and if the remaining events take longer than + * a preset time, we temporarily lower the priority to force a context + * switch. For applications that do not take unecessarily long in the + * event loop, the priority will not be altered. + */ + QTime time; + enum { + FirstRun, + SubsequentRun, + TimeStarted + } timeState = FirstRun; + + TProcessPriority priority; + + while (1) { + if (block) { + // This is where Qt will spend most of its time. + CActiveScheduler::Current()->WaitForAnyRequest(); + } else { + if (thread.RequestCount() == 0) { + break; + } + // This one should return without delay. + CActiveScheduler::Current()->WaitForAnyRequest(); + } + + if (timeState == SubsequentRun) { + time.start(); + timeState = TimeStarted; + } + + TInt error; + handledSymbianEvent = CActiveScheduler::RunIfReady(error, CActive::EPriorityIdle); + if (error) { + qWarning("CActiveScheduler::RunIfReady() returned error: %i\n", error); + CActiveScheduler::Current()->Error(error); + } + + if (!handledSymbianEvent) { + qFatal("QEventDispatcherSymbian::processEvents(): Caught Symbian stray signal"); + } + handledAnyEvent = true; + if (m_interrupt) { + break; + } + block = false; if (timeState == TimeStarted && time.elapsed() > 100) { - priority = m_processHandle.Priority(); - m_processHandle.SetPriority(EPriorityLow); - time.start(); - // Slight chance of race condition in the next lines, but nothing fatal - // will happen, just wrong priority. - if (m_processHandle.Priority() == EPriorityLow) { - m_processHandle.SetPriority(priority); + priority = m_processHandle.Priority(); + m_processHandle.SetPriority(EPriorityLow); + time.start(); + // Slight chance of race condition in the next lines, but nothing fatal + // will happen, just wrong priority. + if (m_processHandle.Priority() == EPriorityLow) { + m_processHandle.SetPriority(priority); + } } - } - if (timeState == FirstRun) - timeState = SubsequentRun; - }; - - emit awake(); - - m_noSocketEvents = oldNoSocketEventsValue; + if (timeState == FirstRun) + timeState = SubsequentRun; + }; + + emit awake(); + + m_noSocketEvents = oldNoSocketEventsValue; + } QT_CATCH (const std::exception& ex) { +#ifndef QT_NO_EXCEPTIONS + CActiveScheduler::Current()->Error(qt_translateExceptionToSymbianError(ex)); +#endif + } return handledAnyEvent; } diff --git a/src/corelib/kernel/qeventdispatcher_symbian_p.h b/src/corelib/kernel/qeventdispatcher_symbian_p.h index 64ea282..3593055 100644 --- a/src/corelib/kernel/qeventdispatcher_symbian_p.h +++ b/src/corelib/kernel/qeventdispatcher_symbian_p.h @@ -136,6 +136,9 @@ public: protected: void DoCancel(); void RunL(); + +private: + void Run(); private: SymbianTimerInfo *m_timerInfo; diff --git a/src/corelib/kernel/qeventdispatcher_unix.cpp b/src/corelib/kernel/qeventdispatcher_unix.cpp index f7293d4..ea8299c 100644 --- a/src/corelib/kernel/qeventdispatcher_unix.cpp +++ b/src/corelib/kernel/qeventdispatcher_unix.cpp @@ -184,7 +184,7 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, continue; for (int i = 0; i < list.size(); ++i) { - QSockNot *sn = list.at(i); + QSockNot *sn = list[i]; FD_ZERO(&fdset); FD_SET(sn->fd, &fdset); @@ -241,7 +241,7 @@ int QEventDispatcherUNIXPrivate::doSelect(QEventLoop::ProcessEventsFlags flags, for (int i=0; i<3; i++) { QSockNotType::List &list = sn_vec[i].list; for (int j = 0; j < list.size(); ++j) { - QSockNot *sn = list.at(j); + QSockNot *sn = list[j]; if (FD_ISSET(sn->fd, &sn_vec[i].select_fds)) q->setSocketNotifierPending(sn->obj); } @@ -599,7 +599,10 @@ QEventDispatcherUNIX::QEventDispatcherUNIX(QEventDispatcherUNIXPrivate &dd, QObj { } QEventDispatcherUNIX::~QEventDispatcherUNIX() -{ } +{ + Q_D(QEventDispatcherUNIX); + d->threadData->eventDispatcher = 0; +} int QEventDispatcherUNIX::select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, timeval *timeout) @@ -706,8 +709,8 @@ QSockNotType::QSockNotType() QSockNotType::~QSockNotType() { - while (!list.isEmpty()) - delete list.takeFirst(); + for (int i = 0; i < list.size(); ++i) + delete list[i]; } /***************************************************************************** @@ -743,7 +746,7 @@ void QEventDispatcherUNIX::registerSocketNotifier(QSocketNotifier *notifier) int i; for (i = 0; i < list.size(); ++i) { - QSockNot *p = list.at(i); + QSockNot *p = list[i]; if (p->fd < sockfd) break; if (p->fd == sockfd) { @@ -781,7 +784,7 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) QSockNot *sn = 0; int i; for (i = 0; i < list.size(); ++i) { - sn = list.at(i); + sn = list[i]; if(sn->obj == notifier && sn->fd == sockfd) break; } @@ -799,7 +802,7 @@ void QEventDispatcherUNIX::unregisterSocketNotifier(QSocketNotifier *notifier) for (int i=0; i<3; i++) { if (!d->sn_vec[i].list.isEmpty()) d->sn_highest = qMax(d->sn_highest, // list is fd-sorted - d->sn_vec[i].list.first()->fd); + d->sn_vec[i].list[0]->fd); } } } @@ -823,7 +826,7 @@ void QEventDispatcherUNIX::setSocketNotifierPending(QSocketNotifier *notifier) QSockNot *sn = 0; int i; for (i = 0; i < list.size(); ++i) { - sn = list.at(i); + sn = list[i]; if(sn->obj == notifier && sn->fd == sockfd) break; } diff --git a/src/corelib/kernel/qeventdispatcher_unix_p.h b/src/corelib/kernel/qeventdispatcher_unix_p.h index 41329cf..816add5 100644 --- a/src/corelib/kernel/qeventdispatcher_unix_p.h +++ b/src/corelib/kernel/qeventdispatcher_unix_p.h @@ -57,6 +57,7 @@ #include "QtCore/qlist.h" #include "private/qabstracteventdispatcher_p.h" #include "private/qpodlist_p.h" +#include "QtCore/qvarlengtharray.h" #include <sys/types.h> #include <sys/time.h> diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index 860180e..ac505e1 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -392,7 +392,9 @@ void QMetaObject::removeGuard(QObject **ptr) if (!*ptr) return; GuardHash *hash = guardHash(); - if (!hash) + /* check that the hash is empty - otherwise we might detach + the shared_null hash, which will alloc, which is not nice */ + if (!hash || hash->isEmpty()) return; QMutexLocker locker(guardHashLock()); GuardHash::iterator it = hash->find(*ptr); @@ -434,9 +436,19 @@ void QMetaObject::changeGuard(QObject **ptr, QObject *o) */ void QObjectPrivate::clearGuards(QObject *object) { - GuardHash *hash = guardHash(); - if (hash) { - QMutexLocker locker(guardHashLock()); + GuardHash *hash = 0; + QMutex *mutex = 0; + QT_TRY { + hash = guardHash(); + mutex = guardHashLock(); + } QT_CATCH(const std::bad_alloc &) { + // do nothing in case of OOM - code below is safe + } + + /* check that the hash is empty - otherwise we might detach + the shared_null hash, which will alloc, which is not nice */ + if (hash && !hash->isEmpty()) { + QMutexLocker locker(mutex); GuardHash::iterator it = hash->find(object); const GuardHash::iterator end = hash->end(); while (it.key() == object && it != end) { @@ -754,7 +766,14 @@ QObject::~QObject() QObjectPrivate::clearGuards(this); } - emit destroyed(this); + QT_TRY { + emit destroyed(this); + } QT_CATCH(...) { + // 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()."); + QT_RETHROW; + } { QMutexLocker locker(&d->threadData->mutex); @@ -853,9 +872,6 @@ QObject::~QObject() objectName().isNull() ? "unnamed" : qPrintable(objectName())); } #endif - - delete d; - d_ptr = 0; } @@ -1098,11 +1114,11 @@ bool QObject::event(QEvent *e) #if defined(QT_NO_EXCEPTIONS) mce->placeMetaCall(this); #else - try { + QT_TRY { mce->placeMetaCall(this); - } catch (...) { + } QT_CATCH(...) { QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender); - throw; + QT_RETHROW; } #endif QObjectPrivate::resetCurrentSender(this, ¤tSender, previousSender); @@ -3102,9 +3118,9 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal #if defined(QT_NO_EXCEPTIONS) receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); #else - try { + QT_TRY { receiver->qt_metacall(QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv); - } catch (...) { + } QT_CATCH(...) { locker.relock(); QObjectPrivate::resetCurrentSender(receiver, ¤tSender, previousSender); @@ -3113,7 +3129,7 @@ void QMetaObject::activate(QObject *sender, int from_signal_index, int to_signal Q_ASSERT(connectionLists->inUse >= 0); if (connectionLists->orphaned && !connectionLists->inUse) delete connectionLists; - throw; + QT_RETHROW; } #endif diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index dbec0a6..8d5c4e3 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -51,6 +51,7 @@ #ifdef QT_INCLUDE_COMPAT #include <QtCore/qcoreevent.h> #endif +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -286,7 +287,7 @@ protected: QObject(QObjectPrivate &dd, QObject *parent = 0); protected: - QObjectData *d_ptr; + QScopedPointer<QObjectData> d_ptr; static const QMetaObject staticQtMetaObject; diff --git a/src/corelib/kernel/qsharedmemory_symbian.cpp b/src/corelib/kernel/qsharedmemory_symbian.cpp index b3b50e3..d05f9f3 100644 --- a/src/corelib/kernel/qsharedmemory_symbian.cpp +++ b/src/corelib/kernel/qsharedmemory_symbian.cpp @@ -116,11 +116,9 @@ bool QSharedMemoryPrivate::create(int size) return false; } - HBufC* buffer = qt_QString2HBufCNewL(safeKey); + TPtrC ptr(qt_QString2TPtrC(safeKey)); - TInt err = chunk.CreateGlobal(*buffer, size, size); - - delete buffer; + TInt err = chunk.CreateGlobal(ptr, size, size); setErrorString(function, err); @@ -147,15 +145,11 @@ bool QSharedMemoryPrivate::attach(QSharedMemory::AccessMode mode) return false; } - HBufC* buffer = qt_QString2HBufCNewL(safeKey); + TPtrC ptr(qt_QString2TPtrC(safeKey)); TInt err = KErrNoMemory; - if (buffer) { - err = chunk.OpenGlobal(*buffer, false); - } - - delete buffer; + err = chunk.OpenGlobal(ptr, false); if (err != KErrNone) { setErrorString(function, err); diff --git a/src/corelib/kernel/qsystemsemaphore.cpp b/src/corelib/kernel/qsystemsemaphore.cpp index 7e09a6e..fb9385a 100644 --- a/src/corelib/kernel/qsystemsemaphore.cpp +++ b/src/corelib/kernel/qsystemsemaphore.cpp @@ -170,8 +170,8 @@ QT_BEGIN_NAMESPACE \sa acquire(), key() */ QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue, AccessMode mode) + : d(new QSystemSemaphorePrivate) { - d = new QSystemSemaphorePrivate; setKey(key, initialValue, mode); } @@ -193,7 +193,6 @@ QSystemSemaphore::QSystemSemaphore(const QString &key, int initialValue, AccessM QSystemSemaphore::~QSystemSemaphore() { d->cleanHandle(); - delete d; } /*! diff --git a/src/corelib/kernel/qsystemsemaphore.h b/src/corelib/kernel/qsystemsemaphore.h index 5a02072..3cafebf 100644 --- a/src/corelib/kernel/qsystemsemaphore.h +++ b/src/corelib/kernel/qsystemsemaphore.h @@ -43,6 +43,7 @@ #define QSYSTEMSEMAPHORE_H #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -89,7 +90,7 @@ public: private: Q_DISABLE_COPY(QSystemSemaphore) - QSystemSemaphorePrivate *d; + QScopedPointer<QSystemSemaphorePrivate> d; }; #endif // QT_NO_SYSTEMSEMAPHORE diff --git a/src/corelib/kernel/qsystemsemaphore_symbian.cpp b/src/corelib/kernel/qsystemsemaphore_symbian.cpp index cd5c3ff..8179046 100644 --- a/src/corelib/kernel/qsystemsemaphore_symbian.cpp +++ b/src/corelib/kernel/qsystemsemaphore_symbian.cpp @@ -90,13 +90,12 @@ int QSystemSemaphorePrivate::handle(QSystemSemaphore::AccessMode) if (key.isEmpty()) return 0; QString safeName = makeKeyFileName(); - HBufC* name = qt_QString2HBufCNewL(safeName); + TPtrC name(qt_QString2TPtrC(safeName)); int err; - err = semaphore.OpenGlobal(*name,EOwnerProcess); + err = semaphore.OpenGlobal(name,EOwnerProcess); if (err == KErrNotFound){ - err = semaphore.CreateGlobal(*name,initialValue, EOwnerProcess); + err = semaphore.CreateGlobal(name,initialValue, EOwnerProcess); } - delete name; if (err){ setErrorString(QLatin1String("QSystemSemaphore::handle"),err); return 0; diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 420dd1d..0ca0169 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -611,10 +611,10 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) .arg(fileName); QStringList reg; #ifndef QT_NO_SETTINGS - bool madeSettings = false; + QScopedPointer<QSettings> madeSettings; if (!settings) { settings = new QSettings(QSettings::UserScope, QLatin1String("Trolltech")); - madeSettings = true; + madeSettings.reset(settings); } reg = settings->value(regkey).toStringList(); #endif @@ -708,8 +708,7 @@ bool QLibraryPrivate::isPlugin(QSettings *settings) #endif } #ifndef QT_NO_SETTINGS - if (madeSettings) - delete settings; + madeSettings.reset(); #endif if (!success) { diff --git a/src/corelib/thread/qthread.cpp b/src/corelib/thread/qthread.cpp index cb44a25..f1bdc64 100644 --- a/src/corelib/thread/qthread.cpp +++ b/src/corelib/thread/qthread.cpp @@ -163,9 +163,9 @@ QAdoptedThread::~QAdoptedThread() QThread *QAdoptedThread::createThreadForAdoption() { - QThread *t = new QAdoptedThread(0); - t->moveToThread(t); - return t; + QScopedPointer<QThread> t(new QAdoptedThread(0)); + t->moveToThread(t.data()); + return t.take(); } void QAdoptedThread::run() @@ -483,10 +483,10 @@ uint QThread::stackSize() const int QThread::exec() { Q_D(QThread); - d->mutex.lock(); + QMutexLocker locker(&d->mutex); d->data->quitNow = false; QEventLoop eventLoop; - d->mutex.unlock(); + locker.unlock(); int returnCode = eventLoop.exec(); return returnCode; } @@ -734,8 +734,9 @@ QThreadData* QThreadData::current() { static QThreadData *data = 0; // reinterpret_cast<QThreadData *>(pthread_getspecific(current_thread_data_key)); if (!data) { - data = new QThreadData; - data->thread = new QAdoptedThread(data); + QScopedPointer<QThreadData> newdata(new QThreadData); + newdata->thread = new QAdoptedThread(newdata.data()); + data = newdata.take(); data->deref(); } return data; diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp index 567c936..d2a824a 100644 --- a/src/corelib/thread/qthread_unix.cpp +++ b/src/corelib/thread/qthread_unix.cpp @@ -124,7 +124,14 @@ QThreadData *QThreadData::current() } else { data = new QThreadData; pthread_setspecific(current_thread_data_key, data); - data->thread = new QAdoptedThread(data); + QT_TRY { + data->thread = new QAdoptedThread(data); + } QT_CATCH(...) { + pthread_setspecific(current_thread_data_key, 0); + data->deref(); + data = 0; + QT_RETHROW; + } data->deref(); } if (!QCoreApplicationPrivate::theMainThread) diff --git a/src/corelib/thread/qthread_win.cpp b/src/corelib/thread/qthread_win.cpp index 7094e3d..76e551e 100644 --- a/src/corelib/thread/qthread_win.cpp +++ b/src/corelib/thread/qthread_win.cpp @@ -112,7 +112,14 @@ QThreadData *QThreadData::current() // This needs to be called prior to new AdoptedThread() to // avoid recursion. TlsSetValue(qt_current_thread_data_tls_index, threadData); - threadData->thread = new QAdoptedThread(threadData); + QT_TRY { + threadData->thread = new QAdoptedThread(threadData); + } QT_CATCH(...) { + TlsSetValue(qt_current_thread_data_tls_index, 0); + threadData->deref(); + threadData = 0; + QT_RETHROW; + } threadData->deref(); } diff --git a/src/corelib/thread/qthreadstorage.cpp b/src/corelib/thread/qthreadstorage.cpp index 35c55c1..4657009 100644 --- a/src/corelib/thread/qthreadstorage.cpp +++ b/src/corelib/thread/qthreadstorage.cpp @@ -101,12 +101,14 @@ void **QThreadStorageData::get() const qWarning("QThreadStorage::get: QThreadStorage can only be used with threads started with QThread"); return 0; } - QMap<int, void *>::iterator it = data->tls.find(id); + QMap<int, void *>::const_iterator it = data->tls.constFind(id); DEBUG_MSG("QThreadStorageData: Returning storage %d, data %p, for thread %p", id, it != data->tls.end() ? it.value() : 0, data->thread); - return it != data->tls.end() && it.value() != 0 ? &it.value() : 0; + // const_cast below is a bit evil - but we have to make sure not to detach here + // otherwise we'll go bonkers in oom situations + return it != data->tls.constEnd() && it.value() != 0 ? const_cast<void **>(&it.value()) : 0; } void **QThreadStorageData::set(void *p) @@ -129,9 +131,9 @@ void **QThreadStorageData::set(void *p) void *q = it.value(); it.value() = 0; - mutex()->lock(); + QMutexLocker locker(mutex()); void (*destructor)(void *) = destructors()->value(id); - mutex()->unlock(); + locker.unlock(); destructor(q); } @@ -167,9 +169,9 @@ void QThreadStorageData::finish(void **p) continue; } - mutex()->lock(); + QMutexLocker locker(mutex()); void (*destructor)(void *) = destructors()->value(id); - mutex()->unlock(); + locker.unlock(); if (!destructor) { if (QThread::currentThread()) diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index a947ab5..7168a9a 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -209,6 +209,8 @@ void QBitArray::resize(int size) uchar* c = reinterpret_cast<uchar*>(d.data()); if (size > (s << 3)) memset(c + s, 0, d.size() - s); + else if ( size % 8) + *(c+1+size/8) &= (1 << (size%8)) - 1; *c = d.size()*8 - size; } } diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 6aa35f3..ae6561f 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -1233,14 +1233,11 @@ QByteArray::QByteArray(const char *str) } else { int len = qstrlen(str); d = static_cast<Data *>(qMalloc(sizeof(Data)+len)); - if (!d) { - d = &shared_null; - } else { - d->ref = 0;; - d->alloc = d->size = len; - d->data = d->array; - memcpy(d->array, str, len+1); // include null terminator - } + Q_CHECK_PTR(d); + d->ref = 0;; + d->alloc = d->size = len; + d->data = d->array; + memcpy(d->array, str, len+1); // include null terminator } d->ref.ref(); } @@ -1264,15 +1261,12 @@ QByteArray::QByteArray(const char *data, int size) d = &shared_empty; } else { d = static_cast<Data *>(qMalloc(sizeof(Data) + size)); - if (!d) { - d = &shared_null; - } else { - d->ref = 0; - d->alloc = d->size = size; - d->data = d->array; - memcpy(d->array, data, size); - d->array[size] = '\0'; - } + Q_CHECK_PTR(d); + d->ref = 0; + d->alloc = d->size = size; + d->data = d->array; + memcpy(d->array, data, size); + d->array[size] = '\0'; } d->ref.ref(); } @@ -1290,15 +1284,12 @@ QByteArray::QByteArray(int size, char ch) d = &shared_null; } else { d = static_cast<Data *>(qMalloc(sizeof(Data)+size)); - if (!d) { - d = &shared_null; - } else { - d->ref = 0; - d->alloc = d->size = size; - d->data = d->array; - d->array[size] = '\0'; - memset(d->array, ch, size); - } + Q_CHECK_PTR(d); + d->ref = 0; + d->alloc = d->size = size; + d->data = d->array; + d->array[size] = '\0'; + memset(d->array, ch, size); } d->ref.ref(); } @@ -1334,8 +1325,7 @@ void QByteArray::resize(int size) // QByteArray a(sz); // Data *x = static_cast<Data *>(qMalloc(sizeof(Data)+size)); - if (!x) - return; + Q_CHECK_PTR(x); x->ref = 1; x->alloc = x->size = size; x->data = x->array; @@ -1377,8 +1367,7 @@ void QByteArray::realloc(int alloc) { if (d->ref != 1 || d->data != d->array) { Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc)); - if (!x) - return; + Q_CHECK_PTR(x); x->size = qMin(alloc, d->size); ::memcpy(x->array, d->data, x->size); x->array[x->size] = '\0'; @@ -1390,8 +1379,7 @@ void QByteArray::realloc(int alloc) d = x; } else { Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc)); - if (!x) - return; + Q_CHECK_PTR(x); x->alloc = alloc; x->data = x->array; d = x; @@ -1812,11 +1800,13 @@ QByteArray &QByteArray::replace(const char *before, int bsize, const char *after const char *b = before; if (after >= d->data && after < d->data + d->size) { char *copy = (char *)malloc(asize); + Q_CHECK_PTR(copy); memcpy(copy, after, asize); a = copy; } if (before >= d->data && before < d->data + d->size) { char *copy = (char *)malloc(bsize); + Q_CHECK_PTR(copy); memcpy(copy, before, bsize); b = copy; } @@ -3738,6 +3728,7 @@ QByteArray QByteArray::number(double n, char f, int prec) QByteArray QByteArray::fromRawData(const char *data, int size) { Data *x = static_cast<Data *>(qMalloc(sizeof(Data))); + Q_CHECK_PTR(x); if (data) { x->data = const_cast<char *>(data); } else { diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 781514c..b43891c 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2200,8 +2200,8 @@ int QTime::elapsed() const \sa isValid() */ QDateTime::QDateTime() + : d(new QDateTimePrivate) { - d = new QDateTimePrivate; } @@ -2211,8 +2211,8 @@ QDateTime::QDateTime() */ QDateTime::QDateTime(const QDate &date) + : d(new QDateTimePrivate) { - d = new QDateTimePrivate; d->date = date; d->time = QTime(0, 0, 0); } @@ -2225,8 +2225,8 @@ QDateTime::QDateTime(const QDate &date) */ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) + : d(new QDateTimePrivate) { - d = new QDateTimePrivate; d->date = date; d->time = date.isValid() && !time.isValid() ? QTime(0, 0, 0) : time; d->spec = (spec == Qt::UTC) ? QDateTimePrivate::UTC : QDateTimePrivate::LocalUnknown; @@ -2237,8 +2237,8 @@ QDateTime::QDateTime(const QDate &date, const QTime &time, Qt::TimeSpec spec) */ QDateTime::QDateTime(const QDateTime &other) + : d(other.d.data()) { - d = other.d; d->ref.ref(); } @@ -2247,8 +2247,6 @@ QDateTime::QDateTime(const QDateTime &other) */ QDateTime::~QDateTime() { - if (!d->ref.deref()) - delete d; } /*! @@ -2258,7 +2256,7 @@ QDateTime::~QDateTime() QDateTime &QDateTime::operator=(const QDateTime &other) { - qAtomicAssign(d, other.d); + d.assign(other.d.data()); return *this; } @@ -3298,7 +3296,7 @@ QDateTime QDateTime::fromString(const QString &string, const QString &format) */ void QDateTime::detach() { - qAtomicDetach(d); + d.detach(); } /***************************************************************************** diff --git a/src/corelib/tools/qdatetime.h b/src/corelib/tools/qdatetime.h index 3278297..cf4246d 100644 --- a/src/corelib/tools/qdatetime.h +++ b/src/corelib/tools/qdatetime.h @@ -44,6 +44,7 @@ #include <QtCore/qstring.h> #include <QtCore/qnamespace.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -284,7 +285,7 @@ public: private: friend class QDateTimePrivate; void detach(); - QDateTimePrivate *d; + QScopedSharedPointer<QDateTimePrivate> d; #ifndef QT_NO_DATASTREAM friend Q_CORE_EXPORT QDataStream &operator<<(QDataStream &, const QDateTime &); diff --git a/src/corelib/tools/qharfbuzz.cpp b/src/corelib/tools/qharfbuzz.cpp index 1940209..923eda4 100644 --- a/src/corelib/tools/qharfbuzz.cpp +++ b/src/corelib/tools/qharfbuzz.cpp @@ -126,6 +126,7 @@ char *HB_TextCodec_ConvertFromUnicode(void *codec, const HB_UChar16 *unicode, hb QByteArray data = reinterpret_cast<QTextCodec *>(codec)->fromUnicode((const QChar *)unicode, length); // ### suboptimal char *output = (char *)malloc(data.length() + 1); + Q_CHECK_PTR(output); memcpy(output, data.constData(), data.length() + 1); if (outputLength) *outputLength = data.length(); diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index 2313e0e..a703621 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -171,7 +171,9 @@ QHashData QHashData::shared_null = { void *QHashData::allocateNode() { - return qMalloc(nodeSize); + void *ptr = qMalloc(nodeSize); + Q_CHECK_PTR(ptr); + return ptr; } void QHashData::freeNode(void *node) @@ -181,6 +183,13 @@ void QHashData::freeNode(void *node) QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize) { + return detach_helper( node_duplicate, 0, nodeSize ); +} + +QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), + void (*node_delete)(Node *), + int nodeSize) +{ union { QHashData *d; Node *e; @@ -197,18 +206,43 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int d->sharable = true; if (numBuckets) { - d->buckets = new Node *[numBuckets]; + QT_TRY { + d->buckets = new Node *[numBuckets]; + } QT_CATCH(...) { + // restore a consistent state for d + d->numBuckets = 0; + // roll back + d->free_helper(node_delete); + QT_RETHROW; + } + Node *this_e = reinterpret_cast<Node *>(this); for (int i = 0; i < numBuckets; ++i) { Node **nextNode = &d->buckets[i]; Node *oldNode = buckets[i]; while (oldNode != this_e) { - Node *dup = static_cast<Node *>(allocateNode()); - node_duplicate(oldNode, dup); - dup->h = oldNode->h; - *nextNode = dup; - nextNode = &dup->next; - oldNode = oldNode->next; + QT_TRY { + Node *dup = static_cast<Node *>(allocateNode()); + + QT_TRY { + node_duplicate(oldNode, dup); + } QT_CATCH(...) { + freeNode( dup ); + QT_RETHROW; + } + + dup->h = oldNode->h; + *nextNode = dup; + nextNode = &dup->next; + oldNode = oldNode->next; + } QT_CATCH(...) { + // restore a consistent state for d + *nextNode = e; + d->numBuckets = i+1; + // roll back + d->free_helper(node_delete); + QT_RETHROW; + } } *nextNode = e; } @@ -216,6 +250,26 @@ QHashData *QHashData::detach_helper(void (*node_duplicate)(Node *, void *), int return d; } +void QHashData::free_helper(void (*node_delete)(Node *)) +{ + if (node_delete) { + Node *this_e = reinterpret_cast<Node *>(this); + Node **bucket = reinterpret_cast<Node **>(this->buckets); + + int n = numBuckets; + while (n--) { + Node *cur = *bucket++; + while (cur != this_e) { + Node *next = cur->next; + node_delete(cur); + cur = next; + } + } + } + delete [] buckets; + delete this; +} + QHashData::Node *QHashData::nextNode(Node *node) { union { @@ -298,9 +352,10 @@ void QHashData::rehash(int hint) Node **oldBuckets = buckets; int oldNumBuckets = numBuckets; + int nb = primeForNumBits(hint); + buckets = new Node *[nb]; numBits = hint; - numBuckets = primeForNumBits(hint); - buckets = new Node *[numBuckets]; + numBuckets = nb; for (int i = 0; i < numBuckets; ++i) buckets[i] = e; @@ -327,8 +382,7 @@ void QHashData::rehash(int hint) void QHashData::destroyAndFree() { - delete [] buckets; - delete this; + free_helper(0); } #ifdef QT_QHASH_DEBUG diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 41b4794..b3f82e9 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -129,12 +129,15 @@ struct Q_CORE_EXPORT QHashData void *allocateNode(); void freeNode(void *node); - QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); + QHashData *detach_helper(void (*node_duplicate)(Node *, void *), int nodeSize); // ### Qt5 remove me + QHashData *detach_helper(void (*node_duplicate)(Node *, void *), void (*node_delete)(Node *), + int nodeSize); void mightGrow(); bool willGrow(); void hasShrunk(); void rehash(int hint); - void destroyAndFree(); + void free_helper(void (*node_delete)(Node *)); + void destroyAndFree(); // ### Qt5 remove me Node *firstNode(); #ifdef QT_QHASH_DEBUG void dump(); @@ -476,21 +479,30 @@ private: Node **findNode(const Key &key, uint *hp = 0) const; Node *createNode(uint h, const Key &key, const T &value, Node **nextNode); void deleteNode(Node *node); + static void deleteNode(QHashData::Node *node); static void duplicateNode(QHashData::Node *originalNode, void *newNode); }; + template <class Key, class T> Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(Node *node) { + deleteNode(reinterpret_cast<QHashData::Node*>(node)); +} + + +template <class Key, class T> +Q_INLINE_TEMPLATE void QHash<Key, T>::deleteNode(QHashData::Node *node) +{ #ifdef Q_CC_BOR - node->~QHashNode<Key, T>(); + concrete(node)->~QHashNode<Key, T>(); #elif defined(QT_NO_PARTIAL_TEMPLATE_SPECIALIZATION) - node->~QHashNode(); + concrete(node)->~QHashNode(); #else - node->~Node(); + concrete(node)->~Node(); #endif - d->freeNode(node); + qFree(node); } template <class Key, class T> @@ -538,18 +550,7 @@ Q_INLINE_TEMPLATE QHash<Key, T> &QHash<Key, T>::unite(const QHash<Key, T> &other template <class Key, class T> Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::freeData(QHashData *x) { - Node *e_for_x = reinterpret_cast<Node *>(x); - Node **bucket = reinterpret_cast<Node **>(x->buckets); - int n = x->numBuckets; - while (n--) { - Node *cur = *bucket++; - while (cur != e_for_x) { - Node *next = cur->next; - deleteNode(cur); - cur = next; - } - } - x->destroyAndFree(); + x->free_helper(deleteNode); } template <class Key, class T> @@ -561,7 +562,7 @@ Q_INLINE_TEMPLATE void QHash<Key, T>::clear() template <class Key, class T> Q_OUTOFLINE_TEMPLATE void QHash<Key, T>::detach_helper() { - QHashData *x = d->detach_helper(duplicateNode, + QHashData *x = d->detach_helper(duplicateNode, deleteNode, QTypeInfo<T>::isDummy ? sizeof(DummyNode) : sizeof(Node)); if (!d->ref.deref()) freeData(d); diff --git a/src/corelib/tools/qlinkedlist.h b/src/corelib/tools/qlinkedlist.h index 6a85386..79311bc 100644 --- a/src/corelib/tools/qlinkedlist.h +++ b/src/corelib/tools/qlinkedlist.h @@ -265,15 +265,22 @@ void QLinkedList<T>::detach_helper() x.d->ref = 1; x.d->size = d->size; x.d->sharable = true; - Node *i = e->n, *j = x.e; - while (i != e) { - j->n = new Node(i->t); - j->n->p = j; - i = i->n; - j = j->n; + Node *original = e->n; + Node *copy = x.e; + while (original != e) { + QT_TRY { + copy->n = new Node(original->t); + copy->n->p = copy; + original = original->n; + copy = copy->n; + } QT_CATCH(...) { + copy->n = x.e; + free(x.d); + QT_RETHROW; + } } - j->n = x.e; - x.e->p = j; + copy->n = x.e; + x.e->p = copy; if (!d->ref.deref()) free(d); d = x.d; @@ -474,14 +481,21 @@ QLinkedList<T> &QLinkedList<T>::operator+=(const QLinkedList<T> &l) detach(); int n = l.d->size; d->size += n; - Node *o = l.e->n; + Node *original = l.e->n; while (n--) { - Node *i = new Node(o->t); - o = o->n; - i->n = e; - i->p = e->p; - i->p->n = i; - e->p = i; + QT_TRY { + Node *copy = new Node(original->t); + original = original->n; + copy->n = e; + copy->p = e->p; + copy->p->n = copy; + e->p = copy; + } QT_CATCH(...) { + // restore the original list + while (n++<d->size) + removeLast(); + QT_RETHROW; + } } return *this; } diff --git a/src/corelib/tools/qlist.h b/src/corelib/tools/qlist.h index 3c21ec1..89e082b 100644 --- a/src/corelib/tools/qlist.h +++ b/src/corelib/tools/qlist.h @@ -117,6 +117,7 @@ public: inline int size() const { return p.size(); } inline void detach() { if (d->ref != 1) detach_helper(); } + inline void detachShared() { if (d->ref != 1 && d != &QListData::shared_null) detach_helper(); } inline bool isDetached() const { return d->ref == 1; } inline void setSharable(bool sharable) { if (!sharable) detach(); d->sharable = sharable; } @@ -352,12 +353,27 @@ Q_INLINE_TEMPLATE void QList<T>::node_destruct(Node *n) template <typename T> Q_INLINE_TEMPLATE void QList<T>::node_copy(Node *from, Node *to, Node *src) { - if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) - while(from != to) - (from++)->v = new T(*reinterpret_cast<T*>((src++)->v)); - else if (QTypeInfo<T>::isComplex) - while(from != to) - new (from++) T(*reinterpret_cast<T*>(src++)); + Node *current = from; + if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { + QT_TRY { + while(current != to) + (current++)->v = new T(*reinterpret_cast<T*>((src++)->v)); + } QT_CATCH(...) { + while (current != from) + delete reinterpret_cast<T*>(current--); + QT_RETHROW; + } + } + else if (QTypeInfo<T>::isComplex) { + QT_TRY { + while(current != to) + new (current++) T(*reinterpret_cast<T*>(src++)); + } QT_CATCH(...) { + while (current != from) + (reinterpret_cast<T*>(current--))->~T(); + QT_RETHROW; + } + } } template <typename T> @@ -384,8 +400,16 @@ Q_INLINE_TEMPLATE QList<T> &QList<T>::operator=(const QList<T> &l) } template <typename T> inline typename QList<T>::iterator QList<T>::insert(iterator before, const T &t) -{ Node *n = reinterpret_cast<Node *>(p.insert(before.i-reinterpret_cast<Node *>(p.begin()))); - node_construct(n,t); return n; } +{ + Node *n = reinterpret_cast<Node *>(p.insert(before.i - reinterpret_cast<Node *>(p.begin()))); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + p.remove(before.i - reinterpret_cast<Node *>(p.begin())); + QT_RETHROW; + } + return n; +} template <typename T> inline typename QList<T>::iterator QList<T>::erase(iterator it) { node_destruct(it.i); @@ -423,10 +447,22 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::append(const T &t) { detach(); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - node_construct(reinterpret_cast<Node *>(p.append()), t); + Node *n = reinterpret_cast<Node *>(p.append()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } } else { const T cpy(t); - node_construct(reinterpret_cast<Node *>(p.append()), cpy); + Node *n = reinterpret_cast<Node *>(p.append()); + QT_TRY { + node_construct(n, cpy); + } QT_CATCH(...) { + --d->end; + QT_RETHROW; + } } } @@ -435,10 +471,22 @@ inline void QList<T>::prepend(const T &t) { detach(); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - node_construct(reinterpret_cast<Node *>(p.prepend()), t); + Node *n = reinterpret_cast<Node *>(p.prepend()); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } } else { const T cpy(t); - node_construct(reinterpret_cast<Node *>(p.prepend()), cpy); + Node *n = reinterpret_cast<Node *>(p.prepend()); + QT_TRY { + node_construct(n, cpy); + } QT_CATCH(...) { + ++d->begin; + QT_RETHROW; + } } } @@ -447,10 +495,22 @@ inline void QList<T>::insert(int i, const T &t) { detach(); if (QTypeInfo<T>::isLarge || QTypeInfo<T>::isStatic) { - node_construct(reinterpret_cast<Node *>(p.insert(i)), t); + Node *n = reinterpret_cast<Node *>(p.insert(i)); + QT_TRY { + node_construct(n, t); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } } else { const T cpy(t); - node_construct(reinterpret_cast<Node *>(p.insert(i)), cpy); + Node *n = reinterpret_cast<Node *>(p.insert(i)); + QT_TRY { + node_construct(n, cpy); + } QT_CATCH(...) { + p.remove(i); + QT_RETHROW; + } } } @@ -522,7 +582,14 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::detach_helper() { Node *n = reinterpret_cast<Node *>(p.begin()); QListData::Data *x = p.detach2(); - node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n); + QT_TRY { + node_copy(reinterpret_cast<Node *>(p.begin()), reinterpret_cast<Node *>(p.end()), n); + } QT_CATCH(...) { + qFree(d); + d = x; + QT_RETHROW; + } + if (!x->ref.deref()) free(x); } @@ -572,7 +639,7 @@ Q_OUTOFLINE_TEMPLATE void QList<T>::clear() template <typename T> Q_OUTOFLINE_TEMPLATE int QList<T>::removeAll(const T &_t) { - detach(); + detachShared(); const T t = _t; int removedCount=0, i=0; Node *n; @@ -590,7 +657,7 @@ Q_OUTOFLINE_TEMPLATE int QList<T>::removeAll(const T &_t) template <typename T> Q_OUTOFLINE_TEMPLATE bool QList<T>::removeOne(const T &_t) { - detach(); + detachShared(); int index = indexOf(_t); if (index != -1) { removeAt(index); diff --git a/src/corelib/tools/qlistdata.cpp b/src/corelib/tools/qlistdata.cpp index 34a5d80..efdde64 100644 --- a/src/corelib/tools/qlistdata.cpp +++ b/src/corelib/tools/qlistdata.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include <new> #include "qlist.h" #include "qtools_p.h" #include <string.h> @@ -71,8 +72,7 @@ static int grow(int size) QListData::Data *QListData::detach() { Data *x = static_cast<Data *>(qMalloc(DataHeaderSize + d->alloc * sizeof(void *))); - if (!x) - qFatal("QList: Out of memory"); + Q_CHECK_PTR(x); ::memcpy(x, d, DataHeaderSize + d->alloc * sizeof(void *)); x->alloc = d->alloc; @@ -91,10 +91,10 @@ QListData::Data *QListData::detach() QListData::Data *QListData::detach2() { Data *x = d; - d = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); - if (!d) - qFatal("QList: Out of memory"); + Data* t = static_cast<Data *>(qMalloc(DataHeaderSize + x->alloc * sizeof(void *))); + Q_CHECK_PTR(t); + d = t; ::memcpy(d, x, DataHeaderSize + x->alloc * sizeof(void *)); d->alloc = x->alloc; d->ref = 1; @@ -109,8 +109,7 @@ void QListData::realloc(int alloc) { Q_ASSERT(d->ref == 1); Data *x = static_cast<Data *>(qRealloc(d, DataHeaderSize + alloc * sizeof(void *))); - if (!x) - qFatal("QList: Out of memory"); + Q_CHECK_PTR(x); d = x; d->alloc = alloc; @@ -514,6 +513,15 @@ void **QListData::erase(void **xi) \internal */ +/*! \fn void QList::detachShared() + + \internal + + like detach(), but does nothing if we're shared_null. + This prevents needless mallocs, and makes QList more exception safe + in case of cleanup work done in destructors on empty lists. +*/ + /*! \fn bool QList::isDetached() const \internal diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 4d042ae..4317933 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -5124,6 +5124,7 @@ static Bigint *Balloc(int k) x = 1 << k; rv = static_cast<Bigint *>(MALLOC(sizeof(Bigint) + (x-1)*sizeof(Long))); + Q_CHECK_PTR(rv); rv->k = k; rv->maxwds = x; rv->sign = rv->wds = 0; @@ -6788,6 +6789,7 @@ static char *_qdtoa( NEEDS_VOLATILE double d, int mode, int ndigits, int *decpt, i = 1; } *resultp = static_cast<char *>(malloc(i + 1)); + Q_CHECK_PTR(resultp); s = s0 = *resultp; if (ilim >= 0 && ilim <= Quick_max && try_quick) { @@ -7209,6 +7211,7 @@ Q_CORE_EXPORT char *qdtoa( double d, int mode, int ndigits, int *decpt, int *sig n = i + 1; } *resultp = static_cast<char*>(malloc(n + 1)); + Q_CHECK_PTR(resultp); qstrncpy(*resultp, res, n + 1); return *resultp; } diff --git a/src/corelib/tools/qmap.cpp b/src/corelib/tools/qmap.cpp index 07df28d..ceaf370 100644 --- a/src/corelib/tools/qmap.cpp +++ b/src/corelib/tools/qmap.cpp @@ -59,6 +59,7 @@ QMapData QMapData::shared_null = { QMapData *QMapData::createData() { QMapData *d = new QMapData; + Q_CHECK_PTR(d); Node *e = reinterpret_cast<Node *>(d); e->backward = e; e->forward[0] = e; @@ -84,6 +85,15 @@ void QMapData::continueFreeData(int offset) delete this; } +/*! + Creates a new node inside the data structure. + + \a update is an array with pointers to the node after which the new node + should be inserted. Because of the strange skip list data structure there + could be several pointers to this node on different levels. + \a offset is an amount of bytes that needs to reserved just before the + QMapData::Node structure. +*/ QMapData::Node *QMapData::node_create(Node *update[], int offset) { int level = 0; @@ -94,10 +104,6 @@ QMapData::Node *QMapData::node_create(Node *update[], int offset) mask <<= Sparseness; } - ++randomBits; - if (level == 3 && !insertInOrder) - randomBits = qrand(); - if (level > topLevel) { Node *e = reinterpret_cast<Node *>(this); level = ++topLevel; @@ -105,7 +111,13 @@ QMapData::Node *QMapData::node_create(Node *update[], int offset) update[level] = e; } + ++randomBits; + if (level == 3 && !insertInOrder) + randomBits = qrand(); + void *concreteNode = qMalloc(offset + sizeof(Node) + level * sizeof(Node *)); + Q_CHECK_PTR(concreteNode); + Node *abstractNode = reinterpret_cast<Node *>(reinterpret_cast<char *>(concreteNode) + offset); abstractNode->backward = update[0]; @@ -116,6 +128,7 @@ QMapData::Node *QMapData::node_create(Node *update[], int offset) update[i]->forward[i] = abstractNode; update[i] = abstractNode; } + // update[level+1]=reinterpret_cast<Node *>(this); ++size; return abstractNode; } @@ -146,7 +159,7 @@ uint QMapData::adjust_ptr(Node *node) void QMapData::dump() { - qDebug("Map data (ref = %d, size = %d, randomBits = %#.8x)", ref.atomic, size, randomBits); + qDebug("Map data (ref = %d, size = %d, randomBits = %#.8x)", int(ref), size, randomBits); QString preOutput; QVector<QString> output(topLevel + 1); @@ -158,12 +171,12 @@ void QMapData::dump() Node *update[LastLevel + 1]; for (int i = 0; i <= topLevel; ++i) { - str.sprintf("%d: [%.8x] -", i, adjust_ptr(forward[i])); + str.sprintf("%d: [%.8x] -", i, adjust_ptr(reinterpret_cast<Node *>(forward[i]))); output[i] += str; - update[i] = forward[i]; + update[i] = reinterpret_cast<Node *>(forward[i]); } - Node *node = forward[0]; + Node *node = reinterpret_cast<Node *>(forward[0]); while (node != e) { int level = 0; while (level < topLevel && update[level + 1] == node) @@ -178,13 +191,13 @@ void QMapData::dump() update[i] = node->forward[i]; } for (int j = level + 1; j <= topLevel; ++j) - output[j] += "---------------"; + output[j] += QString("---------------"); node = node->forward[0]; } - qDebug(preOutput.ascii()); + qDebug("%s", preOutput.ascii()); for (int i = 0; i <= topLevel; ++i) - qDebug(output[i].ascii()); + qDebug("%s", output[i].ascii()); } #endif diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h index 0215a78..bd9ba74 100644 --- a/src/corelib/tools/qmap.h +++ b/src/corelib/tools/qmap.h @@ -416,9 +416,29 @@ Q_INLINE_TEMPLATE typename QMapData::Node * QMap<Key, T>::node_create(QMapData *adt, QMapData::Node *aupdate[], const Key &akey, const T &avalue) { QMapData::Node *abstractNode = adt->node_create(aupdate, payload()); - Node *concreteNode = concrete(abstractNode); - new (&concreteNode->key) Key(akey); - new (&concreteNode->value) T(avalue); + QT_TRY { + Node *concreteNode = concrete(abstractNode); + new (&concreteNode->key) Key(akey); + QT_TRY { + new (&concreteNode->value) T(avalue); + } QT_CATCH(...) { + concreteNode->key.~Key(); + QT_RETHROW; + } + } QT_CATCH(...) { + adt->node_delete(aupdate, payload(), abstractNode); + QT_RETHROW; + } + + // clean up the update array for further insertions + /* + for (int i = 0; i <= d->topLevel; ++i) { + if ( aupdate[i]==reinterpret_cast<QMapData::Node *>(adt) || aupdate[i]->forward[i] != abstractNode) + break; + aupdate[i] = abstractNode; + } +*/ + return abstractNode; } @@ -704,8 +724,13 @@ Q_OUTOFLINE_TEMPLATE void QMap<Key, T>::detach_helper() QMapData::Node *cur = e->forward[0]; update[0] = x.e; while (cur != e) { - Node *concreteNode = concrete(cur); - node_create(x.d, update, concreteNode->key, concreteNode->value); + QT_TRY { + Node *concreteNode = concrete(cur); + node_create(x.d, update, concreteNode->key, concreteNode->value); + } QT_CATCH(...) { + freeData(x.d); + QT_RETHROW; + } cur = cur->forward[0]; } x.d->insertInOrder = false; diff --git a/src/corelib/tools/qpodlist_p.h b/src/corelib/tools/qpodlist_p.h index 9708f8d..9e6d19b 100644 --- a/src/corelib/tools/qpodlist_p.h +++ b/src/corelib/tools/qpodlist_p.h @@ -53,9 +53,7 @@ // We mean it. // -#include <QtCore/qcontainerfwd.h> -#include <QtCore/qglobal.h> -#include <new> +#include <QtCore/qvarlengtharray.h> QT_BEGIN_HEADER @@ -63,87 +61,29 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) -template<class T, int Prealloc> -class QPodList +template <typename T, int Prealloc> +class QPodList : public QVarLengthArray<T, Prealloc> { + using QVarLengthArray<T, Prealloc>::s; + using QVarLengthArray<T, Prealloc>::a; + using QVarLengthArray<T, Prealloc>::ptr; + using QVarLengthArray<T, Prealloc>::realloc; public: - inline explicit QPodList(int size = 0); + inline explicit QPodList(int size = 0) + : QVarLengthArray<T, Prealloc>(size) + {} - inline QPodList(const QPodList<T, Prealloc> &other) - : a(Prealloc), s(0), ptr(reinterpret_cast<T *>(array)) + inline void insert(int idx, const T &t) { - append(other.constData(), other.size()); - } - - inline ~QPodList() { - if (ptr != reinterpret_cast<T *>(array)) - qFree(ptr); - } - inline QPodList<T, Prealloc> &operator=(const QPodList<T, Prealloc> &other) - { - if (this != &other) { - clear(); - append(other.constData(), other.size()); - } - return *this; - } - - inline int size() const { return s; } - inline int count() const { return s; } - inline bool isEmpty() const { return (s == 0); } - inline void resize(int size); - inline void clear() { resize(0); } - - inline int capacity() const { return a; } - inline void reserve(int size); - - inline T &operator[](int idx) { - Q_ASSERT(idx >= 0 && idx < s); - return ptr[idx]; - } - inline const T &operator[](int idx) const { - Q_ASSERT(idx >= 0 && idx < s); - return ptr[idx]; - } - - inline const T &at(int idx) const { - Q_ASSERT(idx >= 0 && idx < s); - return ptr[idx]; - } - - inline const T &first() const { - return at(0); - } - - inline T& append() { - const int idx = s++; - if (s == a) - realloc(s, s<<1); - return ptr[idx]; - } - inline void append(const T &t) { - append() = t; - } - - inline T& insert(int idx) { - Q_ASSERT(idx >= 0 && idx <= s); const int sz = s++; if (s == a) - realloc(s, s<<1); + realloc(s, s << 1); ::memmove(ptr + idx + 1, ptr + idx, (sz - idx) * sizeof(T)); - return ptr[idx]; - } - inline void insert(int idx, const T &t) { - insert(idx) = t; + ptr[idx] = t; } - inline void removeAt(int idx) { - Q_ASSERT(idx >= 0 && idx < s); - ::memmove(ptr + idx, ptr + idx + 1, (s - idx - 1) * sizeof(T)); - --s; - } - - inline void removeAll(const T &t) { + inline void removeAll(const T &t) + { int i = 0; for (int j = 0; j < s; ++j) { if (ptr[j] != t) @@ -152,110 +92,22 @@ public: s = i; } - inline int indexOf(const T &t, int from = 0) const { - if (from < 0) - from = qMax(from + s, 0); - if (from < s) { - const T *n = ptr + from - 1; - const T *e = ptr + s; - while (++n != e) - if (*n == t) - return n - ptr; - } - return -1; - } - - inline bool contains(const T &t) const { - return indexOf(t) >= 0; + inline void removeAt(int idx) + { + Q_ASSERT(idx >= 0 && idx < s); + ::memmove(ptr + idx, ptr + idx + 1, (s - idx - 1) * sizeof(T)); + --s; } - inline T takeFirst() { + inline T takeFirst() + { Q_ASSERT(s > 0); T tmp = ptr[0]; removeAt(0); return tmp; } - - inline T *data() { return ptr; } - inline const T *data() const { return ptr; } - inline const T * constData() const { return ptr; } - -private: - void append(const T *buf, int size); - void realloc(int size, int alloc); - - int a; - int s; - T *ptr; - union { - // ### Qt 5: Use 'Prealloc * sizeof(T)' as array size - char array[sizeof(qint64) * (((Prealloc * sizeof(T)) / sizeof(qint64)) + 1)]; - qint64 q_for_alignment_1; - double q_for_alignment_2; - }; }; -template <class T, int Prealloc> -Q_INLINE_TEMPLATE QPodList<T, Prealloc>::QPodList(int asize) - : s(asize) { - if (s > Prealloc) { - ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T))); - a = s; - } else { - ptr = reinterpret_cast<T *>(array); - a = Prealloc; - } -} - -template <class T, int Prealloc> -Q_INLINE_TEMPLATE void QPodList<T, Prealloc>::resize(int asize) -{ realloc(asize, qMax(asize, a)); } - -template <class T, int Prealloc> -Q_INLINE_TEMPLATE void QPodList<T, Prealloc>::reserve(int asize) -{ if (asize > a) realloc(s, asize); } - -template <class T, int Prealloc> -Q_OUTOFLINE_TEMPLATE void QPodList<T, Prealloc>::append(const T *abuf, int asize) -{ - Q_ASSERT(abuf); - if (asize <= 0) - return; - - const int idx = s; - const int news = s + asize; - if (news >= a) - realloc(news, news<<1); - else - s = news; - - qMemCopy(&ptr[idx], abuf, asize * sizeof(T)); -} - -template <class T, int Prealloc> -Q_OUTOFLINE_TEMPLATE void QPodList<T, Prealloc>::realloc(int asize, int aalloc) -{ - Q_ASSERT(aalloc >= asize); - T *oldPtr = ptr; - int osize = s; - s = asize; - - if (aalloc != a) { - ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T))); - if (ptr) { - a = aalloc; - qMemCopy(ptr, oldPtr, osize * sizeof(T)); - } else { - ptr = oldPtr; - s = 0; - asize = 0; - } - } - - if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr) - qFree(oldPtr); -} - QT_END_NAMESPACE QT_END_HEADER diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp index e1c3921..f357956 100644 --- a/src/corelib/tools/qregexp.cpp +++ b/src/corelib/tools/qregexp.cpp @@ -1297,14 +1297,20 @@ void QRegExpMatchState::prepareForMatch(QRegExpEngine *eng) int ns = eng->s.size(); // number of states int ncap = eng->ncap; #ifndef QT_NO_REGEXP_OPTIM - slideTabSize = qMax(eng->minl + 1, 16); + int newSlideTabSize = qMax(eng->minl + 1, 16); #else - slideTabSize = 0; + int newSlideTabSize = 0; #endif int numCaptures = eng->numCaptures(); - capturedSize = 2 + 2 * numCaptures; - bigArray = (int *)realloc(bigArray, ((3 + 4 * ncap) * ns + 4 * ncap + slideTabSize + capturedSize)*sizeof(int)); + int newCapturedSize = 2 + 2 * numCaptures; + bigArray = (int *)realloc(bigArray, ((3 + 4 * ncap) * ns + 4 * ncap + newSlideTabSize + newCapturedSize)*sizeof(int)); + Q_CHECK_PTR(bigArray); + // set all internal variables only _after_ bigArray is realloc'ed + // to prevent a broken regexp in oom case + + slideTabSize = newSlideTabSize; + capturedSize = newCapturedSize; inNextStack = bigArray; memset(inNextStack, -1, ns * sizeof(int)); curStack = inNextStack + ns; @@ -3281,10 +3287,15 @@ static void derefEngine(QRegExpEngine *eng, const QRegExpEngineKey &key) #if !defined(QT_NO_REGEXP_OPTIM) if (globalEngineCache()) { QMutexLocker locker(mutex()); - globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4); - } - else + QT_TRY { + globalEngineCache()->insert(key, eng, 4 + key.pattern.length() / 4); + } QT_CATCH(const std::bad_alloc &) { + // in case of an exception (e.g. oom), just delete the engine + delete eng; + } + } else { delete eng; + } #else Q_UNUSED(key); delete eng; diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h index 3a0901d..ac33353 100644 --- a/src/corelib/tools/qringbuffer_p.h +++ b/src/corelib/tools/qringbuffer_p.h @@ -199,9 +199,8 @@ public: inline void clear() { if(!buffers.isEmpty()) { - QByteArray tmp = buffers[0]; - buffers.clear(); - buffers << tmp; + // remove all but the first + buffers.erase(buffers.begin() + 1, buffers.end()); if (buffers.at(0).size() != basicBlockSize) buffers[0].resize(basicBlockSize); } diff --git a/src/corelib/tools/qscopedpointer.cpp b/src/corelib/tools/qscopedpointer.cpp new file mode 100644 index 0000000..8150a18 --- /dev/null +++ b/src/corelib/tools/qscopedpointer.cpp @@ -0,0 +1,132 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the $MODULE$ of the Qt Toolkit. +** +** $TROLLTECH_DUAL_LICENSE$ +** +****************************************************************************/ + +/*! + \class QScopedPointer + \brief The QScopedPointer class stores a pointer to a dynamically allocated object, and deletes it upon destruction. + \since 4.6 + \reentrant + \ingroup misc + + Managing heap allocated objects manually is hard and error prone, with the + common result that code leaks memory and is hard to maintain. + QScopedPointer is a small utility class that heavily simplifies this by + assigning stack-based memory ownership to heap allocations, more generally + called resource acquisition is initialization(RAII). + + QScopedPointer guarantees that the object pointed to will get deleted when + the current scope dissapears, and it also has no way of releasing + ownership, hence clearly communicating the lifetime and ownership of the + object. These guarantees are convenient when reading the code. + + Consider this function which does heap allocations, and have various exit points: + + \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 0 + + It's encumbered by the manual delete calls. With QScopedPointer, the code + can be simplified to: + + \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 1 + + The code the compiler generates for QScopedPointer is the same as when + writing it manually. Code that makes use of \a delete are candidates for + QScopedPointer usage(and if not, possibly another type of smart pointer + such as QSharedPointer). QScopedPointer intentionally has no copy + constructor or assignment operator, such that ownership and lifetime is + clearly communicated. + + The const qualification on a regular C++ pointer can also be expressed with + a QScopedPointer: + + \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 2 + + \note QScopedPointer does not work with arrays. + + \sa QSharedPointer +*/ + +/*! + \fn QScopedPointer::QScopedPointer(T *p = 0) + + Constructs this QScopedPointer instance and sets its pointer to \a p. +*/ + +/*! + \fn QScopedPointer::~QScopedPointer() + + Destroys this QScopedPointer object. Delete the object its pointer points + to. +*/ + +/*! + \fn T *QScopedPointer::data() const + + Returns the value of the pointer referenced by this object. QScopedPointer + still owns the object pointed to. +*/ + +/*! + \fn T &QScopedPointer::operator*() const + + Provides access to the scoped pointer's object. + + If the contained pointer is \c null, behavior is undefined. + \sa isNull() +*/ + +/*! + \fn T *QScopedPointer::operator->() const + + Provides access to the scoped pointer's object. + + If the contained pointer is \c null, behavior is undefined. + + \sa isNull() +*/ + +/*! + \fn QScopedPointer::operator bool() const + + Returns \c true if this object is not \c null. This function is suitable + for use in \tt if-constructs, like: + + \snippet doc/src/snippets/code/src_corelib_tools_qscopedpointer.cpp 3 + + \sa isNull() +*/ + +/*! + \fn bool QScopedPointer::isNull() const + + Returns \c true if this object is holding a pointer that is \c null. +*/ + +/*! + \fn void QScopedPointer::reset(T *other = 0) + + Deletes the existing object its pointing to if any, and sets its pointer to + \a other. QScopedPointer now owns \a other and will delete it in its + destructor. + + If \a other is equal to the value returned by data(), behavior is + undefined. +*/ + +/*! + \fn T *QScopedPointer::take() + + Returns the value of the pointer referenced by this object. The pointer of this + QScopedPointer object will be reset to \c null. +*/ + +QT_END_NAMESPACE + +#endif diff --git a/src/corelib/tools/qscopedpointer.h b/src/corelib/tools/qscopedpointer.h new file mode 100644 index 0000000..fc8f9e2 --- /dev/null +++ b/src/corelib/tools/qscopedpointer.h @@ -0,0 +1,199 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSCOPEDPOINTER_H +#define QSCOPEDPOINTER_H + +#include <QtCore/qglobal.h> + +QT_BEGIN_HEADER +QT_BEGIN_NAMESPACE +QT_MODULE(Core) + +template <typename T> +class QScopedPointer +{ +public: + explicit inline QScopedPointer(T *p = 0) : d(p) + { + } + + inline ~QScopedPointer() + { + delete d; + } + + inline T &operator*() const + { + return *d; + } + + inline T *operator->() const + { + return d; + } + + inline bool operator==(const QScopedPointer<T> &other) const + { + return d == other.d; + } + + inline bool operator!=(const QScopedPointer<T> &other) const + { + return d != other.d; + } + + inline operator bool() const + { + return d; + } + + inline T *data() const + { + return d; + } + + inline bool isNull() const + { + return !d; + } + + inline void reset(T *other = 0) + { + T *oldD = d; + d = other; + delete oldD; + } + + inline T *take() + { + T *oldD = d; + d = 0; + return oldD; + } + +protected: + T *d; + +private: + Q_DISABLE_COPY(QScopedPointer) +}; + +/* internal class - allows special handling for resetting and cleaning the pointer */ +template <typename T, typename CustomHandler> +class QScopedCustomPointer : public QScopedPointer<T> +{ +public: + inline QScopedCustomPointer(T *p = 0) + : QScopedPointer<T>(p) + { + } + + inline ~QScopedCustomPointer() + { + T *oldD = this->d; + this->d = 0; + CustomHandler::cleanup(oldD); + } + + inline void reset(T *other = 0) + { + CustomHandler::reset(this->d, other); + } + + inline T *&data_ptr() + { + return this->d; + } +}; + +/* Internal helper class - a handler for QShared* classes, to be used in QScopedCustomPointer */ +template <typename T> +class QScopedSharedPointerHandler +{ +public: + static inline void cleanup(T *d) + { + if (d && !d->ref.deref()) + delete d; + } + + static inline void reset(T *&d, T *other) + { + T *oldD = d; + d = other; + cleanup(oldD); + } +}; + +/* Internal. This should really have been a typedef, but you can't have a templated typedef :) + This class is basically a scoped pointer pointing to a ref-counted object + */ +template <typename T> +class QScopedSharedPointer : public QScopedCustomPointer<T, QScopedSharedPointerHandler<T> > +{ +public: + inline QScopedSharedPointer(T *p = 0) + : QScopedCustomPointer<T, QScopedSharedPointerHandler<T> >(p) + { + } + + inline void detach() + { + qAtomicDetach(this->d); + } + + inline void assign(T *other) + { + if (this->d == other) + return; + if (other) + other->ref.ref(); + T *oldD = this->d; + this->d = other; + QScopedSharedPointerHandler<T>::cleanup(oldD); + } +}; + +QT_END_NAMESPACE +QT_END_HEADER + +#endif // QSCOPEDPOINTER_H diff --git a/src/corelib/tools/qshareddata.cpp b/src/corelib/tools/qshareddata.cpp index 2b879ea..03bc964 100644 --- a/src/corelib/tools/qshareddata.cpp +++ b/src/corelib/tools/qshareddata.cpp @@ -231,7 +231,7 @@ QT_BEGIN_NAMESPACE In the member function documentation, \e{d pointer} always refers to the internal pointer to the shared data object. - \sa QSharedData, QExplicitlySharedDataPointer + \sa QSharedData, QExplicitlySharedDataPointer, QScopedPointer, QSharedPointer */ /*! \fn T& QSharedDataPointer::operator*() diff --git a/src/corelib/tools/qsharedpointer.cpp b/src/corelib/tools/qsharedpointer.cpp index c3a989e..dee06f0 100644 --- a/src/corelib/tools/qsharedpointer.cpp +++ b/src/corelib/tools/qsharedpointer.cpp @@ -102,13 +102,18 @@ except that it only detaches if QExplicitlySharedDataPointer::detach() is explicitly called. + QScopedPointer simply holds a pointer to a heap allocated object and + deletes it in its destructor. This class is useful when an object needs to + be heap allocated and deleted, but no more. QScopedPointer is lightweight, + it makes no use of additional structure or reference counting. + Finally, QPointer holds a pointer to a QObject-derived object, but it does so weakly. QPointer is similar, in that behaviour, to QWeakPointer: it does not allow you to prevent the object from being destroyed. All you can do is query whether it has been destroyed or not. - \sa QSharedDataPointer, QWeakPointer + \sa QSharedDataPointer, QWeakPointer, QScopedPointer */ /*! @@ -130,7 +135,7 @@ must first create a QSharedPointer object and verify if the pointer is null or not. - \sa QSharedPointer + \sa QSharedPointer, QScopedPointer */ /*! diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index c3649e3..e61a568 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -846,6 +846,7 @@ QString::QString(const QChar *unicode, int size) 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; @@ -869,6 +870,7 @@ QString::QString(int size, QChar ch) 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; @@ -894,7 +896,9 @@ QString::QString(int size, QChar ch) */ QString::QString(QChar ch) { - d = (Data *)qMalloc(sizeof(Data) + sizeof(QChar)); + void *buf = qMalloc(sizeof(Data) + sizeof(QChar)); + Q_CHECK_PTR(buf); + d = reinterpret_cast<Data *>(buf); d->ref = 1; d->alloc = d->size = 1; d->clean = d->asciiCache = d->simpletext = d->righttoleft = d->capacity = 0; @@ -1064,8 +1068,7 @@ void QString::realloc(int alloc) { if (d->ref != 1 || d->data != d->array) { Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + alloc * sizeof(QChar))); - if (!x) - return; + Q_CHECK_PTR(x); x->size = qMin(alloc, d->size); ::memcpy(x->array, d->data, x->size * sizeof(QChar)); x->array[x->size] = 0; @@ -1088,8 +1091,7 @@ void QString::realloc(int alloc) } #endif Data *x = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar))); - if (!x) - return; + Q_CHECK_PTR(x); x->alloc = alloc; x->data = x->array; d = x; @@ -1246,6 +1248,7 @@ QString& QString::insert(int i, const QChar *unicode, int size) if (s >= d->data && s < d->data + d->alloc) { // Part of me - take a copy ushort *tmp = static_cast<ushort *>(qMalloc(size * sizeof(QChar))); + Q_CHECK_PTR(tmp); memcpy(tmp, s, size * sizeof(QChar)); insert(i, reinterpret_cast<const QChar *>(tmp), size); qFree(tmp); @@ -1600,51 +1603,69 @@ QString &QString::replace(const QString &before, const QString &after, Qt::CaseS */ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar *after, int alen) { - if (blen == alen) { - detach(); - for (int i = 0; i < nIndices; ++i) - memcpy(d->data + indices[i], after, alen * sizeof(QChar)); - } else if (alen < blen) { + // copy *after in case it lies inside our own d->data area + // (which we could possibly invalidate via a realloc or corrupt via memcpy operations.) + QChar *afterBuffer = const_cast<QChar *>(after); + if (after >= reinterpret_cast<QChar *>(d->data) && after < reinterpret_cast<QChar *>(d->data) + d->size) { + afterBuffer = static_cast<QChar *>(qMalloc(alen*sizeof(QChar))); + Q_CHECK_PTR(afterBuffer); + ::memcpy(afterBuffer, after, alen*sizeof(QChar)); + } + + QT_TRY { detach(); - uint to = indices[0]; - if (alen) - memcpy(d->data+to, after, alen*sizeof(QChar)); - to += alen; - uint movestart = indices[0] + blen; - for (int i = 1; i < nIndices; ++i) { - int msize = indices[i] - movestart; - if (msize > 0) { - memmove(d->data + to, d->data + movestart, msize * sizeof(QChar)); - to += msize; + if (blen == alen) { + // replace in place + for (int i = 0; i < nIndices; ++i) + memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar)); + } else if (alen < blen) { + // replace from front + uint to = indices[0]; + if (alen) + memcpy(d->data+to, after, alen*sizeof(QChar)); + to += alen; + uint movestart = indices[0] + blen; + for (int i = 1; i < nIndices; ++i) { + int msize = indices[i] - movestart; + if (msize > 0) { + memmove(d->data + to, d->data + movestart, msize * sizeof(QChar)); + to += msize; + } + if (alen) { + memcpy(d->data + to, afterBuffer, alen*sizeof(QChar)); + to += alen; + } + movestart = indices[i] + blen; } - if (alen) { - memcpy(d->data + to, after, alen*sizeof(QChar)); - to += alen; + int msize = d->size - movestart; + if (msize > 0) + memmove(d->data + to, d->data + movestart, msize * sizeof(QChar)); + resize(d->size - nIndices*(blen-alen)); + } else { + // replace from back + int adjust = nIndices*(alen-blen); + int newLen = d->size + adjust; + int moveend = d->size; + resize(newLen); + + while (nIndices) { + --nIndices; + int movestart = indices[nIndices] + blen; + int insertstart = indices[nIndices] + nIndices*(alen-blen); + int moveto = insertstart + alen; + memmove(d->data + moveto, d->data + movestart, + (moveend - movestart)*sizeof(QChar)); + memcpy(d->data + insertstart, afterBuffer, alen*sizeof(QChar)); + moveend = movestart-blen; } - movestart = indices[i] + blen; - } - int msize = d->size - movestart; - if (msize > 0) - memmove(d->data + to, d->data + movestart, msize * sizeof(QChar)); - resize(d->size - nIndices*(blen-alen)); - } else { - // we have a table of replacement positions, use them for fast replacing - int adjust = nIndices*(alen-blen); - int newLen = d->size + adjust; - int moveend = d->size; - resize(newLen); - - while (nIndices) { - --nIndices; - int movestart = indices[nIndices] + blen; - int insertstart = indices[nIndices] + nIndices*(alen-blen); - int moveto = insertstart + alen; - memmove(d->data + moveto, d->data + movestart, - (moveend - movestart)*sizeof(QChar)); - memcpy(d->data + insertstart, after, alen*sizeof(QChar)); - moveend = movestart-blen; } + } QT_CATCH(const std::bad_alloc &) { + if (afterBuffer != after) + qFree(afterBuffer); + QT_RETHROW; } + if (afterBuffer != after) + qFree(afterBuffer); } /*! @@ -1672,21 +1693,7 @@ QString &QString::replace(const QChar *before, int blen, if (alen == 0 && blen == 0) return *this; - // protect against before or after being part of this - const QChar *a = after; - const QChar *b = before; - if (after >= (const QChar *)d->data && after < (const QChar *)d->data + d->size) { - QChar *copy = (QChar *)malloc(alen*sizeof(QChar)); - memcpy(copy, after, alen*sizeof(QChar)); - a = copy; - } - if (before >= (const QChar *)d->data && before < (const QChar *)d->data + d->size) { - QChar *copy = (QChar *)malloc(blen*sizeof(QChar)); - memcpy(copy, before, blen*sizeof(QChar)); - b = copy; - } - - QStringMatcher matcher(b, blen, cs); + QStringMatcher matcher(before, blen, cs); int index = 0; while (1) { @@ -1705,7 +1712,7 @@ QString &QString::replace(const QChar *before, int blen, if (!pos) break; - replace_helper(indices, pos, blen, a, alen); + replace_helper(indices, pos, blen, after, alen); if (index == -1) break; @@ -1713,11 +1720,6 @@ QString &QString::replace(const QChar *before, int blen, index += pos*(alen-blen); } - if (a != after) - ::free((QChar *)a); - if (b != before) - ::free((QChar *)b); - return *this; } @@ -3450,6 +3452,7 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size) if (size < 0) size = qstrlen(str); d = static_cast<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; @@ -3457,7 +3460,7 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size) ushort *i = d->data; d->array[size] = '\0'; while (size--) - *i++ = (uchar)*str++; + *i++ = (uchar)*str++; } return d; } @@ -6867,6 +6870,7 @@ void QString::updateProperties() const QString QString::fromRawData(const QChar *unicode, int size) { Data *x = static_cast<Data *>(qMalloc(sizeof(Data))); + Q_CHECK_PTR(x); if (unicode) { x->data = (ushort *)unicode; } else { diff --git a/src/corelib/tools/qtextboundaryfinder.cpp b/src/corelib/tools/qtextboundaryfinder.cpp index 8a8e95b..5ca6a11 100644 --- a/src/corelib/tools/qtextboundaryfinder.cpp +++ b/src/corelib/tools/qtextboundaryfinder.cpp @@ -176,6 +176,7 @@ QTextBoundaryFinder::QTextBoundaryFinder(const QTextBoundaryFinder &other) , freePrivate(true) { d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes)); + Q_CHECK_PTR(d); memcpy(d, other.d, length*sizeof(HB_CharAttributes)); } @@ -193,8 +194,11 @@ QTextBoundaryFinder &QTextBoundaryFinder::operator=(const QTextBoundaryFinder &o length = other.length; pos = other.pos; freePrivate = true; - - d = (QTextBoundaryFinderPrivate *) realloc(d, length*sizeof(HB_CharAttributes)); + + QTextBoundaryFinderPrivate *newD = (QTextBoundaryFinderPrivate *) + realloc(d, length*sizeof(HB_CharAttributes)); + Q_CHECK_PTR(newD); + d = newD; memcpy(d, other.d, length*sizeof(HB_CharAttributes)); return *this; @@ -221,6 +225,7 @@ QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QString &strin , freePrivate(true) { d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes)); + Q_CHECK_PTR(d); init(t, chars, length, d->attributes); } @@ -248,6 +253,7 @@ QTextBoundaryFinder::QTextBoundaryFinder(BoundaryType type, const QChar *chars, freePrivate = false; } else { d = (QTextBoundaryFinderPrivate *) malloc(length*sizeof(HB_CharAttributes)); + Q_CHECK_PTR(d); freePrivate = true; } init(t, chars, length, d->attributes); diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index e2f60ed..b41240e 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -52,6 +52,9 @@ QT_BEGIN_NAMESPACE QT_MODULE(Core) +template<class T, int Prealloc> +class QPodList; + // Prealloc = 256 by default, specified in qcontainerfwd.h template<class T, int Prealloc> class QVarLengthArray @@ -122,6 +125,7 @@ public: inline const T * constData() const { return ptr; } private: + friend class QPodList<T, Prealloc>; void realloc(int size, int alloc); int a; @@ -140,6 +144,7 @@ Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize) : s(asize) { if (s > Prealloc) { ptr = reinterpret_cast<T *>(qMalloc(s * sizeof(T))); + Q_CHECK_PTR(ptr); a = s; } else { ptr = reinterpret_cast<T *>(array); @@ -161,25 +166,24 @@ Q_INLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::reserve(int asize) { if (asize > a) realloc(s, asize); } template <class T, int Prealloc> -Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int asize) +Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::append(const T *abuf, int increment) { Q_ASSERT(abuf); - if (asize <= 0) + if (increment <= 0) return; - const int idx = s; - const int news = s + asize; - if (news >= a) - realloc(s, qMax(s<<1, news)); - s = news; + const int asize = s + increment; + + if (asize >= a) + realloc(s, qMax(s*2, asize)); if (QTypeInfo<T>::isComplex) { - T *i = ptr + idx; - T *j = i + asize; - while (i < j) - new (i++) T(*abuf++); + // call constructor for new objects (which can throw) + while (s < asize) + new (ptr+(s++)) T(*abuf++); } else { - qMemCopy(&ptr[idx], abuf, asize * sizeof(T)); + qMemCopy(&ptr[s], abuf, increment * sizeof(T)); + s = asize; } } @@ -189,46 +193,58 @@ Q_OUTOFLINE_TEMPLATE void QVarLengthArray<T, Prealloc>::realloc(int asize, int a Q_ASSERT(aalloc >= asize); T *oldPtr = ptr; int osize = s; - s = asize; + // s = asize; if (aalloc != a) { ptr = reinterpret_cast<T *>(qMalloc(aalloc * sizeof(T))); + Q_CHECK_PTR(ptr); if (ptr) { + s = 0; a = aalloc; if (QTypeInfo<T>::isStatic) { - T *i = ptr + osize; - T *j = oldPtr + osize; - while (i != ptr) { - new (--i) T(*--j); - j->~T(); + QT_TRY { + while (s < asize) { + new (ptr+s) T(*(oldPtr+s)); + (oldPtr+s)->~T(); + s++; + } + } QT_CATCH(...) { + // clean up all the old objects and then free the old ptr + int sClean = s; + while (sClean < osize) + (oldPtr+(sClean++))->~T(); + if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr) + qFree(oldPtr); + QT_RETHROW; } } else { - qMemCopy(ptr, oldPtr, osize * sizeof(T)); + qMemCopy(ptr, oldPtr, qMin(asize, osize) * sizeof(T)); + s = asize; } } else { ptr = oldPtr; - s = 0; - asize = 0; + return; } } if (QTypeInfo<T>::isComplex) { - if (asize < osize) { - T *i = oldPtr + osize; - T *j = oldPtr + asize; - while (i-- != j) - i->~T(); - } else { - T *i = ptr + asize; - T *j = ptr + osize; - while (i != j) - new (--i) T; - } + while (osize > asize) + (oldPtr+(--osize))->~T(); + if( oldPtr == ptr ) + s = osize; } if (oldPtr != reinterpret_cast<T *>(array) && oldPtr != ptr) qFree(oldPtr); + + if (QTypeInfo<T>::isComplex) { + // call default constructor for new objects (which can throw) + while (s < asize) + new (ptr+(s++)) T; + } else { + s = asize; + } } QT_END_NAMESPACE diff --git a/src/corelib/tools/qvector.cpp b/src/corelib/tools/qvector.cpp index 6b26b2e..04e9ace 100644 --- a/src/corelib/tools/qvector.cpp +++ b/src/corelib/tools/qvector.cpp @@ -50,6 +50,7 @@ QVectorData QVectorData::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1), 0, 0, tr QVectorData *QVectorData::malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init) { QVectorData* p = (QVectorData *)qMalloc(sizeofTypedData + (size - 1) * sizeofT); + Q_CHECK_PTR(p); ::memcpy(p, init, sizeofTypedData + (qMin(size, init->alloc) - 1) * sizeofT); return p; } diff --git a/src/corelib/tools/qvector.h b/src/corelib/tools/qvector.h index 1f047b8..610b8e7 100644 --- a/src/corelib/tools/qvector.h +++ b/src/corelib/tools/qvector.h @@ -77,6 +77,7 @@ struct Q_CORE_EXPORT QVectorData static QVectorData shared_null; // ### Qt 5: rename to 'allocate()'. The current name causes problems for // some debugges when the QVector is member of a class within an unnamed namespace. + // ### Qt 5: can be removed completely. (Ralf) static QVectorData *malloc(int sizeofTypedData, int size, int sizeofT, QVectorData *init); static int grow(int sizeofTypedData, int size, int sizeofT, bool excessive); }; @@ -379,7 +380,9 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v) template <typename T> inline QVectorData *QVector<T>::malloc(int aalloc) { - return static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + QVectorData *data = static_cast<QVectorData *>(qMalloc(sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + Q_CHECK_PTR(data); + return data; } template <typename T> @@ -428,74 +431,79 @@ void QVector<T>::free(Data *x) template <typename T> void QVector<T>::realloc(int asize, int aalloc) { - T *j, *i, *b; + T *pOld; + T *pNew; union { QVectorData *p; Data *d; } x; x.d = d; - if (QTypeInfo<T>::isComplex && aalloc == d->alloc && d->ref == 1) { - // pure resize - i = d->array + d->size; - j = d->array + asize; - if (i > j) { - while (i-- != j) - i->~T(); - } else { - while (j-- != i) - new (j) T; + if (QTypeInfo<T>::isComplex && asize < d->size && d->ref == 1 ) { + // call the destructor on all objects that need to be + // destroyed when shrinking + pOld = d->array + d->size; + pNew = d->array + asize; + while (asize < d->size) { + (--pOld)->~T(); + d->size--; } - d->size = asize; - return; } if (aalloc != d->alloc || d->ref != 1) { // (re)allocate memory if (QTypeInfo<T>::isStatic) { x.p = malloc(aalloc); + Q_CHECK_PTR(x.p); + x.d->size = 0; } else if (d->ref != 1) { - x.p = QVectorData::malloc(sizeOfTypedData(), aalloc, sizeof(T), p); - } else { + x.p = malloc(aalloc); + Q_CHECK_PTR(x.p); if (QTypeInfo<T>::isComplex) { - // call the destructor on all objects that need to be - // destroyed when shrinking - if (asize < d->size) { - j = d->array + asize; - i = d->array + d->size; - while (i-- != j) - i->~T(); - i = d->array + asize; - } + x.d->size = 0; + } else { + ::memcpy(x.p, p, sizeOfTypedData() + (qMin(aalloc, p->alloc) - 1) * sizeof(T)); + x.d->size = d->size; + } + } else { + QT_TRY { + QVectorData *mem = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T))); + Q_CHECK_PTR(mem); + x.p = p = mem; + x.d->size = d->size; + } QT_CATCH (const std::bad_alloc &) { + if (aalloc > d->alloc) // ignore the error in case we are just shrinking. + QT_RETHROW; } - x.p = p = static_cast<QVectorData *>(qRealloc(p, sizeOfTypedData() + (aalloc - 1) * sizeof(T))); } x.d->ref = 1; + x.d->alloc = aalloc; x.d->sharable = true; x.d->capacity = d->capacity; - } + if (QTypeInfo<T>::isComplex) { - if (asize < d->size) { - j = d->array + asize; - i = x.d->array + asize; - } else { - // construct all new objects when growing - i = x.d->array + asize; - j = x.d->array + d->size; - while (i != j) - new (--i) T; - j = d->array + d->size; - } - if (i != j) { + QT_TRY { + pOld = d->array + x.d->size; + pNew = x.d->array + x.d->size; // copy objects from the old array into the new array - b = x.d->array; - while (i != b) - new (--i) T(*--j); + while (x.d->size < qMin(asize, d->size)) { + new (pNew++) T(*pOld++); + x.d->size++; + } + // construct all new objects when growing + while (x.d->size < asize) { + new (pNew++) T; + x.d->size++; + } + } QT_CATCH (...) { + free(x.d); + QT_RETHROW; } - } else if (asize > d->size) { + + } else if (asize > x.d->size) { // initialize newly allocated memory to 0 - qMemSet(x.d->array + d->size, 0, (asize - d->size) * sizeof(T)); + qMemSet(x.d->array + x.d->size, 0, (asize - x.d->size) * sizeof(T)); } x.d->size = asize; - x.d->alloc = aalloc; + if (d != x.d) { if (!d->ref.deref()) free(d); diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri index c2381ce..8d27100 100644 --- a/src/corelib/tools/tools.pri +++ b/src/corelib/tools/tools.pri @@ -36,7 +36,8 @@ HEADERS += \ tools/qtimeline.h \ tools/qunicodetables_p.h \ tools/qvarlengtharray.h \ - tools/qvector.h + tools/qvector.h \ + tools/qscopedpointer.h SOURCES += \ diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp index ff1a01f..6fe6ebf 100644 --- a/src/corelib/xml/qxmlstream.cpp +++ b/src/corelib/xml/qxmlstream.cpp @@ -429,7 +429,6 @@ QXmlStreamReader::~QXmlStreamReader() Q_D(QXmlStreamReader); if (d->deleteDevice) delete d->device; - delete d; } /*! \fn bool QXmlStreamReader::hasError() const @@ -819,7 +818,9 @@ inline void QXmlStreamReaderPrivate::reallocateStack() { stack_size <<= 1; sym_stack = reinterpret_cast<Value*> (qRealloc(sym_stack, stack_size * sizeof(Value))); + Q_CHECK_PTR(sym_stack); state_stack = reinterpret_cast<int*> (qRealloc(state_stack, stack_size * sizeof(int))); + Q_CHECK_PTR(sym_stack); } @@ -3131,8 +3132,6 @@ QXmlStreamWriter::QXmlStreamWriter(QString *string) */ QXmlStreamWriter::~QXmlStreamWriter() { - Q_D(QXmlStreamWriter); - delete d; } diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h index 2ba7972..6903d56 100644 --- a/src/corelib/xml/qxmlstream.h +++ b/src/corelib/xml/qxmlstream.h @@ -48,6 +48,7 @@ #include <QtCore/QString> #include <QtCore/QVector> +#include <QtCore/QScopedPointer> QT_BEGIN_HEADER @@ -392,7 +393,7 @@ public: private: Q_DISABLE_COPY(QXmlStreamReader) Q_DECLARE_PRIVATE(QXmlStreamReader) - QXmlStreamReaderPrivate *d_ptr; + QScopedPointer<QXmlStreamReaderPrivate> d_ptr; }; #endif // QT_NO_XMLSTREAMREADER @@ -465,7 +466,7 @@ public: private: Q_DISABLE_COPY(QXmlStreamWriter) Q_DECLARE_PRIVATE(QXmlStreamWriter) - QXmlStreamWriterPrivate *d_ptr; + QScopedPointer<QXmlStreamWriterPrivate> d_ptr; }; #endif // QT_NO_XMLSTREAMWRITER diff --git a/src/dbus/qdbusabstractadaptor.cpp b/src/dbus/qdbusabstractadaptor.cpp index 883aabf..350f1aa 100644 --- a/src/dbus/qdbusabstractadaptor.cpp +++ b/src/dbus/qdbusabstractadaptor.cpp @@ -264,7 +264,7 @@ void QDBusAdaptorConnector::polish() void QDBusAdaptorConnector::relaySlot(void **argv) { - QObjectPrivate *d = static_cast<QObjectPrivate *>(d_ptr); + QObjectPrivate *d = static_cast<QObjectPrivate *>(d_ptr.data()); relay(d->currentSender->sender, d->currentSender->signal, argv); } diff --git a/src/dbus/qdbuscontext.h b/src/dbus/qdbuscontext.h index 3d043cf..6ece5b6 100644 --- a/src/dbus/qdbuscontext.h +++ b/src/dbus/qdbuscontext.h @@ -74,7 +74,7 @@ public: private: QDBusContextPrivate *d_ptr; - Q_DECLARE_PRIVATE(QDBusContext) + friend class QDBusContextPrivate; }; QT_END_NAMESPACE diff --git a/src/gui/dialogs/dialogs.pri b/src/gui/dialogs/dialogs.pri index 92347a7..b9fad41 100644 --- a/src/gui/dialogs/dialogs.pri +++ b/src/gui/dialogs/dialogs.pri @@ -7,6 +7,7 @@ HEADERS += \ dialogs/qabstractpagesetupdialog_p.h \ dialogs/qcolordialog.h \ dialogs/qcolordialog_p.h \ + dialogs/qfscompleter_p.h \ dialogs/qdialog.h \ dialogs/qdialog_p.h \ dialogs/qerrormessage.h \ diff --git a/src/gui/dialogs/qdialog.cpp b/src/gui/dialogs/qdialog.cpp index ef562f4..cecbb87 100644 --- a/src/gui/dialogs/qdialog.cpp +++ b/src/gui/dialogs/qdialog.cpp @@ -296,9 +296,13 @@ QDialog::QDialog(QDialogPrivate &dd, QWidget *parent, Qt::WindowFlags f) QDialog::~QDialog() { - // Need to hide() here, as our (to-be) overridden hide() - // will not be called in ~QWidget. - hide(); + QT_TRY { + // Need to hide() here, as our (to-be) overridden hide() + // will not be called in ~QWidget. + hide(); + } QT_CATCH(...) { + // we're in the destructor - just swallow the exception + } } /*! diff --git a/src/gui/dialogs/qfiledialog.cpp b/src/gui/dialogs/qfiledialog.cpp index aab79d0..60d3034 100644 --- a/src/gui/dialogs/qfiledialog.cpp +++ b/src/gui/dialogs/qfiledialog.cpp @@ -356,7 +356,6 @@ QFileDialog::~QFileDialog() settings.beginGroup(QLatin1String("Qt")); settings.setValue(QLatin1String("filedialog"), saveState()); #endif - delete d->qFileDialogUi; d->deleteNativeDialog_sys(); } @@ -488,6 +487,10 @@ void QFileDialog::changeEvent(QEvent *e) QDialog::changeEvent(e); } +QFileDialogPrivate::~QFileDialogPrivate() +{ +} + void QFileDialogPrivate::retranslateWindowTitle() { Q_Q(QFileDialog); @@ -2121,7 +2124,7 @@ void QFileDialogPrivate::createWidgets() q, SLOT(_q_rowsInserted(const QModelIndex &))); model->setReadOnly(false); - qFileDialogUi = new Ui_QFileDialog(); + qFileDialogUi.reset(new Ui_QFileDialog()); qFileDialogUi->setupUi(q); QList<QUrl> initialBookmarks; @@ -2147,7 +2150,7 @@ void QFileDialogPrivate::createWidgets() qFileDialogUi->fileNameLabel->setBuddy(qFileDialogUi->fileNameEdit); #endif #ifndef QT_NO_COMPLETER - completer = new QFSCompletor(model, q); + completer = new QFSCompleter(model, q); qFileDialogUi->fileNameEdit->setCompleter(completer); QObject::connect(qFileDialogUi->fileNameEdit, SIGNAL(textChanged(QString)), q, SLOT(_q_autoCompleteFileName(QString))); @@ -2205,9 +2208,9 @@ void QFileDialogPrivate::createWidgets() treeHeader->addAction(showHeader); } - QItemSelectionModel *selModel = qFileDialogUi->treeView->selectionModel(); + QScopedPointer<QItemSelectionModel> selModel(qFileDialogUi->treeView->selectionModel()); qFileDialogUi->treeView->setSelectionModel(qFileDialogUi->listView->selectionModel()); - delete selModel; + QObject::connect(qFileDialogUi->treeView, SIGNAL(activated(QModelIndex)), q, SLOT(_q_enterDirectory(QModelIndex))); QObject::connect(qFileDialogUi->treeView, SIGNAL(customContextMenuRequested(QPoint)), @@ -2289,9 +2292,9 @@ void QFileDialog::setProxyModel(QAbstractProxyModel *proxyModel) connect(d->model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(_q_rowsInserted(const QModelIndex &))); } - QItemSelectionModel *selModel = d->qFileDialogUi->treeView->selectionModel(); + QScopedPointer<QItemSelectionModel> selModel(d->qFileDialogUi->treeView->selectionModel()); d->qFileDialogUi->treeView->setSelectionModel(d->qFileDialogUi->listView->selectionModel()); - delete selModel; + d->setRootIndex(idx); // reconnect selection @@ -3172,7 +3175,7 @@ void QFileDialogLineEdit::keyPressEvent(QKeyEvent *e) #ifndef QT_NO_COMPLETER -QString QFSCompletor::pathFromIndex(const QModelIndex &index) const +QString QFSCompleter::pathFromIndex(const QModelIndex &index) const { const QFileSystemModel *dirModel; if (proxyModel) @@ -3187,7 +3190,7 @@ QString QFSCompletor::pathFromIndex(const QModelIndex &index) const return index.data(QFileSystemModel::FilePathRole).toString(); } -QStringList QFSCompletor::splitPath(const QString &path) const +QStringList QFSCompleter::splitPath(const QString &path) const { if (path.isEmpty()) return QStringList(completionPrefix()); diff --git a/src/gui/dialogs/qfiledialog_p.h b/src/gui/dialogs/qfiledialog_p.h index de7e332..99f61f0 100644 --- a/src/gui/dialogs/qfiledialog_p.h +++ b/src/gui/dialogs/qfiledialog_p.h @@ -76,6 +76,7 @@ #include <qtimeline.h> #include <qdebug.h> #include "qsidebar_p.h" +#include "qfscompleter_p.h" #if defined (Q_OS_UNIX) #include <unistd.h> @@ -91,25 +92,6 @@ class QCompleter; class QHBoxLayout; class Ui_QFileDialog; -#ifndef QT_NO_COMPLETER -/*! - QCompleter that can deal with QFileSystemModel - */ -class QFSCompletor : public QCompleter { -public: - QFSCompletor(QFileSystemModel *model, QObject *parent = 0) : QCompleter(model, parent), proxyModel(0), sourceModel(model) - { -#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) - setCaseSensitivity(Qt::CaseInsensitive); -#endif - } - QString pathFromIndex(const QModelIndex &index) const; - QStringList splitPath(const QString& path) const; - - QAbstractProxyModel *proxyModel; - QFileSystemModel *sourceModel; -}; -#endif // QT_NO_COMPLETER struct QFileDialogArgs { @@ -275,7 +257,7 @@ public: // data QStringList watching; QFileSystemModel *model; - QFSCompletor *completer; + QFSCompleter *completer; QFileDialog::FileMode fileMode; QFileDialog::AcceptMode acceptMode; @@ -357,7 +339,7 @@ public: void mac_nativeDialogModalHelp(); #endif - Ui_QFileDialog *qFileDialogUi; + QScopedPointer<Ui_QFileDialog> qFileDialogUi; QString acceptLabel; @@ -366,6 +348,11 @@ public: QByteArray signalToDisconnectOnClose; QFileDialog::Options opts; + + ~QFileDialogPrivate(); + +private: + Q_DISABLE_COPY(QFileDialogPrivate) }; class QFileDialogLineEdit : public QLineEdit diff --git a/src/gui/dialogs/qfileinfogatherer.cpp b/src/gui/dialogs/qfileinfogatherer.cpp index a2abe54..119164d 100644 --- a/src/gui/dialogs/qfileinfogatherer.cpp +++ b/src/gui/dialogs/qfileinfogatherer.cpp @@ -83,10 +83,10 @@ QFileInfoGatherer::QFileInfoGatherer(QObject *parent) */ QFileInfoGatherer::~QFileInfoGatherer() { - mutex.lock(); + QMutexLocker locker(&mutex); abort = true; condition.wakeOne(); - mutex.unlock(); + locker.unlock(); wait(); } @@ -94,9 +94,8 @@ void QFileInfoGatherer::setResolveSymlinks(bool enable) { Q_UNUSED(enable); #ifdef Q_OS_WIN - mutex.lock(); + QMutexLocker locker(&mutex); m_resolveSymlinks = enable; - mutex.unlock(); #endif } @@ -107,9 +106,8 @@ bool QFileInfoGatherer::resolveSymlinks() const void QFileInfoGatherer::setIconProvider(QFileIconProvider *provider) { - mutex.lock(); + QMutexLocker locker(&mutex); m_iconProvider = provider; - mutex.unlock(); } QFileIconProvider *QFileInfoGatherer::iconProvider() const @@ -124,12 +122,11 @@ QFileIconProvider *QFileInfoGatherer::iconProvider() const */ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStringList &files) { - mutex.lock(); + QMutexLocker locker(&mutex); // See if we already have this dir/file in our que int loc = this->path.lastIndexOf(path); while (loc > 0) { if (this->files.at(loc) == files) { - mutex.unlock(); return; } loc = this->path.lastIndexOf(path, loc - 1); @@ -137,7 +134,6 @@ void QFileInfoGatherer::fetchExtendedInformation(const QString &path, const QStr this->path.push(path); this->files.push(files); condition.wakeAll(); - mutex.unlock(); } /*! @@ -160,10 +156,9 @@ void QFileInfoGatherer::updateFile(const QString &filePath) void QFileInfoGatherer::clear() { #ifndef QT_NO_FILESYSTEMWATCHER - mutex.lock(); + QMutexLocker locker(&mutex); watcher->removePaths(watcher->files()); watcher->removePaths(watcher->directories()); - mutex.unlock(); #endif } @@ -175,9 +170,8 @@ void QFileInfoGatherer::clear() void QFileInfoGatherer::removePath(const QString &path) { #ifndef QT_NO_FILESYSTEMWATCHER - mutex.lock(); + QMutexLocker locker(&mutex); watcher->removePath(path); - mutex.unlock(); #endif } @@ -198,9 +192,8 @@ void QFileInfoGatherer::run() { forever { bool updateFiles = false; - mutex.lock(); + QMutexLocker locker(&mutex); if (abort) { - mutex.unlock(); return; } if (this->path.isEmpty()) @@ -214,8 +207,9 @@ void QFileInfoGatherer::run() this->files.pop_front(); updateFiles = true; } - mutex.unlock(); - if (updateFiles) getFileInfos(path, list); + locker.unlock(); + if (updateFiles) + getFileInfos(path, list); } } diff --git a/src/gui/dialogs/qfscompleter_p.h b/src/gui/dialogs/qfscompleter_p.h new file mode 100644 index 0000000..37d9c74 --- /dev/null +++ b/src/gui/dialogs/qfscompleter_p.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the QtGui 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 either Technology Preview License Agreement or the +** Beta Release License Agreement. +** +** 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.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QCOMPLETOR_P_H +#define QCOMPLETOR_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qcompleter.h" +#include <QtGui/qfilesystemmodel.h> + +#ifndef QT_NO_COMPLETER +/*! + QCompleter that can deal with QFileSystemModel + */ +class QFSCompleter : public QCompleter { +public: + QFSCompleter(QFileSystemModel *model, QObject *parent = 0) + : QCompleter(model, parent), proxyModel(0), sourceModel(model) + { +#if defined(Q_OS_WIN) || defined(Q_OS_SYMBIAN) + setCaseSensitivity(Qt::CaseInsensitive); +#endif + } + QString pathFromIndex(const QModelIndex &index) const; + QStringList splitPath(const QString& path) const; + + QAbstractProxyModel *proxyModel; + QFileSystemModel *sourceModel; +}; +#endif // QT_NO_COMPLETER + +#endif // QCOMPLETOR_P_H + diff --git a/src/gui/dialogs/qpagesetupdialog_win.cpp b/src/gui/dialogs/qpagesetupdialog_win.cpp index 4bb571c..bdce8ab 100644 --- a/src/gui/dialogs/qpagesetupdialog_win.cpp +++ b/src/gui/dialogs/qpagesetupdialog_win.cpp @@ -71,7 +71,7 @@ int QPageSetupDialog::exec() return Rejected; QWin32PrintEngine *engine = static_cast<QWin32PrintEngine*>(d->printer->paintEngine()); - QWin32PrintEnginePrivate *ep = static_cast<QWin32PrintEnginePrivate *>(engine->d_ptr); + QWin32PrintEnginePrivate *ep = static_cast<QWin32PrintEnginePrivate *>(engine->d_ptr.data()); PAGESETUPDLG psd; memset(&psd, 0, sizeof(PAGESETUPDLG)); diff --git a/src/gui/dialogs/qprintdialog_unix.cpp b/src/gui/dialogs/qprintdialog_unix.cpp index 87a4e65..17d0047 100644 --- a/src/gui/dialogs/qprintdialog_unix.cpp +++ b/src/gui/dialogs/qprintdialog_unix.cpp @@ -44,7 +44,6 @@ #ifndef QT_NO_PRINTDIALOG #include "private/qabstractprintdialog_p.h" -#include "qfiledialog_p.h" #include <QtGui/qmessagebox.h> #include "qprintdialog.h" #include "qfiledialog.h" @@ -55,6 +54,7 @@ #include <QtGui/qdialogbuttonbox.h> +#include "qfscompleter_p.h" #include "ui_qprintpropertieswidget.h" #include "ui_qprintsettingsoutput.h" #include "ui_qprintwidget.h" @@ -696,7 +696,7 @@ QUnixPrintWidgetPrivate::QUnixPrintWidgetPrivate(QUnixPrintWidget *p) QFileSystemModel *fsm = new QFileSystemModel(widget.filename); fsm->setRootPath(QDir::homePath()); #if !defined(QT_NO_COMPLETER) && !defined(QT_NO_FILEDIALOG) - widget.filename->setCompleter(new QFSCompletor(fsm, widget.filename)); + widget.filename->setCompleter(new QFSCompleter(fsm, widget.filename)); #endif #endif _q_printerChanged(currentPrinterIndex); diff --git a/src/gui/dialogs/qprintpreviewdialog.cpp b/src/gui/dialogs/qprintpreviewdialog.cpp index c00bd14..61949d8 100644 --- a/src/gui/dialogs/qprintpreviewdialog.cpp +++ b/src/gui/dialogs/qprintpreviewdialog.cpp @@ -42,6 +42,7 @@ #include "qprintpreviewdialog.h" #include "qprintpreviewwidget.h" #include <private/qprinter_p.h> +#include "private/qdialog_p.h" #include <QtGui/qaction.h> #include <QtGui/qboxlayout.h> @@ -128,12 +129,12 @@ private: }; } // anonymous namespace -class QPrintPreviewDialogPrivate +class QPrintPreviewDialogPrivate : public QDialogPrivate { Q_DECLARE_PUBLIC(QPrintPreviewDialog) public: - QPrintPreviewDialogPrivate(QPrintPreviewDialog *q) - : q_ptr(q), printDialog(0), ownPrinter(false), + QPrintPreviewDialogPrivate() + : printDialog(0), ownPrinter(false), initialized(false) {} // private slots @@ -158,7 +159,6 @@ public: void updatePageNumLabel(); void updateZoomFactor(); - QPrintPreviewDialog *q_ptr; QPrintDialog *printDialog; QPrintPreviewWidget *preview; QPrinter *printer; @@ -680,7 +680,7 @@ void QPrintPreviewDialogPrivate::_q_zoomFactorChanged() \sa QWidget::setWindowFlags() */ QPrintPreviewDialog::QPrintPreviewDialog(QPrinter* printer, QWidget *parent, Qt::WindowFlags flags) - : QDialog(parent, flags), d_ptr(new QPrintPreviewDialogPrivate(this)) + : QDialog(*new QPrintPreviewDialogPrivate, parent, flags) { Q_D(QPrintPreviewDialog); d->init(printer); @@ -694,7 +694,7 @@ QPrintPreviewDialog::QPrintPreviewDialog(QPrinter* printer, QWidget *parent, Qt: system default printer. */ QPrintPreviewDialog::QPrintPreviewDialog(QWidget *parent, Qt::WindowFlags f) - : QDialog(parent, f), d_ptr(new QPrintPreviewDialogPrivate(this)) + : QDialog(*new QPrintPreviewDialogPrivate, parent, f) { Q_D(QPrintPreviewDialog); d->init(); @@ -709,7 +709,6 @@ QPrintPreviewDialog::~QPrintPreviewDialog() if (d->ownPrinter) delete d->printer; delete d->printDialog; - delete d_ptr; } /*! diff --git a/src/gui/dialogs/qprintpreviewdialog.h b/src/gui/dialogs/qprintpreviewdialog.h index c3a4d57..49262db 100644 --- a/src/gui/dialogs/qprintpreviewdialog.h +++ b/src/gui/dialogs/qprintpreviewdialog.h @@ -94,7 +94,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_previewChanged()) Q_PRIVATE_SLOT(d_func(), void _q_zoomFactorChanged()) - QPrintPreviewDialogPrivate *d_ptr; + void *dummy; // ### Qt 5 - remove me }; diff --git a/src/gui/embedded/qsoundqss_qws.cpp b/src/gui/embedded/qsoundqss_qws.cpp index 283bbd3..ed988ca 100644 --- a/src/gui/embedded/qsoundqss_qws.cpp +++ b/src/gui/embedded/qsoundqss_qws.cpp @@ -1036,24 +1036,28 @@ void QWSSoundServerPrivate::stopFile(int wid, int sid) void QWSSoundServerPrivate::stopAll(int wid) { QWSSoundServerProvider *bucket; - QList<QWSSoundServerProvider*>::Iterator it = active.begin(); - while (it != active.end()) { - bucket = *it; - if (bucket->groupId() == wid) { - it = active.erase(it); - delete bucket; - } else { - ++it; + if (!active.isEmpty()) { + QList<QWSSoundServerProvider*>::Iterator it = active.begin(); + while (it != active.end()) { + bucket = *it; + if (bucket->groupId() == wid) { + it = active.erase(it); + delete bucket; + } else { + ++it; + } } } - it = inactive.begin(); - while (it != inactive.end()) { - bucket = *it; - if (bucket->groupId() == wid) { - it = inactive.erase(it); - delete bucket; - } else { - ++it; + if (!inactive.isEmpty()) { + QList<QWSSoundServerProvider*>::Iterator it = inactive.begin(); + while (it != inactive.end()) { + bucket = *it; + if (bucket->groupId() == wid) { + it = inactive.erase(it); + delete bucket; + } else { + ++it; + } } } } diff --git a/src/gui/embedded/qwindowsystem_qws.cpp b/src/gui/embedded/qwindowsystem_qws.cpp index fdcd193..e3d56ad 100644 --- a/src/gui/embedded/qwindowsystem_qws.cpp +++ b/src/gui/embedded/qwindowsystem_qws.cpp @@ -1304,7 +1304,13 @@ QWSServer::QWSServer(int flags, QObject *parent) : QObject(*new QWSServerPrivate, parent) { Q_D(QWSServer); - d->initServer(flags); + QT_TRY { + d->initServer(flags); + } QT_CATCH(...) { + qwsServer = 0; + qwsServerPrivate = 0; + QT_RETHROW; + } } #ifdef QT3_SUPPORT @@ -1750,21 +1756,23 @@ void QWSServerPrivate::cleanupFonts(bool force) #if defined(QWS_DEBUG_FONTCLEANUP) qDebug() << "cleanupFonts()"; #endif - QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin(); - while (it != fontReferenceCount.end()) { - if (it.value() && !force) { - ++it; - continue; - } + if (!fontReferenceCount.isEmpty()) { + QMap<QByteArray, int>::Iterator it = fontReferenceCount.begin(); + while (it != fontReferenceCount.end()) { + if (it.value() && !force) { + ++it; + continue; + } - const QByteArray &fontName = it.key(); + const QByteArray &fontName = it.key(); #if defined(QWS_DEBUG_FONTCLEANUP) - qDebug() << "removing unused font file" << fontName; + qDebug() << "removing unused font file" << fontName; #endif - QFile::remove(QFile::decodeName(fontName)); - sendFontRemovedEvent(fontName); + QFile::remove(QFile::decodeName(fontName)); + sendFontRemovedEvent(fontName); - it = fontReferenceCount.erase(it); + it = fontReferenceCount.erase(it); + } } if (crashedClientIds.isEmpty()) @@ -3966,7 +3974,8 @@ void QWSServerPrivate::openDisplay() void QWSServerPrivate::closeDisplay() { - qt_screen->shutdownDevice(); + if (qt_screen) + qt_screen->shutdownDevice(); } /*! @@ -4065,9 +4074,14 @@ void QWSServer::startup(int flags) void QWSServer::closedown() { - unlink(qws_qtePipeFilename().toLatin1().constData()); - delete qwsServer; + QScopedPointer<QWSServer> server(qwsServer); qwsServer = 0; + QT_TRY { + unlink(qws_qtePipeFilename().toLatin1().constData()); + } QT_CATCH(const std::bad_alloc &) { + // ### TODO - what to do when we run out of memory + // when calling toLatin1? + } } void QWSServerPrivate::emergency_cleanup() diff --git a/src/gui/embedded/qwscursor_qws.cpp b/src/gui/embedded/qwscursor_qws.cpp index 3a5bd2c..b25e9b1 100644 --- a/src/gui/embedded/qwscursor_qws.cpp +++ b/src/gui/embedded/qwscursor_qws.cpp @@ -531,7 +531,7 @@ void QWSCursor::set(const uchar *data, const uchar *mask, cursor = QImage(width,height, QImage::Format_Indexed8); - if (!width || !height || !data || !mask) + if (!width || !height || !data || !mask || cursor.isNull()) return; cursor.setNumColors(3); diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index ed1891c..596326b 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -875,8 +875,6 @@ QGraphicsItem::~QGraphicsItem() if (d_ptr->scene) d_ptr->scene->d_func()->_q_removeItemLater(this); - delete d_ptr; - qt_dataStore()->data.remove(this); } @@ -2732,7 +2730,7 @@ QTransform QGraphicsItem::itemTransform(const QGraphicsItem *other, bool *ok) co QTransform x; const QGraphicsItem *p = child; do { - const QGraphicsItemPrivate *pd = p->d_ptr; + const QGraphicsItemPrivate *pd = p->d_ptr.data(); if (pd->hasTransform) x *= p->transform(); if (!pd->pos.isNull()) @@ -3070,7 +3068,7 @@ QRectF QGraphicsItem::sceneBoundingRect() const const QGraphicsItem *parentItem = this; const QGraphicsItemPrivate *itemd; do { - itemd = parentItem->d_ptr; + itemd = parentItem->d_ptr.data(); if (itemd->hasTransform) break; offset += itemd->pos; diff --git a/src/gui/graphicsview/qgraphicsitem.h b/src/gui/graphicsview/qgraphicsitem.h index b98882d..25678a6 100644 --- a/src/gui/graphicsview/qgraphicsitem.h +++ b/src/gui/graphicsview/qgraphicsitem.h @@ -46,6 +46,7 @@ #include <QtCore/qobject.h> #include <QtCore/qvariant.h> #include <QtCore/qrect.h> +#include <QtCore/qscopedpointer.h> #include <QtGui/qpainterpath.h> #include <QtGui/qpixmap.h> @@ -380,7 +381,7 @@ protected: protected: QGraphicsItem(QGraphicsItemPrivate &dd, QGraphicsItem *parent, QGraphicsScene *scene); - QGraphicsItemPrivate *d_ptr; + QScopedPointer<QGraphicsItemPrivate> d_ptr; void addToIndex(); void removeFromIndex(); diff --git a/src/gui/graphicsview/qgraphicslayoutitem.cpp b/src/gui/graphicsview/qgraphicslayoutitem.cpp index b46e05e..c291763 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.cpp +++ b/src/gui/graphicsview/qgraphicslayoutitem.cpp @@ -307,7 +307,6 @@ QGraphicsLayoutItem::~QGraphicsLayoutItem() } } } - delete d_ptr; } /*! diff --git a/src/gui/graphicsview/qgraphicslayoutitem.h b/src/gui/graphicsview/qgraphicslayoutitem.h index 31f5d90..d667c4f 100644 --- a/src/gui/graphicsview/qgraphicslayoutitem.h +++ b/src/gui/graphicsview/qgraphicslayoutitem.h @@ -42,6 +42,7 @@ #ifndef QGRAPHICSLAYOUTITEM_H #define QGRAPHICSLAYOUTITEM_H +#include <QtCore/qscopedpointer.h> #include <QtGui/qsizepolicy.h> #include <QtGui/qevent.h> @@ -112,7 +113,7 @@ protected: QGraphicsLayoutItem(QGraphicsLayoutItemPrivate &dd); virtual QSizeF sizeHint(Qt::SizeHint which, const QSizeF &constraint = QSizeF()) const = 0; - QGraphicsLayoutItemPrivate *d_ptr; + QScopedPointer<QGraphicsLayoutItemPrivate> d_ptr; private: QSizeF *effectiveSizeHints(const QSizeF &constraint) const; diff --git a/src/gui/graphicsview/qgraphicsproxywidget.h b/src/gui/graphicsview/qgraphicsproxywidget.h index b2c3c8f..f006319 100644 --- a/src/gui/graphicsview/qgraphicsproxywidget.h +++ b/src/gui/graphicsview/qgraphicsproxywidget.h @@ -127,7 +127,7 @@ protected Q_SLOTS: private: Q_DISABLE_COPY(QGraphicsProxyWidget) - Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr, QGraphicsProxyWidget) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsProxyWidget) Q_PRIVATE_SLOT(d_func(), void _q_removeWidgetSlot()) friend class QWidget; diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp index b89e352..5114351 100644 --- a/src/gui/graphicsview/qgraphicsscene.cpp +++ b/src/gui/graphicsview/qgraphicsscene.cpp @@ -1824,8 +1824,8 @@ void QGraphicsScenePrivate::invalidateSortCache() inline bool qt_closestLeaf(const QGraphicsItem *item1, const QGraphicsItem *item2) { // Return true if sibling item1 is on top of item2. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; + const QGraphicsItemPrivate *d1 = item1->d_ptr.data(); + const QGraphicsItemPrivate *d2 = item2->d_ptr.data(); bool f1 = d1->flags & QGraphicsItem::ItemStacksBehindParent; bool f2 = d2->flags & QGraphicsItem::ItemStacksBehindParent; if (f1 != f2) return f2; @@ -1852,8 +1852,8 @@ inline bool qt_closestItemFirst(const QGraphicsItem *item1, const QGraphicsItem bool QGraphicsScenePrivate::closestItemFirst_withoutCache(const QGraphicsItem *item1, const QGraphicsItem *item2) { // Siblings? Just check their z-values. - const QGraphicsItemPrivate *d1 = item1->d_ptr; - const QGraphicsItemPrivate *d2 = item2->d_ptr; + const QGraphicsItemPrivate *d1 = item1->d_ptr.data(); + const QGraphicsItemPrivate *d2 = item2->d_ptr.data(); if (d1->parent == d2->parent) return qt_closestLeaf(item1, item2); @@ -4687,7 +4687,7 @@ void QGraphicsScenePrivate::drawItemHelper(QGraphicsItem *item, QPainter *painte const QStyleOptionGraphicsItem *option, QWidget *widget, bool painterStateProtection) { - QGraphicsItemPrivate *itemd = item->d_ptr; + QGraphicsItemPrivate *itemd = item->d_ptr.data(); QGraphicsItem::CacheMode cacheMode = QGraphicsItem::CacheMode(itemd->cacheMode); // Render directly, using no cache. diff --git a/src/gui/graphicsview/qgraphicssceneevent.cpp b/src/gui/graphicsview/qgraphicssceneevent.cpp index 0ffd2b1..ad57aac 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.cpp +++ b/src/gui/graphicsview/qgraphicssceneevent.cpp @@ -313,7 +313,6 @@ QGraphicsSceneEvent::QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type ty */ QGraphicsSceneEvent::~QGraphicsSceneEvent() { - delete d_ptr; } /*! diff --git a/src/gui/graphicsview/qgraphicssceneevent.h b/src/gui/graphicsview/qgraphicssceneevent.h index be50e96..4ebe3df 100644 --- a/src/gui/graphicsview/qgraphicssceneevent.h +++ b/src/gui/graphicsview/qgraphicssceneevent.h @@ -44,6 +44,7 @@ #include <QtCore/qcoreevent.h> #include <QtCore/qpoint.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -70,7 +71,7 @@ public: protected: QGraphicsSceneEvent(QGraphicsSceneEventPrivate &dd, Type type = None); - QGraphicsSceneEventPrivate *d_ptr; + QScopedPointer<QGraphicsSceneEventPrivate> d_ptr; Q_DECLARE_PRIVATE(QGraphicsSceneEvent) }; diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp index 8137f8e..96e9a96 100644 --- a/src/gui/graphicsview/qgraphicsview.cpp +++ b/src/gui/graphicsview/qgraphicsview.cpp @@ -753,7 +753,7 @@ QRect QGraphicsViewPrivate::mapToViewRect(const QGraphicsItem *item, const QRect const QGraphicsItem *parentItem = item; const QGraphicsItemPrivate *itemd; do { - itemd = parentItem->d_ptr; + itemd = parentItem->d_ptr.data(); if (itemd->hasTransform) break; offset += itemd->pos; diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp index 7781258..aa2b9bf 100644 --- a/src/gui/graphicsview/qgraphicswidget.cpp +++ b/src/gui/graphicsview/qgraphicswidget.cpp @@ -366,7 +366,7 @@ void QGraphicsWidget::resize(const QSizeF &size) void QGraphicsWidget::setGeometry(const QRectF &rect) { QGraphicsWidgetPrivate *wd = QGraphicsWidget::d_func(); - QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr; + QGraphicsLayoutItemPrivate *d = QGraphicsLayoutItem::d_ptr.data(); QRectF newGeom; QPointF oldPos = d->geom.topLeft(); if (!wd->inSetPos) { diff --git a/src/gui/graphicsview/qgraphicswidget.h b/src/gui/graphicsview/qgraphicswidget.h index 34f1c5f..49de542 100644 --- a/src/gui/graphicsview/qgraphicswidget.h +++ b/src/gui/graphicsview/qgraphicswidget.h @@ -225,7 +225,7 @@ protected: private: Q_DISABLE_COPY(QGraphicsWidget) - Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr, QGraphicsWidget) + Q_DECLARE_PRIVATE_D(QGraphicsItem::d_ptr.data(), QGraphicsWidget) friend class QGraphicsScene; friend class QGraphicsScenePrivate; friend class QGraphicsView; diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 70d4e2c..34ad99c 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -185,6 +185,13 @@ static int depthForFormat(QImage::Format format) return depth; } +/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) + + \internal + + Creates a new image data. + Returns 0 if invalid parameters are give or anything else failed. +*/ QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) { if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) @@ -223,7 +230,7 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu || INT_MAX/sizeof(uchar *) < uint(height)) return 0; - QImageData *d = new QImageData; + QScopedPointer<QImageData> d(new QImageData); d->colortable.resize(numColors); if (depth == 1) { d->colortable[0] = QColor(Qt::black).rgba(); @@ -246,12 +253,11 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu d->data = (uchar *)malloc(d->nbytes); if (!d->data) { - delete d; return 0; } d->ref.ref(); - return d; + return d.take(); } @@ -1621,6 +1627,7 @@ int QImage::numColors() const /*! Returns a pointer to the scanline pointer table. This is the beginning of the data block for the image. + Returns 0 in case of an error. Use the bits() or scanLine() function instead. */ @@ -1636,6 +1643,8 @@ uchar **QImage::jumpTable() if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; @@ -1656,6 +1665,8 @@ const uchar * const *QImage::jumpTable() const return 0; if (!d->jumptable) { d->jumptable = (uchar **)malloc(d->height*sizeof(uchar *)); + if (!d->jumptable) + return 0; uchar *data = d->data; int height = d->height; uchar **p = d->jumptable; diff --git a/src/gui/image/qimageiohandler.cpp b/src/gui/image/qimageiohandler.cpp index a47c69e..f432f87 100644 --- a/src/gui/image/qimageiohandler.cpp +++ b/src/gui/image/qimageiohandler.cpp @@ -272,7 +272,6 @@ QImageIOHandler::QImageIOHandler(QImageIOHandlerPrivate &dd) */ QImageIOHandler::~QImageIOHandler() { - delete d_ptr; } /*! diff --git a/src/gui/image/qimageiohandler.h b/src/gui/image/qimageiohandler.h index 3b654f3..34de715 100644 --- a/src/gui/image/qimageiohandler.h +++ b/src/gui/image/qimageiohandler.h @@ -44,6 +44,7 @@ #include <QtCore/qplugin.h> #include <QtCore/qfactoryinterface.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -109,7 +110,7 @@ public: protected: QImageIOHandler(QImageIOHandlerPrivate &dd); - QImageIOHandlerPrivate *d_ptr; + QScopedPointer<QImageIOHandlerPrivate> d_ptr; private: Q_DISABLE_COPY(QImageIOHandler) }; diff --git a/src/gui/image/qpicture.cpp b/src/gui/image/qpicture.cpp index 92023e0..8528173 100644 --- a/src/gui/image/qpicture.cpp +++ b/src/gui/image/qpicture.cpp @@ -132,7 +132,6 @@ QPicture::QPicture(int formatVersion) { Q_D(QPicture); d_ptr->q_ptr = this; - d->paintEngine = 0; if (formatVersion == 0) qWarning("QPicture: invalid format version 0"); @@ -155,7 +154,7 @@ QPicture::QPicture(int formatVersion) */ QPicture::QPicture(const QPicture &pic) - : QPaintDevice(), d_ptr(pic.d_ptr) + : QPaintDevice(), d_ptr(pic.d_ptr.data()) { d_func()->ref.ref(); } @@ -173,10 +172,6 @@ QPicture::QPicture(QPicturePrivate &dptr) */ QPicture::~QPicture() { - if (!d_func()->ref.deref()) { - delete d_func()->paintEngine; - delete d_func(); - } } /*! @@ -1030,9 +1025,7 @@ void QPicture::detach_helper() x->formatMinor = d->formatMinor; x->brect = d->brect; x->override_rect = d->override_rect; - if (!d->ref.deref()) - delete d; - d_ptr = x; + d_ptr.reset(x); } /*! @@ -1041,7 +1034,7 @@ void QPicture::detach_helper() */ QPicture& QPicture::operator=(const QPicture &p) { - qAtomicAssign<QPicturePrivate>(d_ptr, p.d_ptr); + d_ptr.assign(p.d_ptr.data()); return *this; } @@ -1135,8 +1128,8 @@ bool QPicturePrivate::checkFormat() QPaintEngine *QPicture::paintEngine() const { if (!d_func()->paintEngine) - const_cast<QPicture*>(this)->d_func()->paintEngine = new QPicturePaintEngine; - return d_func()->paintEngine; + const_cast<QPicture*>(this)->d_func()->paintEngine.reset(new QPicturePaintEngine); + return d_func()->paintEngine.data(); } /***************************************************************************** diff --git a/src/gui/image/qpicture.h b/src/gui/image/qpicture.h index fe86e8d..7de1f79 100644 --- a/src/gui/image/qpicture.h +++ b/src/gui/image/qpicture.h @@ -106,7 +106,7 @@ private: bool exec(QPainter *p, QDataStream &ds, int i); void detach_helper(); - QPicturePrivate *d_ptr; + QScopedSharedPointer<QPicturePrivate> d_ptr; friend class QPicturePaintEngine; friend class Q3Picture; friend class QAlphaPaintEngine; @@ -114,7 +114,7 @@ private: public: typedef QPicturePrivate* DataPtr; - inline DataPtr &data_ptr() { return d_ptr; } + inline DataPtr &data_ptr() { return d_ptr.data_ptr(); } }; Q_DECLARE_SHARED(QPicture) diff --git a/src/gui/image/qpicture_p.h b/src/gui/image/qpicture_p.h index a3fd34f..e0c3117 100644 --- a/src/gui/image/qpicture_p.h +++ b/src/gui/image/qpicture_p.h @@ -156,7 +156,7 @@ public: int formatMinor; QRect brect; QRect override_rect; - QPaintEngine *paintEngine; + QScopedPointer<QPaintEngine> paintEngine; bool in_memory_only; QList<QImage> image_list; QList<QPixmap> pixmap_list; diff --git a/src/gui/image/qpixmap_s60.cpp b/src/gui/image/qpixmap_s60.cpp index 3ea50ff..132e26e 100644 --- a/src/gui/image/qpixmap_s60.cpp +++ b/src/gui/image/qpixmap_s60.cpp @@ -38,6 +38,7 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include <exception> #include <w32std.h> #include <fbs.h> diff --git a/src/gui/image/qpixmapcache.cpp b/src/gui/image/qpixmapcache.cpp index c9973d0..4f71e09 100644 --- a/src/gui/image/qpixmapcache.cpp +++ b/src/gui/image/qpixmapcache.cpp @@ -323,7 +323,12 @@ void QPixmapCache::remove(const QString &key) void QPixmapCache::clear() { - pm_cache()->clear(); + QT_TRY { + pm_cache()->clear(); + } QT_CATCH(const std::bad_alloc &) { + // if we ran out of memory during pm_cache(), it's no leak, + // so just ignore it. + } } QT_END_NAMESPACE diff --git a/src/gui/itemviews/qabstractitemview_p.h b/src/gui/itemviews/qabstractitemview_p.h index 16bd1ab..c4bf4db 100644 --- a/src/gui/itemviews/qabstractitemview_p.h +++ b/src/gui/itemviews/qabstractitemview_p.h @@ -304,7 +304,7 @@ public: */ inline bool isPersistent(const QModelIndex &index) const { - return static_cast<QAbstractItemModelPrivate *>(model->d_ptr)->persistent.indexes.contains(index); + return static_cast<QAbstractItemModelPrivate *>(model->d_ptr.data())->persistent.indexes.contains(index); } QModelIndexList selectedDraggableIndexes() const; diff --git a/src/gui/itemviews/qfileiconprovider.cpp b/src/gui/itemviews/qfileiconprovider.cpp index ac62551..af4d42a 100644 --- a/src/gui/itemviews/qfileiconprovider.cpp +++ b/src/gui/itemviews/qfileiconprovider.cpp @@ -180,7 +180,6 @@ QFileIconProvider::QFileIconProvider() QFileIconProvider::~QFileIconProvider() { - delete d_ptr; } /*! diff --git a/src/gui/itemviews/qfileiconprovider.h b/src/gui/itemviews/qfileiconprovider.h index 7928552..a6152ea 100644 --- a/src/gui/itemviews/qfileiconprovider.h +++ b/src/gui/itemviews/qfileiconprovider.h @@ -42,8 +42,9 @@ #ifndef QFILEICONPROVIDER_H #define QFILEICONPROVIDER_H -#include <QtGui/qicon.h> #include <QtCore/qfileinfo.h> +#include <QtCore/qscopedpointer.h> +#include <QtGui/qicon.h> QT_BEGIN_HEADER @@ -67,7 +68,7 @@ public: private: Q_DECLARE_PRIVATE(QFileIconProvider) - QFileIconProviderPrivate *d_ptr; + QScopedPointer<QFileIconProviderPrivate> d_ptr; Q_DISABLE_COPY(QFileIconProvider) }; diff --git a/src/gui/itemviews/qstandarditemmodel.cpp b/src/gui/itemviews/qstandarditemmodel.cpp index 61e410d..4ec00bb 100644 --- a/src/gui/itemviews/qstandarditemmodel.cpp +++ b/src/gui/itemviews/qstandarditemmodel.cpp @@ -778,8 +778,6 @@ QStandardItem &QStandardItem::operator=(const QStandardItem &other) */ QStandardItem::~QStandardItem() { - Q_D(QStandardItem); - delete d; } /*! diff --git a/src/gui/itemviews/qstandarditemmodel.h b/src/gui/itemviews/qstandarditemmodel.h index f24f0ab..66d7576 100644 --- a/src/gui/itemviews/qstandarditemmodel.h +++ b/src/gui/itemviews/qstandarditemmodel.h @@ -240,7 +240,7 @@ protected: QStandardItem(const QStandardItem &other); QStandardItem(QStandardItemPrivate &dd); QStandardItem &operator=(const QStandardItem &other); - QStandardItemPrivate *d_ptr; + QScopedPointer<QStandardItemPrivate> d_ptr; void emitDataChanged(); diff --git a/src/gui/itemviews/qtreewidget.cpp b/src/gui/itemviews/qtreewidget.cpp index 6103225..0f2a27c 100644 --- a/src/gui/itemviews/qtreewidget.cpp +++ b/src/gui/itemviews/qtreewidget.cpp @@ -853,7 +853,7 @@ void QTreeModel::sortItems(QList<QTreeWidgetItem*> *items, int column, Qt::SortO items->replace(r, item); for (int c = 0; c < colCount; ++c) { QModelIndex from = createIndex(oldRow, c, item); - if (static_cast<QAbstractItemModelPrivate *>(d_ptr)->persistent.indexes.contains(from)) { + if (static_cast<QAbstractItemModelPrivate *>(d_ptr.data())->persistent.indexes.contains(from)) { QModelIndex to = createIndex(r, c, item); fromList << from; toList << to; diff --git a/src/gui/itemviews/qtreewidgetitemiterator.cpp b/src/gui/itemviews/qtreewidgetitemiterator.cpp index 3e30e03..7e167b9 100644 --- a/src/gui/itemviews/qtreewidgetitemiterator.cpp +++ b/src/gui/itemviews/qtreewidgetitemiterator.cpp @@ -97,7 +97,7 @@ QTreeWidgetItemIterator::QTreeWidgetItemIterator(QTreeWidget *widget, IteratorFl Q_ASSERT(widget); QTreeModel *model = qobject_cast<QTreeModel*>(widget->model()); Q_ASSERT(model); - d_ptr = new QTreeWidgetItemIteratorPrivate(this, model); + d_ptr.reset(new QTreeWidgetItemIteratorPrivate(this, model)); model->iterators.append(this); if (!model->rootItem->children.isEmpty()) current = model->rootItem->children.first(); if (current && !matchesFlags(current)) @@ -150,7 +150,6 @@ QTreeWidgetItemIterator::QTreeWidgetItemIterator(QTreeWidgetItem *item, Iterator QTreeWidgetItemIterator::~QTreeWidgetItemIterator() { d_func()->m_model->iterators.removeAll(this); - delete d_ptr; } /*! diff --git a/src/gui/itemviews/qtreewidgetitemiterator.h b/src/gui/itemviews/qtreewidgetitemiterator.h index 8a76c69..535339d 100644 --- a/src/gui/itemviews/qtreewidgetitemiterator.h +++ b/src/gui/itemviews/qtreewidgetitemiterator.h @@ -43,6 +43,7 @@ #define QTREEWIDGETITEMITERATOR_H #include <QtCore/qglobal.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -105,7 +106,7 @@ public: private: bool matchesFlags(const QTreeWidgetItem *item) const; - QTreeWidgetItemIteratorPrivate *d_ptr; + QScopedPointer<QTreeWidgetItemIteratorPrivate> d_ptr; QTreeWidgetItem *current; IteratorFlags flags; Q_DECLARE_PRIVATE(QTreeWidgetItemIterator) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index eaaeb4b..aa6d21e 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -1006,7 +1006,8 @@ QApplication::~QApplication() if (QWidgetPrivate::mapper) { QWidgetMapper * myMapper = QWidgetPrivate::mapper; QWidgetPrivate::mapper = 0; - for (QWidgetMapper::Iterator it = myMapper->begin(); it != myMapper->end(); ++it) { + for (QWidgetMapper::ConstIterator it = myMapper->constBegin(); + it != myMapper->constEnd(); ++it) { register QWidget *w = *it; if (!w->parent()) // window w->destroy(true, true); @@ -1018,7 +1019,7 @@ QApplication::~QApplication() if (QWidgetPrivate::uncreatedWidgets) { QWidgetSet *mySet = QWidgetPrivate::uncreatedWidgets; QWidgetPrivate::uncreatedWidgets = 0; - for (QWidgetSet::Iterator it = mySet->begin(); it != mySet->end(); ++it) { + for (QWidgetSet::ConstIterator it = mySet->constBegin(); it != mySet->constEnd(); ++it) { register QWidget *w = *it; if (!w->parent()) // window w->destroy(true, true); @@ -4993,8 +4994,7 @@ void QApplication::setInputContext(QInputContext *inputContext) qWarning("QApplication::setInputContext: called with 0 input context"); return; } - if (d->inputContext) - delete d->inputContext; + delete d->inputContext; d->inputContext = inputContext; } diff --git a/src/gui/kernel/qapplication_p.h b/src/gui/kernel/qapplication_p.h index a6fc602..35a532a 100644 --- a/src/gui/kernel/qapplication_p.h +++ b/src/gui/kernel/qapplication_p.h @@ -100,6 +100,7 @@ extern QSysInfo::MacVersion qt_macver; #if defined(Q_WS_QWS) class QWSManager; class QDirectPainter; +struct QWSServerCleaner { ~QWSServerCleaner(); }; #endif #ifndef QT_NO_TABLET @@ -382,6 +383,7 @@ public: #ifdef Q_WS_QWS QPointer<QWSManager> last_manager; + QWSServerCleaner qwsServerCleaner; # ifndef QT_NO_DIRECTPAINTER QMap<WId, QDirectPainter *> *directPainters; # endif diff --git a/src/gui/kernel/qapplication_qws.cpp b/src/gui/kernel/qapplication_qws.cpp index 018440f..aeebde4 100644 --- a/src/gui/kernel/qapplication_qws.cpp +++ b/src/gui/kernel/qapplication_qws.cpp @@ -159,6 +159,8 @@ bool qws_overrideCursor = false; #ifndef QT_NO_QWS_MANAGER #include "qdecorationfactory_qws.h" +extern Q_GUI_EXPORT QWSServer *qwsServer; + QT_BEGIN_NAMESPACE QT_USE_NAMESPACE @@ -485,8 +487,13 @@ QList<QWSCommand*> *qt_get_server_queue() void qt_server_enqueue(const QWSCommand *command) { QWSCommand *copy = QWSCommand::factory(command->type); - copy->copyFrom(command); - outgoing.append(copy); + QT_TRY { + copy->copyFrom(command); + outgoing.append(copy); + } QT_CATCH(...) { + delete copy; + QT_RETHROW; + } } QWSDisplay::Data::Data(QObject* parent, bool singleProcess) @@ -2295,7 +2302,7 @@ void qt_init(QApplicationPrivate *priv, int type) qws_decoration = QApplication::qwsSetDecoration(decoration); #endif // QT_NO_QWS_MANAGER #ifndef QT_NO_QWS_INPUTMETHODS - qApp->setInputContext(new QWSInputContext); + qApp->setInputContext(new QWSInputContext(qApp)); #endif } @@ -3542,10 +3549,10 @@ bool QETWidget::translateKeyEvent(const QWSKeyEvent *event, bool grab) /* grab i #if defined QT3_SUPPORT && !defined(QT_NO_SHORTCUT) if (type == QEvent::KeyPress && !grab - && static_cast<QApplicationPrivate*>(qApp->d_ptr)->use_compat()) { + && static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->use_compat()) { // send accel events if the keyboard is not grabbed QKeyEvent a(type, code, state, text, autor, int(text.length())); - if (static_cast<QApplicationPrivate*>(qApp->d_ptr)->qt_tryAccelEvent(this, &a)) + if (static_cast<QApplicationPrivate*>(qApp->d_ptr.data())->qt_tryAccelEvent(this, &a)) return true; } #else @@ -3745,4 +3752,14 @@ void QApplication::setArgs(int c, char **v) d->argv = v; } +/* \internal + This is used to clean up the qws server + in case the QApplication constructor threw an exception + */ +QWSServerCleaner::~QWSServerCleaner() +{ + if (qwsServer && qws_single_process) + QWSServer::closedown(); +} + QT_END_NAMESPACE diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp index 2f7bdcf..976d9f6 100644 --- a/src/gui/kernel/qapplication_s60.cpp +++ b/src/gui/kernel/qapplication_s60.cpp @@ -441,6 +441,13 @@ void QSymbianControl::sendMouseEvent(QWidget *widget, QMouseEvent *mEvent) TKeyResponse QSymbianControl::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type) { + TKeyResponse r = EKeyWasNotConsumed; + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE(r = OfferKeyEvent(keyEvent, type)); + return r; +} + +TKeyResponse QSymbianControl::OfferKeyEvent(const TKeyEvent& keyEvent, TEventCode type) +{ switch (type) { //case EEventKeyDown: // <-- Intentionally left out. See below. case EEventKeyUp: diff --git a/src/gui/kernel/qcursor_qws.cpp b/src/gui/kernel/qcursor_qws.cpp index 097b982..99800a8 100644 --- a/src/gui/kernel/qcursor_qws.cpp +++ b/src/gui/kernel/qcursor_qws.cpp @@ -66,7 +66,11 @@ QCursorData::~QCursorData() { delete bm; delete bmm; - QPaintDevice::qwsDisplay()->destroyCursor(id); + QT_TRY { + QPaintDevice::qwsDisplay()->destroyCursor(id); + } QT_CATCH(const std::bad_alloc &) { + // do nothing. + } } diff --git a/src/gui/kernel/qeventdispatcher_s60.cpp b/src/gui/kernel/qeventdispatcher_s60.cpp index 6ac2863..fcf572e 100644 --- a/src/gui/kernel/qeventdispatcher_s60.cpp +++ b/src/gui/kernel/qeventdispatcher_s60.cpp @@ -62,18 +62,22 @@ bool QEventDispatcherS60::processEvents ( QEventLoop::ProcessEventsFlags flags ) { bool ret = false; - bool oldNoInputEventsValue = m_noInputEvents; - if (flags & QEventLoop::ExcludeUserInputEvents) { - m_noInputEvents = true; - } else { - m_noInputEvents = false; - ret = sendDeferredInputEvents() || ret; + QT_TRY { + bool oldNoInputEventsValue = m_noInputEvents; + if (flags & QEventLoop::ExcludeUserInputEvents) { + m_noInputEvents = true; + } else { + m_noInputEvents = false; + ret = sendDeferredInputEvents() || ret; + } + + ret = QEventDispatcherSymbian::processEvents(flags) || ret; + + m_noInputEvents = oldNoInputEventsValue; + } QT_CATCH (const std::exception& ex) { + CActiveScheduler::Current()->Error(qt_translateExceptionToSymbianError(ex)); } - ret = QEventDispatcherSymbian::processEvents(flags) || ret; - - m_noInputEvents = oldNoInputEventsValue; - return ret; } diff --git a/src/gui/kernel/qshortcutmap.cpp b/src/gui/kernel/qshortcutmap.cpp index 86894b4..7a19252 100644 --- a/src/gui/kernel/qshortcutmap.cpp +++ b/src/gui/kernel/qshortcutmap.cpp @@ -148,9 +148,8 @@ public: QShortcutMap constructor. */ QShortcutMap::QShortcutMap() + : d_ptr(new QShortcutMapPrivate(this)) { - d_ptr = new QShortcutMapPrivate(this); - Q_ASSERT(d_ptr != 0); resetState(); } @@ -159,8 +158,6 @@ QShortcutMap::QShortcutMap() */ QShortcutMap::~QShortcutMap() { - delete d_ptr; - d_ptr = 0; } /*! \internal diff --git a/src/gui/kernel/qshortcutmap_p.h b/src/gui/kernel/qshortcutmap_p.h index 3fe9546..28ee1f0 100644 --- a/src/gui/kernel/qshortcutmap_p.h +++ b/src/gui/kernel/qshortcutmap_p.h @@ -55,6 +55,7 @@ #include "QtGui/qkeysequence.h" #include "QtCore/qvector.h" +#include "QtCore/qscopedpointer.h" QT_BEGIN_NAMESPACE @@ -104,7 +105,7 @@ private: #ifndef QT_NO_ACTION bool correctContext(Qt::ShortcutContext context,QAction *a, QWidget *active_window) const; #endif - QShortcutMapPrivate *d_ptr; + QScopedPointer<QShortcutMapPrivate> d_ptr; QKeySequence::SequenceMatch find(QKeyEvent *e); QKeySequence::SequenceMatch matches(const QKeySequence &seq1, const QKeySequence &seq2) const; diff --git a/src/gui/kernel/qsound_s60.cpp b/src/gui/kernel/qsound_s60.cpp index 7eb6463..00fc2fe 100644 --- a/src/gui/kernel/qsound_s60.cpp +++ b/src/gui/kernel/qsound_s60.cpp @@ -146,10 +146,11 @@ QAuServer* qt_new_audio_server() QAuBucketS60::QAuBucketS60( QAuServerS60 *server, QSound *sound ) : m_sound( sound ), m_server( server ), m_prepared(false), m_playCalled(false) { + QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); + filepath = QDir::toNativeSeparators(filepath); + TPtrC filepathPtr(qt_QString2TPtrC(filepath)); TRAPD(err, m_playUtility = CMdaAudioPlayerUtility::NewL(*this); - QString filepath = QFileInfo( m_sound->fileName() ).absoluteFilePath(); - filepath = QDir::toNativeSeparators(filepath); - m_playUtility->OpenFileL(qt_QString2TPtrC(filepath))); + m_playUtility->OpenFileL(filepathPtr)); if(err){ m_server->playCompleted(this, err); } diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h index d2fa5da..2d47a14 100644 --- a/src/gui/kernel/qt_s60_p.h +++ b/src/gui/kernel/qt_s60_p.h @@ -147,6 +147,7 @@ protected: void FocusChanged(TDrawNow aDrawNow); private: + TKeyResponse OfferKeyEvent(const TKeyEvent& aKeyEvent,TEventCode aType); TKeyResponse sendKeyEvent(QWidget *widget, QKeyEvent *keyEvent); void sendMouseEvent(QWidget *widget, QMouseEvent *mEvent); void HandleLongTapEventL( const TPoint& aPenEventLocation, const TPoint& aPenEventScreenLocation ); diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index b376f20..09299dc 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -172,7 +172,8 @@ extern bool qt_sendSpontaneousEvent(QObject*, QEvent*); // qapplication.cpp extern QDesktopWidget *qt_desktopWidget; // qapplication.cpp QWidgetPrivate::QWidgetPrivate(int version) : - QObjectPrivate(version), extra(0), focus_child(0) + QObjectPrivate(version), extra(0), + focus_next(0), focus_prev(0), focus_child(0) ,layout(0), widgetItem(0) ,leftmargin(0), topmargin(0), rightmargin(0), bottommargin(0) ,leftLayoutItemMargin(0), topLayoutItemMargin(0), rightLayoutItemMargin(0) @@ -927,6 +928,23 @@ QRegion qt_dirtyRegion(QWidget *widget) \endlist */ +struct QWidgetExceptionCleaner +{ + /* this cleans up when the constructor throws an exception */ + static inline void cleanup(QWidget *that, QWidgetPrivate *d) + { +#ifndef QT_NO_EXCEPTIONS + QWidgetPrivate::uncreatedWidgets->remove(that); + if (d->focus_next != that) { + if (d->focus_next) + d->focus_next->d_func()->focus_prev = d->focus_prev; + if (d->focus_prev) + d->focus_prev->d_func()->focus_next = d->focus_next; + } +#endif + } +}; + /*! Constructs a widget which is a child of \a parent, with widget flags set to \a f. @@ -956,7 +974,12 @@ QRegion qt_dirtyRegion(QWidget *widget) QWidget::QWidget(QWidget *parent, Qt::WindowFlags f) : QObject(*new QWidgetPrivate, 0), QPaintDevice() { - d_func()->init(parent, f); + QT_TRY { + d_func()->init(parent, f); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } #ifdef QT3_SUPPORT @@ -967,8 +990,13 @@ QWidget::QWidget(QWidget *parent, Qt::WindowFlags f) QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f) : QObject(*new QWidgetPrivate, 0), QPaintDevice() { - d_func()->init(parent , f); - setObjectName(QString::fromAscii(name)); + QT_TRY { + d_func()->init(parent , f); + setObjectName(QString::fromAscii(name)); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } #endif @@ -977,7 +1005,13 @@ QWidget::QWidget(QWidget *parent, const char *name, Qt::WindowFlags f) QWidget::QWidget(QWidgetPrivate &dd, QWidget* parent, Qt::WindowFlags f) : QObject(dd, 0), QPaintDevice() { - d_func()->init(parent, f); + Q_D(QWidget); + QT_TRY { + d->init(parent, f); + } QT_CATCH(...) { + QWidgetExceptionCleaner::cleanup(this, d_func()); + QT_RETHROW; + } } /*! @@ -5068,7 +5102,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP #ifndef QT_NO_SCROLLAREA QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(q->parent()); if (scrollArea && scrollArea->viewport() == q) { - QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr; + QObjectData *scrollPrivate = static_cast<QWidget *>(scrollArea)->d_ptr.data(); QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(scrollPrivate); scrollAreaOffset = priv->contentsOffset(); p.translate(-scrollAreaOffset); diff --git a/src/gui/kernel/qwidget.h b/src/gui/kernel/qwidget.h index 0dd470d..1b67ba7 100644 --- a/src/gui/kernel/qwidget.h +++ b/src/gui/kernel/qwidget.h @@ -728,6 +728,7 @@ private: friend class QGraphicsProxyWidget; friend class QGraphicsProxyWidgetPrivate; friend class QStyleSheetStyle; + friend class QWidgetExceptionCleaner; #ifdef Q_WS_MAC friend class QCoreGraphicsPaintEnginePrivate; diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index b2256cd..e2197c6 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -1215,7 +1215,7 @@ OSStatus QWidgetPrivate::qt_widget_event(EventHandlerCallRef er, EventRef event, QAbstractScrollArea *scrollArea = qobject_cast<QAbstractScrollArea *>(widget->parent()); QPoint scrollAreaOffset; if (scrollArea && scrollArea->viewport() == widget) { - QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr); + QAbstractScrollAreaPrivate *priv = static_cast<QAbstractScrollAreaPrivate *>(static_cast<QWidget *>(scrollArea)->d_ptr.data()); scrollAreaOffset = priv->contentsOffset(); p.translate(-scrollAreaOffset); } diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index 1445f57..0073d3f 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -652,7 +652,8 @@ void QWidgetPrivate::hide_sys() q->releaseMouse(); // requestWindowRegion(QRegion()); - extra->topextra->backingStore->releaseBuffer(); + if (extra->topextra->backingStore) + extra->topextra->backingStore->releaseBuffer(); QWidget::qwsDisplay()->requestFocus(data.winid,false); diff --git a/src/gui/painting/qbrush.cpp b/src/gui/painting/qbrush.cpp index 854d0aa..c22791a 100644 --- a/src/gui/painting/qbrush.cpp +++ b/src/gui/painting/qbrush.cpp @@ -221,7 +221,7 @@ bool qHasPixmapTexture(const QBrush& brush) { if (brush.style() != Qt::TexturePattern) return false; - QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d); + QTexturedBrushData *tx_data = static_cast<QTexturedBrushData *>(brush.d.data()); return tx_data->m_has_pixmap_texture; } @@ -230,6 +230,37 @@ struct QGradientBrushData : public QBrushData QGradient gradient; }; +struct QBrushDataPointerHandler +{ + static inline void deleteData(QBrushData *d) + { + switch (d->style) { + case Qt::TexturePattern: + delete static_cast<QTexturedBrushData*>(d); + break; + case Qt::LinearGradientPattern: + case Qt::RadialGradientPattern: + case Qt::ConicalGradientPattern: + delete static_cast<QGradientBrushData*>(d); + break; + default: + delete d; + } + } + + static inline void cleanup(QBrushData *d) + { + if (d && !d->ref.deref()) { + deleteData(d); + } + } + + static inline void reset(QBrushData *&d, QBrushData *other) + { + cleanup(d); + d = other; + } +}; /*! \class QBrush @@ -364,20 +395,20 @@ void QBrush::init(const QColor &color, Qt::BrushStyle style) { switch(style) { case Qt::NoBrush: - d = nullBrushInstance(); + d.data_ptr() = nullBrushInstance(); d->ref.ref(); if (d->color != color) setColor(color); return; case Qt::TexturePattern: - d = new QTexturedBrushData; + d.data_ptr() = new QTexturedBrushData; break; case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: - d = new QGradientBrushData; + d.data_ptr() = new QGradientBrushData; break; default: - d = new QBrushData; + d.data_ptr() = new QBrushData; break; } d->ref = 1; @@ -391,8 +422,8 @@ void QBrush::init(const QColor &color, Qt::BrushStyle style) */ QBrush::QBrush() + : d(nullBrushInstance()) { - d = nullBrushInstance(); Q_ASSERT(d); d->ref.ref(); } @@ -435,7 +466,7 @@ QBrush::QBrush(Qt::BrushStyle style) if (qbrush_check_type(style)) init(Qt::black, style); else { - d = nullBrushInstance(); + d.data_ptr() = nullBrushInstance(); d->ref.ref(); } } @@ -451,7 +482,7 @@ QBrush::QBrush(const QColor &color, Qt::BrushStyle style) if (qbrush_check_type(style)) init(color, style); else { - d = nullBrushInstance(); + d.data_ptr() = nullBrushInstance(); d->ref.ref(); } } @@ -468,7 +499,7 @@ QBrush::QBrush(Qt::GlobalColor color, Qt::BrushStyle style) if (qbrush_check_type(style)) init(color, style); else { - d = nullBrushInstance(); + d.data_ptr() = nullBrushInstance(); d->ref.ref(); } } @@ -510,8 +541,8 @@ QBrush::QBrush(Qt::GlobalColor color, const QPixmap &pixmap) */ QBrush::QBrush(const QBrush &other) + : d(other.d.data()) { - d = other.d; d->ref.ref(); } @@ -535,7 +566,7 @@ QBrush::QBrush(const QGradient &gradient) }; init(QColor(), enum_table[gradient.type()]); - QGradientBrushData *grad = static_cast<QGradientBrushData *>(d); + QGradientBrushData *grad = static_cast<QGradientBrushData *>(d.data()); grad->gradient = gradient; } @@ -545,24 +576,11 @@ QBrush::QBrush(const QGradient &gradient) QBrush::~QBrush() { - if (!d->ref.deref()) - cleanUp(d); } void QBrush::cleanUp(QBrushData *x) { - switch (x->style) { - case Qt::TexturePattern: - delete static_cast<QTexturedBrushData*>(x); - break; - case Qt::LinearGradientPattern: - case Qt::RadialGradientPattern: - case Qt::ConicalGradientPattern: - delete static_cast<QGradientBrushData*>(x); - break; - default: - delete x; - } + QBrushDataPointerHandler::deleteData(x); } @@ -571,38 +589,36 @@ void QBrush::detach(Qt::BrushStyle newStyle) if (newStyle == d->style && d->ref == 1) return; - QBrushData *x; + QScopedPointer<QBrushData> x; switch(newStyle) { case Qt::TexturePattern: { QTexturedBrushData *tbd = new QTexturedBrushData; if (d->style == Qt::TexturePattern) { - QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d); + QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); if (data->m_has_pixmap_texture) tbd->setPixmap(data->pixmap()); else tbd->setImage(data->image()); } - x = tbd; + x.reset(tbd); break; } case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: - x = new QGradientBrushData; - static_cast<QGradientBrushData *>(x)->gradient = - static_cast<QGradientBrushData *>(d)->gradient; + x.reset(new QGradientBrushData); + static_cast<QGradientBrushData *>(x.data())->gradient = + static_cast<QGradientBrushData *>(d.data())->gradient; break; default: - x = new QBrushData; + x.reset(new QBrushData); break; } x->ref = 1; x->style = newStyle; x->color = d->color; x->transform = d->transform; - if (!d->ref.deref()) - cleanUp(d); - d = x; + d.reset(x.take()); } @@ -615,10 +631,11 @@ void QBrush::detach(Qt::BrushStyle newStyle) QBrush &QBrush::operator=(const QBrush &b) { + if (this == &b) + return *this; + b.d->ref.ref(); - if (!d->ref.deref()) - cleanUp(d); - d = b.d; + d.reset(b.d.data()); return *this; } @@ -713,7 +730,7 @@ QPixmap *QBrush::pixmap() const { if (d->style != Qt::TexturePattern) return 0; - QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d); + QTexturedBrushData *data = static_cast<QTexturedBrushData*>(d.data()); QPixmap &pixmap = data->pixmap(); return pixmap.isNull() ? 0 : &pixmap; } @@ -730,7 +747,7 @@ QPixmap *QBrush::pixmap() const QPixmap QBrush::texture() const { return d->style == Qt::TexturePattern - ? ((QTexturedBrushData*) d)->pixmap() + ? (static_cast<QTexturedBrushData *>(d.data()))->pixmap() : QPixmap(); } @@ -748,7 +765,7 @@ void QBrush::setTexture(const QPixmap &pixmap) { if (!pixmap.isNull()) { detach(Qt::TexturePattern); - QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d); + QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); data->setPixmap(pixmap); } else { detach(Qt::NoBrush); @@ -771,7 +788,7 @@ void QBrush::setTexture(const QPixmap &pixmap) QImage QBrush::textureImage() const { return d->style == Qt::TexturePattern - ? ((QTexturedBrushData *) d)->image() + ? (static_cast<QTexturedBrushData *>(d.data()))->image() : QImage(); } @@ -796,7 +813,7 @@ void QBrush::setTextureImage(const QImage &image) { if (!image.isNull()) { detach(Qt::TexturePattern); - QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d); + QTexturedBrushData *data = static_cast<QTexturedBrushData *>(d.data()); data->setImage(image); } else { detach(Qt::NoBrush); @@ -812,7 +829,7 @@ const QGradient *QBrush::gradient() const if (d->style == Qt::LinearGradientPattern || d->style == Qt::RadialGradientPattern || d->style == Qt::ConicalGradientPattern) { - return &static_cast<const QGradientBrushData *>(d)->gradient; + return &static_cast<const QGradientBrushData *>(d.data())->gradient; } return 0; } @@ -923,16 +940,16 @@ bool QBrush::operator==(const QBrush &b) const if (b.d->style == d->style && b.d->color == d->color) { switch (d->style) { case Qt::TexturePattern: { - QPixmap &us = ((QTexturedBrushData *) d)->pixmap(); - QPixmap &them = ((QTexturedBrushData *) b.d)->pixmap(); + QPixmap &us = (static_cast<QTexturedBrushData *>(d.data()))->pixmap(); + QPixmap &them = (static_cast<QTexturedBrushData *>(b.d.data()))->pixmap(); return ((us.isNull() && them.isNull()) || us.cacheKey() == them.cacheKey()); } case Qt::LinearGradientPattern: case Qt::RadialGradientPattern: case Qt::ConicalGradientPattern: { - QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d); - QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d); + QGradientBrushData *d1 = static_cast<QGradientBrushData *>(d.data()); + QGradientBrushData *d2 = static_cast<QGradientBrushData *>(b.d.data()); return d1->gradient == d2->gradient; } default: diff --git a/src/gui/painting/qbrush.h b/src/gui/painting/qbrush.h index d6d0da3..b3aa04d 100644 --- a/src/gui/painting/qbrush.h +++ b/src/gui/painting/qbrush.h @@ -45,6 +45,7 @@ #include <QtCore/qpair.h> #include <QtCore/qpoint.h> #include <QtCore/qvector.h> +#include <QtCore/qscopedpointer.h> #include <QtGui/qcolor.h> #include <QtGui/qmatrix.h> #include <QtGui/qtransform.h> @@ -61,6 +62,7 @@ struct QBrushData; class QPixmap; class QGradient; class QVariant; +struct QBrushDataPointerHandler; class Q_GUI_EXPORT QBrush { @@ -126,13 +128,13 @@ private: friend bool qHasPixmapTexture(const QBrush& brush); void detach(Qt::BrushStyle newStyle); void init(const QColor &color, Qt::BrushStyle bs); - QBrushData *d; + QScopedCustomPointer<QBrushData, QBrushDataPointerHandler> d; void cleanUp(QBrushData *x); public: inline bool isDetached() const; typedef QBrushData * DataPtr; - inline DataPtr &data_ptr() { return d; } + inline DataPtr &data_ptr() { return d.data_ptr(); } }; inline void QBrush::setColor(Qt::GlobalColor acolor) diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp index ed4dd57..0b5e5bb 100644 --- a/src/gui/painting/qdrawhelper.cpp +++ b/src/gui/painting/qdrawhelper.cpp @@ -7426,8 +7426,8 @@ void qt_build_pow_tables() { } #else for (int i=0; i<256; ++i) { - qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / 255.0, smoothing) * 255)); - qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / 255.0, 1 / smoothing) * 255)); + qt_pow_rgb_gamma[i] = uchar(qRound(pow(i / qreal(255), smoothing) * 255)); + qt_pow_rgb_invgamma[i] = uchar(qRound(pow(i / qreal(255), 1 / smoothing) * 255)); } #endif diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp index 7de1ec4..c5be802 100644 --- a/src/gui/painting/qpaintengine.cpp +++ b/src/gui/painting/qpaintengine.cpp @@ -713,7 +713,6 @@ QPaintEngine::QPaintEngine(QPaintEnginePrivate &dptr, PaintEngineFeatures caps) */ QPaintEngine::~QPaintEngine() { - delete d_ptr; } /*! diff --git a/src/gui/painting/qpaintengine.h b/src/gui/painting/qpaintengine.h index 520f71f..6f56adb 100644 --- a/src/gui/painting/qpaintengine.h +++ b/src/gui/painting/qpaintengine.h @@ -44,6 +44,7 @@ #include <QtCore/qnamespace.h> #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> #include <QtGui/qpainter.h> QT_BEGIN_HEADER @@ -239,7 +240,7 @@ protected: uint selfDestruct : 1; uint extended : 1; - QPaintEnginePrivate *d_ptr; + QScopedPointer<QPaintEnginePrivate> d_ptr; private: void setAutoDestruct(bool autoDestr) { selfDestruct = autoDestr; } diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 95b4100..ada3ebf 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -349,6 +349,7 @@ void QRasterPaintEngine::init() #else (unsigned char *) malloc(d->rasterPoolSize); #endif + Q_CHECK_PTR(d->rasterPoolBase); // The antialiasing raster. d->grayRaster = new QT_FT_Raster; @@ -3904,7 +3905,7 @@ static void qt_merge_clip(const QClipData *c1, const QClipData *c2, QClipData *r // find required length int max = qMax(c1_spans[c1_count - 1].x + c1_spans[c1_count - 1].len, - c2_spans[c2_count - 1].x + c2_spans[c2_count - 1].len); + c2_spans[c2_count - 1].x + c2_spans[c2_count - 1].len); buffer.resize(max); memset(buffer.data(), 0, buffer.size() * sizeof(short)); @@ -3958,7 +3959,7 @@ void QRasterPaintEnginePrivate::initializeRasterizer(QSpanData *data) const QClipData *c = clip(); if (c) { const QRect r(QPoint(c->xmin, c->ymin), - QPoint(c->xmax, c->ymax)); + QPoint(c->xmax, c->ymax)); clipRect = clipRect.intersected(r); blend = data->blend; } else { @@ -4066,6 +4067,7 @@ void QRasterPaintEnginePrivate::rasterize(QT_FT_Outline *outline, #else (unsigned char *) malloc(rasterPoolSize); #endif + Q_CHECK_PTR(rasterPoolBase); // note: we just freed the old rasterPoolBase. I hope it's not fatal. qt_ft_grays_raster.raster_done(*grayRaster); qt_ft_grays_raster.raster_new(0, grayRaster); @@ -4301,93 +4303,107 @@ void QClipData::initialize() return; m_clipLines = (ClipLine *)calloc(sizeof(ClipLine), clipSpanHeight); - m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan)); - - if (hasRectClip) { - int y = 0; - while (y < ymin) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; - } + Q_CHECK_PTR(m_clipLines); + QT_TRY { + m_spans = (QSpan *)malloc(clipSpanHeight*sizeof(QSpan)); + Q_CHECK_PTR(m_spans); + + QT_TRY { + if (hasRectClip) { + int y = 0; + while (y < ymin) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } - const int len = clipRect.width(); - count = 0; - while (y < ymax) { - QSpan *span = m_spans + count; - span->x = xmin; - span->len = len; - span->y = y; - span->coverage = 255; - ++count; - - m_clipLines[y].spans = span; - m_clipLines[y].count = 1; - ++y; - } + const int len = clipRect.width(); + count = 0; + while (y < ymax) { + QSpan *span = m_spans + count; + span->x = xmin; + span->len = len; + span->y = y; + span->coverage = 255; + ++count; - while (y < clipSpanHeight) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; - } - } else if (hasRegionClip) { + m_clipLines[y].spans = span; + m_clipLines[y].count = 1; + ++y; + } - const QVector<QRect> rects = clipRegion.rects(); - const int numRects = rects.size(); + while (y < clipSpanHeight) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } + } else if (hasRegionClip) { + + const QVector<QRect> rects = clipRegion.rects(); + const int numRects = rects.size(); + + { // resize + const int maxSpans = (ymax - ymin) * numRects; + if (maxSpans > allocated) { + QSpan *newSpans = (QSpan *)realloc(m_spans, maxSpans * sizeof(QSpan)); + Q_CHECK_PTR(newSpans); + m_spans = newSpans; + allocated = maxSpans; + } + } - { // resize - const int maxSpans = (ymax - ymin) * numRects; - if (maxSpans > allocated) { - m_spans = (QSpan *)realloc(m_spans, maxSpans * sizeof(QSpan)); - allocated = maxSpans; - } - } + int y = 0; + int firstInBand = 0; + while (firstInBand < numRects) { + const int currMinY = rects.at(firstInBand).y(); + const int currMaxY = currMinY + rects.at(firstInBand).height(); - int y = 0; - int firstInBand = 0; - while (firstInBand < numRects) { - const int currMinY = rects.at(firstInBand).y(); - const int currMaxY = currMinY + rects.at(firstInBand).height(); + while (y < currMinY) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } - while (y < currMinY) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; - } + int lastInBand = firstInBand; + while (lastInBand + 1 < numRects && rects.at(lastInBand+1).top() == y) + ++lastInBand; - int lastInBand = firstInBand; - while (lastInBand + 1 < numRects && rects.at(lastInBand+1).top() == y) - ++lastInBand; + while (y < currMaxY) { - while (y < currMaxY) { + m_clipLines[y].spans = m_spans + count; + m_clipLines[y].count = lastInBand - firstInBand + 1; - m_clipLines[y].spans = m_spans + count; - m_clipLines[y].count = lastInBand - firstInBand + 1; + for (int r = firstInBand; r <= lastInBand; ++r) { + const QRect &currRect = rects.at(r); + QSpan *span = m_spans + count; + span->x = currRect.x(); + span->len = currRect.width(); + span->y = y; + span->coverage = 255; + ++count; + } + ++y; + } - for (int r = firstInBand; r <= lastInBand; ++r) { - const QRect &currRect = rects.at(r); - QSpan *span = m_spans + count; - span->x = currRect.x(); - span->len = currRect.width(); - span->y = y; - span->coverage = 255; - ++count; + firstInBand = lastInBand + 1; } - ++y; - } - firstInBand = lastInBand + 1; - } + Q_ASSERT(count <= allocated); - Q_ASSERT(count <= allocated); + while (y < clipSpanHeight) { + m_clipLines[y].spans = 0; + m_clipLines[y].count = 0; + ++y; + } - while (y < clipSpanHeight) { - m_clipLines[y].spans = 0; - m_clipLines[y].count = 0; - ++y; + } + } QT_CATCH(...) { + free(m_spans); + QT_RETHROW; } - + } QT_CATCH(...) { + free(m_clipLines); + QT_RETHROW; } } @@ -4764,8 +4780,10 @@ static void qt_span_clip(int count, const QSpan *spans, void *userData) &newspans, newClip->allocated - newClip->count); newClip->count = newspans - newClip->m_spans; if (spans < end) { + QSpan *newSpan = (QSpan *)realloc(newClip->m_spans, newClip->allocated*2*sizeof(QSpan)); + Q_CHECK_PTR(newSpan); + newClip->m_spans = newSpan; newClip->allocated *= 2; - newClip->m_spans = (QSpan *)realloc(newClip->m_spans, newClip->allocated*sizeof(QSpan)); } } } diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index cc48d24..0caf13b 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -83,6 +83,21 @@ static const qreal aliasedCoordinateDelta = 0.5 - 0.015625; bool qt_show_painter_debug_output = true; #endif +class QPainterPrivateCleaner +{ +public: + static inline void cleanup(QPainterPrivate *d) + { + delete d; + } + + static inline void reset(QPainterPrivate *&d, QPainterPrivate *other) + { + delete d; + d = other; + } +}; + extern QPixmap qt_pixmapForBrush(int style, bool invert); void qt_format_text(const QFont &font, @@ -259,14 +274,17 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev) // in 99% of all cases). E.g: A renders B which renders C which renders D. sp->d_ptr->d_ptrs_size = 4; sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *)); + Q_CHECK_PTR(sp->d_ptr->d_ptrs); } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) { // However, to support corner cases we grow the array dynamically if needed. sp->d_ptr->d_ptrs_size <<= 1; const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *); - sp->d_ptr->d_ptrs = (QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize); + QPainterPrivate ** newPointers = (QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize); + Q_CHECK_PTR(newPointers); + sp->d_ptr->d_ptrs = newPointers; } - sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr; - q->d_ptr = sp->d_ptr; + sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr.data(); + q->d_ptr.data_ptr() = sp->d_ptr.data(); Q_ASSERT(q->d_ptr->state); @@ -315,7 +333,7 @@ void QPainterPrivate::detachPainterPrivate(QPainter *q) d_ptrs[refcount - 1] = 0; q->restore(); - q->d_ptr = original; + q->d_ptr.data_ptr() = original; if (emulationEngine) { extended = emulationEngine->real_engine; @@ -1374,8 +1392,8 @@ void QPainterPrivate::updateState(QPainterState *newState) */ QPainter::QPainter() + : d_ptr(new QPainterPrivate(this)) { - d_ptr = new QPainterPrivate(this); } /*! @@ -1407,7 +1425,7 @@ QPainter::QPainter(QPaintDevice *pd) { Q_ASSERT(pd != 0); if (!QPainterPrivate::attachPainterPrivate(this, pd)) { - d_ptr = new QPainterPrivate(this); + d_ptr.reset(new QPainterPrivate(this)); begin(pd); } Q_ASSERT(d_ptr); @@ -1419,11 +1437,14 @@ QPainter::QPainter(QPaintDevice *pd) QPainter::~QPainter() { d_ptr->inDestructor = true; - if (isActive()) - end(); - else if (d_ptr->refcount > 1) - d_ptr->detachPainterPrivate(this); - + QT_TRY { + if (isActive()) + end(); + else if (d_ptr->refcount > 1) + d_ptr->detachPainterPrivate(this); + } QT_CATCH(...) { + // don't throw anything in the destructor. + } if (d_ptr) { // Make sure we haven't messed things up. Q_ASSERT(d_ptr->inDestructor); @@ -1431,7 +1452,6 @@ QPainter::~QPainter() Q_ASSERT(d_ptr->refcount == 1); if (d_ptr->d_ptrs) free(d_ptr->d_ptrs); - delete d_ptr; } } @@ -7417,8 +7437,21 @@ QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset) void qt_painter_removePaintDevice(QPaintDevice *dev) { - QMutexLocker locker(globalRedirectionsMutex()); - if(QPaintDeviceRedirectionList *redirections = globalRedirections()) { + QMutex *mutex = 0; + QT_TRY { + mutex = globalRedirectionsMutex(); + } QT_CATCH(...) { + // ignore the missing mutex, since we could be called from + // a destructor, and destructors shall not throw + } + QMutexLocker locker(mutex); + QPaintDeviceRedirectionList *redirections = 0; + QT_TRY { + redirections = globalRedirections(); + } QT_CATCH(...) { + // do nothing - code below is safe with redirections being 0. + } + if (redirections) { for (int i = 0; i < redirections->size(); ) { if(redirections->at(i) == dev || redirections->at(i).replacement == dev) redirections->removeAt(i); diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h index f3df7a3..d8c6980 100644 --- a/src/gui/painting/qpainter.h +++ b/src/gui/painting/qpainter.h @@ -45,6 +45,7 @@ #include <QtCore/qnamespace.h> #include <QtCore/qrect.h> #include <QtCore/qpoint.h> +#include <QtCore/qscopedpointer.h> #include <QtGui/qpixmap.h> #include <QtGui/qimage.h> #include <QtGui/qtextoption.h> @@ -78,6 +79,8 @@ class QTextItem; class QMatrix; class QTransform; +class QPainterPrivateCleaner; + class Q_GUI_EXPORT QPainter { Q_DECLARE_PRIVATE(QPainter) @@ -497,7 +500,7 @@ private: Q_DISABLE_COPY(QPainter) friend class Q3Painter; - QPainterPrivate *d_ptr; + QScopedCustomPointer<QPainterPrivate, QPainterPrivateCleaner> d_ptr; friend class QFontEngine; friend class QFontEngineBox; diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp index 1b2c4e3..12dbc62 100644 --- a/src/gui/painting/qpainterpath.cpp +++ b/src/gui/painting/qpainterpath.cpp @@ -506,10 +506,10 @@ QPainterPath::QPainterPath() \sa operator=() */ QPainterPath::QPainterPath(const QPainterPath &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { - if (d_func()) - d_func()->ref.ref(); + if (d_ptr) + d_ptr->ref.ref(); } /*! @@ -530,9 +530,7 @@ QPainterPath::QPainterPath(const QPointF &startPoint) void QPainterPath::detach_helper() { QPainterPathPrivate *data = new QPainterPathData(*d_func()); - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); } /*! @@ -544,9 +542,7 @@ void QPainterPath::ensureData_helper() data->elements.reserve(16); QPainterPath::Element e = { 0, 0, QPainterPath::MoveToElement }; data->elements << e; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); Q_ASSERT(d_ptr != 0); } @@ -563,9 +559,7 @@ QPainterPath &QPainterPath::operator=(const QPainterPath &other) QPainterPathPrivate *data = other.d_func(); if (data) data->ref.ref(); - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = data; + d_ptr.reset(data); } return *this; } @@ -575,8 +569,6 @@ QPainterPath &QPainterPath::operator=(const QPainterPath &other) */ QPainterPath::~QPainterPath() { - if (d_func() && !d_func()->ref.deref()) - delete d_func(); } /*! @@ -2408,7 +2400,6 @@ QPainterPathStroker::QPainterPathStroker() */ QPainterPathStroker::~QPainterPathStroker() { - delete d_ptr; } diff --git a/src/gui/painting/qpainterpath.h b/src/gui/painting/qpainterpath.h index 6cd2af8..0513593 100644 --- a/src/gui/painting/qpainterpath.h +++ b/src/gui/painting/qpainterpath.h @@ -47,6 +47,7 @@ #include <QtCore/qrect.h> #include <QtCore/qline.h> #include <QtCore/qvector.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -195,7 +196,7 @@ public: QPainterPath &operator-=(const QPainterPath &other); private: - QPainterPathPrivate *d_ptr; + QScopedSharedPointer<QPainterPathPrivate> d_ptr; inline void ensureData() { if (!d_ptr) ensureData_helper(); } void ensureData_helper(); @@ -205,7 +206,7 @@ private: void computeBoundingRect() const; void computeControlPointRect() const; - QPainterPathData *d_func() const { return reinterpret_cast<QPainterPathData *>(d_ptr); } + QPainterPathData *d_func() const { return reinterpret_cast<QPainterPathData *>(d_ptr.data()); } friend class QPainterPathData; friend class QPainterPathStroker; @@ -229,6 +230,8 @@ public: friend class QPainterPathStrokerPrivate; friend class QMatrix; friend class QTransform; + friend class QScopedSharedPointer<QPainterPathPrivate>; + friend class QScopedSharedPointerHandler<QPainterPathPrivate>; #ifndef QT_NO_DATASTREAM friend Q_GUI_EXPORT QDataStream &operator<<(QDataStream &, const QPainterPath &); friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QPainterPath &); @@ -279,7 +282,7 @@ public: private: friend class QX11PaintEngine; - QPainterPathStrokerPrivate *d_ptr; + QScopedPointer<QPainterPathStrokerPrivate> d_ptr; }; inline void QPainterPath::moveTo(qreal x, qreal y) diff --git a/src/gui/painting/qprinter.cpp b/src/gui/painting/qprinter.cpp index ed72077..ba6baa6 100644 --- a/src/gui/painting/qprinter.cpp +++ b/src/gui/painting/qprinter.cpp @@ -712,7 +712,6 @@ QPrinter::~QPrinter() #ifndef QT_NO_PRINTPREVIEWWIDGET delete d->previewEngine; #endif - delete d; } /*! diff --git a/src/gui/painting/qprinter.h b/src/gui/painting/qprinter.h index 949c8f9..24e867b 100644 --- a/src/gui/painting/qprinter.h +++ b/src/gui/painting/qprinter.h @@ -42,8 +42,9 @@ #ifndef QPRINTER_H #define QPRINTER_H -#include <QtGui/qpaintdevice.h> #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> +#include <QtGui/qpaintdevice.h> QT_BEGIN_HEADER @@ -288,7 +289,7 @@ private: Q_DISABLE_COPY(QPrinter) - QPrinterPrivate *d_ptr; + QScopedPointer<QPrinterPrivate> d_ptr; friend class QPrintDialogPrivate; friend class QAbstractPrintDialog; diff --git a/src/gui/painting/qprinterinfo.h b/src/gui/painting/qprinterinfo.h index b826306..d188d73 100644 --- a/src/gui/painting/qprinterinfo.h +++ b/src/gui/painting/qprinterinfo.h @@ -53,6 +53,7 @@ QT_MODULE(Gui) #ifndef QT_NO_PRINTER class QPrinterInfoPrivate; +class QPrinterInfoPrivateCleanup; class Q_GUI_EXPORT QPrinterInfo { Q_DECLARE_PRIVATE(QPrinterInfo) @@ -76,7 +77,7 @@ public: private: QPrinterInfo(const QString& name); - QPrinterInfoPrivate* d_ptr; + QScopedCustomPointer<QPrinterInfoPrivate, QPrinterInfoPrivateCleanup> d_ptr; }; #endif // QT_NO_PRINTER diff --git a/src/gui/painting/qprinterinfo_mac.cpp b/src/gui/painting/qprinterinfo_mac.cpp index ecd4b5b..ae689f4 100644 --- a/src/gui/painting/qprinterinfo_mac.cpp +++ b/src/gui/painting/qprinterinfo_mac.cpp @@ -65,6 +65,22 @@ private: static QPrinterInfoPrivate nullQPrinterInfoPrivate; +class QPrinterInfoPrivateCleanup +{ +public: + static inline void cleanup(QPrinterInfoPrivate *d) + { + if (d != &nullQPrinterInfoPrivate) + delete d; + } + + static inline void reset(QPrinterInfoPrivate *&d, QPrinterInfoPrivate *other) + { + cleanup(d); + d = other; + } +}; + extern QPrinter::PaperSize qSizeFTopaperSize(const QSizeF& size); ///////////////////////////////////////////////////////////////////////////// @@ -106,8 +122,8 @@ QPrinterInfo QPrinterInfo::defaultPrinter(){ ///////////////////////////////////////////////////////////////////////////// QPrinterInfo::QPrinterInfo(const QPrinter& prn) + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; QList<QPrinterInfo> list = availablePrinters(); for (int c = 0; c < list.size(); ++c) { if (prn.printerName() == list[c].printerName()) { @@ -115,39 +131,33 @@ QPrinterInfo::QPrinterInfo(const QPrinter& prn) return; } } - - *this = QPrinterInfo(); } QPrinterInfo::~QPrinterInfo() { - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; } QPrinterInfo::QPrinterInfo() + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; } QPrinterInfo::QPrinterInfo(const QString& name) + : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr = new QPrinterInfoPrivate(name); d_ptr->q_ptr = this; } QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; *this = src; } QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; - d_ptr = new QPrinterInfoPrivate(*src.d_ptr); + d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); d_ptr->q_ptr = this; return *this; } diff --git a/src/gui/painting/qprinterinfo_unix.cpp b/src/gui/painting/qprinterinfo_unix.cpp index 0f33ea7..55e3226 100644 --- a/src/gui/painting/qprinterinfo_unix.cpp +++ b/src/gui/painting/qprinterinfo_unix.cpp @@ -82,6 +82,22 @@ private: static QPrinterInfoPrivate nullQPrinterInfoPrivate; +class QPrinterInfoPrivateCleanup +{ +public: + static inline void cleanup(QPrinterInfoPrivate *d) + { + if (d != &nullQPrinterInfoPrivate) + delete d; + } + + static inline void reset(QPrinterInfoPrivate *&d, QPrinterInfoPrivate *other) + { + cleanup(d); + d = other; + } +}; + ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -867,19 +883,19 @@ QPrinterInfo QPrinterInfo::defaultPrinter() } QPrinterInfo::QPrinterInfo() + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; } QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; *this = src; } QPrinterInfo::QPrinterInfo(const QPrinter& printer) + : d_ptr(new QPrinterInfoPrivate(printer.printerName())) { - d_ptr = new QPrinterInfoPrivate(printer.printerName()); Q_D(QPrinterInfo); d->q_ptr = this; @@ -929,28 +945,23 @@ QPrinterInfo::QPrinterInfo(const QPrinter& printer) #endif // Printer not found. - delete d; - d_ptr = &nullQPrinterInfoPrivate; + d_ptr.reset(&nullQPrinterInfoPrivate); } QPrinterInfo::QPrinterInfo(const QString& name) + : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr = new QPrinterInfoPrivate(name); d_ptr->q_ptr = this; } QPrinterInfo::~QPrinterInfo() { - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; } QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; - d_ptr = new QPrinterInfoPrivate(*src.d_ptr); + d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); d_ptr->q_ptr = this; return *this; } diff --git a/src/gui/painting/qprinterinfo_win.cpp b/src/gui/painting/qprinterinfo_win.cpp index 7cd3cf3..7607391 100644 --- a/src/gui/painting/qprinterinfo_win.cpp +++ b/src/gui/painting/qprinterinfo_win.cpp @@ -69,6 +69,22 @@ private: static QPrinterInfoPrivate nullQPrinterInfoPrivate; +class QPrinterInfoPrivateCleanup +{ +public: + static inline void cleanup(QPrinterInfoPrivate *d) + { + if (d != &nullQPrinterInfoPrivate) + delete d; + } + + static inline void reset(QPrinterInfoPrivate *&d, QPrinterInfoPrivate *other) + { + cleanup(d); + d = other; + } +}; + ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -155,25 +171,25 @@ QPrinterInfo QPrinterInfo::defaultPrinter() ///////////////////////////////////////////////////////////////////////////// QPrinterInfo::QPrinterInfo() + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; } QPrinterInfo::QPrinterInfo(const QString& name) + : d_ptr(new QPrinterInfoPrivate(name)) { - d_ptr = new QPrinterInfoPrivate(name); d_ptr->q_ptr = this; } QPrinterInfo::QPrinterInfo(const QPrinterInfo& src) + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; *this = src; } QPrinterInfo::QPrinterInfo(const QPrinter& prn) + : d_ptr(&nullQPrinterInfoPrivate) { - d_ptr = &nullQPrinterInfoPrivate; QList<QPrinterInfo> list = availablePrinters(); for (int c = 0; c < list.size(); ++c) { if (prn.printerName() == list[c].printerName()) { @@ -187,16 +203,12 @@ QPrinterInfo::QPrinterInfo(const QPrinter& prn) QPrinterInfo::~QPrinterInfo() { - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; } QPrinterInfo& QPrinterInfo::operator=(const QPrinterInfo& src) { Q_ASSERT(d_ptr); - if (d_ptr != &nullQPrinterInfoPrivate) - delete d_ptr; - d_ptr = new QPrinterInfoPrivate(*src.d_ptr); + d_ptr.reset(new QPrinterInfoPrivate(*src.d_ptr)); d_ptr->q_ptr = this; return *this; } diff --git a/src/gui/painting/qrasterizer.cpp b/src/gui/painting/qrasterizer.cpp index 583885c..3c06bb4 100644 --- a/src/gui/painting/qrasterizer.cpp +++ b/src/gui/painting/qrasterizer.cpp @@ -436,8 +436,11 @@ void QScanConverter::end() inline void QScanConverter::allocate(int size) { if (m_alloc < size) { - m_alloc = qMax(size, 2 * m_alloc); - m_intersections = (Intersection *)realloc(m_intersections, m_alloc * sizeof(Intersection)); + int newAlloc = qMax(size, 2 * m_alloc); + Intersection *newIntersections = (Intersection *)realloc(m_intersections, newAlloc * sizeof(Intersection)); + Q_CHECK_PTR(newIntersections); + m_alloc = newAlloc; + m_intersections = newIntersections; } } diff --git a/src/gui/painting/qregion.cpp b/src/gui/painting/qregion.cpp index c88af7c..65964de 100644 --- a/src/gui/painting/qregion.cpp +++ b/src/gui/painting/qregion.cpp @@ -3167,6 +3167,7 @@ static void InsertEdgeInET(EdgeTable *ET, EdgeTableEntry *ETE, int scanline, { tmpSLLBlock = (ScanLineListBlock *)malloc(sizeof(ScanLineListBlock)); + Q_CHECK_PTR(tmpSLLBlock); (*SLLBlock)->next = tmpSLLBlock; tmpSLLBlock->next = (ScanLineListBlock *)NULL; *SLLBlock = tmpSLLBlock; @@ -3553,6 +3554,8 @@ static void PtsToRegion(register int numFullPtBlocks, register int iCurPtBlock, * Scan converts a polygon by returning a run-length * encoding of the resultant bitmap -- the run-length * encoding is in the form of an array of rectangles. + * + * Can return 0 in case of errors. */ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) //Point *Pts; /* the pts */ @@ -3624,75 +3627,28 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) } - if (rule == EvenOddRule) { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; ++y) { - - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - + QT_TRY { + if (rule == EvenOddRule) { /* - * for each active edge + * for each scanline */ - while (pAET) { - pts->setX(pAET->bres.minor_axis); - pts->setY(y); - ++pts; - ++iPts; + for (y = ET.ymin; y < ET.ymax; ++y) { /* - * send out the buffer + * Add a new edge to the active edge table when we + * get to the next edge. */ - if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); - tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data); - curPtBlock->next = tmpPtBlock; - curPtBlock = tmpPtBlock; - pts = curPtBlock->pts; - ++numFullPtBlocks; - iPts = 0; + if (pSLL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + pSLL = pSLL->next; } - EVALUATEEDGEEVENODD(pAET, pPrevAET, y) - } - InsertionSort(&AET); - } - } else { - /* - * for each scanline - */ - for (y = ET.ymin; y < ET.ymax; ++y) { - /* - * Add a new edge to the active edge table when we - * get to the next edge. - */ - if (pSLL && y == pSLL->scanline) { - loadAET(&AET, pSLL->edgelist); - computeWAET(&AET); - pSLL = pSLL->next; - } - pPrevAET = &AET; - pAET = AET.next; - pWETE = pAET; + pPrevAET = &AET; + pAET = AET.next; - /* - * for each active edge - */ - while (pAET) { /* - * add to the buffer only those edges that - * are in the Winding active edge table. + * for each active edge */ - if (pWETE == pAET) { + while (pAET) { pts->setX(pAET->bres.minor_axis); pts->setY(y); ++pts; @@ -3702,7 +3658,8 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) * send out the buffer */ if (iPts == NUMPTSTOBUFFER) { - tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK))); + tmpPtBlock = (POINTBLOCK *)malloc(sizeof(POINTBLOCK)); + Q_CHECK_PTR(tmpPtBlock); tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data); curPtBlock->next = tmpPtBlock; curPtBlock = tmpPtBlock; @@ -3710,21 +3667,81 @@ static QRegionPrivate *PolygonRegion(const QPoint *Pts, int Count, int rule) ++numFullPtBlocks; iPts = 0; } - pWETE = pWETE->nextWETE; + EVALUATEEDGEEVENODD(pAET, pPrevAET, y) } - EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) + InsertionSort(&AET); } - + } else { /* - * recompute the winding active edge table if - * we just resorted or have exited an edge. + * for each scanline */ - if (InsertionSort(&AET) || fixWAET) { - computeWAET(&AET); - fixWAET = false; + for (y = ET.ymin; y < ET.ymax; ++y) { + /* + * Add a new edge to the active edge table when we + * get to the next edge. + */ + if (pSLL && y == pSLL->scanline) { + loadAET(&AET, pSLL->edgelist); + computeWAET(&AET); + pSLL = pSLL->next; + } + pPrevAET = &AET; + pAET = AET.next; + pWETE = pAET; + + /* + * for each active edge + */ + while (pAET) { + /* + * add to the buffer only those edges that + * are in the Winding active edge table. + */ + if (pWETE == pAET) { + pts->setX(pAET->bres.minor_axis); + pts->setY(y); + ++pts; + ++iPts; + + /* + * send out the buffer + */ + if (iPts == NUMPTSTOBUFFER) { + tmpPtBlock = static_cast<POINTBLOCK *>(malloc(sizeof(POINTBLOCK))); + tmpPtBlock->pts = reinterpret_cast<QPoint *>(tmpPtBlock->data); + curPtBlock->next = tmpPtBlock; + curPtBlock = tmpPtBlock; + pts = curPtBlock->pts; + ++numFullPtBlocks; + iPts = 0; + } + pWETE = pWETE->nextWETE; + } + EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET) + } + + /* + * recompute the winding active edge table if + * we just resorted or have exited an edge. + */ + if (InsertionSort(&AET) || fixWAET) { + computeWAET(&AET); + fixWAET = false; + } } } + } QT_CATCH(...) { + FreeStorage(SLLBlock.next); + PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); + for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { + tmpPtBlock = curPtBlock->next; + free(curPtBlock); + curPtBlock = tmpPtBlock; + } + free(pETEs); + return 0; // this function returns 0 in case of an error } + FreeStorage(SLLBlock.next); PtsToRegion(numFullPtBlocks, iPts, &FirstPtBlock, region); for (curPtBlock = FirstPtBlock.next; --numFullPtBlocks >= 0;) { @@ -3923,11 +3940,10 @@ QRegion &QRegion::operator=(const QRegion &r) /*! \internal */ - QRegion QRegion::copy() const { QRegion r; - QRegionData *x = new QRegionData; + QScopedPointer<QRegionData> x(new QRegionData); x->ref = 1; #if defined(Q_WS_X11) x->rgn = 0; @@ -3941,7 +3957,7 @@ QRegion QRegion::copy() const x->qt_rgn = new QRegionPrivate; if (!r.d->ref.deref()) cleanUp(r.d); - r.d = x; + r.d = x.take(); return r; } diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 0a6a04e..97178a6 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -115,8 +115,6 @@ QRasterWindowSurface::~QRasterWindowSurface() #endif if (d_ptr->image) delete d_ptr->image; - - delete d_ptr; } diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h index 2a3535f..c10bec3 100644 --- a/src/gui/painting/qwindowsurface_raster_p.h +++ b/src/gui/painting/qwindowsurface_raster_p.h @@ -112,7 +112,7 @@ public: private: void prepareBuffer(QImage::Format format, QWidget *widget); Q_DECLARE_PRIVATE(QRasterWindowSurface) - QRasterWindowSurfacePrivate *d_ptr; + QScopedPointer<QRasterWindowSurfacePrivate> d_ptr; }; QT_END_NAMESPACE diff --git a/src/gui/styles/qs60style.h b/src/gui/styles/qs60style.h index 21cdd1c..d8e9a40 100644 --- a/src/gui/styles/qs60style.h +++ b/src/gui/styles/qs60style.h @@ -90,12 +90,12 @@ public: #endif // !Q_WS_S60 #ifdef Q_WS_S60 -public slots: +public Q_SLOTS: void handleDynamicLayoutVariantSwitch(); void handleSkinChange(); #endif // Q_WS_S60 -protected slots: +protected Q_SLOTS: QIcon standardIconImplementation( StandardPixmap standardIcon, const QStyleOption * option = 0, const QWidget * widget = 0 ) const; diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index dd50d12..e324db6 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -314,7 +314,7 @@ QFontPrivate *QFontPrivate::smallCapsFontPrivate() const font.setPointSizeF(pointSize * .7); else font.setPixelSize((font.pixelSize() * 7 + 5) / 10); - scFont = font.d; + scFont = font.d.data(); if (scFont != this) scFont->ref.ref(); return scFont; @@ -721,12 +721,11 @@ QFont::QFont(const QFont &font, QPaintDevice *pd) const int screen = 0; #endif if (font.d->dpi != dpi || font.d->screen != screen ) { - d = new QFontPrivate(*font.d); + d.reset(new QFontPrivate(*font.d)); d->dpi = dpi; d->screen = screen; } else { - d = font.d; - d->ref.ref(); + d.assign(font.d.data()); } #ifdef Q_WS_WIN if (pd->devType() == QInternal::Printer && pd->getDC()) @@ -740,8 +739,7 @@ QFont::QFont(const QFont &font, QPaintDevice *pd) QFont::QFont(QFontPrivate *data) : resolve_mask(QFont::AllPropertiesResolved) { - d = data; - d->ref.ref(); + d.assign(data); } /*! \internal @@ -753,13 +751,13 @@ void QFont::detach() if (d->engineData) d->engineData->ref.deref(); d->engineData = 0; - if (d->scFont && d->scFont != d) + if (d->scFont && d->scFont != d.data()) d->scFont->ref.deref(); d->scFont = 0; return; } - qAtomicDetach(d); + d.detach(); } /*! @@ -768,9 +766,9 @@ void QFont::detach() \sa QApplication::setFont(), QApplication::font() */ QFont::QFont() - :d(QApplication::font().d), resolve_mask(0) + :resolve_mask(0) { - d->ref.ref(); + d.assign(QApplication::font().d.data()); } /*! @@ -790,8 +788,8 @@ QFont::QFont() setStyleHint() QApplication::font() */ QFont::QFont(const QString &family, int pointSize, int weight, bool italic) - :d(new QFontPrivate) { + d.reset(new QFontPrivate()); resolve_mask = QFont::FamilyResolved; if (pointSize <= 0) { @@ -822,8 +820,7 @@ QFont::QFont(const QString &family, int pointSize, int weight, bool italic) */ QFont::QFont(const QFont &font) { - d = font.d; - d->ref.ref(); + d.assign(font.d.data()); resolve_mask = font.resolve_mask; } @@ -832,8 +829,6 @@ QFont::QFont(const QFont &font) */ QFont::~QFont() { - if (!d->ref.deref()) - delete d; } /*! @@ -841,7 +836,7 @@ QFont::~QFont() */ QFont &QFont::operator=(const QFont &font) { - qAtomicAssign(d, font.d); + d.assign(font.d.data()); resolve_mask = font.resolve_mask; return *this; } @@ -1724,7 +1719,7 @@ QFont QFont::resolve(const QFont &other) const QFont font(*this); font.detach(); - font.d->resolve(resolve_mask, other.d); + font.d->resolve(resolve_mask, other.d.data()); return font; } @@ -2177,11 +2172,11 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) s << (quint8) font.d->request.styleStrategy; s << (quint8) 0 << (quint8) font.d->request.weight - << get_font_bits(s.version(), font.d); + << get_font_bits(s.version(), font.d.data()); if (s.version() >= QDataStream::Qt_4_3) s << (quint16)font.d->request.stretch; if (s.version() >= QDataStream::Qt_4_4) - s << get_extended_font_bits(font.d); + s << get_extended_font_bits(font.d.data()); if (s.version() >= QDataStream::Qt_4_5) { s << font.d->letterSpacing.value(); s << font.d->wordSpacing.value(); @@ -2200,10 +2195,8 @@ QDataStream &operator<<(QDataStream &s, const QFont &font) */ QDataStream &operator>>(QDataStream &s, QFont &font) { - if (!font.d->ref.deref()) - delete font.d; - - font.d = new QFontPrivate; + font.d.assign(0); + font.d.reset(new QFontPrivate); font.resolve_mask = QFont::AllPropertiesResolved; quint8 styleHint, styleStrategy = QFont::PreferDefault, charSet, weight, bits; @@ -2244,7 +2237,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) font.d->request.styleStrategy = styleStrategy; font.d->request.weight = weight; - set_font_bits(s.version(), bits, font.d); + set_font_bits(s.version(), bits, font.d.data()); if (s.version() >= QDataStream::Qt_4_3) { quint16 stretch; @@ -2255,7 +2248,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) if (s.version() >= QDataStream::Qt_4_4) { quint8 extendedBits; s >> extendedBits; - set_extended_font_bits(extendedBits, font.d); + set_extended_font_bits(extendedBits, font.d.data()); } if (s.version() >= QDataStream::Qt_4_5) { int value; @@ -2337,7 +2330,7 @@ QDataStream &operator>>(QDataStream &s, QFont &font) that is not screen-compatible. */ QFontInfo::QFontInfo(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } /*! @@ -2610,7 +2603,14 @@ QFontCache *QFontCache::instance() void QFontCache::cleanup() { - theFontCache()->setLocalData(0); + QThreadStorage<QFontCache *> *cache = 0; + QT_TRY { + cache = theFontCache(); + } QT_CATCH (const std::bad_alloc &) { + // no cache - just ignore + } + if (cache && cache->hasLocalData()) + cache->setLocalData(0); } #endif // QT_NO_THREAD @@ -2623,8 +2623,8 @@ QFontCache::QFontCache() QFontCache::~QFontCache() { { - EngineDataCache::Iterator it = engineDataCache.begin(), - end = engineDataCache.end(); + EngineDataCache::ConstIterator it = engineDataCache.constBegin(), + end = engineDataCache.constEnd(); while (it != end) { if (it.value()->ref == 0) delete it.value(); @@ -2634,8 +2634,8 @@ QFontCache::~QFontCache() ++it; } } - EngineCache::Iterator it = engineCache.begin(), - end = engineCache.end(); + EngineCache::ConstIterator it = engineCache.constBegin(), + end = engineCache.constEnd(); while (it != end) { if (--it.value().data->cache_count == 0) { if (it.value().data->ref == 0) { diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index eec83b5..a513b7a 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -44,6 +44,7 @@ #include <QtGui/qwindowdefs.h> #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> #if defined(Q_WS_X11) || defined(Q_WS_QWS) typedef struct FT_FaceRec_* FT_Face; @@ -312,7 +313,7 @@ private: friend Q_GUI_EXPORT QDataStream &operator>>(QDataStream &, QFont &); #endif - QFontPrivate *d; + QScopedSharedPointer<QFontPrivate> d; uint resolve_mask; }; diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 9426fef..416017d 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -167,10 +167,13 @@ QtFontEncoding *QtFontSize::encodingID(int id, uint xpoint, uint xres, if (!add) return 0; - if (!(count % 4)) - encodings = (QtFontEncoding *) + if (!(count % 4)) { + QtFontEncoding *newEncodings = (QtFontEncoding *) realloc(encodings, (((count+4) >> 2) << 2) * sizeof(QtFontEncoding)); + Q_CHECK_PTR(newEncodings); + encodings = newEncodings; + } encodings[count].encoding = id; encodings[count].xpoint = xpoint; encodings[count].xres = xres; @@ -274,10 +277,13 @@ QtFontSize *QtFontStyle::pixelSize(unsigned short size, bool add) if (!add) return 0; - if (!(count % 8)) - pixelSizes = (QtFontSize *) + if (!(count % 8)) { + QtFontSize *newPixelSizes = (QtFontSize *) realloc(pixelSizes, (((count+8) >> 3) << 3) * sizeof(QtFontSize)); + Q_CHECK_PTR(newPixelSizes); + pixelSizes = newPixelSizes; + } pixelSizes[count].pixelSize = size; #ifdef Q_WS_X11 pixelSizes[count].count = 0; @@ -328,12 +334,16 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create) return 0; // qDebug("adding key (weight=%d, style=%d, oblique=%d stretch=%d) at %d", key.weight, key.style, key.oblique, key.stretch, pos); - if (!(count % 8)) - styles = (QtFontStyle **) + if (!(count % 8)) { + QtFontStyle **newStyles = (QtFontStyle **) realloc(styles, (((count+8) >> 3) << 3) * sizeof(QtFontStyle *)); + Q_CHECK_PTR(newStyles); + styles = newStyles; + } + QtFontStyle *style = new QtFontStyle(key); memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *)); - styles[pos] = new QtFontStyle(key); + styles[pos] = style; count++; return styles[pos]; } @@ -438,10 +448,13 @@ QtFontFoundry *QtFontFamily::foundry(const QString &f, bool create) if (!create) return 0; - if (!(count % 8)) - foundries = (QtFontFoundry **) + if (!(count % 8)) { + QtFontFoundry **newFoundries = (QtFontFoundry **) realloc(foundries, (((count+8) >> 3) << 3) * sizeof(QtFontFoundry *)); + Q_CHECK_PTR(newFoundries); + foundries = newFoundries; + } foundries[count] = new QtFontFoundry(f); return foundries[count++]; @@ -684,13 +697,17 @@ QtFontFamily *QFontDatabasePrivate::family(const QString &f, bool create) pos++; // qDebug("adding family %s at %d total=%d", f.latin1(), pos, count); - if (!(count % 8)) - families = (QtFontFamily **) + if (!(count % 8)) { + QtFontFamily **newFamilies = (QtFontFamily **) realloc(families, (((count+8) >> 3) << 3) * sizeof(QtFontFamily *)); + Q_CHECK_PTR(newFamilies); + families = newFamilies; + } + QtFontFamily *family = new QtFontFamily(f); memmove(families + pos + 1, families + pos, (count-pos)*sizeof(QtFontFamily *)); - families[pos] = new QtFontFamily(f); + families[pos] = family; count++; return families[pos]; } diff --git a/src/gui/text/qfontdatabase_qws.cpp b/src/gui/text/qfontdatabase_qws.cpp index 33b0728..978ff8e 100644 --- a/src/gui/text/qfontdatabase_qws.cpp +++ b/src/gui/text/qfontdatabase_qws.cpp @@ -566,8 +566,8 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QFontEngineQPF *fe = new QFontEngineQPF(request, res.data(), res.size()); if (fe->isValid()) return fe; - qDebug() << "fontengine is not valid! " << size->fileName; delete fe; + qDebug() << "fontengine is not valid! " << size->fileName; } else { qDebug() << "Resource not valid" << size->fileName; } @@ -577,8 +577,8 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, QFontEngineQPF *fe = new QFontEngineQPF(request, f); if (fe->isValid()) return fe; - qDebug() << "fontengine is not valid!"; delete fe; // will close f + qDebug() << "fontengine is not valid!"; } #endif } else @@ -592,70 +592,67 @@ QFontEngine *loadSingleEngine(int script, const QFontPrivate *fp, static bool dontShareFonts = !qgetenv("QWS_NO_SHARE_FONTS").isEmpty(); bool shareFonts = !dontShareFonts; - QFontEngine *engine = 0; + QScopedPointer<QFontEngine> engine; #ifndef QT_NO_LIBRARY QFontEngineFactoryInterface *factory = qobject_cast<QFontEngineFactoryInterface *>(loader()->instance(foundry->name)); - if (factory) { - QFontEngineInfo info; - info.setFamily(request.family); - info.setPixelSize(request.pixelSize); - info.setStyle(QFont::Style(request.style)); - info.setWeight(request.weight); - // #### antialiased - - QAbstractFontEngine *customEngine = factory->create(info); - if (customEngine) { - engine = new QProxyFontEngine(customEngine, def); - - if (shareFonts) { - QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint); - if (hint.isValid()) - shareFonts = hint.toBool(); - else - shareFonts = (pixelSize < 64); - } + if (factory) { + QFontEngineInfo info; + info.setFamily(request.family); + info.setPixelSize(request.pixelSize); + info.setStyle(QFont::Style(request.style)); + info.setWeight(request.weight); + // #### antialiased + + QAbstractFontEngine *customEngine = factory->create(info); + if (customEngine) { + engine.reset(new QProxyFontEngine(customEngine, def)); + + if (shareFonts) { + QVariant hint = customEngine->fontProperty(QAbstractFontEngine::CacheGlyphsHint); + if (hint.isValid()) + shareFonts = hint.toBool(); + else + shareFonts = (pixelSize < 64); } + } } #endif // QT_NO_LIBRARY - if (!engine && !file.isEmpty() && QFile::exists(file) || privateDb()->isApplicationFont(file)) { + if ((engine.isNull() && !file.isEmpty() && QFile::exists(file)) || privateDb()->isApplicationFont(file)) { QFontEngine::FaceId faceId; faceId.filename = file.toLocal8Bit(); faceId.index = size->fileIndex; #ifndef QT_NO_FREETYPE - QFontEngineFT *fte = new QFontEngineFT(def); + QScopedPointer<QFontEngineFT> fte(new QFontEngineFT(def)); if (fte->init(faceId, style->antialiased, style->antialiased ? QFontEngineFT::Format_A8 : QFontEngineFT::Format_Mono)) { #ifdef QT_NO_QWS_QPF2 - return fte; + return fte.take(); #else - engine = fte; // try to distinguish between bdf and ttf fonts we can pre-render // and don't try to share outline fonts shareFonts = shareFonts && !fte->defaultGlyphs()->outline_drawing && !fte->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd')).isEmpty(); + engine.reset(fte.take()); #endif - } else { - delete fte; } #endif // QT_NO_FREETYPE } - if (engine) { + if (!engine.isNull()) { #if !defined(QT_NO_QWS_QPF2) && !defined(QT_FONTS_ARE_RESOURCES) if (shareFonts) { - QFontEngineQPF *fe = new QFontEngineQPF(def, -1, engine); - engine = 0; + QScopedPointer<QFontEngineQPF> fe(new QFontEngineQPF(def, -1, engine.data())); + engine.take(); if (fe->isValid()) - return fe; + return fe.take(); qWarning("Initializing QFontEngineQPF failed for %s", qPrintable(file)); - engine = fe->takeRenderingEngine(); - delete fe; + engine.reset(fe->takeRenderingEngine()); } #endif - return engine; + return engine.take(); } } else { @@ -682,20 +679,22 @@ QFontEngine *loadEngine(int script, const QFontPrivate *fp, QtFontFamily *family, QtFontFoundry *foundry, QtFontStyle *style, QtFontSize *size) { - QFontEngine *fe = loadSingleEngine(script, fp, request, family, foundry, - style, size); - if (fe + QScopedPointer<QFontEngine> engine(loadSingleEngine(script, fp, request, family, foundry, + style, size)); + if (!engine.isNull() && script == QUnicodeTables::Common - && !(request.styleStrategy & QFont::NoFontMerging) && !fe->symbol) { + && !(request.styleStrategy & QFont::NoFontMerging) && !engine->symbol) { QStringList fallbacks = privateDb()->fallbackFamilies; if (family && !family->fallbackFamilies.isEmpty()) fallbacks = family->fallbackFamilies; - fe = new QFontEngineMultiQWS(fe, script, fallbacks); + QFontEngine *fe = new QFontEngineMultiQWS(engine.data(), script, fallbacks); + engine.take(); + engine.reset(fe); } - return fe; + return engine.take(); } static void registerFont(QFontDatabasePrivate::ApplicationFont *fnt) diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index c2c23ee..2f96984 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -191,18 +191,20 @@ QFontEngine::QFontEngine() QFontEngine::~QFontEngine() { - for (GlyphPointerHash::iterator it = m_glyphPointerHash.begin(), end = m_glyphPointerHash.end(); - it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); - it2 != end2; ++it2) - delete *it2; + for (GlyphPointerHash::const_iterator it = m_glyphPointerHash.constBegin(), + end = m_glyphPointerHash.constEnd(); it != end; ++it) { + for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), + end2 = it.value().constEnd(); it2 != end2; ++it2) { + delete *it2; + } } m_glyphPointerHash.clear(); - for (GlyphIntHash::iterator it = m_glyphIntHash.begin(), end = m_glyphIntHash.end(); - it != end; ++it) { - for (QList<QFontEngineGlyphCache*>::iterator it2 = it.value().begin(), end2 = it.value().end(); - it2 != end2; ++it2) - delete *it2; + for (GlyphIntHash::const_iterator it = m_glyphIntHash.constBegin(), + end = m_glyphIntHash.constEnd(); it != end; ++it) { + for (QList<QFontEngineGlyphCache*>::const_iterator it2 = it.value().constBegin(), + end2 = it.value().constEnd(); it2 != end2; ++it2) { + delete *it2; + } } m_glyphIntHash.clear(); qHBFreeFace(hbFace); diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 6f5ee1f..f1dac96 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -193,6 +193,9 @@ HB_Error QFreetypeFace::getPointInOutline(HB_Glyph glyph, int flags, hb_uint32 p /* * One font file can contain more than one font (bold/italic for example) * find the right one and return it. + * + * Returns the freetype face or 0 in case of an empty file or any other problems + * (like not being able to open the file) */ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) { @@ -205,7 +208,7 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) QFreetypeFace *freetype = freetypeData->faces.value(face_id, 0); if (!freetype) { - freetype = new QFreetypeFace; + QScopedPointer<QFreetypeFace> newFreetype(new QFreetypeFace); FT_Face face; QFile file(QString::fromUtf8(face_id.filename)); if (face_id.filename.startsWith(":qmemoryfonts/")) { @@ -214,84 +217,82 @@ QFreetypeFace *QFreetypeFace::getFace(const QFontEngine::FaceId &face_id) QByteArray idx = face_id.filename; idx.remove(0, 14); // remove ':qmemoryfonts/' bool ok = false; - freetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); + newFreetype->fontData = qt_fontdata_from_index(idx.toInt(&ok)); if (!ok) - freetype->fontData = QByteArray(); + newFreetype->fontData = QByteArray(); } else if (!(file.fileEngine()->fileFlags(QAbstractFileEngine::FlagsMask) & QAbstractFileEngine::LocalDiskFlag)) { if (!file.open(QIODevice::ReadOnly)) { - delete freetype; return 0; } - freetype->fontData = file.readAll(); + newFreetype->fontData = file.readAll(); } - if (!freetype->fontData.isEmpty()) { - if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)freetype->fontData.constData(), freetype->fontData.size(), face_id.index, &face)) { - delete freetype; + if (!newFreetype->fontData.isEmpty()) { + if (FT_New_Memory_Face(freetypeData->library, (const FT_Byte *)newFreetype->fontData.constData(), newFreetype->fontData.size(), face_id.index, &face)) { return 0; } } else if (FT_New_Face(freetypeData->library, face_id.filename, face_id.index, &face)) { - delete freetype; return 0; } - freetype->face = face; - - freetype->hbFace = qHBNewFace(face, hb_getSFntTable); - freetype->ref = 0; - freetype->xsize = 0; - freetype->ysize = 0; - freetype->matrix.xx = 0x10000; - freetype->matrix.yy = 0x10000; - freetype->matrix.xy = 0; - freetype->matrix.yx = 0; - freetype->unicode_map = 0; - freetype->symbol_map = 0; + newFreetype->face = face; + + newFreetype->hbFace = qHBNewFace(face, hb_getSFntTable); + newFreetype->ref = 0; + newFreetype->xsize = 0; + newFreetype->ysize = 0; + newFreetype->matrix.xx = 0x10000; + newFreetype->matrix.yy = 0x10000; + newFreetype->matrix.xy = 0; + newFreetype->matrix.yx = 0; + newFreetype->unicode_map = 0; + newFreetype->symbol_map = 0; #ifndef QT_NO_FONTCONFIG - freetype->charset = 0; + newFreetype->charset = 0; #endif - memset(freetype->cmapCache, 0, sizeof(freetype->cmapCache)); + memset(newFreetype->cmapCache, 0, sizeof(newFreetype->cmapCache)); - for (int i = 0; i < freetype->face->num_charmaps; ++i) { - FT_CharMap cm = freetype->face->charmaps[i]; + for (int i = 0; i < newFreetype->face->num_charmaps; ++i) { + FT_CharMap cm = newFreetype->face->charmaps[i]; switch(cm->encoding) { case FT_ENCODING_UNICODE: - freetype->unicode_map = cm; + newFreetype->unicode_map = cm; break; case FT_ENCODING_APPLE_ROMAN: case FT_ENCODING_ADOBE_LATIN_1: - if (!freetype->unicode_map || freetype->unicode_map->encoding != FT_ENCODING_UNICODE) - freetype->unicode_map = cm; + if (!newFreetype->unicode_map || newFreetype->unicode_map->encoding != FT_ENCODING_UNICODE) + newFreetype->unicode_map = cm; break; case FT_ENCODING_ADOBE_CUSTOM: case FT_ENCODING_MS_SYMBOL: - if (!freetype->symbol_map) - freetype->symbol_map = cm; + if (!newFreetype->symbol_map) + newFreetype->symbol_map = cm; break; default: break; } } - if (!FT_IS_SCALABLE(freetype->face) && freetype->face->num_fixed_sizes == 1) - FT_Set_Char_Size (face, X_SIZE(freetype->face, 0), Y_SIZE(freetype->face, 0), 0, 0); + if (!FT_IS_SCALABLE(newFreetype->face) && newFreetype->face->num_fixed_sizes == 1) + FT_Set_Char_Size (face, X_SIZE(newFreetype->face, 0), Y_SIZE(newFreetype->face, 0), 0, 0); # if 0 FcChar8 *name; FcPatternGetString(pattern, FC_FAMILY, 0, &name); qDebug("%s: using maps: default: %x unicode: %x, symbol: %x", name, - freetype->face->charmap ? freetype->face->charmap->encoding : 0, - freetype->unicode_map ? freetype->unicode_map->encoding : 0, - freetype->symbol_map ? freetype->symbol_map->encoding : 0); + newFreetype->face->charmap ? newFreetype->face->charmap->encoding : 0, + newFreetype->unicode_map ? newFreetype->unicode_map->encoding : 0, + newFreetype->symbol_map ? newFreetype->symbol_map->encoding : 0); for (int i = 0; i < 256; i += 8) qDebug(" %x: %d %d %d %d %d %d %d %d", i, - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i), - FcCharSetHasChar(freetype->charset, i), FcCharSetHasChar(freetype->charset, i)); + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i), + FcCharSetHasChar(newFreetype->charset, i), FcCharSetHasChar(newFreetype->charset, i)); #endif - FT_Set_Charmap(freetype->face, freetype->unicode_map); - freetypeData->faces.insert(face_id, freetype); + FT_Set_Charmap(newFreetype->face, newFreetype->unicode_map); + freetypeData->faces.insert(face_id, newFreetype.data()); + freetype = newFreetype.take(); } freetype->ref.ref(); return freetype; @@ -608,6 +609,7 @@ QFontEngineFT::QFontEngineFT(const QFontDef &fd) kerning_pairs_loaded = false; transform = false; antialias = true; + freetype = 0; default_load_flags = 0; default_hint_style = HintNone; subpixelType = Subpixel_None; diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 649d78b..b67895b 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -119,6 +119,7 @@ struct QFreetypeFace static void addBitmapToPath(FT_GlyphSlot slot, const QFixedPoint &point, QPainterPath *path, bool = false); private: + friend class QScopedPointer<QFreetypeFace>; QFreetypeFace() : _lock(QMutex::Recursive) {} ~QFreetypeFace() {} QAtomicInt ref; diff --git a/src/gui/text/qfontengine_qpf.cpp b/src/gui/text/qfontengine_qpf.cpp index e9fcac4..435a102 100644 --- a/src/gui/text/qfontengine_qpf.cpp +++ b/src/gui/text/qfontengine_qpf.cpp @@ -325,21 +325,21 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng fileName.replace(QLatin1Char(' '), QLatin1Char('_')); fileName.prepend(qws_fontCacheDir()); - const QByteArray encodedName = QFile::encodeName(fileName); - if (::access(encodedName, F_OK) == 0) { + encodedFileName = QFile::encodeName(fileName); + if (::access(encodedFileName, F_OK) == 0) { #if defined(DEBUG_FONTENGINE) qDebug() << "found existing qpf:" << fileName; #endif - if (::access(encodedName, W_OK | R_OK) == 0) - fd = ::open(encodedName, O_RDWR); - else if (::access(encodedName, R_OK) == 0) - fd = ::open(encodedName, O_RDONLY); + if (::access(encodedFileName, W_OK | R_OK) == 0) + fd = ::open(encodedFileName, O_RDWR); + else if (::access(encodedFileName, R_OK) == 0) + fd = ::open(encodedFileName, O_RDONLY); } else { #if defined(DEBUG_FONTENGINE) qDebug() << "creating qpf on the fly:" << fileName; #endif if (::access(QFile::encodeName(qws_fontCacheDir()), W_OK) == 0) { - fd = ::open(encodedName, O_RDWR | O_EXCL | O_CREAT, 0644); + fd = ::open(encodedFileName, O_RDWR | O_EXCL | O_CREAT, 0644); QBuffer buffer; buffer.open(QIODevice::ReadWrite); @@ -474,15 +474,21 @@ QFontEngineQPF::QFontEngineQPF(const QFontDef &def, int fileDescriptor, QFontEng #endif #if defined(Q_WS_QWS) if (isValid() && renderingFontEngine) - qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, QFile::encodeName(fileName)); + qt_fbdpy->sendFontCommand(QWSFontCommand::StartedUsingFont, encodedFileName); #endif } QFontEngineQPF::~QFontEngineQPF() { #if defined(Q_WS_QWS) - if (isValid() && renderingFontEngine) - qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, QFile::encodeName(fileName)); + if (isValid() && renderingFontEngine) { + QT_TRY { + qt_fbdpy->sendFontCommand(QWSFontCommand::StoppedUsingFont, encodedFileName); + } QT_CATCH(...) { + qDebug("QFontEngineQPF::~QFontEngineQPF: Out of memory"); + // ignore. + } + } #endif delete renderingFontEngine; if (fontData) @@ -1128,6 +1134,11 @@ void QPFGenerator::writeTaggedQFixed(QFontEngineQPF::HeaderTag tag, QFixed value #endif // QT_NO_QWS_QPF2 +/* + Creates a new multi qws engine. + + This function takes ownership of the QFontEngine, increasing it's refcount. +*/ QFontEngineMultiQWS::QFontEngineMultiQWS(QFontEngine *fe, int _script, const QStringList &fallbacks) : QFontEngineMulti(fallbacks.size() + 1), fallbackFamilies(fallbacks), script(_script) diff --git a/src/gui/text/qfontengine_qpf_p.h b/src/gui/text/qfontengine_qpf_p.h index a9b87ff..629f5c6 100644 --- a/src/gui/text/qfontengine_qpf_p.h +++ b/src/gui/text/qfontengine_qpf_p.h @@ -243,6 +243,7 @@ private: quint32 glyphDataOffset; quint32 glyphDataSize; QString fileName; + QByteArray encodedFileName; bool readOnly; QFreetypeFace *freetype; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 87da628..991fed7 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -164,7 +164,7 @@ extern int qt_defaultDpi(); metrics that are compatible with a certain paint device. */ QFontMetrics::QFontMetrics(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } @@ -196,7 +196,7 @@ QFontMetrics::QFontMetrics(const QFont &font, QPaintDevice *paintdevice) d->dpi = dpi; d->screen = screen; } else { - d = font.d; + d = font.d.data(); d->ref.ref(); } @@ -1006,7 +1006,7 @@ QFontMetricsF &QFontMetricsF::operator=(const QFontMetrics &other) metrics that are compatible with a certain paint device. */ QFontMetricsF::QFontMetricsF(const QFont &font) - : d(font.d) + : d(font.d.data()) { d->ref.ref(); } @@ -1038,7 +1038,7 @@ QFontMetricsF::QFontMetricsF(const QFont &font, QPaintDevice *paintdevice) d->dpi = dpi; d->screen = screen; } else { - d = font.d; + d = font.d.data(); d->ref.ref(); } diff --git a/src/gui/text/qfragmentmap_p.h b/src/gui/text/qfragmentmap_p.h index 737a717..0f0e0ff 100644 --- a/src/gui/text/qfragmentmap_p.h +++ b/src/gui/text/qfragmentmap_p.h @@ -214,6 +214,7 @@ private: template <class Fragment> QFragmentMapData<Fragment>::QFragmentMapData() + : fragments(0) { init(); } @@ -222,6 +223,7 @@ template <class Fragment> void QFragmentMapData<Fragment>::init() { fragments = (Fragment *)malloc(64*fragmentSize); + Q_CHECK_PTR(fragments); head->tag = (((quint32)'p') << 24) | (((quint32)'m') << 16) | (((quint32)'a') << 8) | 'p'; //TAG('p', 'm', 'a', 'p'); head->root = 0; head->freelist = 1; @@ -247,7 +249,9 @@ uint QFragmentMapData<Fragment>::createFragment() // need to create some free space uint needed = qAllocMore((freePos+1)*fragmentSize, 0); Q_ASSERT(needed/fragmentSize > head->allocated); - fragments = (Fragment *)realloc(fragments, needed); + Fragment *newFragments = (Fragment *)realloc(fragments, needed); + Q_CHECK_PTR(newFragments); + fragments = newFragments; head->allocated = needed/fragmentSize; F(freePos).right = 0; } @@ -787,6 +791,8 @@ public: QFragmentMap() {} ~QFragmentMap() { + if (!data.fragments) + return; // in case of out-of-memory, we won't have fragments for (Iterator it = begin(); !it.atEnd(); ++it) it.value()->free(); } diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d41d414..0c55ce5 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -2069,10 +2069,12 @@ void QTextEngine::LayoutData::reallocate(int totalGlyphs) int newAllocated = space_charAttributes + space_glyphs + space_logClusters; Q_ASSERT(newAllocated >= allocated); - void **old_mem = memory; - memory = (void **)::realloc(memory_on_stack ? 0 : old_mem, newAllocated*sizeof(void *)); - if (memory_on_stack && memory) - memcpy(memory, old_mem, allocated*sizeof(void *)); + void **newMem = memory; + newMem = (void **)::realloc(memory_on_stack ? 0 : memory, newAllocated*sizeof(void *)); + Q_CHECK_PTR(newMem); + if (memory_on_stack && newMem) + memcpy(newMem, memory, allocated*sizeof(void *)); + memory = newMem; memory_on_stack = false; void **m = memory; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index fa624ef..6c67a68 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -367,7 +367,7 @@ QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *p QFont f(font); if (paintdevice) f = QFont(font, paintdevice); - d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d); + d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d.data()); } /*! diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index e1b9844..0f24d9b 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -117,7 +117,13 @@ QTextOption &QTextOption::operator=(const QTextOption &o) { if (this == &o) return *this; - delete d; d = 0; + + QTextOptionPrivate* dNew = 0; + if (o.d) + dNew = new QTextOptionPrivate(*o.d); + delete d; + d = dNew; + align = o.align; wordWrap = o.wordWrap; design = o.design; @@ -125,8 +131,6 @@ QTextOption &QTextOption::operator=(const QTextOption &o) unused = o.unused; f = o.f; tab = o.tab; - if (o.d) - d = new QTextOptionPrivate(*o.d); return *this; } diff --git a/src/gui/text/qtexttable.cpp b/src/gui/text/qtexttable.cpp index 48708c9..edba2c4 100644 --- a/src/gui/text/qtexttable.cpp +++ b/src/gui/text/qtexttable.cpp @@ -432,6 +432,13 @@ void QTextTablePrivate::fragmentRemoved(const QChar &type, uint fragment) QTextFramePrivate::fragmentRemoved(type, fragment); } +/*! + /fn void QTextTablePrivate::update() const + + This function is usually called when the table is "dirty". + It seems to update all kind of table information. + +*/ void QTextTablePrivate::update() const { Q_Q(const QTextTable); @@ -439,7 +446,9 @@ void QTextTablePrivate::update() const nRows = (cells.size() + nCols-1)/nCols; // qDebug(">>>> QTextTablePrivate::update, nRows=%d, nCols=%d", nRows, nCols); - grid = (int *)realloc(grid, nRows*nCols*sizeof(int)); + int* newGrid = (int *)realloc(grid, nRows*nCols*sizeof(int)); + Q_CHECK_PTR(newGrid); + grid = newGrid; memset(grid, 0, nRows*nCols*sizeof(int)); QTextDocumentPrivate *p = pieceTable; @@ -463,7 +472,9 @@ void QTextTablePrivate::update() const cellIndices[i] = cell; if (r + rowspan > nRows) { - grid = (int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols); + newGrid = (int *)realloc(grid, sizeof(int)*(r + rowspan)*nCols); + Q_CHECK_PTR(newGrid); + grid = newGrid; memset(grid + (nRows*nCols), 0, sizeof(int)*(r+rowspan-nRows)*nCols); nRows = r + rowspan; } diff --git a/src/gui/text/qzip.cpp b/src/gui/text/qzip.cpp index c6c2e69..04f081e 100644 --- a/src/gui/text/qzip.cpp +++ b/src/gui/text/qzip.cpp @@ -695,7 +695,7 @@ void QZipWriterPrivate::addEntry(EntryType type, const QString &fileName, const */ QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode) { - QFile *f = new QFile(archive); + QScopedPointer<QFile> f(new QFile(archive)); f->open(mode); QZipReader::Status status; if (f->error() == QFile::NoError) @@ -711,7 +711,8 @@ QZipReader::QZipReader(const QString &archive, QIODevice::OpenMode mode) status = FileError; } - d = new QZipReaderPrivate(f, /*ownDevice=*/true); + d = new QZipReaderPrivate(f.data(), /*ownDevice=*/true); + f.take(); d->status = status; } @@ -969,7 +970,7 @@ void QZipReader::close() */ QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode) { - QFile *f = new QFile(fileName); + QScopedPointer<QFile> f(new QFile(fileName)); f->open(mode); QZipWriter::Status status; if (f->error() == QFile::NoError) @@ -985,7 +986,8 @@ QZipWriter::QZipWriter(const QString &fileName, QIODevice::OpenMode mode) status = QZipWriter::FileError; } - d = new QZipWriterPrivate(f, /*ownDevice=*/true); + d = new QZipWriterPrivate(f.data(), /*ownDevice=*/true); + f.take(); d->status = status; } diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp index 9886969..1ff56e8 100644 --- a/src/gui/widgets/qabstractscrollarea.cpp +++ b/src/gui/widgets/qabstractscrollarea.cpp @@ -281,8 +281,8 @@ void QAbstractScrollAreaPrivate::init() scrollBarContainers[Qt::Vertical]->setVisible(false); QObject::connect(vbar, SIGNAL(valueChanged(int)), q, SLOT(_q_vslide(int))); QObject::connect(vbar, SIGNAL(rangeChanged(int,int)), q, SLOT(_q_showOrHideScrollBars()), Qt::QueuedConnection); - viewportFilter = new QAbstractScrollAreaFilter(this); - viewport->installEventFilter(viewportFilter); + viewportFilter.reset(new QAbstractScrollAreaFilter(this)); + viewport->installEventFilter(viewportFilter.data()); viewport->setFocusProxy(q); q->setFocusPolicy(Qt::WheelFocus); q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken); @@ -471,7 +471,12 @@ QAbstractScrollArea::QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget :QFrame(dd, parent) { Q_D(QAbstractScrollArea); - d->init(); + QT_TRY { + d->init(); + } QT_CATCH(...) { + d->viewportFilter.reset(); + QT_RETHROW; + } } /*! @@ -483,7 +488,12 @@ QAbstractScrollArea::QAbstractScrollArea(QWidget *parent) :QFrame(*new QAbstractScrollAreaPrivate, parent) { Q_D(QAbstractScrollArea); - d->init(); + QT_TRY { + d->init(); + } QT_CATCH(...) { + d->viewportFilter.reset(); + QT_RETHROW; + } } @@ -493,7 +503,8 @@ QAbstractScrollArea::QAbstractScrollArea(QWidget *parent) QAbstractScrollArea::~QAbstractScrollArea() { Q_D(QAbstractScrollArea); - delete d->viewportFilter; + // reset it here, otherwise we'll have a dangling pointer in ~QWidget + d->viewportFilter.reset(); } @@ -517,7 +528,7 @@ void QAbstractScrollArea::setViewport(QWidget *widget) d->viewport = widget; d->viewport->setParent(this); d->viewport->setFocusProxy(this); - d->viewport->installEventFilter(d->viewportFilter); + d->viewport->installEventFilter(d->viewportFilter.data()); d->layoutChildren(); if (isVisible()) d->viewport->show(); diff --git a/src/gui/widgets/qabstractscrollarea_p.h b/src/gui/widgets/qabstractscrollarea_p.h index e4c47e9..999bdfc 100644 --- a/src/gui/widgets/qabstractscrollarea_p.h +++ b/src/gui/widgets/qabstractscrollarea_p.h @@ -98,7 +98,7 @@ public: inline bool viewportEvent(QEvent *event) { return q_func()->viewportEvent(event); } - QObject *viewportFilter; + QScopedPointer<QObject> viewportFilter; }; class QAbstractScrollAreaFilter : public QObject diff --git a/src/gui/widgets/qmacnativewidget_mac.h b/src/gui/widgets/qmacnativewidget_mac.h index 4db65e0..d36d74f 100644 --- a/src/gui/widgets/qmacnativewidget_mac.h +++ b/src/gui/widgets/qmacnativewidget_mac.h @@ -64,7 +64,7 @@ protected: bool event(QEvent *ev); private: - Q_DECLARE_PRIVATE_D(QWidget::d_ptr, QMacNativeWidget) + Q_DECLARE_PRIVATE(QMacNativeWidget) }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp index 48c2cf6..0e5261c 100644 --- a/src/gui/widgets/qmenu_symbian.cpp +++ b/src/gui/widgets/qmenu_symbian.cpp @@ -149,14 +149,14 @@ static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMe // ### FIX THIS, the qt_strippedText2 doesn't work perfectly for stripping & marks. Same bug is in QAction // New really working method is needed in a place where the implementation isn't copy/pasted QString text = qt_strippedText_copy_from_qaction(action->action->text()); - HBufC* menuItemText = qt_QString2HBufCNewL(text); + TPtrC menuItemText(qt_QString2TPtrC(text)); if (action->action->menu()) { SymbianMenuItem* menuItem = new SymbianMenuItem(); menuItem->menuItemData.iCascadeId = action->command; menuItem->menuItemData.iCommandId = action->command; menuItem->menuItemData.iFlags = 0; - menuItem->menuItemData.iText = *menuItemText; + menuItem->menuItemData.iText = menuItemText; menuItem->action = action->action; if (action->action->menu()->actions().size() == 0 || !action->action->isEnabled() ) menuItem->menuItemData.iFlags |= EEikMenuItemDimmed; @@ -177,7 +177,7 @@ static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMe menuItem->menuItemData.iCascadeId = 0; menuItem->menuItemData.iCommandId = action->command; menuItem->menuItemData.iFlags = 0; - menuItem->menuItemData.iText = *menuItemText; + menuItem->menuItemData.iText = menuItemText; menuItem->action = action->action; if (!action->action->isEnabled()){ menuItem->menuItemData.iFlags += EEikMenuItemDimmed; @@ -191,7 +191,6 @@ static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMe } parent->append(menuItem); } - delete menuItemText; } } diff --git a/src/gui/widgets/qmenudata.h b/src/gui/widgets/qmenudata.h index 24d960a..d570f20 100644 --- a/src/gui/widgets/qmenudata.h +++ b/src/gui/widgets/qmenudata.h @@ -67,6 +67,8 @@ private: friend class QMenuBar; void setId(int); void setSignalValue(int); + + Q_DISABLE_COPY(QMenuItem); }; QT_END_NAMESPACE diff --git a/src/gui/widgets/qprintpreviewwidget.cpp b/src/gui/widgets/qprintpreviewwidget.cpp index 16334b8..80c1271 100644 --- a/src/gui/widgets/qprintpreviewwidget.cpp +++ b/src/gui/widgets/qprintpreviewwidget.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qprintpreviewwidget.h" +#include "private/qwidget_p.h" #include <private/qprinter_p.h> #include <QtCore/qmath.h> @@ -170,12 +171,12 @@ protected: } // anonymous namespace -class QPrintPreviewWidgetPrivate +class QPrintPreviewWidgetPrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QPrintPreviewWidget) public: - QPrintPreviewWidgetPrivate(QPrintPreviewWidget *q) - : q_ptr(q), scene(0), curPage(1), + QPrintPreviewWidgetPrivate() + : scene(0), curPage(1), viewMode(QPrintPreviewWidget::SinglePageView), zoomMode(QPrintPreviewWidget::FitInView), zoomFactor(1), initialized(false), fitting(true) @@ -194,7 +195,6 @@ public: void setZoomFactor(qreal zoomFactor); int calcCurrentPage(); - QPrintPreviewWidget *q_ptr; GraphicsView *graphicsView; QGraphicsScene *scene; @@ -518,7 +518,7 @@ void QPrintPreviewWidgetPrivate::setZoomFactor(qreal _zoomFactor) \sa QWidget::setWindowFlags() */ QPrintPreviewWidget::QPrintPreviewWidget(QPrinter *printer, QWidget *parent, Qt::WindowFlags flags) - : QWidget(parent, flags), d_ptr(new QPrintPreviewWidgetPrivate(this)) + : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags) { Q_D(QPrintPreviewWidget); d->printer = printer; @@ -534,7 +534,7 @@ QPrintPreviewWidget::QPrintPreviewWidget(QPrinter *printer, QWidget *parent, Qt: preview. */ QPrintPreviewWidget::QPrintPreviewWidget(QWidget *parent, Qt::WindowFlags flags) - : QWidget(parent, flags), d_ptr(new QPrintPreviewWidgetPrivate(this)) + : QWidget(*new QPrintPreviewWidgetPrivate, parent, flags) { Q_D(QPrintPreviewWidget); d->printer = new QPrinter; @@ -551,7 +551,6 @@ QPrintPreviewWidget::~QPrintPreviewWidget() Q_D(QPrintPreviewWidget); if (d->ownPrinter) delete d->printer; - delete d_ptr; } /*! diff --git a/src/gui/widgets/qprintpreviewwidget.h b/src/gui/widgets/qprintpreviewwidget.h index 27110a4..9f7ea6e 100644 --- a/src/gui/widgets/qprintpreviewwidget.h +++ b/src/gui/widgets/qprintpreviewwidget.h @@ -111,7 +111,7 @@ Q_SIGNALS: void previewChanged(); private: - QPrintPreviewWidgetPrivate *d_ptr; + void *dummy; // ### remove in Qt 5.0 Q_PRIVATE_SLOT(d_func(), void _q_fit()) Q_PRIVATE_SLOT(d_func(), void _q_updateCurrentPage()) }; diff --git a/src/network/access/qftp.cpp b/src/network/access/qftp.cpp index 569d2fd..c54c420 100644 --- a/src/network/access/qftp.cpp +++ b/src/network/access/qftp.cpp @@ -314,8 +314,10 @@ void QFtpDTP::connectToHost(const QString & host, quint16 port) { bytesFromSocket.clear(); - if (socket) + if (socket) { delete socket; + socket = 0; + } socket = new QTcpSocket(this); socket->setObjectName(QLatin1String("QFtpDTP Passive state socket")); connect(socket, SIGNAL(connected()), SLOT(socketConnected())); @@ -1658,11 +1660,12 @@ QFtp::QFtp(QObject *parent, const char *name) */ int QFtp::connectToHost(const QString &host, quint16 port) { - d_func()->pi.transferConnectionExtended = true; QStringList cmds; cmds << host; cmds << QString::number((uint)port); - return d_func()->addCommand(new QFtpCommand(ConnectToHost, cmds)); + int id = d_func()->addCommand(new QFtpCommand(ConnectToHost, cmds)); + d_func()->pi.transferConnectionExtended = true; + return id; } /*! @@ -1721,9 +1724,10 @@ int QFtp::close() */ int QFtp::setTransferMode(TransferMode mode) { + int id = d_func()->addCommand(new QFtpCommand(SetTransferMode, QStringList())); d_func()->pi.transferConnectionExtended = true; d_func()->transferMode = mode; - return d_func()->addCommand(new QFtpCommand(SetTransferMode, QStringList())); + return id; } /*! diff --git a/src/network/access/qhttp.cpp b/src/network/access/qhttp.cpp index 30befb3..332c67b 100644 --- a/src/network/access/qhttp.cpp +++ b/src/network/access/qhttp.cpp @@ -624,7 +624,6 @@ QHttpHeader::QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header) */ QHttpHeader::~QHttpHeader() { - delete d_ptr; } /*! diff --git a/src/network/access/qhttp.h b/src/network/access/qhttp.h index 771176a..d575644 100644 --- a/src/network/access/qhttp.h +++ b/src/network/access/qhttp.h @@ -46,6 +46,7 @@ #include <QtCore/qstringlist.h> #include <QtCore/qmap.h> #include <QtCore/qpair.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -108,7 +109,7 @@ protected: QHttpHeader(QHttpHeaderPrivate &dd, const QString &str = QString()); QHttpHeader(QHttpHeaderPrivate &dd, const QHttpHeader &header); - QHttpHeaderPrivate *d_ptr; + QScopedPointer<QHttpHeaderPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QHttpHeader) diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp index ae518df..cec9c87 100644 --- a/src/network/access/qhttpnetworkconnection.cpp +++ b/src/network/access/qhttpnetworkconnection.cpp @@ -77,8 +77,10 @@ QHttpNetworkConnectionPrivate::QHttpNetworkConnectionPrivate(const QString &host QHttpNetworkConnectionPrivate::~QHttpNetworkConnectionPrivate() { for (int i = 0; i < channelCount; ++i) { - channels[i].socket->close(); - delete channels[i].socket; + if (channels[i].socket) { + channels[i].socket->close(); + delete channels[i].socket; + } } } diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h index 09bd459..0f80bd9 100644 --- a/src/network/access/qhttpnetworkconnection_p.h +++ b/src/network/access/qhttpnetworkconnection_p.h @@ -244,8 +244,8 @@ public: #ifndef QT_NO_OPENSSL bool ignoreSSLErrors; #endif - Channel() :state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), reconnectAttempts(2), - authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) + Channel() : socket(0), state(IdleState), reply(0), written(0), bytesTotal(0), resendCurrent(false), + reconnectAttempts(2), authMehtod(QAuthenticatorPrivate::None), proxyAuthMehtod(QAuthenticatorPrivate::None) #ifndef QT_NO_OPENSSL , ignoreSSLErrors(false) #endif diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp index f214699..4874d9d 100644 --- a/src/network/access/qnetworkaccesshttpbackend.cpp +++ b/src/network/access/qnetworkaccesshttpbackend.cpp @@ -605,6 +605,7 @@ void QNetworkAccessHttpBackend::open() QNetworkAccessCache *cache = QNetworkAccessManagerPrivate::getCache(this); if ((http = static_cast<QNetworkAccessHttpBackendCache *>(cache->requestEntryNow(cacheKey))) == 0) { // no entry in cache; create an object + //### thiago: can we try/catch/ignore this???? http = new QNetworkAccessHttpBackendCache(url.host(), url.port(), encrypt); #ifndef QT_NO_NETWORKPROXY @@ -732,10 +733,15 @@ void QNetworkAccessHttpBackend::replyFinished() // store the SSL configuration now // once we call finished(), we won't have access to httpReply anymore QSslConfiguration sslConfig = httpReply->sslConfiguration(); - if (pendingSslConfiguration) + if (pendingSslConfiguration) { *pendingSslConfiguration = sslConfig; - else if (!sslConfig.isNull()) - pendingSslConfiguration = new QSslConfiguration(sslConfig); + } else if (!sslConfig.isNull()) { + QT_TRY { + pendingSslConfiguration = new QSslConfiguration(sslConfig); + } QT_CATCH(...) { + qWarning("QNetworkAccess: could not allocate a QSslConfiguration object for a SSL connection."); + } + } #endif finished(); diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index bcbeef1..38e8af9 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -748,8 +748,8 @@ void QNetworkAccessManagerPrivate::createCookieJar() const if (!cookieJarCreated) { // keep the ugly hack in here QNetworkAccessManagerPrivate *that = const_cast<QNetworkAccessManagerPrivate *>(this); - that->cookieJarCreated = true; that->cookieJar = new QNetworkCookieJar(that->q_func()); + that->cookieJarCreated = true; } } diff --git a/src/network/access/qnetworkdiskcache.cpp b/src/network/access/qnetworkdiskcache.cpp index 44a8298..daa2335 100644 --- a/src/network/access/qnetworkdiskcache.cpp +++ b/src/network/access/qnetworkdiskcache.cpp @@ -43,6 +43,7 @@ #include "qnetworkdiskcache.h" #include "qnetworkdiskcache_p.h" +#include "QtCore/qscopedpointer.h" #include <qfile.h> #include <qdir.h> @@ -180,8 +181,7 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) break; } } - - QCacheItem *cacheItem = new QCacheItem; + QScopedPointer<QCacheItem> cacheItem(new QCacheItem); cacheItem->metaData = metaData; QIODevice *device = 0; @@ -190,16 +190,20 @@ QIODevice *QNetworkDiskCache::prepare(const QNetworkCacheMetaData &metaData) device = &(cacheItem->data); } else { QString templateName = d->tmpCacheFileName(); - cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data); - if (!cacheItem->file->open()) { + QT_TRY { + cacheItem->file = new QTemporaryFile(templateName, &cacheItem->data); + } QT_CATCH(...) { + cacheItem->file = 0; + } + if (!cacheItem->file || !cacheItem->file->open()) { qWarning() << "QNetworkDiskCache::prepare() unable to open temporary file"; - delete cacheItem; + cacheItem.reset(); return 0; } cacheItem->writeHeader(cacheItem->file); device = cacheItem->file; } - d->inserting[device] = cacheItem; + d->inserting[device] = cacheItem.take(); return device; } @@ -358,31 +362,28 @@ QIODevice *QNetworkDiskCache::data(const QUrl &url) qDebug() << "QNetworkDiskCache::data()" << url; #endif Q_D(QNetworkDiskCache); - QBuffer *buffer = 0; + QScopedPointer<QBuffer> buffer; if (!url.isValid()) - return buffer; + return 0; if (d->lastItem.metaData.url() == url && d->lastItem.data.isOpen()) { - buffer = new QBuffer; + buffer.reset(new QBuffer); buffer->setData(d->lastItem.data.data()); } else { - QFile *file = new QFile(d->cacheFileName(url)); - if (!file->open(QFile::ReadOnly | QIODevice::Unbuffered)) { - delete file; + QScopedPointer<QFile> file(new QFile(d->cacheFileName(url))); + if (!file->open(QFile::ReadOnly | QIODevice::Unbuffered)) return 0; - } - if (!d->lastItem.read(file, true)) { + + if (!d->lastItem.read(file.data(), true)) { file->close(); remove(url); - delete file; return 0; } if (d->lastItem.data.isOpen()) { // compressed - buffer = new QBuffer; + buffer.reset(new QBuffer); buffer->setData(d->lastItem.data.data()); - delete file; } else { - buffer = new QBuffer; + buffer.reset(new QBuffer); // ### verify that QFile uses the fd size and not the file name qint64 size = file->size() - file->pos(); const uchar *p = 0; @@ -390,16 +391,15 @@ QIODevice *QNetworkDiskCache::data(const QUrl &url) p = file->map(file->pos(), size); #endif if (p) { - file->setParent(buffer); buffer->setData((const char *)p, size); + file.take()->setParent(buffer.data()); } else { buffer->setData(file->readAll()); - delete file; } } } buffer->open(QBuffer::ReadOnly); - return buffer; + return buffer.take(); } /*! diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index 4f9ea52..2ff561a 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -216,10 +216,9 @@ public: url = other.url; #ifndef QT_NO_OPENSSL + sslConfiguration = 0; if (other.sslConfiguration) sslConfiguration = new QSslConfiguration(*other.sslConfiguration); - else - sslConfiguration = 0; #endif } diff --git a/src/network/kernel/qhostaddress.cpp b/src/network/kernel/qhostaddress.cpp index b225c17..a3634ce 100644 --- a/src/network/kernel/qhostaddress.cpp +++ b/src/network/kernel/qhostaddress.cpp @@ -523,7 +523,7 @@ QHostAddress::QHostAddress(const struct sockaddr *sockaddr) Constructs a copy of the given \a address. */ QHostAddress::QHostAddress(const QHostAddress &address) - : d(new QHostAddressPrivate(*address.d)) + : d(new QHostAddressPrivate(*address.d.data())) { } @@ -559,7 +559,6 @@ QHostAddress::QHostAddress(SpecialAddress address) */ QHostAddress::~QHostAddress() { - delete d; } /*! @@ -568,7 +567,7 @@ QHostAddress::~QHostAddress() */ QHostAddress &QHostAddress::operator=(const QHostAddress &address) { - *d = *address.d; + *d.data() = *address.d.data(); return *this; } diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h index 02a6f97..857b4af 100644 --- a/src/network/kernel/qhostaddress.h +++ b/src/network/kernel/qhostaddress.h @@ -44,6 +44,7 @@ #include <QtCore/qpair.h> #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qabstractsocket.h> struct sockaddr; @@ -130,7 +131,7 @@ public: static QPair<QHostAddress, int> parseSubnet(const QString &subnet); protected: - QHostAddressPrivate *d; + QScopedPointer<QHostAddressPrivate> d; }; inline bool operator ==(QHostAddress::SpecialAddress address1, const QHostAddress &address2) diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp index ca4124d..1858e02 100644 --- a/src/network/kernel/qhostinfo.cpp +++ b/src/network/kernel/qhostinfo.cpp @@ -42,6 +42,7 @@ #include "qhostinfo.h" #include "qhostinfo_p.h" +#include "QtCore/qscopedpointer.h" #include <qabstracteventdispatcher.h> #include <private/qunicodetables_p.h> #include <qcoreapplication.h> @@ -165,24 +166,24 @@ int QHostInfo::lookupHost(const QString &name, QObject *receiver, // Support for IDNA QString lookup = QString::fromLatin1(QUrl::toAce(name)); - QHostInfoResult *result = new QHostInfoResult; - result->autoDelete = false; - QObject::connect(result, SIGNAL(resultsReady(QHostInfo)), + QScopedPointer<QHostInfoResult> result(new QHostInfoResult); + result.data()->autoDelete = false; + QObject::connect(result.data(), SIGNAL(resultsReady(QHostInfo)), receiver, member); - int id = result->lookupId = theIdCounter.fetchAndAddRelaxed(1); + int id = result.data()->lookupId = theIdCounter.fetchAndAddRelaxed(1); if (lookup.isEmpty()) { QHostInfo info(id); info.setError(QHostInfo::HostNotFound); info.setErrorString(QObject::tr("No host name given")); - QMetaObject::invokeMethod(result, "emitResultsReady", Qt::QueuedConnection, + QMetaObject::invokeMethod(result.data(), "emitResultsReady", Qt::QueuedConnection, Q_ARG(QHostInfo, info)); - result->autoDelete = true; + result.take()->autoDelete = true; return id; } QHostInfoAgent *agent = theAgent(); - agent->addHostName(lookup, result); + agent->addHostName(lookup, result.take()); #if !defined QT_NO_THREAD if (!agent->isRunning()) @@ -327,7 +328,7 @@ QHostInfo::QHostInfo(int id) Constructs a copy of \a other. */ QHostInfo::QHostInfo(const QHostInfo &other) - : d(new QHostInfoPrivate(*other.d)) + : d(new QHostInfoPrivate(*other.d.data())) { } @@ -337,7 +338,7 @@ QHostInfo::QHostInfo(const QHostInfo &other) */ QHostInfo &QHostInfo::operator=(const QHostInfo &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } @@ -346,7 +347,6 @@ QHostInfo &QHostInfo::operator=(const QHostInfo &other) */ QHostInfo::~QHostInfo() { - delete d; } /*! diff --git a/src/network/kernel/qhostinfo.h b/src/network/kernel/qhostinfo.h index 084ec89..c68b111 100644 --- a/src/network/kernel/qhostinfo.h +++ b/src/network/kernel/qhostinfo.h @@ -43,6 +43,7 @@ #define QHOSTINFO_H #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qhostaddress.h> QT_BEGIN_HEADER @@ -91,7 +92,7 @@ public: static QString localDomainName(); private: - QHostInfoPrivate *d; + QScopedPointer<QHostInfoPrivate> d; }; QT_END_NAMESPACE diff --git a/src/network/kernel/qhostinfo_unix.cpp b/src/network/kernel/qhostinfo_unix.cpp index 3271deb..f5d7166 100644 --- a/src/network/kernel/qhostinfo_unix.cpp +++ b/src/network/kernel/qhostinfo_unix.cpp @@ -320,6 +320,8 @@ QString QHostInfo::localDomainName() if (local_res_ninit) { // using thread-safe version res_state_ptr state = res_state_ptr(qMalloc(sizeof(*state))); + if (!state) + qBadAlloc(); memset(state, 0, sizeof(*state)); local_res_ninit(state); QString domainName = QUrl::fromAce(state->defdname); diff --git a/src/network/kernel/qnetworkinterface.cpp b/src/network/kernel/qnetworkinterface.cpp index ff3624e..f8fff88 100644 --- a/src/network/kernel/qnetworkinterface.cpp +++ b/src/network/kernel/qnetworkinterface.cpp @@ -170,7 +170,7 @@ QNetworkAddressEntry::QNetworkAddressEntry() object \a other. */ QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other) - : d(new QNetworkAddressEntryPrivate(*other.d)) + : d(new QNetworkAddressEntryPrivate(*other.d.data())) { } @@ -179,7 +179,7 @@ QNetworkAddressEntry::QNetworkAddressEntry(const QNetworkAddressEntry &other) */ QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } @@ -188,7 +188,6 @@ QNetworkAddressEntry &QNetworkAddressEntry::operator=(const QNetworkAddressEntry */ QNetworkAddressEntry::~QNetworkAddressEntry() { - delete d; } /*! diff --git a/src/network/kernel/qnetworkinterface.h b/src/network/kernel/qnetworkinterface.h index 09fbd0f..dd16550 100644 --- a/src/network/kernel/qnetworkinterface.h +++ b/src/network/kernel/qnetworkinterface.h @@ -43,6 +43,7 @@ #define QNETWORKINTERFACE_H #include <QtCore/qshareddata.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qhostaddress.h> #ifndef QT_NO_NETWORKINTERFACE @@ -79,7 +80,7 @@ public: void setBroadcast(const QHostAddress &newBroadcast); private: - QNetworkAddressEntryPrivate *d; + QScopedPointer<QNetworkAddressEntryPrivate> d; }; class QNetworkInterfacePrivate; diff --git a/src/network/kernel/qnetworkinterface_win.cpp b/src/network/kernel/qnetworkinterface_win.cpp index de97629..c783c33 100644 --- a/src/network/kernel/qnetworkinterface_win.cpp +++ b/src/network/kernel/qnetworkinterface_win.cpp @@ -115,6 +115,8 @@ static QHash<QHostAddress, QHostAddress> ipv4Netmasks() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); + if (!pAdapter) + return ipv4netmasks; // try again if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -156,7 +158,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWinXP() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_ADDRESSES *)qMalloc(bufSize); - + if (!pAdapter) + return interfaces; // try again if (ptrGetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -236,7 +239,8 @@ static QList<QNetworkInterfacePrivate *> interfaceListingWin2k() if (retval == ERROR_BUFFER_OVERFLOW) { // need more memory pAdapter = (IP_ADAPTER_INFO *)qMalloc(bufSize); - + if (!pAdapter) + return interfaces; // try again if (ptrGetAdaptersInfo(pAdapter, &bufSize) != ERROR_SUCCESS) { qFree(pAdapter); @@ -306,7 +310,8 @@ QString QHostInfo::localDomainName() pinfo = &info; if (ptrGetNetworkParams(pinfo, &bufSize) == ERROR_BUFFER_OVERFLOW) { pinfo = (FIXED_INFO *)qMalloc(bufSize); - + if (!pinfo) + return QString(); // try again if (ptrGetNetworkParams(pinfo, &bufSize) != ERROR_SUCCESS) { qFree(pinfo); diff --git a/src/network/socket/qlocalsocket_unix.cpp b/src/network/socket/qlocalsocket_unix.cpp index 9e3cbde..03723cf 100644 --- a/src/network/socket/qlocalsocket_unix.cpp +++ b/src/network/socket/qlocalsocket_unix.cpp @@ -305,7 +305,7 @@ void QLocalSocketPrivate::_q_connectToSocket() case EAGAIN: // Try again later, all of the sockets listening are full if (!delayConnect) { - delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write); + delayConnect = new QSocketNotifier(connectingSocket, QSocketNotifier::Write, q); q->connect(delayConnect, SIGNAL(activated(int)), q, SLOT(_q_connectToSocket())); } if (!connectTimer) { diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index b6b0e89..98666c2 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1834,9 +1834,9 @@ QSocks5SocketEngineHandler::createSocketEngine(QAbstractSocket::SocketType socke QSOCKS5_DEBUG << "not proxying"; return 0; } - QSocks5SocketEngine *engine = new QSocks5SocketEngine(parent); + QScopedPointer<QSocks5SocketEngine> engine(new QSocks5SocketEngine(parent)); engine->setProxy(proxy); - return engine; + return engine.take(); } QAbstractSocketEngine *QSocks5SocketEngineHandler::createSocketEngine(int socketDescriptor, QObject *parent) diff --git a/src/network/socket/qtcpserver.cpp b/src/network/socket/qtcpserver.cpp index c1fedc3..1978ee2 100644 --- a/src/network/socket/qtcpserver.cpp +++ b/src/network/socket/qtcpserver.cpp @@ -354,7 +354,12 @@ void QTcpServer::close() if (d->socketEngine) { d->socketEngine->close(); - d->socketEngine->deleteLater(); + QT_TRY { + d->socketEngine->deleteLater(); + } QT_CATCH(const std::bad_alloc &) { + // in out of memory situations, the socketEngine + // will be deleted in ~QTcpServer (it's a child-object of this) + } d->socketEngine = 0; } diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp index 7b554dc..c4aa43e 100644 --- a/src/network/ssl/qsslcertificate.cpp +++ b/src/network/ssl/qsslcertificate.cpp @@ -155,7 +155,7 @@ QSslCertificate::QSslCertificate(const QByteArray &data, QSsl::EncodingFormat fo /*! Constructs an identical copy of \a other. */ -QSslCertificate::QSslCertificate(const QSslCertificate &other) : d(other.d) +QSslCertificate::QSslCertificate(const QSslCertificate &other) : d(other.d.data()) { d->ref.ref(); } @@ -165,8 +165,6 @@ QSslCertificate::QSslCertificate(const QSslCertificate &other) : d(other.d) */ QSslCertificate::~QSslCertificate() { - if (!d->ref.deref()) - delete d; } /*! @@ -175,7 +173,7 @@ QSslCertificate::~QSslCertificate() */ QSslCertificate &QSslCertificate::operator=(const QSslCertificate &other) { - qAtomicAssign(d, other.d); + d.assign(other.d.data()); return *this; } @@ -241,12 +239,7 @@ void QSslCertificate::clear() { if (isNull()) return; - if (d->ref == 1) - delete d; - else - d->ref.deref(); - - d = new QSslCertificatePrivate; + d.reset(new QSslCertificatePrivate); } /*! diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h index d4597cd..19152fb 100644 --- a/src/network/ssl/qsslcertificate.h +++ b/src/network/ssl/qsslcertificate.h @@ -118,7 +118,7 @@ public: Qt::HANDLE handle() const; private: - QSslCertificatePrivate *d; + QScopedSharedPointer<QSslCertificatePrivate> d; friend class QSslCertificatePrivate; friend class QSslSocketBackendPrivate; }; diff --git a/src/network/ssl/qsslcipher.cpp b/src/network/ssl/qsslcipher.cpp index 7fec2df..a72879d 100644 --- a/src/network/ssl/qsslcipher.cpp +++ b/src/network/ssl/qsslcipher.cpp @@ -103,7 +103,7 @@ QSslCipher::QSslCipher(const QString &name, QSsl::SslProtocol protocol) QSslCipher::QSslCipher(const QSslCipher &other) : d(new QSslCipherPrivate) { - *d = *other.d; + *d.data() = *other.d.data(); } /*! @@ -111,7 +111,6 @@ QSslCipher::QSslCipher(const QSslCipher &other) */ QSslCipher::~QSslCipher() { - delete d; } /*! @@ -120,7 +119,7 @@ QSslCipher::~QSslCipher() */ QSslCipher &QSslCipher::operator=(const QSslCipher &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } diff --git a/src/network/ssl/qsslcipher.h b/src/network/ssl/qsslcipher.h index 404dc3d..d9ac7a9 100644 --- a/src/network/ssl/qsslcipher.h +++ b/src/network/ssl/qsslcipher.h @@ -44,6 +44,7 @@ #define QSSLCIPHER_H #include <QtCore/qstring.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qssl.h> QT_BEGIN_HEADER @@ -78,7 +79,7 @@ public: QSsl::SslProtocol protocol() const; private: - QSslCipherPrivate *d; + QScopedPointer<QSslCipherPrivate> d; friend class QSslSocketBackendPrivate; }; diff --git a/src/network/ssl/qsslerror.cpp b/src/network/ssl/qsslerror.cpp index 3096fee..280c659 100644 --- a/src/network/ssl/qsslerror.cpp +++ b/src/network/ssl/qsslerror.cpp @@ -140,7 +140,7 @@ QSslError::QSslError(SslError error, const QSslCertificate &certificate) QSslError::QSslError(const QSslError &other) : d(new QSslErrorPrivate) { - *d = *other.d; + *d.data() = *other.d.data(); } /*! @@ -148,7 +148,6 @@ QSslError::QSslError(const QSslError &other) */ QSslError::~QSslError() { - delete d; } /*! @@ -158,7 +157,7 @@ QSslError::~QSslError() */ QSslError &QSslError::operator=(const QSslError &other) { - *d = *other.d; + *d.data() = *other.d.data(); return *this; } diff --git a/src/network/ssl/qsslerror.h b/src/network/ssl/qsslerror.h index 50cc142..8b8ebff 100644 --- a/src/network/ssl/qsslerror.h +++ b/src/network/ssl/qsslerror.h @@ -105,7 +105,7 @@ public: QSslCertificate certificate() const; private: - QSslErrorPrivate *d; + QScopedPointer<QSslErrorPrivate> d; }; #ifndef QT_NO_DEBUG_STREAM diff --git a/src/network/ssl/qsslkey.cpp b/src/network/ssl/qsslkey.cpp index 8d550c0..d076112 100644 --- a/src/network/ssl/qsslkey.cpp +++ b/src/network/ssl/qsslkey.cpp @@ -269,7 +269,7 @@ QSslKey::QSslKey(QIODevice *device, QSsl::KeyAlgorithm algorithm, QSsl::Encoding /*! Constructs an identical copy of \a other. */ -QSslKey::QSslKey(const QSslKey &other) : d(other.d) +QSslKey::QSslKey(const QSslKey &other) : d(other.d.data()) { d->ref.ref(); } @@ -279,8 +279,6 @@ QSslKey::QSslKey(const QSslKey &other) : d(other.d) */ QSslKey::~QSslKey() { - if (!d->ref.deref()) - delete d; } /*! @@ -291,7 +289,7 @@ QSslKey::~QSslKey() */ QSslKey &QSslKey::operator=(const QSslKey &other) { - qAtomicAssign(d, other.d); + d.assign(other.d.data()); return *this; } @@ -312,10 +310,13 @@ bool QSslKey::isNull() const */ void QSslKey::clear() { - if (!d->ref.deref()) { - delete d; - d = new QSslKeyPrivate; - } + d.reset(new QSslKeyPrivate); + + //### old code: is this really correct??? + //if (!d->ref.deref()) { + // delete d; + // d = new QSslKeyPrivate; + //} } /*! diff --git a/src/network/ssl/qsslkey.h b/src/network/ssl/qsslkey.h index 45d03f7..d5d60a6 100644 --- a/src/network/ssl/qsslkey.h +++ b/src/network/ssl/qsslkey.h @@ -45,6 +45,7 @@ #include <QtCore/qnamespace.h> #include <QtCore/qbytearray.h> +#include <QtCore/qscopedpointer.h> #include <QtNetwork/qssl.h> QT_BEGIN_HEADER @@ -92,7 +93,7 @@ public: inline bool operator!=(const QSslKey &key) const { return !operator==(key); } private: - QSslKeyPrivate *d; + QScopedSharedPointer<QSslKeyPrivate> d; friend class QSslCertificate; }; diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index ca5c732..cd7a7f0 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -1484,8 +1484,8 @@ Q_OPENGL_EXPORT QGLShareRegister* qgl_share_reg() */ QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device) + : d_ptr(new QGLContextPrivate(this)) { - d_ptr = new QGLContextPrivate(this); Q_D(QGLContext); d->init(device, format); } @@ -1507,8 +1507,8 @@ QGLContext::QGLContext(const QGLFormat &format, QPaintDevice *device) \sa format(), isValid() */ QGLContext::QGLContext(const QGLFormat &format) + : d_ptr(new QGLContextPrivate(this)) { - d_ptr = new QGLContextPrivate(this); Q_D(QGLContext); d->init(0, format); } @@ -1539,7 +1539,6 @@ QGLContext::~QGLContext() QGLSignalProxy::instance()->emitAboutToDestroyContext(this); reset(); - delete d; } void QGLContextPrivate::cleanup() diff --git a/src/opengl/qgl.h b/src/opengl/qgl.h index 01b1d6f..b7b2f36 100644 --- a/src/opengl/qgl.h +++ b/src/opengl/qgl.h @@ -45,6 +45,7 @@ #include <QtGui/qwidget.h> #include <QtOpenGL/qglcolormap.h> #include <QtCore/qmap.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -348,7 +349,7 @@ protected: static QGLContext* currentCtx; private: - QGLContextPrivate* d_ptr; + QScopedPointer<QGLContextPrivate> d_ptr; friend class QGLPixelBuffer; friend class QGLPixelBufferPrivate; diff --git a/src/opengl/qglframebufferobject.cpp b/src/opengl/qglframebufferobject.cpp index c362b7e..6e908e2 100644 --- a/src/opengl/qglframebufferobject.cpp +++ b/src/opengl/qglframebufferobject.cpp @@ -448,7 +448,6 @@ QGLFramebufferObject::~QGLFramebufferObject() glDeleteRenderbuffersEXT(1, &d->depth_stencil_buffer); glDeleteFramebuffersEXT(1, &d->fbo); } - delete d_ptr; } /*! diff --git a/src/opengl/qglframebufferobject.h b/src/opengl/qglframebufferobject.h index a9e1b2f..fea8920 100644 --- a/src/opengl/qglframebufferobject.h +++ b/src/opengl/qglframebufferobject.h @@ -116,7 +116,7 @@ protected: private: Q_DISABLE_COPY(QGLFramebufferObject) - QGLFramebufferObjectPrivate *d_ptr; + QScopedPointer<QGLFramebufferObjectPrivate> d_ptr; friend class QGLDrawable; }; diff --git a/src/opengl/qglpaintdevice_qws.cpp b/src/opengl/qglpaintdevice_qws.cpp index 18905ab..60a1238 100644 --- a/src/opengl/qglpaintdevice_qws.cpp +++ b/src/opengl/qglpaintdevice_qws.cpp @@ -68,8 +68,6 @@ QWSGLPaintDevice::QWSGLPaintDevice(QWidget *widget) : QWSGLPaintDevice::~QWSGLPaintDevice() { - Q_D(QWSGLPaintDevice); - delete d; } QPaintEngine* QWSGLPaintDevice::paintEngine() const diff --git a/src/opengl/qglpaintdevice_qws_p.h b/src/opengl/qglpaintdevice_qws_p.h index 369de7f..a471b1b 100644 --- a/src/opengl/qglpaintdevice_qws_p.h +++ b/src/opengl/qglpaintdevice_qws_p.h @@ -53,6 +53,7 @@ // We mean it. // +#include <QtCore/qscopedpointer.h> #include <QPaintDevice> QT_BEGIN_NAMESPACE @@ -76,7 +77,7 @@ public: private: friend class QWSGLWindowSurface; - QWSGLPaintDevicePrivate *d_ptr; + QScopedPointer<QWSGLPaintDevicePrivate> d_ptr; }; diff --git a/src/opengl/qglpixelbuffer.cpp b/src/opengl/qglpixelbuffer.cpp index 5f74f26..8ff2e1d 100644 --- a/src/opengl/qglpixelbuffer.cpp +++ b/src/opengl/qglpixelbuffer.cpp @@ -186,7 +186,6 @@ QGLPixelBuffer::~QGLPixelBuffer() delete d->qctx; if (current && current != d->qctx) current->makeCurrent(); - delete d_ptr; } /*! \fn bool QGLPixelBuffer::makeCurrent() diff --git a/src/opengl/qglpixelbuffer.h b/src/opengl/qglpixelbuffer.h index 0131570..8264c22 100644 --- a/src/opengl/qglpixelbuffer.h +++ b/src/opengl/qglpixelbuffer.h @@ -107,7 +107,7 @@ protected: private: Q_DISABLE_COPY(QGLPixelBuffer) - QGLPixelBufferPrivate *d_ptr; + QScopedPointer<QGLPixelBufferPrivate> d_ptr; friend class QGLDrawable; friend class QGLWindowSurface; }; diff --git a/src/opengl/qpaintengine_opengl.cpp b/src/opengl/qpaintengine_opengl.cpp index 5a212f5..c9fbc7e 100644 --- a/src/opengl/qpaintengine_opengl.cpp +++ b/src/opengl/qpaintengine_opengl.cpp @@ -5625,7 +5625,7 @@ void QOpenGLPaintEngine::fill(const QVectorPath &path, const QBrush &brush) QPainter *p = painter(); QBrush oldBrush = p->brush(); p->setBrush(brush); - qt_draw_helper(p->d_ptr, painterPathFromVectorPath(path), QPainterPrivate::FillDraw); + qt_draw_helper(p->d_ptr.data(), painterPathFromVectorPath(path), QPainterPrivate::FillDraw); p->setBrush(oldBrush); return; } diff --git a/src/phonon/phonon.pro b/src/phonon/phonon.pro index b38adb8..221304d 100644 --- a/src/phonon/phonon.pro +++ b/src/phonon/phonon.pro @@ -119,8 +119,7 @@ symbian: { # would bring in link dependencies, and we don't need that for # numeric_limits, hence we here merely ensure we bring in the necessary # header. - INCLUDEPATH *= $${EPOCROOT}epoc32/include/stdapis/stlport \ - $$OS_LAYER_STDCPP_SYSTEMINCLUDE + INCLUDEPATH *= $$OS_LAYER_STDCPP_SYSTEMINCLUDE # Without this setting, code using numeric_limits will fail # for winscw, although armv5 works fine no matter what. diff --git a/src/plugins/imageformats/mng/qmnghandler.cpp b/src/plugins/imageformats/mng/qmnghandler.cpp index 19cc16d..7fabcd9 100644 --- a/src/plugins/imageformats/mng/qmnghandler.cpp +++ b/src/plugins/imageformats/mng/qmnghandler.cpp @@ -375,8 +375,6 @@ QMngHandler::QMngHandler() QMngHandler::~QMngHandler() { - Q_D(QMngHandler); - delete d; } /*! \reimp */ diff --git a/src/plugins/imageformats/mng/qmnghandler.h b/src/plugins/imageformats/mng/qmnghandler.h index 909be2d..ce2ec6f 100644 --- a/src/plugins/imageformats/mng/qmnghandler.h +++ b/src/plugins/imageformats/mng/qmnghandler.h @@ -42,6 +42,7 @@ #ifndef QMNGHANDLER_H #define QMNGHANDLER_H +#include <QtCore/qscopedpointer.h> #include <QtGui/qimageiohandler.h> QT_BEGIN_NAMESPACE @@ -74,7 +75,7 @@ class QMngHandler : public QImageIOHandler private: Q_DECLARE_PRIVATE(QMngHandler) - QMngHandlerPrivate *d_ptr; + QScopedPointer<QMngHandlerPrivate> d_ptr; }; QT_END_NAMESPACE diff --git a/src/plugins/s60/src/qlocale_3_2.cpp b/src/plugins/s60/src/qlocale_3_2.cpp index ab3040b..7a3a7e5 100644 --- a/src/plugins/s60/src/qlocale_3_2.cpp +++ b/src/plugins/s60/src/qlocale_3_2.cpp @@ -39,6 +39,7 @@ ** ****************************************************************************/ +#include <exception> #include <e32std.h> #include <e32base.h> diff --git a/src/qt3support/itemviews/q3table.cpp b/src/qt3support/itemviews/q3table.cpp index 658b0ad..458f5a5 100644 --- a/src/qt3support/itemviews/q3table.cpp +++ b/src/qt3support/itemviews/q3table.cpp @@ -166,6 +166,7 @@ private: QTimer *stretchTimer, *widgetStretchTimer; Q3TableHeaderPrivate *d; + Q_DISABLE_COPY(Q3TableHeader) }; #ifdef _WS_QWS_ diff --git a/src/qt3support/other/q3accel.cpp b/src/qt3support/other/q3accel.cpp index a570a70..2358092 100644 --- a/src/qt3support/other/q3accel.cpp +++ b/src/qt3support/other/q3accel.cpp @@ -206,7 +206,7 @@ bool Q_COMPAT_EXPORT qt_tryComposeUnicode(QWidget* w, QKeyEvent* e){ void Q3AccelManager::setFuncPtr() { if (qApp->d_func()->qt_compat_used) return; - QApplicationPrivate *data = static_cast<QApplicationPrivate*>(qApp->d_ptr); + QApplicationPrivate *data = static_cast<QApplicationPrivate*>(qApp->d_ptr.data()); data->qt_tryAccelEvent = qt_tryAccelEvent; data->qt_tryComposeUnicode = qt_tryComposeUnicode; data->qt_dispatchAccelEvent = qt_dispatchAccelEvent; diff --git a/src/qt3support/painting/q3painter.h b/src/qt3support/painting/q3painter.h index 6fd17cb..c301ee7 100644 --- a/src/qt3support/painting/q3painter.h +++ b/src/qt3support/painting/q3painter.h @@ -82,6 +82,8 @@ public: private: QRect adjustedRectangle(const QRect &r); + + Q_DISABLE_COPY(Q3Painter) }; void inline Q3Painter::drawRect(const QRect &r) diff --git a/src/s60main/qts60main.cpp b/src/s60main/qts60main.cpp index 965c02b..d7daf4a 100644 --- a/src/s60main/qts60main.cpp +++ b/src/s60main/qts60main.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ // INCLUDE FILES +#include <exception> #include <eikstart.h> #include "qts60mainapplication.h" diff --git a/src/s60main/qts60main_mcrt0.cpp b/src/s60main/qts60main_mcrt0.cpp index b7bf1a3..49a47bd 100644 --- a/src/s60main/qts60main_mcrt0.cpp +++ b/src/s60main/qts60main_mcrt0.cpp @@ -79,7 +79,15 @@ GLDEF_C TInt QtMainWrapper() CleanupArrayDelete<char*>::PushL(argv); CleanupArrayDelete<char*>::PushL(envp); //Call user(application)'s main - int ret = CALLMAIN(argc,argv,envp); + int ret = 0; + try + { + ret = CALLMAIN(argc, argv, envp); + } + catch (...) + { + User::Leave(KErrGeneral); + } CleanupStack::PopAndDestroy(2,argv); return ret; } diff --git a/src/s60main/qts60mainapplication.cpp b/src/s60main/qts60mainapplication.cpp index 680243f..2fada3d 100644 --- a/src/s60main/qts60mainapplication.cpp +++ b/src/s60main/qts60mainapplication.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ // INCLUDE FILES +#include <exception> #include "qts60maindocument.h" #include "qts60mainapplication.h" #include <bautils.h> diff --git a/src/s60main/qts60mainappui.cpp b/src/s60main/qts60mainappui.cpp index 47312af..50f7572 100644 --- a/src/s60main/qts60mainappui.cpp +++ b/src/s60main/qts60mainappui.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ // INCLUDE FILES +#include <exception> #include <avkon.hrh> #include <eikmenub.h> #include <eikmenup.h> @@ -123,7 +124,9 @@ void CQtS60MainAppUi::HandleWsEventL(const TWsEvent& aEvent, CCoeControl *contro { int result = 0; if (qApp) - result = qApp->s60ProcessEvent(const_cast<TWsEvent*>(&aEvent)); + QT_TRANSLATE_EXCEPTION_TO_SYMBIAN_LEAVE( + result = qApp->s60ProcessEvent(const_cast<TWsEvent*>(&aEvent)) + ); if (result <= 0) CAknAppUi::HandleWsEventL(aEvent, control); @@ -162,7 +165,8 @@ TInt CQtS60MainAppUi::OpenCMainStaticCallBack( TAny* aObject ) // void CQtS60MainAppUi::OpenCMainCallBack() { - TInt ret = QtMainWrapper(); + TInt ret; + TRAPD(err, ret = QtMainWrapper()); Exit(); } diff --git a/src/s60main/qts60maindocument.cpp b/src/s60main/qts60maindocument.cpp index b4a2e66..eb7ea42 100644 --- a/src/s60main/qts60maindocument.cpp +++ b/src/s60main/qts60maindocument.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ // INCLUDE FILES +#include <exception> #include "qts60mainappui.h" #include "qts60maindocument.h" diff --git a/src/script/qscriptable.cpp b/src/script/qscriptable.cpp index a6401d6..56291d8 100644 --- a/src/script/qscriptable.cpp +++ b/src/script/qscriptable.cpp @@ -118,8 +118,6 @@ QScriptable::QScriptable() */ QScriptable::~QScriptable() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/script/qscriptable.h b/src/script/qscriptable.h index f990db2..d09b945 100644 --- a/src/script/qscriptable.h +++ b/src/script/qscriptable.h @@ -46,6 +46,8 @@ #ifndef QT_NO_SCRIPT +#include <QtCore/qscopedpointer.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -73,7 +75,7 @@ public: QScriptValue argument(int index) const; private: - QScriptablePrivate *d_ptr; + QScopedPointer<QScriptablePrivate> d_ptr; Q_DISABLE_COPY(QScriptable) Q_DECLARE_PRIVATE(QScriptable) diff --git a/src/script/qscriptclass.cpp b/src/script/qscriptclass.cpp index 14b8add..535a530 100644 --- a/src/script/qscriptclass.cpp +++ b/src/script/qscriptclass.cpp @@ -457,8 +457,6 @@ QScriptClass::QScriptClass(QScriptEngine *engine, QScriptClassPrivate &dd) */ QScriptClass::~QScriptClass() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/script/qscriptclass.h b/src/script/qscriptclass.h index 9c06ea2..77e9b08 100644 --- a/src/script/qscriptclass.h +++ b/src/script/qscriptclass.h @@ -47,6 +47,7 @@ #ifndef QT_NO_SCRIPT #include <QtCore/qvariant.h> +#include <QtCore/qscopedpointer.h> #include <QtScript/qscriptvalue.h> QT_BEGIN_HEADER @@ -103,7 +104,7 @@ public: protected: QScriptClass(QScriptEngine *engine, QScriptClassPrivate &dd); - QScriptClassPrivate *d_ptr; + QScopedPointer<QScriptClassPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptClass) diff --git a/src/script/qscriptclasspropertyiterator.cpp b/src/script/qscriptclasspropertyiterator.cpp index 96f34d5..f328e14 100644 --- a/src/script/qscriptclasspropertyiterator.cpp +++ b/src/script/qscriptclasspropertyiterator.cpp @@ -111,8 +111,6 @@ QScriptClassPropertyIterator::QScriptClassPropertyIterator(const QScriptValue &o */ QScriptClassPropertyIterator::~QScriptClassPropertyIterator() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/script/qscriptclasspropertyiterator.h b/src/script/qscriptclasspropertyiterator.h index 2041a65..05d49d8 100644 --- a/src/script/qscriptclasspropertyiterator.h +++ b/src/script/qscriptclasspropertyiterator.h @@ -46,6 +46,7 @@ #ifndef QT_NO_SCRIPT +#include <QtCore/qscopedpointer.h> #include <QtScript/qscriptvalue.h> QT_BEGIN_HEADER @@ -80,7 +81,7 @@ public: protected: QScriptClassPropertyIterator(const QScriptValue &object, QScriptClassPropertyIteratorPrivate &dd); - QScriptClassPropertyIteratorPrivate *d_ptr; + QScopedPointer<QScriptClassPropertyIteratorPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptClassPropertyIterator) diff --git a/src/script/qscriptcontext.cpp b/src/script/qscriptcontext.cpp index 020601b..0b72342 100644 --- a/src/script/qscriptcontext.cpp +++ b/src/script/qscriptcontext.cpp @@ -219,8 +219,6 @@ QScriptContext::QScriptContext(): */ QScriptContext::~QScriptContext() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/script/qscriptcontext.h b/src/script/qscriptcontext.h index 1e1f987..25a2198 100644 --- a/src/script/qscriptcontext.h +++ b/src/script/qscriptcontext.h @@ -46,6 +46,7 @@ #ifndef QT_NO_SCRIPT +#include <QtCore/qscopedpointer.h> #include <QtScript/qscriptvalue.h> QT_BEGIN_HEADER @@ -111,7 +112,7 @@ public: private: QScriptContext(); - QScriptContextPrivate *d_ptr; + QScopedPointer<QScriptContextPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptContext) Q_DISABLE_COPY(QScriptContext) diff --git a/src/script/qscriptcontextinfo.cpp b/src/script/qscriptcontextinfo.cpp index 260d19f..0fa5c62 100644 --- a/src/script/qscriptcontextinfo.cpp +++ b/src/script/qscriptcontextinfo.cpp @@ -204,13 +204,12 @@ QScriptContextInfoPrivate::~QScriptContextInfoPrivate() previously created QScriptContextInfo. */ QScriptContextInfo::QScriptContextInfo(const QScriptContext *context) + : d_ptr(0) { if (context) { - d_ptr = new QScriptContextInfoPrivate(context); + d_ptr.data_ptr() = new QScriptContextInfoPrivate(context); d_ptr->q_ptr = this; d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -218,7 +217,7 @@ QScriptContextInfo::QScriptContextInfo(const QScriptContext *context) Constructs a new QScriptContextInfo from the \a other info. */ QScriptContextInfo::QScriptContextInfo(const QScriptContextInfo &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -239,10 +238,6 @@ QScriptContextInfo::QScriptContextInfo() */ QScriptContextInfo::~QScriptContextInfo() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } /*! @@ -251,15 +246,7 @@ QScriptContextInfo::~QScriptContextInfo() */ QScriptContextInfo &QScriptContextInfo::operator=(const QScriptContextInfo &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } @@ -510,7 +497,7 @@ QDataStream &operator<<(QDataStream &out, const QScriptContextInfo &info) Q_SCRIPT_EXPORT QDataStream &operator>>(QDataStream &in, QScriptContextInfo &info) { if (!info.d_ptr) { - info.d_ptr = new QScriptContextInfoPrivate(); + info.d_ptr.data_ptr() = new QScriptContextInfoPrivate(); info.d_ptr->ref.ref(); } diff --git a/src/script/qscriptcontextinfo.h b/src/script/qscriptcontextinfo.h index a683733..20b6607 100644 --- a/src/script/qscriptcontextinfo.h +++ b/src/script/qscriptcontextinfo.h @@ -48,6 +48,7 @@ #include <QtCore/qlist.h> #include <QtCore/qstringlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -104,7 +105,7 @@ public: bool operator!=(const QScriptContextInfo &other) const; private: - QScriptContextInfoPrivate *d_ptr; + QScopedSharedPointer<QScriptContextInfoPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptContextInfo) }; diff --git a/src/script/qscriptengine.cpp b/src/script/qscriptengine.cpp index d8908ed..2a36104 100644 --- a/src/script/qscriptengine.cpp +++ b/src/script/qscriptengine.cpp @@ -330,10 +330,6 @@ QScriptEngine::~QScriptEngine() Q_D(QScriptEngine); d->m_frameRepository.release(currentContext()); d->objectAllocator.destruct(); -#ifdef QT_NO_QOBJECT - delete d_ptr; - d_ptr = 0; -#endif } /*! @@ -1777,7 +1773,7 @@ QScriptValue QScriptEngine::objectById(qint64 id) const Constructs a new QScriptSyntaxCheckResult from the \a other result. */ QScriptSyntaxCheckResult::QScriptSyntaxCheckResult(const QScriptSyntaxCheckResult &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -1806,10 +1802,6 @@ QScriptSyntaxCheckResult::QScriptSyntaxCheckResult() */ QScriptSyntaxCheckResult::~QScriptSyntaxCheckResult() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } /*! @@ -1863,15 +1855,7 @@ QString QScriptSyntaxCheckResult::errorMessage() const */ QScriptSyntaxCheckResult &QScriptSyntaxCheckResult::operator=(const QScriptSyntaxCheckResult &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } diff --git a/src/script/qscriptengine.h b/src/script/qscriptengine.h index afd551b..c55caac 100644 --- a/src/script/qscriptengine.h +++ b/src/script/qscriptengine.h @@ -47,6 +47,7 @@ #ifndef QT_NO_SCRIPT #include <QtCore/qvariant.h> +#include <QtCore/qscopedpointer.h> #ifndef QT_NO_QOBJECT #include <QtCore/qobject.h> @@ -114,7 +115,7 @@ public: private: QScriptSyntaxCheckResult(); QScriptSyntaxCheckResult(QScriptSyntaxCheckResultPrivate *d); - QScriptSyntaxCheckResultPrivate *d_ptr; + QScopedSharedPointer<QScriptSyntaxCheckResultPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptSyntaxCheckResult) friend class QScriptEnginePrivate; @@ -282,7 +283,7 @@ private: protected: #ifdef QT_NO_QOBJECT - QScriptEnginePrivate *d_ptr; + QScopedPointer<QScriptEnginePrivate> d_ptr; QScriptEngine(QScriptEnginePrivate &dd); #else diff --git a/src/script/qscriptengineagent.cpp b/src/script/qscriptengineagent.cpp index bda94ae..c3eaf96 100644 --- a/src/script/qscriptengineagent.cpp +++ b/src/script/qscriptengineagent.cpp @@ -173,8 +173,6 @@ QScriptEngineAgent::QScriptEngineAgent(QScriptEngineAgentPrivate &dd, QScriptEng */ QScriptEngineAgent::~QScriptEngineAgent() { - delete d_ptr; - d_ptr = 0; } /*! diff --git a/src/script/qscriptengineagent.h b/src/script/qscriptengineagent.h index 3334bc0..461d756 100644 --- a/src/script/qscriptengineagent.h +++ b/src/script/qscriptengineagent.h @@ -47,6 +47,7 @@ #ifndef QT_NO_SCRIPT #include <QtCore/qvariant.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -96,7 +97,7 @@ public: protected: QScriptEngineAgent(QScriptEngineAgentPrivate &dd, QScriptEngine *engine); - QScriptEngineAgentPrivate *d_ptr; + QScopedPointer<QScriptEngineAgentPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptEngineAgent) diff --git a/src/script/qscriptstring.cpp b/src/script/qscriptstring.cpp index 69b0796..e7591e1 100644 --- a/src/script/qscriptstring.cpp +++ b/src/script/qscriptstring.cpp @@ -54,6 +54,29 @@ QT_BEGIN_NAMESPACE +/*! \internal */ +struct QScriptStringPrivatePointerHandler +{ + static inline void cleanup(QScriptStringPrivate *d) + { + if (!d || d->ref.deref()) + return; + + if (d->nameId) { + d->engine->uninternString(d); + } else { + // the engine has already been deleted + delete d; + } + } + + static inline void reset(QScriptStringPrivate *&d, QScriptStringPrivate *other) + { + cleanup(d); + d = other; + } +}; + /*! \since 4.4 \class QScriptString @@ -108,8 +131,8 @@ QScriptStringPrivate *QScriptStringPrivate::get(const QScriptString &q) void QScriptStringPrivate::init(QScriptString &q, QScriptStringPrivate *d) { Q_ASSERT(q.d_ptr == 0); - q.d_ptr = d; - q.d_ptr->ref.ref(); + q.d_ptr.data_ptr() = d; + d->ref.ref(); } /*! @@ -124,7 +147,7 @@ QScriptString::QScriptString() Constructs a new QScriptString that is a copy of \a other. */ QScriptString::QScriptString(const QScriptString &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -135,15 +158,6 @@ QScriptString::QScriptString(const QScriptString &other) */ QScriptString::~QScriptString() { - if (d_ptr && !d_ptr->ref.deref()) { - if (isValid()) { - d_ptr->engine->uninternString(d_ptr); - } else { - // the engine has already been deleted - delete d_ptr; - } - d_ptr = 0; - } } /*! @@ -153,15 +167,7 @@ QScriptString &QScriptString::operator=(const QScriptString &other) { if (d_ptr == other.d_ptr) return *this; - if (d_ptr && !d_ptr->ref.deref()) { - if (isValid()) { - d_ptr->engine->uninternString(d_ptr); - } else { - // the engine has already been deleted - delete d_ptr; - } - } - d_ptr = other.d_ptr; + d_ptr.reset(other.d_ptr.data()); if (d_ptr) d_ptr->ref.ref(); return *this; diff --git a/src/script/qscriptstring.h b/src/script/qscriptstring.h index d2fecd8..f68be0c 100644 --- a/src/script/qscriptstring.h +++ b/src/script/qscriptstring.h @@ -46,6 +46,8 @@ #ifndef QT_NO_SCRIPT +#include <QtCore/qscopedpointer.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -54,6 +56,7 @@ QT_MODULE(Script) class QScriptEngine; class QScriptStringPrivate; +struct QScriptStringPrivatePointerHandler; class Q_SCRIPT_EXPORT QScriptString { @@ -73,7 +76,7 @@ public: operator QString() const; private: - QScriptStringPrivate *d_ptr; + QScopedCustomPointer<QScriptStringPrivate, QScriptStringPrivatePointerHandler> d_ptr; Q_DECLARE_PRIVATE(QScriptString) }; diff --git a/src/script/qscriptvalue.cpp b/src/script/qscriptvalue.cpp index a253985..4282248 100644 --- a/src/script/qscriptvalue.cpp +++ b/src/script/qscriptvalue.cpp @@ -57,6 +57,28 @@ QT_BEGIN_NAMESPACE +/*! \internal + */ +struct QScriptValuePrivatePointerHandler +{ + static inline void cleanup(QScriptValuePrivate *d) + { + if (!d || d->ref.deref()) + return; + if (d->engine) { + QScriptEnginePrivate::get(d->engine)->unregisterValue(d); + } else { + delete d; + } + } + + static inline void reset(QScriptValuePrivate *&d, QScriptValuePrivate *other) + { + cleanup(d); + d = other; + } +}; + /*! \since 4.3 \class QScriptValue @@ -194,14 +216,6 @@ QScriptValue::QScriptValue() */ QScriptValue::~QScriptValue() { - if (d_ptr && !d_ptr->ref.deref()) { - if (engine()) { - QScriptEnginePrivate::get(engine())->unregisterValue(d_ptr); - } else { - delete d_ptr; - } - d_ptr = 0; - } } /*! @@ -212,7 +226,7 @@ QScriptValue::~QScriptValue() the new script value (i.e., the object itself is not copied). */ QScriptValue::QScriptValue(const QScriptValue &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -225,13 +239,12 @@ QScriptValue::QScriptValue(const QScriptValue &other) registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue value) + : d_ptr(0) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(value)); + d_ptr.data_ptr() = eng_p->registerValue(QScriptValueImpl(value)); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -244,13 +257,12 @@ QScriptValue::QScriptValue(QScriptEngine *engine, QScriptValue::SpecialValue val registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, bool val) + : d_ptr(0) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); + d_ptr.data_ptr() = eng_p->registerValue(QScriptValueImpl(val)); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -262,13 +274,12 @@ QScriptValue::QScriptValue(QScriptEngine *engine, bool val) registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, int val) + : d_ptr(0) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); + d_ptr.data_ptr() = eng_p->registerValue(QScriptValueImpl(val)); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -280,13 +291,12 @@ QScriptValue::QScriptValue(QScriptEngine *engine, int val) registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, uint val) + : d_ptr(0) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); + d_ptr.data_ptr() = eng_p->registerValue(QScriptValueImpl(val)); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -298,13 +308,12 @@ QScriptValue::QScriptValue(QScriptEngine *engine, uint val) registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val) + : d_ptr(0) { if (engine) { QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); - d_ptr = eng_p->registerValue(QScriptValueImpl(val)); + d_ptr.data_ptr() = eng_p->registerValue(QScriptValueImpl(val)); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -316,15 +325,14 @@ QScriptValue::QScriptValue(QScriptEngine *engine, qsreal val) registers it with the script \a engine. */ QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val) + : d_ptr(0) { if (engine) { QScriptValueImpl v; QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); eng_p->newString(&v, val); - d_ptr = eng_p->registerValue(v); + d_ptr.data_ptr() = eng_p->registerValue(v); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } @@ -338,15 +346,14 @@ QScriptValue::QScriptValue(QScriptEngine *engine, const QString &val) #ifndef QT_NO_CAST_FROM_ASCII QScriptValue::QScriptValue(QScriptEngine *engine, const char *val) + : d_ptr(0) { if (engine) { QScriptValueImpl v; QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(engine); eng_p->newString(&v, QString::fromAscii(val)); - d_ptr = eng_p->registerValue(v); + d_ptr.data_ptr() = eng_p->registerValue(v); d_ptr->ref.ref(); - } else { - d_ptr = 0; } } #endif @@ -464,14 +471,7 @@ QScriptValue &QScriptValue::operator=(const QScriptValue &other) { if (d_ptr == other.d_ptr) return *this; - if (d_ptr && !d_ptr->ref.deref()) { - if (engine()) { - QScriptEnginePrivate::get(engine())->unregisterValue(d_ptr); - } else { - delete d_ptr; - } - } - d_ptr = other.d_ptr; + d_ptr.reset(other.d_ptr.data()); if (d_ptr) d_ptr->ref.ref(); return *this; diff --git a/src/script/qscriptvalue.h b/src/script/qscriptvalue.h index 306da53..76b1186 100644 --- a/src/script/qscriptvalue.h +++ b/src/script/qscriptvalue.h @@ -47,6 +47,7 @@ #ifndef QT_NO_SCRIPT #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -71,6 +72,7 @@ typedef QList<QScriptValue> QScriptValueList; typedef double qsreal; class QScriptValuePrivate; +struct QScriptValuePrivatePointerHandler; class Q_SCRIPT_EXPORT QScriptValue { public: @@ -216,12 +218,12 @@ public: private: // force compile error, prevent QScriptValue(bool) to be called - inline QScriptValue(void *) { Q_ASSERT(false); } + inline QScriptValue(void *); // force compile error, prevent QScriptValue(QScriptEngine*, bool) to be called - inline QScriptValue(QScriptEngine *, void *) { Q_ASSERT(false); } + inline QScriptValue(QScriptEngine *, void *); private: - QScriptValuePrivate *d_ptr; + QScopedCustomPointer<QScriptValuePrivate, QScriptValuePrivatePointerHandler> d_ptr; Q_DECLARE_PRIVATE(QScriptValue) }; diff --git a/src/script/qscriptvalue_p.h b/src/script/qscriptvalue_p.h index 8463ed2..6528464 100644 --- a/src/script/qscriptvalue_p.h +++ b/src/script/qscriptvalue_p.h @@ -91,7 +91,7 @@ inline QScriptValueImpl QScriptValuePrivate::valueOf(const QScriptValue &value) inline void QScriptValuePrivate::init(QScriptValue &value, QScriptValuePrivate *p) { - value.d_ptr = p; + value.d_ptr.data_ptr() = p; value.d_ptr->ref.ref(); } diff --git a/src/script/qscriptvalueiterator.cpp b/src/script/qscriptvalueiterator.cpp index 1a60632..2cf5575 100644 --- a/src/script/qscriptvalueiterator.cpp +++ b/src/script/qscriptvalueiterator.cpp @@ -115,12 +115,11 @@ QScriptValueIteratorPrivate::~QScriptValueIteratorPrivate() first property). */ QScriptValueIterator::QScriptValueIterator(const QScriptValue &object) + : d_ptr(0) { QScriptValueImpl val = QScriptValuePrivate::valueOf(object); - if (!val.isObject()) { - d_ptr = 0; - } else { - d_ptr = new QScriptValueIteratorPrivate(); + if (val.isObject()) { + d_ptr.reset(new QScriptValueIteratorPrivate()); d_ptr->it = new QScriptValueIteratorImpl(val); } } @@ -130,10 +129,6 @@ QScriptValueIterator::QScriptValueIterator(const QScriptValue &object) */ QScriptValueIterator::~QScriptValueIterator() { - if (d_ptr) { - delete d_ptr; - d_ptr = 0; - } } /*! @@ -311,13 +306,10 @@ void QScriptValueIterator::remove() */ QScriptValueIterator& QScriptValueIterator::operator=(QScriptValue &object) { - if (d_ptr) { - delete d_ptr; - d_ptr = 0; - } + d_ptr.reset(); QScriptValueImpl val = QScriptValuePrivate::valueOf(object); if (val.isObject()) { - d_ptr = new QScriptValueIteratorPrivate(); + d_ptr.reset(new QScriptValueIteratorPrivate()); d_ptr->it = new QScriptValueIteratorImpl(val); } return *this; diff --git a/src/script/qscriptvalueiterator.h b/src/script/qscriptvalueiterator.h index 91561e8..082158d 100644 --- a/src/script/qscriptvalueiterator.h +++ b/src/script/qscriptvalueiterator.h @@ -46,6 +46,8 @@ #ifndef QT_NO_SCRIPT +#include <QtCore/qscopedpointer.h> + QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -84,7 +86,7 @@ public: QScriptValueIterator& operator=(QScriptValue &value); private: - QScriptValueIteratorPrivate *d_ptr; + QScopedPointer<QScriptValueIteratorPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptValueIterator) Q_DISABLE_COPY(QScriptValueIterator) diff --git a/src/scripttools/debugging/qscriptbreakpointdata.cpp b/src/scripttools/debugging/qscriptbreakpointdata.cpp index 9762ca4..50e597e 100644 --- a/src/scripttools/debugging/qscriptbreakpointdata.cpp +++ b/src/scripttools/debugging/qscriptbreakpointdata.cpp @@ -136,7 +136,6 @@ QScriptBreakpointData::QScriptBreakpointData(const QScriptBreakpointData &other) */ QScriptBreakpointData::~QScriptBreakpointData() { - delete d_ptr; } /*! @@ -355,7 +354,7 @@ bool QScriptBreakpointData::operator!=(const QScriptBreakpointData &other) const */ QDataStream &operator<<(QDataStream &out, const QScriptBreakpointData &data) { - const QScriptBreakpointDataPrivate *d = data.d_ptr; + const QScriptBreakpointDataPrivate *d = data.d_ptr.data(); out << d->scriptId; out << d->fileName; out << d->lineNumber; @@ -377,7 +376,7 @@ QDataStream &operator<<(QDataStream &out, const QScriptBreakpointData &data) */ QDataStream &operator>>(QDataStream &in, QScriptBreakpointData &data) { - QScriptBreakpointDataPrivate *d = data.d_ptr; + QScriptBreakpointDataPrivate *d = data.d_ptr.data(); in >> d->scriptId; in >> d->fileName; in >> d->lineNumber; diff --git a/src/scripttools/debugging/qscriptbreakpointdata_p.h b/src/scripttools/debugging/qscriptbreakpointdata_p.h index c1ff033..6cfceed 100644 --- a/src/scripttools/debugging/qscriptbreakpointdata_p.h +++ b/src/scripttools/debugging/qscriptbreakpointdata_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qmap.h> QT_BEGIN_NAMESPACE @@ -114,7 +114,7 @@ public: bool operator!=(const QScriptBreakpointData &other) const; private: - QScriptBreakpointDataPrivate *d_ptr; + QScopedPointer<QScriptBreakpointDataPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptBreakpointData) }; diff --git a/src/scripttools/debugging/qscriptdebuggerbackend.cpp b/src/scripttools/debugging/qscriptdebuggerbackend.cpp index 3c29130..46d8497 100644 --- a/src/scripttools/debugging/qscriptdebuggerbackend.cpp +++ b/src/scripttools/debugging/qscriptdebuggerbackend.cpp @@ -385,7 +385,6 @@ QScriptDebuggerBackend::QScriptDebuggerBackend() QScriptDebuggerBackend::~QScriptDebuggerBackend() { detach(); - delete d_ptr; } /*! diff --git a/src/scripttools/debugging/qscriptdebuggerbackend_p.h b/src/scripttools/debugging/qscriptdebuggerbackend_p.h index 6d593a6..d9ec307 100644 --- a/src/scripttools/debugging/qscriptdebuggerbackend_p.h +++ b/src/scripttools/debugging/qscriptdebuggerbackend_p.h @@ -144,7 +144,7 @@ protected: protected: QScriptDebuggerBackend(QScriptDebuggerBackendPrivate &dd); - QScriptDebuggerBackendPrivate *d_ptr; + QScopedPointer<QScriptDebuggerBackendPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerBackend) diff --git a/src/scripttools/debugging/qscriptdebuggercommand.cpp b/src/scripttools/debugging/qscriptdebuggercommand.cpp index c40bfc4..98bb3b3 100644 --- a/src/scripttools/debugging/qscriptdebuggercommand.cpp +++ b/src/scripttools/debugging/qscriptdebuggercommand.cpp @@ -118,7 +118,6 @@ QScriptDebuggerCommand::QScriptDebuggerCommand(const QScriptDebuggerCommand &oth */ QScriptDebuggerCommand::~QScriptDebuggerCommand() { - delete d_ptr; } /*! @@ -646,7 +645,7 @@ QScriptDebuggerCommand QScriptDebuggerCommand::clearExceptionsCommand() */ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerCommand &command) { - const QScriptDebuggerCommandPrivate *d = command.d_ptr; + const QScriptDebuggerCommandPrivate *d = command.d_ptr.data(); out << (quint32)d->type; out << (qint32)d->attributes.size(); QHash<QScriptDebuggerCommand::Attribute, QVariant>::const_iterator it; @@ -666,7 +665,7 @@ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerCommand &command) */ QDataStream &operator>>(QDataStream &in, QScriptDebuggerCommand &command) { - QScriptDebuggerCommandPrivate *d = command.d_ptr; + QScriptDebuggerCommandPrivate *d = command.d_ptr.data(); quint32 type; in >> type; diff --git a/src/scripttools/debugging/qscriptdebuggercommand_p.h b/src/scripttools/debugging/qscriptdebuggercommand_p.h index 260e3ec..363738f 100644 --- a/src/scripttools/debugging/qscriptdebuggercommand_p.h +++ b/src/scripttools/debugging/qscriptdebuggercommand_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qhash.h> #include <QtCore/qvariant.h> @@ -250,7 +250,7 @@ public: static QScriptDebuggerCommand clearExceptionsCommand(); private: - QScriptDebuggerCommandPrivate *d_ptr; + QScopedPointer<QScriptDebuggerCommandPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerCommand) }; diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp index 1be8c5f..e75ff99 100644 --- a/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp +++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor.cpp @@ -98,7 +98,6 @@ QScriptDebuggerCommandExecutor::QScriptDebuggerCommandExecutor() QScriptDebuggerCommandExecutor::~QScriptDebuggerCommandExecutor() { - delete d_ptr; } /*! diff --git a/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h b/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h index 8fff5e5..da7de76 100644 --- a/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h +++ b/src/scripttools/debugging/qscriptdebuggercommandexecutor_p.h @@ -54,6 +54,7 @@ // #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE @@ -74,7 +75,7 @@ public: protected: QScriptDebuggerCommandExecutor(QScriptDebuggerCommandExecutorPrivate &dd); - QScriptDebuggerCommandExecutorPrivate *d_ptr; + QScopedPointer<QScriptDebuggerCommandExecutorPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerCommandExecutor) diff --git a/src/scripttools/debugging/qscriptdebuggerconsole.cpp b/src/scripttools/debugging/qscriptdebuggerconsole.cpp index 70bb8b1..09a32db 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsole.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsole.cpp @@ -199,7 +199,6 @@ QScriptDebuggerConsole::QScriptDebuggerConsole() QScriptDebuggerConsole::~QScriptDebuggerConsole() { - delete d_ptr; } void QScriptDebuggerConsole::loadScriptedCommands(const QString &scriptsPath, diff --git a/src/scripttools/debugging/qscriptdebuggerconsole_p.h b/src/scripttools/debugging/qscriptdebuggerconsole_p.h index b5ebf44..a8c4163 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsole_p.h +++ b/src/scripttools/debugging/qscriptdebuggerconsole_p.h @@ -54,6 +54,7 @@ // #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> #include "qscriptdebuggerconsolehistorianinterface_p.h" @@ -109,7 +110,7 @@ public: void bumpSessionId(); private: - QScriptDebuggerConsolePrivate *d_ptr; + QScopedPointer<QScriptDebuggerConsolePrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerConsole) Q_DISABLE_COPY(QScriptDebuggerConsole) diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp index 6cbf58c..8e4bc06 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommand.cpp @@ -72,7 +72,6 @@ QScriptDebuggerConsoleCommand::QScriptDebuggerConsoleCommand() QScriptDebuggerConsoleCommand::~QScriptDebuggerConsoleCommand() { - delete d_ptr; } QScriptDebuggerConsoleCommand::QScriptDebuggerConsoleCommand(QScriptDebuggerConsoleCommandPrivate &dd) diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h index fbf285f..2ce3315 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommand_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qlist.h> QT_BEGIN_NAMESPACE @@ -91,7 +91,7 @@ public: protected: QScriptDebuggerConsoleCommand(QScriptDebuggerConsoleCommandPrivate &dd); - QScriptDebuggerConsoleCommandPrivate *d_ptr; + QScopedPointer<QScriptDebuggerConsoleCommandPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommand) diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp index 9cfac97..1d43dd0 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata.cpp @@ -90,7 +90,7 @@ QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData( QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData( const QScriptDebuggerConsoleCommandGroupData &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -98,22 +98,12 @@ QScriptDebuggerConsoleCommandGroupData::QScriptDebuggerConsoleCommandGroupData( QScriptDebuggerConsoleCommandGroupData::~QScriptDebuggerConsoleCommandGroupData() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } QScriptDebuggerConsoleCommandGroupData &QScriptDebuggerConsoleCommandGroupData::operator=( const QScriptDebuggerConsoleCommandGroupData &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h index c32277f..9b0e281 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandgroupdata_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qmap.h> QT_BEGIN_NAMESPACE @@ -82,7 +82,7 @@ public: const QScriptDebuggerConsoleCommandGroupData &other); private: - QScriptDebuggerConsoleCommandGroupDataPrivate *d_ptr; + QScopedSharedPointer<QScriptDebuggerConsoleCommandGroupDataPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommandGroupData) diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp index ef9687e..f22efc5 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager.cpp @@ -105,7 +105,6 @@ QScriptDebuggerConsoleCommandManager::QScriptDebuggerConsoleCommandManager() QScriptDebuggerConsoleCommandManager::~QScriptDebuggerConsoleCommandManager() { - delete d_ptr; } /*! diff --git a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h index b5c9842..cebb999 100644 --- a/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h +++ b/src/scripttools/debugging/qscriptdebuggerconsolecommandmanager_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qmap.h> #include <QtCore/qlist.h> @@ -86,7 +86,7 @@ public: QStringList completions(const QString &prefix) const; private: - QScriptDebuggerConsoleCommandManagerPrivate *d_ptr; + QScopedPointer<QScriptDebuggerConsoleCommandManagerPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerConsoleCommandManager) }; diff --git a/src/scripttools/debugging/qscriptdebuggerevent.cpp b/src/scripttools/debugging/qscriptdebuggerevent.cpp index 9d971a9..418e8fa 100644 --- a/src/scripttools/debugging/qscriptdebuggerevent.cpp +++ b/src/scripttools/debugging/qscriptdebuggerevent.cpp @@ -97,7 +97,6 @@ QScriptDebuggerEvent::QScriptDebuggerEvent(const QScriptDebuggerEvent &other) QScriptDebuggerEvent::~QScriptDebuggerEvent() { - delete d_ptr; } QScriptDebuggerEvent &QScriptDebuggerEvent::operator=(const QScriptDebuggerEvent &other) @@ -276,7 +275,7 @@ bool QScriptDebuggerEvent::operator!=(const QScriptDebuggerEvent &other) const */ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerEvent &event) { - const QScriptDebuggerEventPrivate *d = event.d_ptr; + const QScriptDebuggerEventPrivate *d = event.d_ptr.data(); out << (quint32)d->type; out << (qint32)d->attributes.size(); QHash<QScriptDebuggerEvent::Attribute, QVariant>::const_iterator it; @@ -296,7 +295,7 @@ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerEvent &event) */ QDataStream &operator>>(QDataStream &in, QScriptDebuggerEvent &event) { - QScriptDebuggerEventPrivate *d = event.d_ptr; + QScriptDebuggerEventPrivate *d = event.d_ptr.data(); quint32 type; in >> type; diff --git a/src/scripttools/debugging/qscriptdebuggerevent_p.h b/src/scripttools/debugging/qscriptdebuggerevent_p.h index d9c073c..0cfde4f 100644 --- a/src/scripttools/debugging/qscriptdebuggerevent_p.h +++ b/src/scripttools/debugging/qscriptdebuggerevent_p.h @@ -57,6 +57,7 @@ #include <QtCore/qcoreevent.h> #include <QtCore/qhash.h> #include <QtCore/qvariant.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE @@ -137,7 +138,7 @@ public: bool operator!=(const QScriptDebuggerEvent &other) const; private: - QScriptDebuggerEventPrivate *d_ptr; + QScopedPointer<QScriptDebuggerEventPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerEvent) }; diff --git a/src/scripttools/debugging/qscriptdebuggerfrontend.cpp b/src/scripttools/debugging/qscriptdebuggerfrontend.cpp index ced20b1..4d0a8b4 100644 --- a/src/scripttools/debugging/qscriptdebuggerfrontend.cpp +++ b/src/scripttools/debugging/qscriptdebuggerfrontend.cpp @@ -143,7 +143,6 @@ QScriptDebuggerFrontend::QScriptDebuggerFrontend() QScriptDebuggerFrontend::~QScriptDebuggerFrontend() { - delete d_ptr; } QScriptDebuggerFrontend::QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd) diff --git a/src/scripttools/debugging/qscriptdebuggerfrontend_p.h b/src/scripttools/debugging/qscriptdebuggerfrontend_p.h index a763463..bed0f85 100644 --- a/src/scripttools/debugging/qscriptdebuggerfrontend_p.h +++ b/src/scripttools/debugging/qscriptdebuggerfrontend_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qstring.h> #include "qscriptdebuggercommandschedulerinterface_p.h" @@ -90,7 +90,7 @@ protected: protected: QScriptDebuggerFrontend(QScriptDebuggerFrontendPrivate &dd); - QScriptDebuggerFrontendPrivate *d_ptr; + QScopedPointer<QScriptDebuggerFrontendPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerFrontend) diff --git a/src/scripttools/debugging/qscriptdebuggerjob.cpp b/src/scripttools/debugging/qscriptdebuggerjob.cpp index 109c805..20d17bb 100644 --- a/src/scripttools/debugging/qscriptdebuggerjob.cpp +++ b/src/scripttools/debugging/qscriptdebuggerjob.cpp @@ -85,7 +85,6 @@ QScriptDebuggerJob::QScriptDebuggerJob(QScriptDebuggerJobPrivate &dd) QScriptDebuggerJob::~QScriptDebuggerJob() { - delete d_ptr; } void QScriptDebuggerJob::finish() diff --git a/src/scripttools/debugging/qscriptdebuggerjob_p.h b/src/scripttools/debugging/qscriptdebuggerjob_p.h index e84d6d5..2f7305f 100644 --- a/src/scripttools/debugging/qscriptdebuggerjob_p.h +++ b/src/scripttools/debugging/qscriptdebuggerjob_p.h @@ -54,6 +54,7 @@ // #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_NAMESPACE @@ -76,7 +77,7 @@ public: protected: QScriptDebuggerJob(QScriptDebuggerJobPrivate &dd); - QScriptDebuggerJobPrivate *d_ptr; + QScopedPointer<QScriptDebuggerJobPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptDebuggerJob) diff --git a/src/scripttools/debugging/qscriptdebuggerresponse.cpp b/src/scripttools/debugging/qscriptdebuggerresponse.cpp index 82bfff2..bf24846 100644 --- a/src/scripttools/debugging/qscriptdebuggerresponse.cpp +++ b/src/scripttools/debugging/qscriptdebuggerresponse.cpp @@ -101,7 +101,6 @@ QScriptDebuggerResponse::QScriptDebuggerResponse(const QScriptDebuggerResponse & QScriptDebuggerResponse::~QScriptDebuggerResponse() { - delete d_ptr; } QScriptDebuggerResponse &QScriptDebuggerResponse::operator=(const QScriptDebuggerResponse &other) @@ -320,7 +319,7 @@ bool QScriptDebuggerResponse::operator!=(const QScriptDebuggerResponse &other) c */ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerResponse &response) { - const QScriptDebuggerResponsePrivate *d = response.d_ptr; + const QScriptDebuggerResponsePrivate *d = response.d_ptr.data(); out << (quint32)d->error; out << d->result; out << d->async; @@ -336,7 +335,7 @@ QDataStream &operator<<(QDataStream &out, const QScriptDebuggerResponse &respons */ QDataStream &operator>>(QDataStream &in, QScriptDebuggerResponse &response) { - QScriptDebuggerResponsePrivate *d = response.d_ptr; + QScriptDebuggerResponsePrivate *d = response.d_ptr.data(); quint32 error; in >> error; diff --git a/src/scripttools/debugging/qscriptdebuggerresponse_p.h b/src/scripttools/debugging/qscriptdebuggerresponse_p.h index dd65ffd..4fa1731 100644 --- a/src/scripttools/debugging/qscriptdebuggerresponse_p.h +++ b/src/scripttools/debugging/qscriptdebuggerresponse_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qmap.h> #include <QtCore/qvariant.h> @@ -127,7 +127,7 @@ public: bool operator!=(const QScriptDebuggerResponse &other) const; private: - QScriptDebuggerResponsePrivate *d_ptr; + QScopedPointer<QScriptDebuggerResponsePrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerResponse) }; diff --git a/src/scripttools/debugging/qscriptdebuggervalue.cpp b/src/scripttools/debugging/qscriptdebuggervalue.cpp index bb41ee8..b92cbd2 100644 --- a/src/scripttools/debugging/qscriptdebuggervalue.cpp +++ b/src/scripttools/debugging/qscriptdebuggervalue.cpp @@ -94,7 +94,7 @@ QScriptDebuggerValue::QScriptDebuggerValue(const QScriptValue &value) : d_ptr(0) { if (value.isValid()) { - d_ptr = new QScriptDebuggerValuePrivate; + d_ptr.reset(new QScriptDebuggerValuePrivate); if (value.isUndefined()) d_ptr->type = UndefinedValue; else if (value.isNull()) @@ -157,7 +157,7 @@ QScriptDebuggerValue::QScriptDebuggerValue(ValueType type) } QScriptDebuggerValue::QScriptDebuggerValue(const QScriptDebuggerValue &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -165,21 +165,11 @@ QScriptDebuggerValue::QScriptDebuggerValue(const QScriptDebuggerValue &other) QScriptDebuggerValue::~QScriptDebuggerValue() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } QScriptDebuggerValue &QScriptDebuggerValue::operator=(const QScriptDebuggerValue &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } diff --git a/src/scripttools/debugging/qscriptdebuggervalue_p.h b/src/scripttools/debugging/qscriptdebuggervalue_p.h index 0142de0..c082bf3 100644 --- a/src/scripttools/debugging/qscriptdebuggervalue_p.h +++ b/src/scripttools/debugging/qscriptdebuggervalue_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qlist.h> QT_BEGIN_NAMESPACE @@ -103,7 +103,7 @@ public: bool operator!=(const QScriptDebuggerValue &other) const; private: - QScriptDebuggerValuePrivate *d_ptr; + QScopedSharedPointer<QScriptDebuggerValuePrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerValue) }; diff --git a/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp index 723e304..63f820b 100644 --- a/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp +++ b/src/scripttools/debugging/qscriptdebuggervalueproperty.cpp @@ -105,7 +105,7 @@ QScriptDebuggerValueProperty::QScriptDebuggerValueProperty(const QString &name, Constructs a QScriptDebuggerValueProperty that is a copy of the \a other property. */ QScriptDebuggerValueProperty::QScriptDebuggerValueProperty(const QScriptDebuggerValueProperty &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -116,10 +116,6 @@ QScriptDebuggerValueProperty::QScriptDebuggerValueProperty(const QScriptDebugger */ QScriptDebuggerValueProperty::~QScriptDebuggerValueProperty() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } /*! @@ -127,13 +123,7 @@ QScriptDebuggerValueProperty::~QScriptDebuggerValueProperty() */ QScriptDebuggerValueProperty &QScriptDebuggerValueProperty::operator=(const QScriptDebuggerValueProperty &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } diff --git a/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h b/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h index f67bafd..be27ebd 100644 --- a/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h +++ b/src/scripttools/debugging/qscriptdebuggervalueproperty_p.h @@ -55,6 +55,7 @@ #include <QtCore/qobjectdefs.h> #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> #include <QtScript/qscriptvalue.h> QT_BEGIN_NAMESPACE @@ -85,7 +86,7 @@ public: bool isValid() const; private: - QScriptDebuggerValuePropertyPrivate *d_ptr; + QScopedSharedPointer<QScriptDebuggerValuePropertyPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptDebuggerValueProperty) }; diff --git a/src/scripttools/debugging/qscriptscriptdata.cpp b/src/scripttools/debugging/qscriptscriptdata.cpp index 068748f..a4f8cd7 100644 --- a/src/scripttools/debugging/qscriptscriptdata.cpp +++ b/src/scripttools/debugging/qscriptscriptdata.cpp @@ -98,7 +98,7 @@ QScriptScriptData::QScriptScriptData(const QString &contents, const QString &fil } QScriptScriptData::QScriptScriptData(const QScriptScriptData &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -106,21 +106,11 @@ QScriptScriptData::QScriptScriptData(const QScriptScriptData &other) QScriptScriptData::~QScriptScriptData() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } QScriptScriptData &QScriptScriptData::operator=(const QScriptScriptData &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } @@ -191,7 +181,7 @@ bool QScriptScriptData::operator!=(const QScriptScriptData &other) const QDataStream &operator<<(QDataStream &out, const QScriptScriptData &data) { - const QScriptScriptDataPrivate *d = data.d_ptr; + const QScriptScriptDataPrivate *d = data.d_ptr.data(); if (d) { out << d->contents; out << d->fileName; @@ -207,10 +197,10 @@ QDataStream &operator<<(QDataStream &out, const QScriptScriptData &data) QDataStream &operator>>(QDataStream &in, QScriptScriptData &data) { if (!data.d_ptr) { - data.d_ptr = new QScriptScriptDataPrivate(); + data.d_ptr.reset(new QScriptScriptDataPrivate()); data.d_ptr->ref.ref(); } - QScriptScriptDataPrivate *d = data.d_ptr; + QScriptScriptDataPrivate *d = data.d_ptr.data(); in >> d->contents; in >> d->fileName; qint32 ln; diff --git a/src/scripttools/debugging/qscriptscriptdata_p.h b/src/scripttools/debugging/qscriptscriptdata_p.h index 50cad32..e871c2c 100644 --- a/src/scripttools/debugging/qscriptscriptdata_p.h +++ b/src/scripttools/debugging/qscriptscriptdata_p.h @@ -54,7 +54,7 @@ // #include <QtCore/qobjectdefs.h> - +#include <QtCore/qscopedpointer.h> #include <QtCore/qdatetime.h> #include <QtCore/qmap.h> @@ -91,7 +91,7 @@ public: bool operator!=(const QScriptScriptData &other) const; private: - QScriptScriptDataPrivate *d_ptr; + QScopedSharedPointer<QScriptScriptDataPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptScriptData) }; diff --git a/src/scripttools/debugging/qscriptstdmessagehandler.cpp b/src/scripttools/debugging/qscriptstdmessagehandler.cpp index 4e0f12c..6742554 100644 --- a/src/scripttools/debugging/qscriptstdmessagehandler.cpp +++ b/src/scripttools/debugging/qscriptstdmessagehandler.cpp @@ -66,7 +66,6 @@ QScriptStdMessageHandler::QScriptStdMessageHandler() QScriptStdMessageHandler::~QScriptStdMessageHandler() { - delete d_ptr; } void QScriptStdMessageHandler::message(QtMsgType type, const QString &text, diff --git a/src/scripttools/debugging/qscriptstdmessagehandler_p.h b/src/scripttools/debugging/qscriptstdmessagehandler_p.h index 8b75f6a..06d680b 100644 --- a/src/scripttools/debugging/qscriptstdmessagehandler_p.h +++ b/src/scripttools/debugging/qscriptstdmessagehandler_p.h @@ -53,6 +53,8 @@ // We mean it. // +#include <QtCore/qscopedpointer.h> + #include "qscriptmessagehandlerinterface_p.h" QT_BEGIN_NAMESPACE @@ -71,7 +73,7 @@ public: const QVariant &data = QVariant()); private: - QScriptStdMessageHandlerPrivate *d_ptr; + QScopedPointer<QScriptStdMessageHandlerPrivate> d_ptr; private: Q_DECLARE_PRIVATE(QScriptStdMessageHandler) diff --git a/src/scripttools/debugging/qscriptvalueproperty.cpp b/src/scripttools/debugging/qscriptvalueproperty.cpp index 245edc3..75cfdd7 100644 --- a/src/scripttools/debugging/qscriptvalueproperty.cpp +++ b/src/scripttools/debugging/qscriptvalueproperty.cpp @@ -95,7 +95,7 @@ QScriptValueProperty::QScriptValueProperty(const QString &name, Constructs a QScriptValueProperty that is a copy of the \a other property. */ QScriptValueProperty::QScriptValueProperty(const QScriptValueProperty &other) - : d_ptr(other.d_ptr) + : d_ptr(other.d_ptr.data()) { if (d_ptr) d_ptr->ref.ref(); @@ -106,10 +106,6 @@ QScriptValueProperty::QScriptValueProperty(const QScriptValueProperty &other) */ QScriptValueProperty::~QScriptValueProperty() { - if (d_ptr && !d_ptr->ref.deref()) { - delete d_ptr; - d_ptr = 0; - } } /*! @@ -117,13 +113,7 @@ QScriptValueProperty::~QScriptValueProperty() */ QScriptValueProperty &QScriptValueProperty::operator=(const QScriptValueProperty &other) { - if (d_ptr == other.d_ptr) - return *this; - if (d_ptr && !d_ptr->ref.deref()) - delete d_ptr; - d_ptr = other.d_ptr; - if (d_ptr) - d_ptr->ref.ref(); + d_ptr.assign(other.d_ptr.data()); return *this; } diff --git a/src/scripttools/debugging/qscriptvalueproperty_p.h b/src/scripttools/debugging/qscriptvalueproperty_p.h index 938ab83..ca6980f 100644 --- a/src/scripttools/debugging/qscriptvalueproperty_p.h +++ b/src/scripttools/debugging/qscriptvalueproperty_p.h @@ -55,6 +55,7 @@ #include <QtCore/qobjectdefs.h> #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> #include <QtScript/qscriptvalue.h> QT_BEGIN_NAMESPACE @@ -81,7 +82,7 @@ public: bool isValid() const; private: - QScriptValuePropertyPrivate *d_ptr; + QScopedSharedPointer<QScriptValuePropertyPrivate> d_ptr; Q_DECLARE_PRIVATE(QScriptValueProperty) }; diff --git a/src/svg/qgraphicssvgitem.h b/src/svg/qgraphicssvgitem.h index c6ab0f7..940ce9b 100644 --- a/src/svg/qgraphicssvgitem.h +++ b/src/svg/qgraphicssvgitem.h @@ -41,8 +41,8 @@ #ifndef QGRAPHICSSVGITEM_H #define QGRAPHICSSVGITEM_H -#include <QtGui/qgraphicsitem.h> #include <QtCore/qobject.h> +#include <QtGui/qgraphicsitem.h> #ifndef QT_NO_GRAPHICSSVGITEM @@ -89,9 +89,9 @@ private: // Q_DECLARE_PRIVATE_WITH_BASE(QGraphicsSvgItem, QObject) inline QGraphicsSvgItemPrivate *d_func() - { return reinterpret_cast<QGraphicsSvgItemPrivate *>(QObject::d_ptr); } + { return reinterpret_cast<QGraphicsSvgItemPrivate *>(QObject::d_ptr.data()); } inline const QGraphicsSvgItemPrivate *d_func() const - { return reinterpret_cast<const QGraphicsSvgItemPrivate *>(QObject::d_ptr); } + { return reinterpret_cast<const QGraphicsSvgItemPrivate *>(QObject::d_ptr.data()); } friend class QGraphicsSvgItemPrivate; Q_PRIVATE_SLOT(d_func(), void _q_repaintItem()) diff --git a/src/svg/qsvggenerator.cpp b/src/svg/qsvggenerator.cpp index fd4c875..5052ec7 100644 --- a/src/svg/qsvggenerator.cpp +++ b/src/svg/qsvggenerator.cpp @@ -567,7 +567,6 @@ QSvgGenerator::~QSvgGenerator() if (d->owns_iodevice) delete d->engine->outputDevice(); delete d->engine; - delete d_ptr; } /*! diff --git a/src/svg/qsvggenerator.h b/src/svg/qsvggenerator.h index 723a220..1d24324 100644 --- a/src/svg/qsvggenerator.h +++ b/src/svg/qsvggenerator.h @@ -49,6 +49,7 @@ #include <QtCore/qnamespace.h> #include <QtCore/qiodevice.h> #include <QtCore/qobjectdefs.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -100,7 +101,7 @@ protected: int metric(QPaintDevice::PaintDeviceMetric metric) const; private: - QSvgGeneratorPrivate *d_ptr; + QScopedPointer<QSvgGeneratorPrivate> d_ptr; }; QT_END_NAMESPACE diff --git a/src/testlib/3rdparty/cycle_p.h b/src/testlib/3rdparty/cycle_p.h index 547fdc1..a292423 100644 --- a/src/testlib/3rdparty/cycle_p.h +++ b/src/testlib/3rdparty/cycle_p.h @@ -190,6 +190,7 @@ INLINE_ELAPSED(__inline__) #endif /* Visual C++ -- thanks to Morten Nissov for his help with this */ +#if defined(_MSC_VER) #if _MSC_VER >= 1200 && (_M_IX86 >= 500 || (defined(_WIN32_WCE) && defined(_X86_))) && !defined(HAVE_TICK_COUNTER) #include <windows.h> typedef LARGE_INTEGER CycleCounterTicks; @@ -215,6 +216,7 @@ static __inline double elapsed(CycleCounterTicks t1, CycleCounterTicks t0) #define HAVE_TICK_COUNTER #define TIME_MIN 5000.0 /* unreliable pentium IV cycle counter */ #endif +#endif #if _MSC_VER >= 1400 && defined(_WIN32_WCE) && !defined(HAVE_TICK_COUNTER) #include <windows.h> diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index b676012..38e63cf 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -1437,7 +1437,7 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) } #endif - #ifndef QT_NO_EXCEPTIONS +#ifndef QT_NO_EXCEPTIONS } catch (...) { QTestResult::addFailure("Caught unhandled exception", __FILE__, __LINE__); if (QTestResult::currentTestFunction()) { @@ -1451,13 +1451,13 @@ int QTest::qExec(QObject *testObject, int argc, char **argv) IOPMAssertionRelease(powerID); } #endif - #ifdef Q_OS_WIN +//# ifdef Q_OS_WIN // rethrow exception to make debugging easier throw; - #endif - return -1; +//# endif + return 1; } - #endif +# endif currentTestObject = 0; #ifdef QT_MAC_USE_COCOA diff --git a/src/xml/dom/qdom.cpp b/src/xml/dom/qdom.cpp index 550abc9..5e2c74b 100644 --- a/src/xml/dom/qdom.cpp +++ b/src/xml/dom/qdom.cpp @@ -512,8 +512,8 @@ public: bool setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn); // Attributes - QDomDocumentTypePrivate* doctype() { return type; }; - QDomImplementationPrivate* implementation() { return impl; }; + QDomDocumentTypePrivate* doctype() { return type.data(); }; + QDomImplementationPrivate* implementation() { return impl.data(); }; QDomElementPrivate* documentElement(); // Factories @@ -537,8 +537,8 @@ public: void clear(); // Variables - QDomImplementationPrivate* impl; - QDomDocumentTypePrivate* type; + QScopedSharedPointer<QDomImplementationPrivate> impl; + QScopedSharedPointer<QDomDocumentTypePrivate> type; void saveDocument(QTextStream& stream, const int indent, QDomNode::EncodingPolicy encUsed) const; @@ -3060,7 +3060,7 @@ QDomNamedNodeMapPrivate::~QDomNamedNodeMapPrivate() QDomNamedNodeMapPrivate* QDomNamedNodeMapPrivate::clone(QDomNodePrivate* p) { - QDomNamedNodeMapPrivate* m = new QDomNamedNodeMapPrivate(p); + QScopedPointer<QDomNamedNodeMapPrivate> m(new QDomNamedNodeMapPrivate(p)); m->readonly = readonly; m->appendToParent = appendToParent; @@ -3073,7 +3073,7 @@ QDomNamedNodeMapPrivate* QDomNamedNodeMapPrivate::clone(QDomNodePrivate* p) // we are no longer interested in ownership m->ref.deref(); - return m; + return m.take(); } void QDomNamedNodeMapPrivate::clearMap() @@ -3499,13 +3499,18 @@ QDomDocumentTypePrivate::~QDomDocumentTypePrivate() void QDomDocumentTypePrivate::init() { entities = new QDomNamedNodeMapPrivate(this); - notations = new QDomNamedNodeMapPrivate(this); - publicId.clear(); - systemId.clear(); - internalSubset.clear(); - - entities->setAppendToParent(true); - notations->setAppendToParent(true); + QT_TRY { + notations = new QDomNamedNodeMapPrivate(this); + publicId.clear(); + systemId.clear(); + internalSubset.clear(); + + entities->setAppendToParent(true); + notations->setAppendToParent(true); + } QT_CATCH(...) { + delete entities; + QT_RETHROW; + } } QDomNodePrivate* QDomDocumentTypePrivate::cloneNode(bool deep) @@ -6148,8 +6153,8 @@ QDomDocumentPrivate::QDomDocumentPrivate() : QDomNodePrivate(0), nodeListTime(1) { - impl = new QDomImplementationPrivate; - type = new QDomDocumentTypePrivate(this, this); + impl.reset(new QDomImplementationPrivate); + type.reset(new QDomDocumentTypePrivate(this, this)); name = QLatin1String("#document"); } @@ -6158,8 +6163,8 @@ QDomDocumentPrivate::QDomDocumentPrivate(const QString& aname) : QDomNodePrivate(0), nodeListTime(1) { - impl = new QDomImplementationPrivate; - type = new QDomDocumentTypePrivate(this, this); + impl.reset(new QDomImplementationPrivate); + type.reset(new QDomDocumentTypePrivate(this, this)); type->name = aname; name = QLatin1String("#document"); @@ -6169,12 +6174,11 @@ QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentTypePrivate* dt) : QDomNodePrivate(0), nodeListTime(1) { - impl = new QDomImplementationPrivate; + impl.reset(new QDomImplementationPrivate); if (dt != 0) { - type = dt; - type->ref.ref(); + type.assign(dt); } else { - type = new QDomDocumentTypePrivate(this, this); + type.reset(new QDomDocumentTypePrivate(this, this)); } name = QLatin1String("#document"); @@ -6184,31 +6188,19 @@ QDomDocumentPrivate::QDomDocumentPrivate(QDomDocumentPrivate* n, bool deep) : QDomNodePrivate(n, deep), nodeListTime(1) { - impl = n->impl->clone(); - // Reference count is down to 0, so we set it to 1 here. - impl->ref.ref(); - type = (QDomDocumentTypePrivate*)n->type->cloneNode(); + impl.assign(n->impl->clone()); + type.assign((QDomDocumentTypePrivate*)n->type->cloneNode()); type->setParent(this); - // Reference count is down to 0, so we set it to 1 here. - type->ref.ref(); } QDomDocumentPrivate::~QDomDocumentPrivate() { - if (!impl->ref.deref()) - delete impl; - if (!type->ref.deref()) - delete type; } void QDomDocumentPrivate::clear() { - if (!impl->ref.deref()) - delete impl; - if (!type->ref.deref()) - delete type; - impl = 0; - type = 0; + impl.assign(0); + type.assign(0); QDomNodePrivate::clear(); } @@ -6229,8 +6221,8 @@ bool QDomDocumentPrivate::setContent(QXmlInputSource *source, bool namespaceProc bool QDomDocumentPrivate::setContent(QXmlInputSource *source, QXmlReader *reader, QString *errorMsg, int *errorLine, int *errorColumn) { clear(); - impl = new QDomImplementationPrivate; - type = new QDomDocumentTypePrivate(this, this); + impl.reset(new QDomImplementationPrivate); + type.reset(new QDomDocumentTypePrivate(this, this)); bool namespaceProcessing = reader->feature(QLatin1String("http://xml.org/sax/features/namespaces")) && !reader->feature(QLatin1String("http://xml.org/sax/features/namespace-prefixes")); @@ -7448,20 +7440,22 @@ bool QDomHandler::characters(const QString& ch) if (node == doc) return false; - QDomNodePrivate *n; + QScopedPointer<QDomNodePrivate> n; if (cdata) { - n = doc->createCDATASection(ch); + n.reset(doc->createCDATASection(ch)); } else if (!entityName.isEmpty()) { - QDomEntityPrivate* e = new QDomEntityPrivate(doc, 0, entityName, - QString(), QString(), QString()); + QScopedPointer<QDomEntityPrivate> e(new QDomEntityPrivate(doc, 0, entityName, + QString(), QString(), QString())); e->value = ch; - doc->doctype()->appendChild(e); - n = doc->createEntityReference(entityName); + doc->doctype()->appendChild(e.data()); + e.take(); + n.reset(doc->createEntityReference(entityName)); } else { - n = doc->createTextNode(ch); + n.reset(doc->createTextNode(ch)); } n->setLocation(locator->lineNumber(), locator->columnNumber()); - node->appendChild(n); + node->appendChild(n.data()); + n.take(); return true; } diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp index ba68636..1655642 100644 --- a/src/xml/sax/qxml.cpp +++ b/src/xml/sax/qxml.cpp @@ -262,10 +262,11 @@ class QXmlDefaultHandlerPrivate class QXmlSimpleReaderPrivate { +public: + ~QXmlSimpleReaderPrivate(); private: // functions - QXmlSimpleReaderPrivate(); - ~QXmlSimpleReaderPrivate(); + QXmlSimpleReaderPrivate(QXmlSimpleReader *reader); void initIncrementalParsing(); // used to determine if elements are correctly nested @@ -350,7 +351,7 @@ private: bool contentCharDataRead; // helper classes - QXmlLocator *locator; + QScopedPointer<QXmlLocator> locator; QXmlNamespaceSupport namespaceSupport; // error string @@ -545,8 +546,8 @@ private: QXmlParseException::QXmlParseException(const QString& name, int c, int l, const QString& p, const QString& s) + : d(new QXmlParseExceptionPrivate) { - d = new QXmlParseExceptionPrivate; d->msg = name; d->column = c; d->line = l; @@ -559,7 +560,6 @@ QXmlParseException::QXmlParseException(const QString& name, int c, int l, */ QXmlParseException::~QXmlParseException() { - delete d; } /*! @@ -928,8 +928,9 @@ void QXmlNamespaceSupport::popContext() */ void QXmlNamespaceSupport::reset() { + QXmlNamespaceSupportPrivate *newD = new QXmlNamespaceSupportPrivate; delete d; - d = new QXmlNamespaceSupportPrivate; + d = newD; } @@ -1260,18 +1261,23 @@ void QXmlInputSource::init() { d = new QXmlInputSourcePrivate; - d->inputDevice = 0; - d->inputStream = 0; + QT_TRY { + d->inputDevice = 0; + d->inputStream = 0; - setData(QString()); + setData(QString()); #ifndef QT_NO_TEXTCODEC - d->encMapper = 0; + d->encMapper = 0; #endif - d->nextReturnedEndOfData = true; // first call to next() will call fetchData() + d->nextReturnedEndOfData = true; // first call to next() will call fetchData() - d->encodingDeclBytes.clear(); - d->encodingDeclChars.clear(); - d->lookingForEncodingDecl = true; + d->encodingDeclBytes.clear(); + d->encodingDeclChars.clear(); + d->lookingForEncodingDecl = true; + } QT_CATCH(...) { + delete(d); + QT_RETHROW; + } } /*! @@ -2715,9 +2721,24 @@ inline void QXmlSimpleReaderPrivate::refClear() refValueLen = 0; refArrayPos = 0; } -QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate() +QXmlSimpleReaderPrivate::QXmlSimpleReaderPrivate(QXmlSimpleReader *reader) { + q_ptr = reader; parseStack = 0; + + locator.reset(new QXmlSimpleReaderLocator(reader)); + entityRes = 0; + dtdHnd = 0; + contentHnd = 0; + errorHnd = 0; + lexicalHnd = 0; + declHnd = 0; + + // default feature settings + useNamespaces = true; + useNamespacePrefixes = false; + reportWhitespaceCharData = true; + reportEntities = false; } QXmlSimpleReaderPrivate::~QXmlSimpleReaderPrivate() @@ -2727,8 +2748,10 @@ QXmlSimpleReaderPrivate::~QXmlSimpleReaderPrivate() void QXmlSimpleReaderPrivate::initIncrementalParsing() { - delete parseStack; - parseStack = new QStack<ParseState>; + if( parseStack ) + parseStack->clear(); + else + parseStack = new QStack<ParseState>; } /********************************************* @@ -3101,25 +3124,8 @@ static NameChar determineNameChar(QChar ch) */ QXmlSimpleReader::QXmlSimpleReader() + : d_ptr(new QXmlSimpleReaderPrivate(this)) { - d_ptr = new QXmlSimpleReaderPrivate(); - Q_D(QXmlSimpleReader); - d->q_ptr = this; - - d->locator = new QXmlSimpleReaderLocator(this); - - d->entityRes = 0; - d->dtdHnd = 0; - d->contentHnd = 0; - d->errorHnd = 0; - d->lexicalHnd = 0; - d->declHnd = 0; - - // default feature settings - d->useNamespaces = true; - d->useNamespacePrefixes = false; - d->reportWhitespaceCharData = true; - d->reportEntities = false; } /*! @@ -3127,9 +3133,6 @@ QXmlSimpleReader::QXmlSimpleReader() */ QXmlSimpleReader::~QXmlSimpleReader() { - Q_D(QXmlSimpleReader); - delete d->locator; - delete d; } /*! @@ -3412,7 +3415,7 @@ bool QXmlSimpleReader::parse(const QXmlInputSource *input, bool incremental) // call the handler if (d->contentHnd) { - d->contentHnd->setDocumentLocator(d->locator); + d->contentHnd->setDocumentLocator(d->locator.data()); if (!d->contentHnd->startDocument()) { d->reportParseError(d->contentHnd->errorString()); d->tags.clear(); diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h index e0165d3..8e3eb25 100644 --- a/src/xml/sax/qxml.h +++ b/src/xml/sax/qxml.h @@ -47,6 +47,7 @@ #include <QtCore/qstring.h> #include <QtCore/qstringlist.h> #include <QtCore/qlist.h> +#include <QtCore/qscopedpointer.h> QT_BEGIN_HEADER @@ -202,7 +203,7 @@ public: QString message() const; private: - QXmlParseExceptionPrivate *d; + QScopedPointer<QXmlParseExceptionPrivate> d; }; @@ -271,7 +272,7 @@ public: private: Q_DISABLE_COPY(QXmlSimpleReader) Q_DECLARE_PRIVATE(QXmlSimpleReader) - QXmlSimpleReaderPrivate* d_ptr; + QScopedPointer<QXmlSimpleReaderPrivate> d_ptr; friend class QXmlSimpleReaderLocator; }; diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp index 0caa8c4..12ce6a7 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel.cpp +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.cpp @@ -302,7 +302,6 @@ QAbstractXmlNodeModel::QAbstractXmlNodeModel(QAbstractXmlNodeModelPrivate *d) : */ QAbstractXmlNodeModel::~QAbstractXmlNodeModel() { - delete d_ptr; } /*! diff --git a/src/xmlpatterns/api/qabstractxmlnodemodel.h b/src/xmlpatterns/api/qabstractxmlnodemodel.h index 6c9574c..9b5b3dd 100644 --- a/src/xmlpatterns/api/qabstractxmlnodemodel.h +++ b/src/xmlpatterns/api/qabstractxmlnodemodel.h @@ -44,6 +44,7 @@ #include <QtXmlPatterns/QXmlName> #include <QtCore/QSharedData> +#include <QtCore/QScopedPointer> QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -339,7 +340,7 @@ protected: return QXmlNodeModelIndex::create(data, this, additionalData); } - QAbstractXmlNodeModelPrivate *d_ptr; + QScopedPointer<QAbstractXmlNodeModelPrivate> d_ptr; private: friend class QPatternist::ItemMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *, QExplicitlySharedDataPointer<QPatternist::DynamicContext> >; friend class QPatternist::SequenceMappingIterator<QXmlNodeModelIndex, QXmlNodeModelIndex, const QAbstractXmlNodeModel *>; diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.cpp b/src/xmlpatterns/api/qabstractxmlreceiver.cpp index ddd01e4..4253ce0 100644 --- a/src/xmlpatterns/api/qabstractxmlreceiver.cpp +++ b/src/xmlpatterns/api/qabstractxmlreceiver.cpp @@ -224,7 +224,6 @@ QAbstractXmlReceiver::QAbstractXmlReceiver() : d_ptr(0) */ QAbstractXmlReceiver::~QAbstractXmlReceiver() { - delete d_ptr; } /*! diff --git a/src/xmlpatterns/api/qabstractxmlreceiver.h b/src/xmlpatterns/api/qabstractxmlreceiver.h index 355576a..270b9da 100644 --- a/src/xmlpatterns/api/qabstractxmlreceiver.h +++ b/src/xmlpatterns/api/qabstractxmlreceiver.h @@ -43,6 +43,7 @@ #define QABSTRACTXMLRECEIVER_H #include <QtCore/QVariant> +#include <QtCore/QScopedPointer> #include <QtXmlPatterns/QXmlNodeModelIndex> QT_BEGIN_HEADER @@ -90,7 +91,7 @@ public: protected: QAbstractXmlReceiver(QAbstractXmlReceiverPrivate *d); - QAbstractXmlReceiverPrivate *d_ptr; + QScopedPointer<QAbstractXmlReceiverPrivate> d_ptr; void sendAsNode(const QPatternist::Item &outputItem); private: diff --git a/src/xmlpatterns/api/qxmlresultitems.cpp b/src/xmlpatterns/api/qxmlresultitems.cpp index a2253c9..652d931 100644 --- a/src/xmlpatterns/api/qxmlresultitems.cpp +++ b/src/xmlpatterns/api/qxmlresultitems.cpp @@ -85,7 +85,6 @@ QXmlResultItems::QXmlResultItems() : d_ptr(new QXmlResultItemsPrivate()) */ QXmlResultItems::~QXmlResultItems() { - delete d_ptr; } /*! diff --git a/src/xmlpatterns/api/qxmlresultitems.h b/src/xmlpatterns/api/qxmlresultitems.h index aeb7d2c..5484616 100644 --- a/src/xmlpatterns/api/qxmlresultitems.h +++ b/src/xmlpatterns/api/qxmlresultitems.h @@ -43,6 +43,7 @@ #define QXMLRESULTITEMS #include <QtCore/QString> +#include <QtCore/QScopedPointer> QT_BEGIN_HEADER QT_BEGIN_NAMESPACE @@ -66,7 +67,7 @@ public: private: friend class QXmlQuery; Q_DECLARE_PRIVATE(QXmlResultItems) - QXmlResultItemsPrivate *d_ptr; + QScopedPointer<QXmlResultItemsPrivate> d_ptr; Q_DISABLE_COPY(QXmlResultItems) }; |