summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorSamuel Rødal <samuel.rodal@nokia.com>2011-07-12 12:52:22 +0200
committerSamuel Rødal <samuel.rodal@nokia.com>2011-07-12 12:52:22 +0200
commit2371147354d4436bb54c588662ac315dd4c2f940 (patch)
tree5c90b1dd18de394cff2fb4e1bedc628da3c7d341 /src
parent54ec6d177e0e8fb04cd01e70461484a80ca1f7a4 (diff)
parent82454b6014a7ee0b048b4db8d64a21de849d4ab9 (diff)
Merge remote branch 'gerrit/master' into refactor
Conflicts: src/gui/image/qicon.cpp src/gui/image/qicon.h src/gui/image/qicon_p.h src/gui/text/qfontdatabase.cpp src/plugins/platforms/wayland/gl_integration/qwaylandglwindowsurface.cpp src/plugins/platforms/wayland/gl_integration/wayland_egl/qwaylandglcontext.cpp src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp sync.profile Change-Id: Ie0a23a12177ff51bf562e15b2dd41f071afb19b4
Diffstat (limited to 'src')
-rw-r--r--src/corelib/concurrent/qtconcurrentexception.cpp22
-rw-r--r--src/corelib/concurrent/qtconcurrentexception.h3
-rw-r--r--src/corelib/global/qglobal.cpp15
-rw-r--r--src/corelib/global/qglobal.h87
-rw-r--r--src/corelib/global/qlibraryinfo.cpp9
-rw-r--r--src/corelib/global/qlibraryinfo.h1
-rw-r--r--src/corelib/io/qtldurl.cpp34
-rw-r--r--src/corelib/io/qtldurl_p.h34
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp101
-rw-r--r--src/corelib/kernel/qeventloop.cpp66
-rw-r--r--src/corelib/kernel/qobject.cpp130
-rw-r--r--src/corelib/tools/qbytearray.h20
-rw-r--r--src/corelib/tools/qchar.cpp4
-rw-r--r--src/corelib/tools/qchar.h19
-rw-r--r--src/corelib/tools/qlist.cpp2
-rw-r--r--src/corelib/tools/qrefcount.cpp51
-rw-r--r--src/corelib/tools/qrefcount.h92
-rw-r--r--src/corelib/tools/qstring.cpp519
-rw-r--r--src/corelib/tools/qstring.h172
-rw-r--r--src/corelib/tools/qstringbuilder.cpp49
-rw-r--r--src/corelib/tools/qstringbuilder.h55
-rw-r--r--src/corelib/tools/qstringlist.h2
-rw-r--r--src/corelib/tools/tools.pri2
-rw-r--r--src/dbus/qdbus_symbols.cpp6
-rw-r--r--src/dbus/qdbusconnection.cpp2
-rw-r--r--src/gui/painting/qcosmeticstroker.cpp34
-rw-r--r--src/gui/painting/qcosmeticstroker_p.h34
-rw-r--r--src/gui/painting/qpainter.cpp16
-rw-r--r--src/gui/text/qfontdatabase.cpp93
-rw-r--r--src/gui/text/qfontdatabase_qpa.cpp2
-rw-r--r--src/gui/text/qtextdocument.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel_p.h2
-rw-r--r--src/network/access/qnetworkaccesshttpbackend.cpp1189
-rw-r--r--src/network/access/qnetworkaccesshttpbackend_p.h169
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp1
-rw-r--r--src/network/access/qnetworkaccessmanager.h1
-rw-r--r--src/network/access/qnetworkrequest.cpp21
-rw-r--r--src/network/access/qnetworkrequest.h4
-rw-r--r--src/network/kernel/qhostinfo.cpp1
-rw-r--r--src/network/ssl/qsslcertificate.cpp101
-rw-r--r--src/network/ssl/qsslcertificate.h6
-rw-r--r--src/network/ssl/qsslcertificate_p.h5
-rw-r--r--src/network/ssl/qsslsocket.cpp21
-rw-r--r--src/network/ssl/qsslsocket.h3
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp17
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols.cpp8
-rw-r--r--src/network/ssl/qsslsocket_openssl_symbols_p.h3
-rw-r--r--src/network/ssl/qsslsocket_p.h2
-rw-r--r--src/plugins/bearer/connman/qofonoservice_linux.cpp18
-rw-r--r--src/plugins/platforms/uikit/README4
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp11
-rw-r--r--src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h1
-rw-r--r--src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp9
-rw-r--r--src/sql/kernel/qsql.h19
-rw-r--r--src/sql/kernel/qsqldatabase.cpp20
-rw-r--r--src/sql/kernel/qsqldatabase.h9
-rw-r--r--src/sql/kernel/qsqldriver.h14
-rw-r--r--src/sql/kernel/qsqlerror.h7
-rw-r--r--src/sql/kernel/qsqlfield.h4
-rw-r--r--src/sql/kernel/qsqlindex.cpp54
-rw-r--r--src/sql/kernel/qsqlindex.h8
-rw-r--r--src/sql/kernel/qsqlquery.h3
-rw-r--r--src/sql/kernel/qsqlrecord.cpp71
-rw-r--r--src/sql/kernel/qsqlrecord.h9
-rw-r--r--src/sql/kernel/qsqlresult.h4
-rw-r--r--src/widgets/platforms/mac/qfontdatabase_mac.cpp6
-rw-r--r--src/widgets/platforms/mac/qfontengine_coretext.mm20
-rw-r--r--src/widgets/platforms/mac/qfontengine_coretext_p.h3
-rw-r--r--src/widgets/platforms/s60/qfontdatabase_s60.cpp2
-rw-r--r--src/widgets/platforms/win/qfontdatabase_win.cpp8
-rw-r--r--src/widgets/platforms/x11/qfontdatabase_x11.cpp10
-rw-r--r--src/xml/sax/qxml.cpp23
-rw-r--r--src/xml/sax/qxml.h5
73 files changed, 1109 insertions, 2465 deletions
diff --git a/src/corelib/concurrent/qtconcurrentexception.cpp b/src/corelib/concurrent/qtconcurrentexception.cpp
index 933ad3c264..237152c0d3 100644
--- a/src/corelib/concurrent/qtconcurrentexception.cpp
+++ b/src/corelib/concurrent/qtconcurrentexception.cpp
@@ -40,6 +40,7 @@
****************************************************************************/
#include "qtconcurrentexception.h"
+#include "QtCore/qshareddata.h"
#ifndef QT_NO_QFUTURE
#ifndef QT_NO_EXCEPTIONS
@@ -141,15 +142,14 @@ Exception *UnhandledException::clone() const
namespace internal {
-class Base
+class Base : public QSharedData
{
public:
Base(Exception *exception)
- : exception(exception), refCount(1), hasThrown(false) { }
+ : exception(exception), hasThrown(false) { }
~Base() { delete exception; }
Exception *exception;
- QAtomicInt refCount;
bool hasThrown;
};
@@ -158,27 +158,15 @@ ExceptionHolder::ExceptionHolder(Exception *exception)
ExceptionHolder::ExceptionHolder(const ExceptionHolder &other)
: base(other.base)
-{
- base->refCount.ref();
-}
+{}
void ExceptionHolder::operator=(const ExceptionHolder &other)
{
- if (base == other.base)
- return;
-
- if (base->refCount.deref() == false)
- delete base;
-
base = other.base;
- base->refCount.ref();
}
ExceptionHolder::~ExceptionHolder()
-{
- if (base->refCount.deref() == 0)
- delete base;
-}
+{}
Exception *ExceptionHolder::exception() const
{
diff --git a/src/corelib/concurrent/qtconcurrentexception.h b/src/corelib/concurrent/qtconcurrentexception.h
index b58b3ba23a..1c100a5206 100644
--- a/src/corelib/concurrent/qtconcurrentexception.h
+++ b/src/corelib/concurrent/qtconcurrentexception.h
@@ -47,6 +47,7 @@
#ifndef QT_NO_QFUTURE
#include <QtCore/qatomic.h>
+#include <QtCore/qshareddata.h>
#ifndef QT_NO_EXCEPTIONS
# include <exception>
@@ -87,7 +88,7 @@ public:
void operator=(const ExceptionHolder &other);
~ExceptionHolder();
Exception *exception() const;
- Base *base;
+ QExplicitlySharedDataPointer<Base> base;
};
class Q_CORE_EXPORT ExceptionStore
diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp
index ca8b30fc00..bbc9a15e74 100644
--- a/src/corelib/global/qglobal.cpp
+++ b/src/corelib/global/qglobal.cpp
@@ -1642,6 +1642,21 @@ bool qSharedBuild()
\sa Q_WS_MAC, Q_WS_WIN, Q_WS_X11, Q_WS_QWS
*/
+/*!
+ \macro QT_DISABLE_DEPRECATED_BEFORE
+ \relates <QtGlobal>
+
+ This macro can be defined in the project file to disable functions deprecated in
+ a specified version of Qt or any earlier version. The default version number is 5.0,
+ meaning that functions deprecated in or before Qt 5.0 will not be included.
+
+ Examples:
+ When using a future release of Qt 5, set QT_DISABLE_DEPRECATED_BEFORE=0x050100 to
+ disable functions deprecated in Qt 5.1 and earlier. In any release, set
+ QT_DISABLE_DEPRECATED_BEFORE=0x000000 to enable any functions, including the ones
+ deprecated in Qt 5.0
+ */
+
#if defined(QT_BUILD_QMAKE)
// needed to bootstrap qmake
static const unsigned int qt_one = 1;
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index af9d86c2ca..844fe0528e 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -54,6 +54,23 @@
*/
#define QT_VERSION_CHECK(major, minor, patch) ((major<<16)|(minor<<8)|(patch))
+#ifndef QT_DISABLE_DEPRECATED_BEFORE
+#define QT_DISABLE_DEPRECATED_BEFORE QT_VERSION_CHECK(5, 0, 0)
+#endif
+
+/*
+ QT_DEPRECATED_SINCE(major, minor) evaluates as true if the Qt version is greater than
+ the deprecation point specified.
+
+ Use it to specify from which version of Qt a function or class has been deprecated
+
+ Example:
+ #if QT_DEPRECATED_SINCE(5,1)
+ QT_DEPRECATED void deprecatedFunction(); //function deprecated sine Qt 5.1
+ #endif
+ */
+#define QT_DEPRECATED_SINCE(major, minor) (QT_VERSION_CHECK(major, minor, 0) > QT_DISABLE_DEPRECATED_BEFORE)
+
#define QT_PACKAGEDATE_STR "YYYY-MM-DD"
#define QT_PACKAGE_TAG ""
@@ -516,6 +533,7 @@ namespace QT_NAMESPACE {}
# endif
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 404
/* C++0x features supported in GCC 4.4: */
+# define Q_COMPILER_UNICODE_STRINGS
# define Q_COMPILER_VARIADIC_TEMPLATES
# define Q_COMPILER_AUTO_TYPE
# define Q_COMPILER_EXTERN_TEMPLATES
@@ -526,8 +544,12 @@ namespace QT_NAMESPACE {}
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 405
/* C++0x features supported in GCC 4.5: */
# define Q_COMPILER_LAMBDA
-# define Q_COMPILER_UNICODE_STRINGS
# endif
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406
+ /* C++0x features supported in GCC 4.6: */
+# define Q_COMPILER_CONSTEXPR
+# endif
+
# endif
/* IBM compiler versions are a bit messy. There are actually two products:
@@ -961,6 +983,7 @@ QT_END_INCLUDE_NAMESPACE
#error "Compiler doesn't support the bool type"
#endif
+
/*
Constant bool values
*/
@@ -1091,6 +1114,12 @@ redefine to built-in booleans to make autotests work properly */
# define QT_FASTCALL
#endif
+#ifdef Q_COMPILER_CONSTEXPR
+# define Q_DECL_CONSTEXPR constexpr
+#else
+# define Q_DECL_CONSTEXPR
+#endif
+
//defines the type for the WNDPROC on windows
//the alignment needs to be forced for sse2 to not crash with mingw
#if defined(Q_OS_WIN)
@@ -1104,10 +1133,6 @@ redefine to built-in booleans to make autotests work properly */
typedef int QNoImplicitBoolCast;
-#if defined(QT_ARCH_ARM) || defined(QT_ARCH_ARMV6) || defined(QT_ARCH_AVR32) || (defined(QT_ARCH_MIPS) && (defined(Q_WS_QWS) || defined(Q_WS_QPA) || defined(Q_OS_WINCE))) || defined(QT_ARCH_SH) || defined(QT_ARCH_SH4A)
-#define QT_NO_FPU
-#endif
-
// This logic must match the one in qmetatype.h
#if defined(QT_COORD_TYPE)
typedef QT_COORD_TYPE qreal;
@@ -1122,25 +1147,25 @@ typedef double qreal;
*/
template <typename T>
-inline T qAbs(const T &t) { return t >= 0 ? t : -t; }
+Q_DECL_CONSTEXPR inline T qAbs(const T &t) { return t >= 0 ? t : -t; }
-inline int qRound(qreal d)
+Q_DECL_CONSTEXPR inline int qRound(qreal d)
{ return d >= qreal(0.0) ? int(d + qreal(0.5)) : int(d - int(d-1) + qreal(0.5)) + int(d-1); }
#if defined(QT_NO_FPU) || defined(QT_ARCH_ARM) || defined(QT_ARCH_WINDOWSCE) || defined(QT_ARCH_SYMBIAN)
-inline qint64 qRound64(double d)
+Q_DECL_CONSTEXPR inline qint64 qRound64(double d)
{ return d >= 0.0 ? qint64(d + 0.5) : qint64(d - qreal(qint64(d-1)) + 0.5) + qint64(d-1); }
#else
-inline qint64 qRound64(qreal d)
+Q_DECL_CONSTEXPR inline qint64 qRound64(qreal d)
{ return d >= qreal(0.0) ? qint64(d + qreal(0.5)) : qint64(d - qreal(qint64(d-1)) + qreal(0.5)) + qint64(d-1); }
#endif
template <typename T>
-inline const T &qMin(const T &a, const T &b) { if (a < b) return a; return b; }
+Q_DECL_CONSTEXPR inline const T &qMin(const T &a, const T &b) { return (a < b) ? a : b; }
template <typename T>
-inline const T &qMax(const T &a, const T &b) { if (a < b) return b; return a; }
+Q_DECL_CONSTEXPR inline const T &qMax(const T &a, const T &b) { return (a < b) ? b : a; }
template <typename T>
-inline const T &qBound(const T &min, const T &val, const T &max)
+Q_DECL_CONSTEXPR inline const T &qBound(const T &min, const T &val, const T &max)
{ return qMax(min, qMin(max, val)); }
/*
@@ -1914,12 +1939,12 @@ inline bool operator!=(QBool b1, bool b2) { return !b1 != !b2; }
inline bool operator!=(bool b1, QBool b2) { return !b1 != !b2; }
inline bool operator!=(QBool b1, QBool b2) { return !b1 != !b2; }
-static inline bool qFuzzyCompare(double p1, double p2)
+Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(double p1, double p2)
{
return (qAbs(p1 - p2) <= 0.000000000001 * qMin(qAbs(p1), qAbs(p2)));
}
-static inline bool qFuzzyCompare(float p1, float p2)
+Q_DECL_CONSTEXPR static inline bool qFuzzyCompare(float p1, float p2)
{
return (qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2)));
}
@@ -1927,7 +1952,7 @@ static inline bool qFuzzyCompare(float p1, float p2)
/*!
\internal
*/
-static inline bool qFuzzyIsNull(double d)
+Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(double d)
{
return qAbs(d) <= 0.000000000001;
}
@@ -1935,7 +1960,7 @@ static inline bool qFuzzyIsNull(double d)
/*!
\internal
*/
-static inline bool qFuzzyIsNull(float f)
+Q_DECL_CONSTEXPR static inline bool qFuzzyIsNull(float f)
{
return qAbs(f) <= 0.00001f;
}
@@ -2203,9 +2228,9 @@ class QFlags
int i;
public:
typedef Enum enum_type;
- inline QFlags(const QFlags &f) : i(f.i) {}
- inline QFlags(Enum f) : i(f) {}
- inline QFlags(Zero = 0) : i(0) {}
+ Q_DECL_CONSTEXPR inline QFlags(const QFlags &f) : i(f.i) {}
+ Q_DECL_CONSTEXPR inline QFlags(Enum f) : i(f) {}
+ Q_DECL_CONSTEXPR inline QFlags(Zero = 0) : i(0) {}
inline QFlags(QFlag f) : i(f) {}
inline QFlags &operator=(const QFlags &f) { i = f.i; return *this; }
@@ -2216,18 +2241,18 @@ public:
inline QFlags &operator^=(QFlags f) { i ^= f.i; return *this; }
inline QFlags &operator^=(Enum f) { i ^= f; return *this; }
- inline operator int() const { return i; }
+ Q_DECL_CONSTEXPR inline operator int() const { return i; }
- inline QFlags operator|(QFlags f) const { QFlags g; g.i = i | f.i; return g; }
- inline QFlags operator|(Enum f) const { QFlags g; g.i = i | f; return g; }
- inline QFlags operator^(QFlags f) const { QFlags g; g.i = i ^ f.i; return g; }
- inline QFlags operator^(Enum f) const { QFlags g; g.i = i ^ f; return g; }
- inline QFlags operator&(int mask) const { QFlags g; g.i = i & mask; return g; }
- inline QFlags operator&(uint mask) const { QFlags g; g.i = i & mask; return g; }
- inline QFlags operator&(Enum f) const { QFlags g; g.i = i & f; return g; }
- inline QFlags operator~() const { QFlags g; g.i = ~i; return g; }
+ Q_DECL_CONSTEXPR inline QFlags operator|(QFlags f) const { return QFlags(Enum(i | f.i)); }
+ Q_DECL_CONSTEXPR inline QFlags operator|(Enum f) const { return QFlags(Enum(i | f)); }
+ Q_DECL_CONSTEXPR inline QFlags operator^(QFlags f) const { return QFlags(Enum(i ^ f.i)); }
+ Q_DECL_CONSTEXPR inline QFlags operator^(Enum f) const { return QFlags(Enum(i ^ f)); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(int mask) const { return QFlags(Enum(i & mask)); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(uint mask) const { return QFlags(Enum(i & mask)); }
+ Q_DECL_CONSTEXPR inline QFlags operator&(Enum f) const { return QFlags(Enum(i & f)); }
+ Q_DECL_CONSTEXPR inline QFlags operator~() const { return QFlags(Enum(~i)); }
- inline bool operator!() const { return !i; }
+ Q_DECL_CONSTEXPR inline bool operator!() const { return !i; }
inline bool testFlag(Enum f) const { return (i & f) == f && (f != 0 || i == int(f) ); }
};
@@ -2240,9 +2265,9 @@ inline QIncompatibleFlag operator|(Flags::enum_type f1, int f2) \
{ return QIncompatibleFlag(int(f1) | f2); }
#define Q_DECLARE_OPERATORS_FOR_FLAGS(Flags) \
-inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
+Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, Flags::enum_type f2) \
{ return QFlags<Flags::enum_type>(f1) | f2; } \
-inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) \
+Q_DECL_CONSTEXPR inline QFlags<Flags::enum_type> operator|(Flags::enum_type f1, QFlags<Flags::enum_type> f2) \
{ return f2 | f1; } Q_DECLARE_INCOMPATIBLE_FLAGS(Flags)
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 5333b71d7b..88f12ab1f7 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -297,11 +297,6 @@ QLibraryInfo::location(LibraryLocation loc)
path = QT_CONFIGURE_EXAMPLES_PATH;
break;
#endif
-#ifdef QT_CONFIGURE_DEMOS_PATH
- case DemosPath:
- path = QT_CONFIGURE_DEMOS_PATH;
- break;
-#endif
default:
break;
}
@@ -352,9 +347,6 @@ QLibraryInfo::location(LibraryLocation loc)
case ExamplesPath:
key = QLatin1String("Examples");
break;
- case DemosPath:
- key = QLatin1String("Demos");
- break;
default:
break;
}
@@ -500,7 +492,6 @@ QLibraryInfo::location(LibraryLocation loc)
\value TranslationsPath The location of translation information for Qt strings.
\value SettingsPath The location for Qt settings.
\value ExamplesPath The location for examples upon install.
- \value DemosPath The location for demos upon install.
\sa location()
*/
diff --git a/src/corelib/global/qlibraryinfo.h b/src/corelib/global/qlibraryinfo.h
index 9af53c315c..a8fb90968c 100644
--- a/src/corelib/global/qlibraryinfo.h
+++ b/src/corelib/global/qlibraryinfo.h
@@ -75,7 +75,6 @@ public:
DataPath,
TranslationsPath,
SettingsPath,
- DemosPath,
ExamplesPath,
ImportsPath
};
diff --git a/src/corelib/io/qtldurl.cpp b/src/corelib/io/qtldurl.cpp
index 7db4bbddd5..7d06ca4b17 100644
--- a/src/corelib/io/qtldurl.cpp
+++ b/src/corelib/io/qtldurl.cpp
@@ -7,29 +7,29 @@
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** 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.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/src/corelib/io/qtldurl_p.h b/src/corelib/io/qtldurl_p.h
index 152ffa0f63..77c0a15823 100644
--- a/src/corelib/io/qtldurl_p.h
+++ b/src/corelib/io/qtldurl_p.h
@@ -7,29 +7,29 @@
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
-** No Commercial Usage
-** This file contains pre-release code and may not be distributed.
-** You may use this file in accordance with the terms and conditions
-** contained in the Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** 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.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index c134881f31..d12391914b 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -805,7 +805,16 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
// call overhead.
QObjectPrivate *d = receiver->d_func();
QThreadData *threadData = d->threadData;
- ++threadData->loopLevel;
+
+ // Exception-safety without try/catch
+ struct Incrementer {
+ int &variable;
+ inline Incrementer(int &variable) : variable(variable)
+ { ++variable; }
+ inline ~Incrementer()
+ { --variable; }
+ };
+ Incrementer inc(threadData->loopLevel);
#ifdef QT_JAMBI_BUILD
int deleteWatch = 0;
@@ -816,12 +825,7 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
#endif
bool returnValue;
- QT_TRY {
- returnValue = notify(receiver, event);
- } QT_CATCH (...) {
- --threadData->loopLevel;
- QT_RETHROW;
- }
+ returnValue = notify(receiver, event);
#ifdef QT_JAMBI_BUILD
// Restore the previous state if the object was not deleted..
@@ -830,7 +834,6 @@ bool QCoreApplication::notifyInternal(QObject *receiver, QEvent *event)
}
QObjectPrivate::resetDeleteWatch(d, oldDeleteWatch, deleteWatch);
#endif
- --threadData->loopLevel;
return returnValue;
}
@@ -1373,6 +1376,40 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
int &i = (!event_type && !receiver) ? data->postEventList.startOffset : startOffset;
data->postEventList.insertionOffset = data->postEventList.size();
+ // Exception-safe cleaning up without the need for a try/catch block
+ struct CleanUp {
+ QObject *receiver;
+ int event_type;
+ QThreadData *data;
+ bool exceptionCaught;
+
+ inline CleanUp(QObject *receiver, int event_type, QThreadData *data) :
+ receiver(receiver), event_type(event_type), data(data), exceptionCaught(true)
+ {}
+ inline ~CleanUp()
+ {
+ if (exceptionCaught) {
+ // since we were interrupted, we need another pass to make sure we clean everything up
+ data->canWait = false;
+ }
+
+ --data->postEventList.recursion;
+ if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
+ data->eventDispatcher->wakeUp();
+
+ // clear the global list, i.e. remove everything that was
+ // delivered.
+ if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
+ const QPostEventList::iterator it = data->postEventList.begin();
+ data->postEventList.erase(it, it + data->postEventList.startOffset);
+ data->postEventList.insertionOffset -= data->postEventList.startOffset;
+ Q_ASSERT(data->postEventList.insertionOffset >= 0);
+ data->postEventList.startOffset = 0;
+ }
+ }
+ };
+ CleanUp cleanup(receiver, event_type, data);
+
while (i < data->postEventList.size()) {
// avoid live-lock
if (i >= data->postEventList.insertionOffset)
@@ -1411,7 +1448,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// first, we diddle the event so that we can deliver
// it, and that no one will try to touch it later.
pe.event->posted = false;
- QEvent * e = pe.event;
+ QScopedPointer<QEvent> e(pe.event);
QObject * r = pe.receiver;
--r->d_func()->postedEvents;
@@ -1421,49 +1458,23 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type
// for the next event.
const_cast<QPostEvent &>(pe).event = 0;
- locker.unlock();
- // after all that work, it's time to deliver the event.
-#ifdef QT_NO_EXCEPTIONS
- QCoreApplication::sendEvent(r, e);
-#else
- try {
- QCoreApplication::sendEvent(r, e);
- } catch (...) {
- delete e;
- locker.relock();
-
- // since we were interrupted, we need another pass to make sure we clean everything up
- data->canWait = false;
-
- // uglehack: copied from below
- --data->postEventList.recursion;
- if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
- data->eventDispatcher->wakeUp();
- throw; // rethrow
- }
-#endif
+ struct MutexUnlocker
+ {
+ QMutexLocker &m;
+ MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); }
+ ~MutexUnlocker() { m.relock(); }
+ };
+ MutexUnlocker unlocker(locker);
- delete e;
- locker.relock();
+ // after all that work, it's time to deliver the event.
+ QCoreApplication::sendEvent(r, e.data());
// careful when adding anything below this point - the
// sendEvent() call might invalidate any invariants this
// function depends on.
}
- --data->postEventList.recursion;
- if (!data->postEventList.recursion && !data->canWait && data->eventDispatcher)
- data->eventDispatcher->wakeUp();
-
- // clear the global list, i.e. remove everything that was
- // delivered.
- if (!event_type && !receiver && data->postEventList.startOffset >= 0) {
- const QPostEventList::iterator it = data->postEventList.begin();
- data->postEventList.erase(it, it + data->postEventList.startOffset);
- data->postEventList.insertionOffset -= data->postEventList.startOffset;
- Q_ASSERT(data->postEventList.insertionOffset >= 0);
- data->postEventList.startOffset = 0;
- }
+ cleanup.exceptionCaught = false;
}
/*!
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 5a4ce973bc..37c06a2093 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -184,49 +184,47 @@ int QEventLoop::exec(ProcessEventsFlags flags)
qWarning("QEventLoop::exec: instance %p has already called exec()", this);
return -1;
}
- d->inExec = true;
- d->exit = false;
- ++d->threadData->loopLevel;
- d->threadData->eventLoops.push(this);
- locker.unlock();
+
+ struct LoopReference {
+ QEventLoopPrivate *d;
+ QMutexLocker &locker;
+
+ bool exceptionCaught;
+ LoopReference(QEventLoopPrivate *d, QMutexLocker &locker) : d(d), locker(locker), exceptionCaught(true)
+ {
+ d->inExec = true;
+ d->exit = false;
+ ++d->threadData->loopLevel;
+ d->threadData->eventLoops.push(d->q_func());
+ locker.unlock();
+ }
+
+ ~LoopReference()
+ {
+ if (exceptionCaught) {
+ qWarning("Qt has caught an exception thrown from an event handler. Throwing\n"
+ "exceptions from an event handler is not supported in Qt. You must\n"
+ "reimplement QApplication::notify() and catch all exceptions there.\n");
+ }
+ locker.relock();
+ QEventLoop *eventLoop = d->threadData->eventLoops.pop();
+ Q_ASSERT_X(eventLoop == d->q_func(), "QEventLoop::exec()", "internal error");
+ Q_UNUSED(eventLoop); // --release warning
+ d->inExec = false;
+ --d->threadData->loopLevel;
+ }
+ };
+ LoopReference ref(d, locker);
// remove posted quit events when entering a new event loop
QCoreApplication *app = QCoreApplication::instance();
if (app && app->thread() == thread())
QCoreApplication::removePostedEvents(app, QEvent::Quit);
-#if defined(QT_NO_EXCEPTIONS)
while (!d->exit)
processEvents(flags | WaitForMoreEvents | EventLoopExec);
-#else
- try {
- while (!d->exit)
- processEvents(flags | WaitForMoreEvents | EventLoopExec);
- } catch (...) {
- qWarning("Qt has caught an exception thrown from an event handler. Throwing\n"
- "exceptions from an event handler is not supported in Qt. You must\n"
- "reimplement QApplication::notify() and catch all exceptions there.\n");
-
- // copied from below
- locker.relock();
- QEventLoop *eventLoop = d->threadData->eventLoops.pop();
- Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
- Q_UNUSED(eventLoop); // --release warning
- d->inExec = false;
- --d->threadData->loopLevel;
-
- throw;
- }
-#endif
-
- // copied above
- locker.relock();
- QEventLoop *eventLoop = d->threadData->eventLoops.pop();
- Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
- Q_UNUSED(eventLoop); // --release warning
- d->inExec = false;
- --d->threadData->loopLevel;
+ ref.exceptionCaught = false;
return d->returnCode;
}
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index d573741654..08236a3fec 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -125,6 +125,39 @@ extern "C" Q_CORE_EXPORT void qt_removeObject(QObject *)
}
}
+struct QConnectionSenderSwitcher {
+ QObject *receiver;
+ QObjectPrivate::Sender *previousSender;
+ QObjectPrivate::Sender currentSender;
+ bool switched;
+
+ inline QConnectionSenderSwitcher() : switched(false) {}
+
+ inline QConnectionSenderSwitcher(QObject *receiver, QObject *sender, int signal_absolute_id)
+ {
+ switchSender(receiver, sender, signal_absolute_id);
+ }
+
+ inline void switchSender(QObject *receiver, QObject *sender, int signal_absolute_id)
+ {
+ this->receiver = receiver;
+ currentSender.sender = sender;
+ currentSender.signal = signal_absolute_id;
+ currentSender.ref = 1;
+ previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
+ switched = true;
+ }
+
+ inline ~QConnectionSenderSwitcher()
+ {
+ if (switched)
+ QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
+ }
+private:
+ Q_DISABLE_COPY(QConnectionSenderSwitcher)
+};
+
+
void (*QAbstractDeclarativeData::destroyed)(QAbstractDeclarativeData *, QObject *) = 0;
void (*QAbstractDeclarativeData::parentChanged)(QAbstractDeclarativeData *, QObject *, QObject *) = 0;
void (*QAbstractDeclarativeData::objectNameChanged)(QAbstractDeclarativeData *, QObject *) = 0;
@@ -1084,23 +1117,10 @@ bool QObject::event(QEvent *e)
d_func()->inEventHandler = false;
#endif
QMetaCallEvent *mce = static_cast<QMetaCallEvent*>(e);
- QObjectPrivate::Sender currentSender;
- currentSender.sender = const_cast<QObject*>(mce->sender());
- currentSender.signal = mce->signalId();
- currentSender.ref = 1;
- QObjectPrivate::Sender * const previousSender =
- QObjectPrivate::setCurrentSender(this, &currentSender);
-#if defined(QT_NO_EXCEPTIONS)
+
+ QConnectionSenderSwitcher sw(this, const_cast<QObject*>(mce->sender()), mce->signalId());
+
mce->placeMetaCall(this);
-#else
- QT_TRY {
- mce->placeMetaCall(this);
- } QT_CATCH(...) {
- QObjectPrivate::resetCurrentSender(this, &currentSender, previousSender);
- QT_RETHROW;
- }
-#endif
- QObjectPrivate::resetCurrentSender(this, &currentSender, previousSender);
break;
}
@@ -2977,7 +2997,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
type &= Qt::UniqueConnection - 1;
}
- QObjectPrivate::Connection *c = new QObjectPrivate::Connection;
+ QScopedPointer<QObjectPrivate::Connection> c(new QObjectPrivate::Connection);
c->sender = s;
c->receiver = r;
c->method_relative = method_index;
@@ -2987,16 +3007,11 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
c->nextConnectionList = 0;
c->callFunction = callFunction;
- QT_TRY {
- QObjectPrivate::get(s)->addConnection(signal_index, c);
- } QT_CATCH(...) {
- delete c;
- QT_RETHROW;
- }
+ QObjectPrivate::get(s)->addConnection(signal_index, c.data());
c->prev = &(QObjectPrivate::get(r)->senders);
c->next = *c->prev;
- *c->prev = c;
+ *c->prev = c.data();
if (c->next)
c->next->prev = &c->next;
@@ -3007,6 +3022,7 @@ bool QMetaObjectPrivate::connect(const QObject *sender, int signal_index,
sender_d->connectedSignals[signal_index >> 5] |= (1 << (signal_index & 0x1f));
}
+ c.take(); // stop tracking
return true;
}
@@ -3265,16 +3281,37 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
Qt::HANDLE currentThreadId = QThread::currentThreadId();
+ {
QMutexLocker locker(signalSlotLock(sender));
- QObjectConnectionListVector *connectionLists = sender->d_func()->connectionLists;
- if (!connectionLists) {
+ struct ConnectionListsRef {
+ QObjectConnectionListVector *connectionLists;
+ ConnectionListsRef(QObjectConnectionListVector *connectionLists) : connectionLists(connectionLists)
+ {
+ if (connectionLists)
+ ++connectionLists->inUse;
+ }
+ ~ConnectionListsRef()
+ {
+ if (!connectionLists)
+ return;
+
+ --connectionLists->inUse;
+ Q_ASSERT(connectionLists->inUse >= 0);
+ if (connectionLists->orphaned) {
+ if (!connectionLists->inUse)
+ delete connectionLists;
+ }
+ }
+
+ QObjectConnectionListVector *operator->() const { return connectionLists; }
+ };
+ ConnectionListsRef connectionLists = sender->d_func()->connectionLists;
+ if (!connectionLists.connectionLists) {
locker.unlock();
if (qt_signal_spy_callback_set.signal_end_callback != 0)
qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
return;
}
- ++connectionLists->inUse;
-
const QObjectPrivate::ConnectionList *list;
if (signal_index < connectionLists->count())
@@ -3324,13 +3361,10 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
#endif
}
- QObjectPrivate::Sender currentSender;
- QObjectPrivate::Sender *previousSender = 0;
+ QConnectionSenderSwitcher sw;
+
if (receiverInSameThread) {
- currentSender.sender = sender;
- currentSender.signal = signal_absolute_index;
- currentSender.ref = 1;
- previousSender = QObjectPrivate::setCurrentSender(receiver, &currentSender);
+ sw.switchSender(receiver, sender, signal_absolute_index);
}
const QObjectPrivate::StaticMetaCallFunction callFunction = c->callFunction;
const int method_relative = c->method_relative;
@@ -3355,23 +3389,7 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
argv ? argv : empty_argv);
}
-#if defined(QT_NO_EXCEPTIONS)
metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
-#else
- QT_TRY {
- metacall(receiver, QMetaObject::InvokeMetaMethod, method, argv ? argv : empty_argv);
- } QT_CATCH(...) {
- locker.relock();
- if (receiverInSameThread)
- QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
-
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned && !connectionLists->inUse)
- delete connectionLists;
- QT_RETHROW;
- }
-#endif
if (qt_signal_spy_callback_set.slot_end_callback != 0)
qt_signal_spy_callback_set.slot_end_callback(receiver, method);
@@ -3379,9 +3397,6 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
locker.relock();
}
- if (receiverInSameThread)
- QObjectPrivate::resetCurrentSender(receiver, &currentSender, previousSender);
-
if (connectionLists->orphaned)
break;
} while (c != last && (c = c->nextConnectionList) != 0);
@@ -3392,17 +3407,8 @@ void QMetaObject::activate(QObject *sender, const QMetaObject *m, int local_sign
//start over for all signals;
((list = &connectionLists->allsignals), true));
- --connectionLists->inUse;
- Q_ASSERT(connectionLists->inUse >= 0);
- if (connectionLists->orphaned) {
- if (!connectionLists->inUse)
- delete connectionLists;
- } else if (connectionLists->dirty) {
- sender->d_func()->cleanConnectionLists();
}
- locker.unlock();
-
if (qt_signal_spy_callback_set.signal_end_callback != 0)
qt_signal_spy_callback_set.signal_end_callback(sender, signal_absolute_index);
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h
index 9f54f1a831..26cf2af59c 100644
--- a/src/corelib/tools/qbytearray.h
+++ b/src/corelib/tools/qbytearray.h
@@ -172,15 +172,9 @@ public:
inline bool isSharedWith(const QByteArray &other) const { return d == other.d; }
void clear();
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
- const char at(int i) const;
- const char operator[](int i) const;
- const char operator[](uint i) const;
-#else
char at(int i) const;
char operator[](int i) const;
char operator[](uint i) const;
-#endif
QByteRef operator[](int i);
QByteRef operator[](uint i);
@@ -359,21 +353,12 @@ inline QByteArray::~QByteArray() { if (!d->ref.deref()) qFree(d); }
inline int QByteArray::size() const
{ return d->size; }
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
-inline const char QByteArray::at(int i) const
-{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
-inline const char QByteArray::operator[](int i) const
-{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
-inline const char QByteArray::operator[](uint i) const
-{ Q_ASSERT(i < uint(size())); return d->data[i]; }
-#else
inline char QByteArray::at(int i) const
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
inline char QByteArray::operator[](int i) const
{ Q_ASSERT(i >= 0 && i < size()); return d->data[i]; }
inline char QByteArray::operator[](uint i) const
{ Q_ASSERT(i < uint(size())); return d->data[i]; }
-#endif
inline bool QByteArray::isEmpty() const
{ return d->size == 0; }
@@ -412,13 +397,8 @@ class Q_CORE_EXPORT QByteRef {
: a(array),i(idx) {}
friend class QByteArray;
public:
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
- inline operator const char() const
- { return i < a.d->size ? a.d->data[i] : char(0); }
-#else
inline operator char() const
{ return i < a.d->size ? a.d->data[i] : char(0); }
-#endif
inline QByteRef &operator=(char c)
{ if (i >= a.d->size) a.expand(i); else a.detach();
a.d->data[i] = c; return *this; }
diff --git a/src/corelib/tools/qchar.cpp b/src/corelib/tools/qchar.cpp
index 9db7d1ae83..475bd55de4 100644
--- a/src/corelib/tools/qchar.cpp
+++ b/src/corelib/tools/qchar.cpp
@@ -1295,11 +1295,7 @@ ushort QChar::toCaseFolded(ushort ucs2)
\sa toLatin1(), unicode(), QTextCodec::codecForCStrings()
*/
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
-const char QChar::toAscii() const
-#else
char QChar::toAscii() const
-#endif
{
#ifndef QT_NO_CODEC_FOR_C_STRINGS
if (QTextCodec::codecForCStrings())
diff --git a/src/corelib/tools/qchar.h b/src/corelib/tools/qchar.h
index b7793403bd..d6db72d5ac 100644
--- a/src/corelib/tools/qchar.h
+++ b/src/corelib/tools/qchar.h
@@ -56,13 +56,8 @@ struct QLatin1Char
{
public:
inline explicit QLatin1Char(char c) : ch(c) {}
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
- inline const char toLatin1() const { return ch; }
- inline const ushort unicode() const { return ushort(uchar(ch)); }
-#else
inline char toLatin1() const { return ch; }
inline ushort unicode() const { return ushort(uchar(ch)); }
-#endif
private:
char ch;
@@ -230,20 +225,10 @@ public:
UnicodeVersion unicodeVersion() const;
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
- const char toAscii() const;
- inline const char toLatin1() const;
- inline const ushort unicode() const { return ucs; }
-#else
char toAscii() const;
inline char toLatin1() const;
inline ushort unicode() const { return ucs; }
-#endif
-#ifdef Q_NO_PACKED_REFERENCE
- inline ushort &unicode() { return const_cast<ushort&>(ucs); }
-#else
inline ushort &unicode() { return ucs; }
-#endif
static QChar fromAscii(char c);
static QChar fromLatin1(char c);
@@ -339,11 +324,7 @@ Q_DECLARE_TYPEINFO(QChar, Q_MOVABLE_TYPE);
inline QChar::QChar() : ucs(0) {}
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
-inline const char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); }
-#else
inline char QChar::toLatin1() const { return ucs > 0xff ? '\0' : char(ucs); }
-#endif
inline QChar QChar::fromLatin1(char c) { return QChar(ushort(uchar(c))); }
inline QChar::QChar(uchar c, uchar r) : ucs(ushort((r << 8) | c)){}
diff --git a/src/corelib/tools/qlist.cpp b/src/corelib/tools/qlist.cpp
index 80c610be36..14dfc6a139 100644
--- a/src/corelib/tools/qlist.cpp
+++ b/src/corelib/tools/qlist.cpp
@@ -164,7 +164,7 @@ void **QListData::append(int n)
if (b - n >= 2 * d->alloc / 3) {
// we have enough space. Just not at the end -> move it.
e -= b;
- ::memcpy(d->array, d->array + b, e * sizeof(void *));
+ ::memmove(d->array, d->array + b, e * sizeof(void *));
d->begin = 0;
} else {
realloc(grow(d->alloc + n));
diff --git a/src/corelib/tools/qrefcount.cpp b/src/corelib/tools/qrefcount.cpp
new file mode 100644
index 0000000000..c40214b2ab
--- /dev/null
+++ b/src/corelib/tools/qrefcount.cpp
@@ -0,0 +1,51 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+ \class QtPrivate::RefCount
+ \internal
+
+ QRefCount implements atomic ref counting for Qt's shared classes. It behaves very similar
+ to QAtomicInt, but ignores negative ref counts.
+
+ This can be used to allow to implement e.g. const read-only QStringData objects. QString::shared_null and
+ the qs(...) macro make use of this feature.
+*/
diff --git a/src/corelib/tools/qrefcount.h b/src/corelib/tools/qrefcount.h
new file mode 100644
index 0000000000..9223cfe352
--- /dev/null
+++ b/src/corelib/tools/qrefcount.h
@@ -0,0 +1,92 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QREFCOUNT_H
+#define QREFCOUNT_H
+
+#include <QtCore/qatomic.h>
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+namespace QtPrivate
+{
+
+class RefCount
+{
+public:
+ inline void ref() {
+ if (atomic >= 0)
+ atomic.ref();
+ }
+
+ inline bool deref() {
+ if (atomic < 0)
+ return true;
+ return atomic.deref();
+ }
+
+ inline bool operator==(int value) const
+ { return atomic.operator ==(value); }
+ inline bool operator!=(int value) const
+ { return atomic.operator !=(value); }
+ inline bool operator!() const
+ { return atomic.operator !(); }
+ inline operator int() const
+ { return atomic.operator int(); }
+ inline RefCount &operator=(int value)
+ { atomic = value; return *this; }
+
+ QBasicAtomicInt atomic;
+};
+
+#define Q_REFCOUNT_INITIALIZER(a) { Q_BASIC_ATOMIC_INITIALIZER(a) }
+
+}
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index afb396ce50..dab281cdf8 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -720,6 +720,18 @@ const QString::Null QString::null = { };
\section1 More Efficient String Construction
+ Many strings are known at compile time. But the trivial
+ constructor QString("Hello"), will convert the string literal
+ to a QString using the codecForCStrings(). To avoid this one
+ can use the QStringLiteral macro to directly create the required
+ data at compile time. Constructing a QString out of the literal
+ does then not cause any overhead at runtime.
+
+ A slightly less efficient way is to use QLatin1String. This class wraps
+ a C string literal, precalculates it length at compile time and can
+ then be used for faster comparison with QStrings and conversion to
+ QStrings than a regular C string literal.
+
Using the QString \c{'+'} operator, it is easy to construct a
complex string from multiple substrings. You will often write code
like this:
@@ -735,9 +747,6 @@ const QString::Null QString::null = { };
where \e{n > 2}, there can be as many as \e{n - 1} calls to the
memory allocator.
- Second, QLatin1String does not store its length internally but
- calls qstrlen() when it needs to know its length.
-
In 4.6, an internal template class \c{QStringBuilder} has been
added along with a few helper functions. This class is marked
internal and does not appear in the documentation, because you
@@ -755,12 +764,6 @@ const QString::Null QString::null = { };
then called \e{once} to get the required space, and the substrings
are copied into it one by one.
- \c{QLatin1Literal} is a second internal class that can replace
- QLatin1String, which can't be changed for compatibility reasons.
- \c{QLatin1Literal} stores its length, thereby saving time when
- \c{QStringBuilder} computes the amount of memory required for the
- final string.
-
Additional efficiency is gained by inlining and reduced reference
counting (the QString created from a \c{QStringBuilder} typically
has a ref count of 1, whereas QString::append() needs an extra
@@ -797,10 +800,8 @@ const QString::Null QString::null = { };
\sa split()
*/
-QString::Data QString::shared_null = { Q_BASIC_ATOMIC_INITIALIZER(1),
- 0, 0, shared_null.array, 0, 0, 0, 0, 0, {0} };
-QString::Data QString::shared_empty = { Q_BASIC_ATOMIC_INITIALIZER(1),
- 0, 0, shared_empty.array, 0, 0, 0, 0, 0, {0} };
+const QConstStringData<1> QString::shared_null = { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
+const QConstStringData<1> QString::shared_empty = { { Q_REFCOUNT_INITIALIZER(-1), 0, 0, false, { 0 } }, { 0 } };
int QString::grow(int size)
{
@@ -1044,20 +1045,15 @@ int QString::toWCharArray(wchar_t *array) const
QString::QString(const QChar *unicode, int size)
{
if (!unicode) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size <= 0) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- memcpy(d->array, unicode, size * sizeof(QChar));
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ memcpy(d->data(), unicode, size * sizeof(QChar));
+ d->data()[size] = '\0';
}
}
@@ -1073,24 +1069,19 @@ QString::QString(const QChar *unicode, int size)
QString::QString(const QChar *unicode)
{
if (!unicode) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else {
int size = 0;
while (unicode[size] != 0)
++size;
if (!size) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- memcpy(d->array, unicode, size * sizeof(QChar));
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ memcpy(d->data(), unicode, size * sizeof(QChar));
+ d->data()[size] = '\0';
}
}
}
@@ -1105,18 +1096,14 @@ QString::QString(const QChar *unicode)
QString::QString(int size, QChar ch)
{
if (size <= 0) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
- ushort *i = d->array + size;
- ushort *b = d->array;
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
+ ushort *i = d->data() + size;
+ ushort *b = d->data();
const ushort value = ch.unicode();
while (i != b)
*--i = value;
@@ -1131,13 +1118,10 @@ QString::QString(int size, QChar ch)
*/
QString::QString(int size, Qt::Initialization)
{
- d = (Data*) qMalloc(sizeof(Data)+size*sizeof(QChar));
+ d = (Data*) qMalloc(sizeof(Data)+(size+1)*sizeof(QChar));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
}
/*! \fn QString::QString(const QLatin1String &str)
@@ -1152,15 +1136,11 @@ QString::QString(int size, Qt::Initialization)
*/
QString::QString(QChar ch)
{
- 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->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[0] = ch.unicode();
- d->array[1] = '\0';
+ d = (Data *) qMalloc(sizeof(Data) + 2*sizeof(QChar));
+ Q_CHECK_PTR(d);
+ *d = (Data) { Q_REFCOUNT_INITIALIZER(1), 1, 1, false, { 0 } };
+ d->data()[0] = ch.unicode();
+ d->data()[1] = '\0';
}
/*! \fn QString::QString(const QByteArray &ba)
@@ -1256,21 +1236,23 @@ void QString::resize(int size)
if (size < 0)
size = 0;
- if (size == 0 && !d->capacity) {
- Data *x = &shared_empty;
- x->ref.ref();
+ if (d->offset && d->ref == 1 && size < d->size) {
+ d->size = size;
+ return;
+ }
+
+ if (size == 0 && !d->capacityReserved) {
+ Data *x = const_cast<Data *>(&shared_empty.str);
if (!d->ref.deref())
QString::free(d);
d = x;
} else {
if (d->ref != 1 || size > d->alloc ||
- (!d->capacity && size < d->size && size < d->alloc >> 1))
+ (!d->capacityReserved && size < d->size && size < d->alloc >> 1))
realloc(grow(size));
if (d->alloc >= size) {
d->size = size;
- if (d->data == d->array) {
- d->array[size] = '\0';
- }
+ d->data()[size] = '\0';
}
}
}
@@ -1328,28 +1310,21 @@ void QString::resize(int size)
// ### Qt 5: rename reallocData() to avoid confusion. 197625
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 (d->ref != 1 || d->offset) {
+ Data *x = static_cast<Data *>(qMalloc(sizeof(Data) + (alloc+1) * sizeof(QChar)));
Q_CHECK_PTR(x);
- x->size = qMin(alloc, d->size);
- ::memcpy(x->array, d->data, x->size * sizeof(QChar));
- x->array[x->size] = 0;
- x->ref = 1;
- x->alloc = alloc;
- x->clean = d->clean;
- x->simpletext = d->simpletext;
- x->righttoleft = d->righttoleft;
- x->capacity = d->capacity;
- x->data = x->array;
+ *x = (Data){ Q_REFCOUNT_INITIALIZER(1), qMin(alloc, d->size), alloc, d->capacityReserved, { 0 } };
+ ::memcpy(x->data(), d->data(), x->size * sizeof(QChar));
+ x->data()[x->size] = 0;
if (!d->ref.deref())
QString::free(d);
d = x;
} else {
- Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + alloc * sizeof(QChar)));
+ Data *p = static_cast<Data *>(qRealloc(d, sizeof(Data) + (alloc+1) * sizeof(QChar)));
Q_CHECK_PTR(p);
d = p;
d->alloc = alloc;
- d->data = d->array;
+ d->offset = 0;
}
}
@@ -1363,8 +1338,8 @@ void QString::expand(int i)
int sz = d->size;
resize(qMax(i + 1, sz));
if (d->size - 1 > sz) {
- ushort *n = d->data + d->size - 1;
- ushort *e = d->data + sz;
+ ushort *n = d->data() + d->size - 1;
+ ushort *e = d->data() + sz;
while (n != e)
* --n = ' ';
}
@@ -1482,9 +1457,9 @@ QString &QString::insert(int i, const QLatin1String &str)
int len = qstrlen(str.latin1());
expand(qMax(d->size, i) + len - 1);
- ::memmove(d->data + i + len, d->data + i, (d->size - i - len) * sizeof(QChar));
+ ::memmove(d->data() + i + len, d->data() + i, (d->size - i - len) * sizeof(QChar));
for (int j = 0; j < len; ++j)
- d->data[i + j] = s[j];
+ d->data()[i + j] = s[j];
return *this;
}
@@ -1501,7 +1476,7 @@ QString& QString::insert(int i, const QChar *unicode, int size)
return *this;
const ushort *s = (const ushort *)unicode;
- if (s >= d->data && s < d->data + d->alloc) {
+ 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);
@@ -1513,8 +1488,8 @@ QString& QString::insert(int i, const QChar *unicode, int size)
expand(qMax(d->size, i) + size - 1);
- ::memmove(d->data + i + size, d->data + i, (d->size - i - size) * sizeof(QChar));
- memcpy(d->data + i, s, size * sizeof(QChar));
+ ::memmove(d->data() + i + size, d->data() + i, (d->size - i - size) * sizeof(QChar));
+ memcpy(d->data() + i, s, size * sizeof(QChar));
return *this;
}
@@ -1532,8 +1507,8 @@ QString& QString::insert(int i, QChar ch)
if (i < 0)
return *this;
expand(qMax(i, d->size));
- ::memmove(d->data + i + 1, d->data + i, (d->size - i) * sizeof(QChar));
- d->data[i] = ch.unicode();
+ ::memmove(d->data() + i + 1, d->data() + i, (d->size - i) * sizeof(QChar));
+ d->data()[i] = ch.unicode();
return *this;
}
@@ -1557,15 +1532,15 @@ QString& QString::insert(int i, QChar ch)
*/
QString &QString::append(const QString &str)
{
- if (str.d != &shared_null) {
- if (d == &shared_null) {
+ if (str.d != &shared_null.str) {
+ if (d == &shared_null.str) {
operator=(str);
} else {
if (d->ref != 1 || d->size + str.d->size > d->alloc)
realloc(grow(d->size + str.d->size));
- memcpy(d->data + d->size, str.d->data, str.d->size * sizeof(QChar));
+ memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar));
d->size += str.d->size;
- d->data[d->size] = '\0';
+ d->data()[d->size] = '\0';
}
}
return *this;
@@ -1583,7 +1558,7 @@ QString &QString::append(const QLatin1String &str)
int len = qstrlen((char *)s);
if (d->ref != 1 || d->size + len > d->alloc)
realloc(grow(d->size + len));
- ushort *i = d->data + d->size;
+ ushort *i = d->data() + d->size;
while ((*i++ = *s++))
;
d->size += len;
@@ -1626,8 +1601,8 @@ QString &QString::append(QChar ch)
{
if (d->ref != 1 || d->size + 1 > d->alloc)
realloc(grow(d->size + 1));
- d->data[d->size++] = ch.unicode();
- d->data[d->size] = '\0';
+ d->data()[d->size++] = ch.unicode();
+ d->data()[d->size] = '\0';
return *this;
}
@@ -1707,7 +1682,7 @@ QString &QString::remove(int pos, int len)
resize(pos); // truncate
} else if (len > 0) {
detach();
- memmove(d->data + pos, d->data + pos + len,
+ memmove(d->data() + pos, d->data() + pos + len,
(d->size - pos - len + 1) * sizeof(ushort));
d->size -= len;
}
@@ -1756,14 +1731,14 @@ QString &QString::remove(QChar ch, Qt::CaseSensitivity cs)
ushort c = ch.unicode();
if (cs == Qt::CaseSensitive) {
while (i < d->size)
- if (d->data[i] == ch)
+ if (d->data()[i] == ch)
remove(i, 1);
else
i++;
} else {
c = foldCase(c);
while (i < d->size)
- if (foldCase(d->data[i]) == c)
+ if (foldCase(d->data()[i]) == c)
remove(i, 1);
else
i++;
@@ -1859,10 +1834,10 @@ 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)
{
- // copy *after in case it lies inside our own d->data area
+ // 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) {
+ 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));
@@ -1873,30 +1848,30 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
// replace in place
detach();
for (int i = 0; i < nIndices; ++i)
- memcpy(d->data + indices[i], afterBuffer, alen * sizeof(QChar));
+ memcpy(d->data() + indices[i], afterBuffer, alen * sizeof(QChar));
} else if (alen < blen) {
// replace from front
detach();
uint to = indices[0];
if (alen)
- memcpy(d->data+to, after, alen*sizeof(QChar));
+ 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));
+ memmove(d->data() + to, d->data() + movestart, msize * sizeof(QChar));
to += msize;
}
if (alen) {
- memcpy(d->data + to, afterBuffer, alen*sizeof(QChar));
+ memcpy(d->data() + to, afterBuffer, alen*sizeof(QChar));
to += alen;
}
movestart = indices[i] + blen;
}
int msize = d->size - movestart;
if (msize > 0)
- memmove(d->data + to, d->data + movestart, msize * sizeof(QChar));
+ memmove(d->data() + to, d->data() + movestart, msize * sizeof(QChar));
resize(d->size - nIndices*(blen-alen));
} else {
// replace from back
@@ -1910,9 +1885,9 @@ void QString::replace_helper(uint *indices, int nIndices, int blen, const QChar
int movestart = indices[nIndices] + blen;
int insertstart = indices[nIndices] + nIndices*(alen-blen);
int moveto = insertstart + alen;
- memmove(d->data + moveto, d->data + movestart,
+ memmove(d->data() + moveto, d->data() + movestart,
(moveend - movestart)*sizeof(QChar));
- memcpy(d->data + insertstart, afterBuffer, alen*sizeof(QChar));
+ memcpy(d->data() + insertstart, afterBuffer, alen*sizeof(QChar));
moveend = movestart-blen;
}
}
@@ -1994,7 +1969,7 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
return remove(ch, cs);
if (after.d->size == 1)
- return replace(ch, after.d->data[0], cs);
+ return replace(ch, after.d->data()[0], cs);
if (d->size == 0)
return *this;
@@ -2007,13 +1982,13 @@ QString& QString::replace(QChar ch, const QString &after, Qt::CaseSensitivity cs
uint pos = 0;
if (cs == Qt::CaseSensitive) {
while (pos < 1023 && index < d->size) {
- if (d->data[index] == cc)
+ if (d->data()[index] == cc)
indices[pos++] = index;
index++;
}
} else {
while (pos < 1023 && index < d->size) {
- if (QChar::toCaseFolded(d->data[index]) == cc)
+ if (QChar::toCaseFolded(d->data()[index]) == cc)
indices[pos++] = index;
index++;
}
@@ -2045,7 +2020,7 @@ QString& QString::replace(QChar before, QChar after, Qt::CaseSensitivity cs)
ushort b = before.unicode();
if (d->size) {
detach();
- ushort *i = d->data;
+ ushort *i = d->data();
const ushort *e = i + d->size;
if (cs == Qt::CaseSensitive) {
for (; i != e; ++i)
@@ -2104,7 +2079,7 @@ QString &QString::replace(const QLatin1String &before,
const QString &after,
Qt::CaseSensitivity cs)
{
- int blen = qstrlen(before.latin1());
+ int blen = before.size();
QVarLengthArray<ushort> b(blen);
for (int i = 0; i < blen; ++i)
b[i] = (uchar)before.latin1()[i];
@@ -2127,7 +2102,7 @@ QString &QString::replace(const QString &before,
const QLatin1String &after,
Qt::CaseSensitivity cs)
{
- int alen = qstrlen(after.latin1());
+ int alen = after.size();
QVarLengthArray<ushort> a(alen);
for (int i = 0; i < alen; ++i)
a[i] = (uchar)after.latin1()[i];
@@ -2148,7 +2123,7 @@ QString &QString::replace(const QString &before,
*/
QString &QString::replace(QChar c, const QLatin1String &after, Qt::CaseSensitivity cs)
{
- int alen = qstrlen(after.latin1());
+ int alen = after.size();
QVarLengthArray<ushort> a(alen);
for (int i = 0; i < alen; ++i)
a[i] = (uchar)after.latin1()[i];
@@ -2170,7 +2145,7 @@ bool QString::operator==(const QString &other) const
if (d->size != other.d->size)
return false;
- return qMemEquals(d->data, other.d->data, d->size);
+ return qMemEquals(d->data(), other.d->data(), d->size);
}
/*!
@@ -2178,20 +2153,23 @@ bool QString::operator==(const QString &other) const
*/
bool QString::operator==(const QLatin1String &other) const
{
- const ushort *uc = d->data;
- const ushort *e = uc + d->size;
- const uchar *c = (uchar *)other.latin1();
+ if (d->size != other.size())
+ return false;
- if (!c)
+ if (!other.size())
return isEmpty();
- while (*c) {
- if (uc == e || *uc != *c)
+ const ushort *uc = d->data();
+ const ushort *e = uc + d->size;
+ const uchar *c = (uchar *)other.latin1();
+
+ while (uc < e) {
+ if (*uc != *c)
return false;
++uc;
++c;
}
- return (uc == e);
+ return true;
}
/*! \fn bool QString::operator==(const QByteArray &other) const
@@ -2240,20 +2218,20 @@ bool QString::operator<(const QString &other) const
*/
bool QString::operator<(const QLatin1String &other) const
{
- const ushort *uc = d->data;
- const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
-
if (!c || *c == 0)
return false;
- while (*c) {
- if (uc == e || *uc != *c)
+ const ushort *uc = d->data();
+ const ushort *e = uc + qMin(d->size, other.size());
+
+ while (uc < e) {
+ if (*uc != *c)
break;
++uc;
++c;
}
- return (uc == e ? *c : *uc < *c);
+ return (uc == (d->data() + d->size) ? *c : *uc < *c);
}
/*! \fn bool QString::operator<(const QByteArray &other) const
@@ -2342,20 +2320,20 @@ bool QString::operator<(const QLatin1String &other) const
*/
bool QString::operator>(const QLatin1String &other) const
{
- const ushort *uc = d->data;;
- const ushort *e = uc + d->size;
const uchar *c = (uchar *) other.latin1();
-
if (!c || *c == '\0')
return !isEmpty();
- while (*c) {
- if (uc == e || *uc != *c)
+ const ushort *uc = d->data();;
+ const ushort *e = uc + qMin(d->size, other.size());
+
+ while (uc < e) {
+ if (*uc != *c)
break;
++uc;
++c;
}
- return (uc == e ? false : *uc > *c);
+ return (uc == (d->data() + d->size) ? false : *uc > *c);
}
/*! \fn bool QString::operator>(const QByteArray &other) const
@@ -2687,7 +2665,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
{
const int sl = str.d->size;
if (sl == 1)
- return lastIndexOf(QChar(str.d->data[0]), from, cs);
+ return lastIndexOf(QChar(str.d->data()[0]), from, cs);
const int l = d->size;
if (from < 0)
@@ -2700,7 +2678,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
if (from > delta)
from = delta;
- return lastIndexOfHelper(d->data, from, str.d->data, str.d->size, cs);
+ return lastIndexOfHelper(d->data(), from, str.d->data(), str.d->size, cs);
}
/*!
@@ -2724,7 +2702,7 @@ int QString::lastIndexOf(const QString &str, int from, Qt::CaseSensitivity cs) c
*/
int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity cs) const
{
- const int sl = qstrlen(str.latin1());
+ const int sl = str.size();
if (sl == 1)
return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
@@ -2743,7 +2721,7 @@ int QString::lastIndexOf(const QLatin1String &str, int from, Qt::CaseSensitivity
for (int i = 0; i < sl; ++i)
s[i] = str.latin1()[i];
- return lastIndexOfHelper(d->data, from, s.data(), sl, cs);
+ return lastIndexOfHelper(d->data(), from, s.data(), sl, cs);
}
/*!
@@ -2789,7 +2767,7 @@ int QString::lastIndexOf(const QStringRef &str, int from, Qt::CaseSensitivity cs
if (from > delta)
from = delta;
- return lastIndexOfHelper(d->data, from, reinterpret_cast<const ushort*>(str.unicode()),
+ return lastIndexOfHelper(d->data(), from, reinterpret_cast<const ushort*>(str.unicode()),
str.size(), cs);
}
@@ -2940,14 +2918,14 @@ QString& QString::replace(const QRegExp &rx, const QString &after)
while (i < pos) {
int copyend = replacements[i].pos;
int size = copyend - copystart;
- memcpy(uc, d->data + copystart, size * sizeof(QChar));
+ memcpy(uc, d->data() + copystart, size * sizeof(QChar));
uc += size;
- memcpy(uc, after.d->data, al * sizeof(QChar));
+ memcpy(uc, after.d->data(), al * sizeof(QChar));
uc += al;
copystart = copyend + replacements[i].length;
i++;
}
- memcpy(uc, d->data + copystart, (d->size - copystart) * sizeof(QChar));
+ memcpy(uc, d->data() + copystart, (d->size - copystart) * sizeof(QChar));
newstring.resize(newlen);
*this = newstring;
caretMode = QRegExp::CaretWontMatch;
@@ -3366,7 +3344,7 @@ QString QString::left(int n) const
{
if (n >= d->size || n < 0)
return *this;
- return QString((const QChar*) d->data, n);
+ return QString((const QChar*) d->data(), n);
}
/*!
@@ -3384,7 +3362,7 @@ QString QString::right(int n) const
{
if (n >= d->size || n < 0)
return *this;
- return QString((const QChar*) d->data + d->size - n, n);
+ return QString((const QChar*) d->data() + d->size - n, n);
}
/*!
@@ -3406,7 +3384,7 @@ QString QString::right(int n) const
QString QString::mid(int position, int n) const
{
- if (d == &shared_null || position >= d->size)
+ if (d == &shared_null.str || position >= d->size)
return QString();
if (n < 0)
n = d->size - position;
@@ -3418,7 +3396,7 @@ QString QString::mid(int position, int n) const
n = d->size - position;
if (position == 0 && n == d->size)
return *this;
- return QString((const QChar*) d->data + position, n);
+ return QString((const QChar*) d->data() + position, n);
}
/*!
@@ -3456,8 +3434,8 @@ bool QString::startsWith(const QChar &c, Qt::CaseSensitivity cs) const
{
return d->size
&& (cs == Qt::CaseSensitive
- ? d->data[0] == c
- : foldCase(d->data[0]) == foldCase(c.unicode()));
+ ? d->data()[0] == c
+ : foldCase(d->data()[0]) == foldCase(c.unicode()));
}
/*!
@@ -3530,8 +3508,8 @@ bool QString::endsWith(const QChar &c, Qt::CaseSensitivity cs) const
{
return d->size
&& (cs == Qt::CaseSensitive
- ? d->data[d->size - 1] == c
- : foldCase(d->data[d->size - 1]) == foldCase(c.unicode()));
+ ? d->data()[d->size - 1] == c
+ : foldCase(d->data()[d->size - 1]) == foldCase(c.unicode()));
}
/*! \fn const char *QString::ascii() const
@@ -3658,10 +3636,6 @@ QByteArray QString::toLatin1() const
return toLatin1_helper(unicode(), length());
}
-// ### Qt 5: Change the return type of at least toAscii(),
-// toLatin1() and unicode() such that the use of Q_COMPILER_MANGLES_RETURN_TYPE
-// isn't necessary in the header. See task 177402.
-
/*!
Returns an 8-bit representation of the string as a QByteArray.
@@ -3765,22 +3739,17 @@ QString::Data *QString::fromLatin1_helper(const char *str, int size)
{
Data *d;
if (!str) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size == 0 || (!*str && size < 0)) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
if (size < 0)
size = qstrlen(str);
- d = static_cast<Data *>(qMalloc(sizeof(Data) + size * sizeof(QChar)));
+ d = static_cast<Data *>(qMalloc(sizeof(Data) + (size+1) * sizeof(QChar)));
Q_CHECK_PTR(d);
- d->ref = 1;
- d->alloc = d->size = size;
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
- d->data = d->array;
- d->array[size] = '\0';
- ushort *dst = d->data;
+ *d = (Data){ Q_REFCOUNT_INITIALIZER(1), size, size, false, { 0 } };
+ d->data()[size] = '\0';
+ ushort *dst = d->data();
/* SIMD:
* Unpacking with SSE has been shown to improve performance on recent CPUs
* The same method gives no improvement with NEON.
@@ -3818,11 +3787,9 @@ QString::Data *QString::fromAscii_helper(const char *str, int size)
if (codecForCStrings) {
Data *d;
if (!str) {
- d = &shared_null;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_null.str);
} else if (size == 0 || (!*str && size < 0)) {
- d = &shared_empty;
- d->ref.ref();
+ d = const_cast<Data *>(&shared_empty.str);
} else {
if (size < 0)
size = qstrlen(str);
@@ -3867,7 +3834,7 @@ QString QString::fromLocal8Bit(const char *str, int size)
if (!str)
return QString();
if (size == 0 || (!*str && size < 0))
- return QLatin1String("");
+ return QString(shared_empty);
#if !defined(QT_NO_TEXTCODEC)
if (size < 0)
size = qstrlen(str);
@@ -3995,7 +3962,7 @@ QString& QString::setUnicode(const QChar *unicode, int size)
{
resize(size);
if (unicode && size)
- memcpy(d->data, unicode, size * sizeof(QChar));
+ memcpy(d->data(), unicode, size * sizeof(QChar));
return *this;
}
@@ -4034,7 +4001,7 @@ QString QString::simplified() const
if (d->size == 0)
return *this;
- const QChar * const start = reinterpret_cast<QChar *>(d->data);
+ const QChar * const start = reinterpret_cast<QChar *>(d->data());
const QChar *from = start;
const QChar *fromEnd = start + d->size;
forever {
@@ -4043,8 +4010,7 @@ QString QString::simplified() const
break;
if (++from == fromEnd) {
// All-whitespace string
- shared_empty.ref.ref();
- return QString(&shared_empty, 0);
+ return QString(shared_empty);
}
}
// This loop needs no underflow check, as we already determined that
@@ -4079,7 +4045,7 @@ QString QString::simplified() const
// of already simplified characters - at least one, obviously -
// without a trailing space.
QString result((fromEnd - from) + copyCount, Qt::Uninitialized);
- QChar *to = reinterpret_cast<QChar *>(result.d->data);
+ QChar *to = reinterpret_cast<QChar *>(result.d->data());
::memcpy(to, copyFrom, copyCount * 2);
to += copyCount;
fromEnd--;
@@ -4100,7 +4066,7 @@ QString QString::simplified() const
}
done:
*to++ = ch;
- result.truncate(to - reinterpret_cast<QChar *>(result.d->data));
+ result.truncate(to - reinterpret_cast<QChar *>(result.d->data()));
return result;
}
@@ -4124,7 +4090,7 @@ QString QString::trimmed() const
{
if (d->size == 0)
return *this;
- const QChar *s = (const QChar*)d->data;
+ const QChar *s = (const QChar*)d->data();
if (!s->isSpace() && !s[d->size-1].isSpace())
return *this;
int start = 0;
@@ -4137,8 +4103,7 @@ QString QString::trimmed() const
}
int l = end - start + 1;
if (l <= 0) {
- shared_empty.ref.ref();
- return QString(&shared_empty, 0);
+ return QString(shared_empty);
}
return QString(s + start, l);
}
@@ -4250,8 +4215,8 @@ QString& QString::fill(QChar ch, int size)
{
resize(size < 0 ? d->size : size);
if (d->size) {
- QChar *i = (QChar*)d->data + d->size;
- QChar *b = (QChar*)d->data;
+ QChar *i = (QChar*)d->data() + d->size;
+ QChar *b = (QChar*)d->data();
while (i != b)
*--i = ch;
}
@@ -4597,7 +4562,7 @@ int QString::compare(const QString &other, Qt::CaseSensitivity cs) const
{
if (cs == Qt::CaseSensitive)
return ucstrcmp(constData(), length(), other.constData(), other.length());
- return ucstricmp(d->data, d->data + d->size, other.d->data, other.d->data + other.d->size);
+ return ucstricmp(d->data(), d->data() + d->size, other.d->data(), other.d->data() + other.d->size);
}
/*!
@@ -4828,12 +4793,9 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
const ushort *QString::utf16() const
{
- if (d->data != d->array) {
- QString *that = const_cast<QString*>(this);
- that->realloc(); // ensure '\\0'-termination for ::fromRawData strings
- return that->d->data;
- }
- return d->array;
+ if (d->offset)
+ const_cast<QString*>(this)->realloc(); // ensure '\\0'-termination for ::fromRawData strings
+ return d->data();
}
/*!
@@ -4862,8 +4824,8 @@ QString QString::leftJustified(int width, QChar fill, bool truncate) const
if (padlen > 0) {
result.resize(len+padlen);
if (len)
- memcpy(result.d->data, d->data, sizeof(QChar)*len);
- QChar *uc = (QChar*)result.d->data + len;
+ memcpy(result.d->data(), d->data(), sizeof(QChar)*len);
+ QChar *uc = (QChar*)result.d->data() + len;
while (padlen--)
* uc++ = fill;
} else {
@@ -4900,11 +4862,11 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
int padlen = width - len;
if (padlen > 0) {
result.resize(len+padlen);
- QChar *uc = (QChar*)result.d->data;
+ QChar *uc = (QChar*)result.d->data();
while (padlen--)
* uc++ = fill;
if (len)
- memcpy(uc, d->data, sizeof(QChar)*len);
+ memcpy(uc, d->data(), sizeof(QChar)*len);
} else {
if (truncate)
result = left(width);
@@ -4924,7 +4886,7 @@ QString QString::rightJustified(int width, QChar fill, bool truncate) const
QString QString::toLower() const
{
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
if (!d->size)
@@ -4939,7 +4901,7 @@ QString QString::toLower() const
}
#endif
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
// this avoids one out of bounds check in the loop
if (QChar(*p).isLowSurrogate())
@@ -4952,17 +4914,17 @@ QString QString::toLower() const
const QUnicodeTables::Properties *prop = qGetProp(c);
if (prop->lowerCaseDiff || prop->lowerCaseSpecial) {
QString s(d->size, Qt::Uninitialized);
- memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
- ushort *pp = s.d->data + (p - d->data);
+ memcpy(s.d->data(), d->data(), (p - d->data())*sizeof(ushort));
+ ushort *pp = s.d->data() + (p - d->data());
while (p < e) {
uint c = *p;
if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
c = QChar::surrogateToUcs4(*(p - 1), c);
prop = qGetProp(c);
if (prop->lowerCaseSpecial) {
- int pos = pp - s.d->data;
+ int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
- pp = s.d->data + pos;
+ pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->lowerCaseDiff;
while (*specialCase)
*pp++ = *specialCase++;
@@ -4971,7 +4933,7 @@ QString QString::toLower() const
}
++p;
}
- s.truncate(pp - s.d->data);
+ s.truncate(pp - s.d->data());
return s;
}
++p;
@@ -4988,11 +4950,11 @@ QString QString::toCaseFolded() const
if (!d->size)
return *this;
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
uint last = 0;
while (p < e) {
@@ -5000,9 +4962,9 @@ QString QString::toCaseFolded() const
if (folded != *p) {
QString s(*this);
s.detach();
- ushort *pp = s.d->data + (p - d->data);
- const ushort *ppe = s.d->data + s.d->size;
- last = pp > s.d->data ? *(pp - 1) : 0;
+ ushort *pp = s.d->data() + (p - d->data());
+ const ushort *ppe = s.d->data() + s.d->size;
+ last = pp > s.d->data() ? *(pp - 1) : 0;
while (pp < ppe) {
*pp = foldCase(*pp, last);
++pp;
@@ -5024,7 +4986,7 @@ QString QString::toCaseFolded() const
QString QString::toUpper() const
{
- const ushort *p = d->data;
+ const ushort *p = d->data();
if (!p)
return *this;
if (!d->size)
@@ -5039,7 +5001,7 @@ QString QString::toUpper() const
}
#endif
- const ushort *e = d->data + d->size;
+ const ushort *e = d->data() + d->size;
// this avoids one out of bounds check in the loop
if (QChar(*p).isLowSurrogate())
@@ -5052,17 +5014,17 @@ QString QString::toUpper() const
const QUnicodeTables::Properties *prop = qGetProp(c);
if (prop->upperCaseDiff || prop->upperCaseSpecial) {
QString s(d->size, Qt::Uninitialized);
- memcpy(s.d->data, d->data, (p - d->data)*sizeof(ushort));
- ushort *pp = s.d->data + (p - d->data);
+ memcpy(s.d->data(), d->data(), (p - d->data())*sizeof(ushort));
+ ushort *pp = s.d->data() + (p - d->data());
while (p < e) {
uint c = *p;
if (QChar(c).isLowSurrogate() && QChar(*(p - 1)).isHighSurrogate())
c = QChar::surrogateToUcs4(*(p - 1), c);
prop = qGetProp(c);
if (prop->upperCaseSpecial) {
- int pos = pp - s.d->data;
+ int pos = pp - s.d->data();
s.resize(s.d->size + SPECIAL_CASE_MAX_LEN);
- pp = s.d->data + pos;
+ pp = s.d->data() + pos;
const ushort *specialCase = specialCaseMap + prop->upperCaseDiff;
while (*specialCase)
*pp++ = *specialCase++;
@@ -5071,7 +5033,7 @@ QString QString::toUpper() const
}
++p;
}
- s.truncate(pp - s.d->data);
+ s.truncate(pp - s.d->data());
return s;
}
++p;
@@ -6196,19 +6158,19 @@ QString QString::repeated(int times) const
if (result.d->alloc != resultSize)
return QString(); // not enough memory
- memcpy(result.d->data, d->data, d->size * sizeof(ushort));
+ memcpy(result.d->data(), d->data(), d->size * sizeof(ushort));
int sizeSoFar = d->size;
- ushort *end = result.d->data + sizeSoFar;
+ ushort *end = result.d->data() + sizeSoFar;
const int halfResultSize = resultSize >> 1;
while (sizeSoFar <= halfResultSize) {
- memcpy(end, result.d->data, sizeSoFar * sizeof(ushort));
+ memcpy(end, result.d->data(), sizeSoFar * sizeof(ushort));
end += sizeSoFar;
sizeSoFar <<= 1;
}
- memcpy(end, result.d->data, (resultSize - sizeSoFar) * sizeof(ushort));
- result.d->data[resultSize] = '\0';
+ memcpy(end, result.d->data(), (resultSize - sizeSoFar) * sizeof(ushort));
+ result.d->data()[resultSize] = '\0';
result.d->size = resultSize;
return result;
}
@@ -6902,7 +6864,7 @@ QString QString::multiArg(int numArgs, const QString **args) const
{
QString result;
QMap<int, int> numbersUsed;
- const QChar *uc = (const QChar *) d->data;
+ const QChar *uc = (const QChar *) d->data();
const int len = d->size;
const int end = len - 1;
int lastNumber = -1;
@@ -6951,62 +6913,50 @@ QString QString::multiArg(int numArgs, const QString **args) const
return result;
}
-static bool isStringRightToLeft(const ushort *p, const ushort *end)
-{
- bool righttoleft = false;
- while (p < end) {
- switch(QChar::direction(*p))
- {
- case QChar::DirL:
- goto end;
- case QChar::DirR:
- case QChar::DirAL:
- righttoleft = true;
- goto end;
- default:
- break;
- }
- ++p;
- }
- end:
- return righttoleft;
-}
-/*! \internal
- */
-void QString::updateProperties() const
+/*! \fn bool QString::isSimpleText() const
+
+ \internal
+*/
+bool QString::isSimpleText() const
{
- ushort *p = d->data;
- ushort *end = p + d->size;
- d->simpletext = true;
+ const ushort *p = d->data();
+ const ushort * const end = p + d->size;
while (p < end) {
ushort uc = *p;
// sort out regions of complex text formatting
if (uc > 0x058f && (uc < 0x1100 || uc > 0xfb0f)) {
- d->simpletext = false;
+ return false;
}
p++;
}
- d->righttoleft = isStringRightToLeft(d->data, d->data + d->size);
- d->clean = true;
-}
-
-bool QString::isRightToLeft() const
-{
- return isStringRightToLeft(d->data, d->data + d->size);
+ return true;
}
-/*! \fn bool QString::isSimpleText() const
-
- \internal
-*/
-
/*! \fn bool QString::isRightToLeft() const
Returns true if the string is read right to left.
*/
-
+bool QString::isRightToLeft() const
+{
+ const ushort *p = d->data();
+ const ushort * const end = p + d->size;
+ while (p < end) {
+ switch(QChar::direction(*p))
+ {
+ case QChar::DirL:
+ return false;
+ case QChar::DirR:
+ case QChar::DirAL:
+ return true;
+ default:
+ break;
+ }
+ ++p;
+ }
+ return false;
+}
/*! \fn QChar *QString::data()
@@ -7122,17 +7072,13 @@ bool QString::isRightToLeft() const
QString QString::fromRawData(const QChar *unicode, int size)
{
Data *x = static_cast<Data *>(qMalloc(sizeof(Data)));
+ *x = (Data){ Q_REFCOUNT_INITIALIZER(1), size, 0, false, { 0 } };
Q_CHECK_PTR(x);
if (unicode) {
- x->data = (ushort *)unicode;
+ x->offset = (const ushort *)unicode - (x->d + sizeof(qptrdiff)/sizeof(ushort));
} else {
- x->data = x->array;
size = 0;
}
- x->ref = 1;
- x->alloc = x->size = size;
- *x->array = '\0';
- x->clean = x->simpletext = x->righttoleft = x->capacity = 0;
return QString(x, 0);
}
@@ -7152,18 +7098,16 @@ QString QString::fromRawData(const QChar *unicode, int size)
*/
QString &QString::setRawData(const QChar *unicode, int size)
{
- if (d->ref != 1 || (d->data == d->array && d->alloc)) {
+ if (d->ref != 1 || d->alloc) {
*this = fromRawData(unicode, size);
} else {
if (unicode) {
- d->data = (ushort *)unicode;
+ d->size = size;
+ d->offset = (const ushort *)unicode - (d->d + sizeof(qptrdiff)/sizeof(ushort));
} else {
- d->data = d->array;
- size = 0;
+ d->offset = 0;
+ d->size = 0;
}
- d->alloc = d->size = size;
- *d->array = '\0';
- d->clean = d->simpletext = d->righttoleft = d->capacity = 0;
}
return *this;
}
@@ -7212,7 +7156,7 @@ QString &QString::setRawData(const QChar *unicode, int size)
\snippet doc/src/snippets/code/src_corelib_tools_qstring.cpp 6
- \sa QString, QLatin1Char
+ \sa QString, QLatin1Char, QStringLiteral
*/
/*! \fn QLatin1String::QLatin1String(const char *str)
@@ -7526,7 +7470,7 @@ QDataStream &operator>>(QDataStream &in, QString &str)
}
}
} else {
- str = QLatin1String("");
+ str = QString(QLatin1String(""));
}
}
return in;
@@ -8345,7 +8289,7 @@ QStringRef QString::rightRef(int n) const
QStringRef QString::midRef(int position, int n) const
{
- if (d == &shared_null || position >= d->size)
+ if (d == &shared_null.str || position >= d->size)
return QStringRef();
if (n < 0)
n = d->size - position;
@@ -8498,7 +8442,7 @@ int QStringRef::lastIndexOf(QChar ch, int from, Qt::CaseSensitivity cs) const
*/
int QStringRef::lastIndexOf(QLatin1String str, int from, Qt::CaseSensitivity cs) const
{
- const int sl = qstrlen(str.latin1());
+ const int sl = str.size();
if (sl == 1)
return lastIndexOf(QLatin1Char(str.latin1()[0]), from, cs);
@@ -8851,7 +8795,7 @@ static inline int qt_find_latin1_string(const QChar *haystack, int size,
int from, Qt::CaseSensitivity cs)
{
const char *latin1 = needle.latin1();
- int len = qstrlen(latin1);
+ int len = needle.size();
QVarLengthArray<ushort> s(len);
for (int i = 0; i < len; ++i)
s[i] = latin1[i];
@@ -8892,7 +8836,7 @@ static inline bool qt_starts_with(const QChar *haystack, int haystackLen,
return !needle.latin1();
if (haystackLen == 0)
return !needle.latin1() || *needle.latin1() == 0;
- const int slen = qstrlen(needle.latin1());
+ const int slen = needle.size();
if (slen > haystackLen)
return false;
const ushort *data = reinterpret_cast<const ushort*>(haystack);
@@ -8943,7 +8887,7 @@ static inline bool qt_ends_with(const QChar *haystack, int haystackLen,
return !needle.latin1();
if (haystackLen == 0)
return !needle.latin1() || *needle.latin1() == 0;
- const int slen = qstrlen(needle.latin1());
+ const int slen = needle.size();
int pos = haystackLen - slen;
if (pos < 0)
return false;
@@ -9071,4 +9015,21 @@ QVector<uint> QStringRef::toUcs4() const
return v;
}
+/*!
+ \macro QStringLiteral(str)
+ \relates QString
+
+ The macro generates the data for a QString out of \a str at compile time if the compiler supports it.
+ Creating a QString from it is free in this case, and the generated string data is stored in
+ the read-only segment of the compiled object file.
+
+ Using QStringLiteral instead of a double quoted ascii literal can significantly speed up creation
+ of QString's from data known at compile time.
+
+ If the compiler is c++0x enabled the string \a str can actually contain unicode data.
+
+ For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to
+ QLatin1String.
+*/
+
QT_END_NAMESPACE
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index 154012d132..27948e04ea 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -44,7 +44,7 @@
#include <QtCore/qchar.h>
#include <QtCore/qbytearray.h>
-#include <QtCore/qatomic.h>
+#include <QtCore/qrefcount.h>
#include <QtCore/qnamespace.h>
#ifndef QT_NO_STL
@@ -77,9 +77,86 @@ class QLatin1String;
class QStringRef;
template <typename T> class QVector;
+struct QStringData {
+ QtPrivate::RefCount ref;
+ int size;
+ uint alloc : 31;
+ uint capacityReserved : 1;
+ union {
+ qptrdiff offset; // will always work as we add/subtract from a ushort ptr
+ ushort d[sizeof(qptrdiff)/sizeof(ushort)];
+ };
+ inline ushort *data() { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
+ inline const ushort *data() const { return d + sizeof(qptrdiff)/sizeof(ushort) + offset; }
+};
+
+template<int N> struct QConstStringData;
+template<int N> struct QConstStringDataPtr
+{
+ const QConstStringData<N> *ptr;
+};
+
+#if defined(Q_COMPILER_UNICODE_STRINGS)
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const char16_t data[n];
+};
+#define QT_QSTRING_UNICODE_MARKER u""
+
+#elif defined(Q_OS_WIN) || (defined(__SIZEOF_WCHAR_T__) && __SIZEOF_WCHAR_T__ == 2) || defined(WCHAR_MAX) && (WCHAR_MAX - 0 < 65536)
+// wchar_t is 2 bytes
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const wchar_t data[n];
+};
+#define QT_QSTRING_UNICODE_MARKER L""
+
+#else
+template<int n> struct QConstStringData
+{
+ const QStringData str;
+ const ushort data[n];
+};
+#endif
+
+#if defined(QT_QSTRING_UNICODE_MARKER)
+# if defined(Q_COMPILER_LAMBDA)
+# define QStringLiteral(str) ([]() { \
+ enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+ static const QConstStringData<Size> qstring_literal = \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ QConstStringDataPtr<Size> holder = { &qstring_literal }; \
+ return holder; }())
+
+# elif defined(Q_CC_GNU)
+// We need to create a QStringData in the .rodata section of memory
+// and the only way to do that is to create a "static const" variable.
+// To do that, we need the __extension__ {( )} trick which only GCC supports
+
+# define QStringLiteral(str) \
+ __extension__ ({ \
+ enum { Size = sizeof(QT_QSTRING_UNICODE_MARKER str)/2 }; \
+ static const QConstStringData<Size> qstring_literal = \
+ { { Q_REFCOUNT_INITIALIZER(-1), Size -1, 0, 0, { 0 } }, QT_QSTRING_UNICODE_MARKER str }; \
+ QConstStringDataPtr<Size> holder = { &qstring_literal }; \
+ holder; })
+# endif
+#endif
+
+#ifndef QStringLiteral
+// no lambdas, not GCC, or GCC in C++98 mode with 4-byte wchar_t
+// fallback, uses QLatin1String as next best options
+
+# define QStringLiteral(str) QLatin1String(str)
+#endif
+
class Q_CORE_EXPORT QString
{
public:
+ typedef QStringData Data;
+
inline QString();
QString(const QChar *unicode, int size); // Qt5: don't cap size < 0
explicit QString(const QChar *unicode); // Qt5: merge with the above
@@ -108,7 +185,7 @@ public:
int capacity() const;
inline void reserve(int size);
- inline void squeeze() { if (d->size < d->alloc || d->ref != 1) realloc(); d->capacity = 0;}
+ inline void squeeze() { if (d->size < d->alloc || d->ref != 1) realloc(); d->capacityReserved = false;}
inline const QChar *unicode() const;
inline QChar *data();
@@ -262,8 +339,8 @@ public:
inline QString &operator+=(QChar c) {
if (d->ref != 1 || d->size + 1 > d->alloc)
realloc(grow(d->size + 1));
- d->data[d->size++] = c.unicode();
- d->data[d->size] = '\0';
+ d->data()[d->size++] = c.unicode();
+ d->data()[d->size] = '\0';
return *this;
}
@@ -491,15 +568,19 @@ public:
// compatibility
struct Null { };
static const Null null;
- inline QString(const Null &): d(&shared_null) { d->ref.ref(); }
+ inline QString(const Null &): d(const_cast<Data *>(&shared_null.str)) {}
inline QString &operator=(const Null &) { *this = QString(); return *this; }
- inline bool isNull() const { return d == &shared_null; }
+ inline bool isNull() const { return d == &shared_null.str; }
- bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; }
+ bool isSimpleText() const;
bool isRightToLeft() const;
QString(int size, Qt::Initialization);
+ template <int n>
+ inline QString(const QConstStringData<n> &dd) : d(const_cast<QStringData *>(&dd.str)) {}
+ template <int N>
+ Q_DECL_CONSTEXPR inline QString(QConstStringDataPtr<N> dd) : d(const_cast<QStringData *>(&dd.ptr->str)) {}
private:
#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
@@ -511,22 +592,11 @@ private:
QString &operator=(const QByteArray &a);
#endif
- struct Data {
- QBasicAtomicInt ref;
- int alloc, size;
- ushort *data; // QT5: put that after the bit field to fill alignment gap; don't use sizeof any more then
- ushort clean : 1;
- ushort simpletext : 1;
- ushort righttoleft : 1;
- ushort capacity : 1;
- ushort reserved : 11;
- // ### Qt5: try to ensure that "array" is aligned to 16 bytes on both 32- and 64-bit
- ushort array[1];
- };
- static Data shared_null;
- static Data shared_empty;
+ static const QConstStringData<1> shared_null;
+ static const QConstStringData<1> shared_empty;
Data *d;
- QString(Data *dd, int /*dummy*/) : d(dd) {}
+ inline QString(Data *dd, int /*dummy*/) : d(dd) {}
+
#ifndef QT_NO_TEXTCODEC
static QTextCodec *codecForCStrings;
#endif
@@ -563,11 +633,11 @@ public:
class Q_CORE_EXPORT QLatin1String
{
public:
- inline explicit QLatin1String(const char *s) : chars(s) {}
- inline QLatin1String &operator=(const QLatin1String &other)
- { chars = other.chars; return *this; }
+ inline explicit QLatin1String(const char *s) : m_size(s ? strlen(s) : 0), m_data(s) {}
- inline const char *latin1() const { return chars; }
+ inline const char *latin1() const { return m_data; }
+ inline int size() const { return m_size; }
+ inline const char *data() const { return m_data; }
inline bool operator==(const QString &s) const
{ return s == *this; }
@@ -595,9 +665,12 @@ public:
inline QT_ASCII_CAST_WARN bool operator>=(const char *s) const
{ return QString::fromAscii(s) <= *this; }
private:
- const char *chars;
+ int m_size;
+ const char *m_data;
};
+// Qt 4.x compatibility
+typedef QLatin1String QLatin1Literal;
inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLatin1.latin1()))
@@ -605,23 +678,23 @@ inline QString::QString(const QLatin1String &aLatin1) : d(fromLatin1_helper(aLat
inline int QString::length() const
{ return d->size; }
inline const QChar QString::at(int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; }
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
inline const QChar QString::operator[](int i) const
-{ Q_ASSERT(uint(i) < uint(size())); return d->data[i]; }
+{ Q_ASSERT(uint(i) < uint(size())); return d->data()[i]; }
inline const QChar QString::operator[](uint i) const
-{ Q_ASSERT(i < uint(size())); return d->data[i]; }
+{ Q_ASSERT(i < uint(size())); return d->data()[i]; }
inline bool QString::isEmpty() const
{ return d->size == 0; }
inline const QChar *QString::unicode() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline const QChar *QString::data() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QChar *QString::data()
-{ detach(); return reinterpret_cast<QChar*>(d->data); }
+{ detach(); return reinterpret_cast<QChar*>(d->data()); }
inline const QChar *QString::constData() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline void QString::detach()
-{ if (d->ref != 1 || d->data != d->array) realloc(); }
+{ if (d->ref != 1 || d->offset) realloc(); }
inline bool QString::isDetached() const
{ return d->ref == 1; }
inline QString &QString::operator=(const QLatin1String &s)
@@ -703,10 +776,10 @@ public:
// all this is not documented: We just say "like QChar" and let it be.
inline operator QChar() const
- { return i < s.d->size ? s.d->data[i] : 0; }
+ { return i < s.d->size ? s.d->data()[i] : 0; }
inline QCharRef &operator=(const QChar &c)
{ if (i >= s.d->size) s.expand(i); else s.detach();
- s.d->data[i] = c.unicode(); return *this; }
+ s.d->data()[i] = c.unicode(); return *this; }
// An operator= for each QChar cast constructors
#ifndef QT_NO_CAST_FROM_ASCII
@@ -756,15 +829,9 @@ public:
inline void setCell(uchar cell);
inline void setRow(uchar row);
-#ifdef Q_COMPILER_MANGLES_RETURN_TYPE
- const char toAscii() const { return QChar(*this).toAscii(); }
- const char toLatin1() const { return QChar(*this).toLatin1(); }
- const ushort unicode() const { return QChar(*this).unicode(); }
-#else
char toAscii() const { return QChar(*this).toAscii(); }
char toLatin1() const { return QChar(*this).toLatin1(); }
ushort unicode() const { return QChar(*this).unicode(); }
-#endif
ushort& unicode() { return s.data()[i].unicode(); }
};
@@ -773,9 +840,9 @@ inline void QCharRef::setRow(uchar arow) { QChar(*this).setRow(arow); }
inline void QCharRef::setCell(uchar acell) { QChar(*this).setCell(acell); }
-inline QString::QString() : d(&shared_null) { d->ref.ref(); }
+inline QString::QString() : d(const_cast<Data *>(&shared_null.str)) {}
inline QString::~QString() { if (!d->ref.deref()) free(d); }
-inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacity = 1;}
+inline void QString::reserve(int asize) { if (d->ref != 1 || asize > d->alloc) realloc(asize); d->capacityReserved = true;}
inline QString &QString::setUtf16(const ushort *autf16, int asize)
{ return setUnicode(reinterpret_cast<const QChar *>(autf16), asize); }
inline QCharRef QString::operator[](int i)
@@ -783,17 +850,17 @@ inline QCharRef QString::operator[](int i)
inline QCharRef QString::operator[](uint i)
{ return QCharRef(*this, i); }
inline QString::iterator QString::begin()
-{ detach(); return reinterpret_cast<QChar*>(d->data); }
+{ detach(); return reinterpret_cast<QChar*>(d->data()); }
inline QString::const_iterator QString::begin() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QString::const_iterator QString::constBegin() const
-{ return reinterpret_cast<const QChar*>(d->data); }
+{ return reinterpret_cast<const QChar*>(d->data()); }
inline QString::iterator QString::end()
-{ detach(); return reinterpret_cast<QChar*>(d->data + d->size); }
+{ detach(); return reinterpret_cast<QChar*>(d->data() + d->size); }
inline QString::const_iterator QString::end() const
-{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
inline QString::const_iterator QString::constEnd() const
-{ return reinterpret_cast<const QChar*>(d->data + d->size); }
+{ return reinterpret_cast<const QChar*>(d->data() + d->size); }
inline QBool QString::contains(const QString &s, Qt::CaseSensitivity cs) const
{ return QBool(indexOf(s, 0, cs) != -1); }
inline QBool QString::contains(const QStringRef &s, Qt::CaseSensitivity cs) const
@@ -1024,7 +1091,7 @@ public:
inline const QChar *unicode() const {
if (!m_string)
- return reinterpret_cast<const QChar *>(QString::shared_null.data);
+ return reinterpret_cast<const QChar *>(QString::shared_null.str.data());
return m_string->unicode() + m_position;
}
inline const QChar *data() const { return unicode(); }
@@ -1154,7 +1221,6 @@ inline QBool QStringRef::contains(const QStringRef &s, Qt::CaseSensitivity cs) c
{ return QBool(indexOf(s, 0, cs) != -1); }
-
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp
index 1cc7e5d2c3..4c6848498b 100644
--- a/src/corelib/tools/qstringbuilder.cpp
+++ b/src/corelib/tools/qstringbuilder.cpp
@@ -45,47 +45,6 @@
QT_BEGIN_NAMESPACE
/*!
- \class QLatin1Literal
- \internal
- \reentrant
- \since 4.6
-
- \brief The QLatin1Literal class provides a thin wrapper around string
- literals used in source code.
-
- \ingroup tools
- \ingroup shared
- \ingroup string-processing
-
-
- Unlike \c QLatin1String, a \c QLatin1Literal can retrieve its size
- without iterating over the literal.
-
- The main use of \c QLatin1Literal is in conjunction with \c QStringBuilder
- to reduce the number of reallocations needed to build up a string from
- smaller chunks.
-
- \sa QStringBuilder, QLatin1String, QString, QStringRef
-*/
-
-/*! \fn int QLatin1Literal::size() const
-
- Returns the number of characters in the literal \e{excluding} the trailing
- NULL char.
-*/
-
-/*! \fn QLatin1Literal::QLatin1Literal(const char str)
-
- Constructs a new literal from the string \a str.
-*/
-
-/*! \fn const char *QLatin1Literal::data() const
-
- Returns a pointer to the first character of the string literal.
- The string literal is terminated by a NUL character.
-*/
-
-/*!
\class QStringBuilder
\internal
\reentrant
@@ -110,7 +69,7 @@ QT_BEGIN_NAMESPACE
The QStringBuilder class is not to be used explicitly in user
code. Instances of the class are created as return values of the
operator%() function, acting on objects of type QString,
- QLatin1String, QLatin1Literal, QStringRef, QChar, QCharRef,
+ QLatin1String, QStringRef, QChar, QCharRef,
QLatin1Char, and \c char.
Concatenating strings with operator%() generally yields better
@@ -118,7 +77,7 @@ QT_BEGIN_NAMESPACE
if there are three or more of them, and performs equally well in other
cases.
- \sa QLatin1Literal, QString
+ \sa QLatin1String, QString
*/
/*! \fn QStringBuilder::QStringBuilder(const A &a, const B &b)
@@ -132,7 +91,7 @@ QT_BEGIN_NAMESPACE
takes a QString parameter.
This function is usable with arguments of type \c QString,
- \c QLatin1String, \c QLatin1Literal, \c QStringRef,
+ \c QLatin1String, \c QStringRef,
\c QChar, \c QCharRef, \c QLatin1Char, and \c char.
*/
@@ -145,7 +104,7 @@ QT_BEGIN_NAMESPACE
/*!
\fn operator QStringBuilder::QString() const
- Converts the \c QLatin1Literal into a \c QString object.
+ Converts the \c QLatin1String into a \c QString object.
*/
/*! \internal
diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h
index 594ab2f183..6d998b62aa 100644
--- a/src/corelib/tools/qstringbuilder.h
+++ b/src/corelib/tools/qstringbuilder.h
@@ -59,22 +59,6 @@ QT_BEGIN_NAMESPACE
QT_MODULE(Core)
-// ### Qt 5: merge with QLatin1String
-class QLatin1Literal
-{
-public:
- int size() const { return m_size; }
- const char *data() const { return m_data; }
-
- template <int N>
- QLatin1Literal(const char (&str)[N])
- : m_size(N - 1), m_data(str) {}
-
-private:
- const int m_size;
- const char * const m_data;
-};
-
struct Q_CORE_EXPORT QAbstractConcatenable
{
protected:
@@ -234,31 +218,13 @@ template <> struct QConcatenable<QLatin1String>
typedef QLatin1String type;
typedef QString ConvertTo;
enum { ExactSize = true };
- static int size(const QLatin1String &a) { return qstrlen(a.latin1()); }
+ static int size(const QLatin1String &a) { return a.size(); }
static inline void appendTo(const QLatin1String &a, QChar *&out)
{
- for (const char *s = a.latin1(); *s; )
- *out++ = QLatin1Char(*s++);
- }
- static inline void appendTo(const QLatin1String &a, char *&out)
- {
- for (const char *s = a.latin1(); *s; )
- *out++ = *s++;
- }
-};
-
-template <> struct QConcatenable<QLatin1Literal>
-{
- typedef QLatin1Literal type;
- typedef QString ConvertTo;
- enum { ExactSize = true };
- static int size(const QLatin1Literal &a) { return a.size(); }
- static inline void appendTo(const QLatin1Literal &a, QChar *&out)
- {
for (const char *s = a.data(); *s; )
*out++ = QLatin1Char(*s++);
}
- static inline void appendTo(const QLatin1Literal &a, char *&out)
+ static inline void appendTo(const QLatin1String &a, char *&out)
{
for (const char *s = a.data(); *s; )
*out++ = *s++;
@@ -283,6 +249,23 @@ template <> struct QConcatenable<QString> : private QAbstractConcatenable
#endif
};
+template <int N> struct QConcatenable<QConstStringDataPtr<N> > : private QAbstractConcatenable
+{
+ typedef QConstStringDataPtr<N> type;
+ typedef QString ConvertTo;
+ enum { ExactSize = true };
+ static int size(const type &) { return N; }
+ static inline void appendTo(const type &a, QChar *&out)
+ {
+ memcpy(out, reinterpret_cast<const char*>(a.ptr->data), sizeof(QChar) * N);
+ out += N;
+ }
+#ifndef QT_NO_CAST_TO_ASCII
+ static inline QT_ASCII_CAST_WARN void appendTo(const type &a, char *&out)
+ { convertToAscii(a.ptr->data, N, out); }
+#endif
+};
+
template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable
{
typedef QStringRef type;
diff --git a/src/corelib/tools/qstringlist.h b/src/corelib/tools/qstringlist.h
index efb7f46c9b..bded94399d 100644
--- a/src/corelib/tools/qstringlist.h
+++ b/src/corelib/tools/qstringlist.h
@@ -68,7 +68,7 @@ public:
inline QStringList(const QStringList &l) : QList<QString>(l) { }
inline QStringList(const QList<QString> &l) : QList<QString>(l) { }
#ifdef Q_COMPILER_INITIALIZER_LISTS
- inline QStringList(std::initializer_list<QString> args) : QList(args) { }
+ inline QStringList(std::initializer_list<QString> args) : QList<QString>(args) { }
#endif
inline void sort();
diff --git a/src/corelib/tools/tools.pri b/src/corelib/tools/tools.pri
index 42cab84cc0..f5b38eb1c0 100644
--- a/src/corelib/tools/tools.pri
+++ b/src/corelib/tools/tools.pri
@@ -30,6 +30,7 @@ HEADERS += \
tools/qrect.h \
tools/qregexp.h \
tools/qringbuffer_p.h \
+ tools/qrefcount.h \
tools/qscopedpointer.h \
tools/qscopedpointer_p.h \
tools/qscopedvaluerollback.h \
@@ -72,6 +73,7 @@ SOURCES += \
tools/qcontiguouscache.cpp \
tools/qrect.cpp \
tools/qregexp.cpp \
+ tools/qrefcount.cpp \
tools/qshareddata.cpp \
tools/qsharedpointer.cpp \
tools/qsimd.cpp \
diff --git a/src/dbus/qdbus_symbols.cpp b/src/dbus/qdbus_symbols.cpp
index 44597c39b6..fed18350bb 100644
--- a/src/dbus/qdbus_symbols.cpp
+++ b/src/dbus/qdbus_symbols.cpp
@@ -62,6 +62,12 @@ void qdbus_unloadLibDBus()
bool qdbus_loadLibDBus()
{
+#ifdef QT_BUILD_INTERNAL
+ // this is to simulate a library load failure for our autotest suite.
+ if (!qgetenv("QT_SIMULATE_DBUS_LIBFAIL").isEmpty())
+ return false;
+#endif
+
static volatile bool triedToLoadLibrary = false;
#ifndef QT_NO_THREAD
QMutexLocker locker(QMutexPool::globalInstanceGet((void *)&qdbus_resolve_me));
diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp
index 0b4133c8dd..9656903846 100644
--- a/src/dbus/qdbusconnection.cpp
+++ b/src/dbus/qdbusconnection.cpp
@@ -1061,7 +1061,7 @@ public:
if (!instance) {
qWarning("QDBusConnection: %s D-Bus connection created before QCoreApplication. Application may misbehave.",
type == SessionBus ? "session" : type == SystemBus ? "system" : "generic");
- } else {
+ } else if (QDBusConnectionPrivate::d(*this)) {
QDBusConnectionPrivate::d(*this)->moveToThread(instance->thread());
}
}
diff --git a/src/gui/painting/qcosmeticstroker.cpp b/src/gui/painting/qcosmeticstroker.cpp
index cdc0978ed7..dbe957e68d 100644
--- a/src/gui/painting/qcosmeticstroker.cpp
+++ b/src/gui/painting/qcosmeticstroker.cpp
@@ -7,29 +7,29 @@
** 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 Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** 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.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/src/gui/painting/qcosmeticstroker_p.h b/src/gui/painting/qcosmeticstroker_p.h
index 0aa71fc9cd..d7bd79ad15 100644
--- a/src/gui/painting/qcosmeticstroker_p.h
+++ b/src/gui/painting/qcosmeticstroker_p.h
@@ -7,29 +7,29 @@
** 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 Technology Preview License Agreement accompanying
-** this package.
-**
** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** 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
+** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
-** If you have questions regarding the use of this file, please contact
-** Nokia at qt-info@nokia.com.
-**
-**
+** 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.
**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
**
**
**
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index be5c41ce76..d5b9f97378 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -1291,7 +1291,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
\o \inlineimage qpainter-compositiondemo.png
\o
- \bold {Composition Modes Demo}
+ \bold {Composition Modes Example}
The \l {painting/composition}{Composition Modes} example, available in
Qt's examples directory, allows you to experiment with the various
@@ -6503,6 +6503,10 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
qreal x = p.x();
qreal y = p.y();
+ bool rtl = ti.flags & QTextItem::RightToLeft;
+ if (rtl)
+ x += ti.width.toReal();
+
int start = 0;
int end, i;
for (end = 0; end < ti.glyphs.numGlyphs; ++end) {
@@ -6519,14 +6523,19 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
ti2.width += ti.glyphs.effectiveAdvance(i);
}
+ if (rtl)
+ x -= ti2.width.toReal();
+
d->engine->drawTextItem(QPointF(x, y), ti2);
+ if (!rtl)
+ x += ti2.width.toReal();
+
// reset the high byte for all glyphs and advance to the next sub-string
const int hi = which << 24;
for (i = start; i < end; ++i) {
glyphs.glyphs[i] = hi | glyphs.glyphs[i];
}
- x += ti2.width.toReal();
// change engine
start = end;
@@ -6541,6 +6550,9 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
ti2.width += ti.glyphs.effectiveAdvance(i);
}
+ if (rtl)
+ x -= ti2.width.toReal();
+
if (d->extended)
d->extended->drawTextItem(QPointF(x, y), ti2);
else
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index 98b43d5b5e..655042a22c 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -218,17 +218,14 @@ struct QtFontStyle
Key(const QString &styleString);
Key() : style(QFont::StyleNormal),
weight(QFont::Normal), stretch(0) { }
- Key(const Key &o) : styleName(o.styleName), style(o.style),
- weight(o.weight), stretch(o.stretch) { }
- QString styleName;
+ Key(const Key &o) : style(o.style), weight(o.weight), stretch(o.stretch) { }
uint style : 2;
signed int weight : 8;
signed int stretch : 12;
bool operator==(const Key & other) {
- return styleName == other.styleName && style == other.style &&
- weight == other.weight &&
- (stretch == 0 || other.stretch == 0 || stretch == other.stretch);
+ return (style == other.style && weight == other.weight &&
+ (stretch == 0 || other.stretch == 0 || stretch == other.stretch));
}
bool operator!=(const Key &other) {
return !operator==(other);
@@ -280,6 +277,7 @@ struct QtFontStyle
bool smoothScalable : 1;
signed int count : 30;
QtFontSize *pixelSizes;
+ QString styleName;
#ifdef Q_WS_X11
const char *weightName;
@@ -293,7 +291,7 @@ struct QtFontStyle
};
QtFontStyle::Key::Key(const QString &styleString)
- : styleName(styleString), style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
+ : style(QFont::StyleNormal), weight(QFont::Normal), stretch(0)
{
weight = getFontWeight(styleString);
@@ -354,13 +352,20 @@ struct QtFontFoundry
int count;
QtFontStyle **styles;
- QtFontStyle *style(const QtFontStyle::Key &, bool = false);
+ QtFontStyle *style(const QtFontStyle::Key &, const QString & = QString(), bool = false);
};
-QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
+QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, const QString &styleName, bool create)
{
int pos = 0;
if (count) {
+ // if styleName for searching first if possible
+ if (!styleName.isEmpty()) {
+ for (; pos < count; pos++) {
+ if (styles[pos]->styleName == styleName)
+ return styles[pos];
+ }
+ }
int low = 0;
int high = count;
pos = count / 2;
@@ -387,6 +392,7 @@ QtFontStyle *QtFontFoundry::style(const QtFontStyle::Key &key, bool create)
}
QtFontStyle *style = new QtFontStyle(key);
+ style->styleName = styleName;
memmove(styles + pos + 1, styles + pos, (count-pos)*sizeof(QtFontStyle *));
styles[pos] = style;
count++;
@@ -815,7 +821,7 @@ void QFontDatabasePrivate::addFont(const QString &familyname, const char *foundr
}
QtFontFoundry *foundry = f->foundry(QString::fromLatin1(foundryname), true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = (pixelSize == 0);
style->antialiased = antialiased;
QtFontSize *size = style->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
@@ -1132,7 +1138,8 @@ QString QFontDatabase::resolveFontFamilyAlias(const QString &family)
}
#endif
-static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey)
+static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &styleKey,
+ const QString &styleName = QString())
{
int best = 0;
int dist = 0xffff;
@@ -1140,7 +1147,7 @@ static QtFontStyle *bestStyle(QtFontFoundry *foundry, const QtFontStyle::Key &st
for ( int i = 0; i < foundry->count; i++ ) {
QtFontStyle *style = foundry->styles[i];
- if (!styleKey.styleName.isEmpty() && styleKey.styleName == style->key.styleName) {
+ if (!styleName.isEmpty() && styleName == style->styleName) {
dist = 0;
best = i;
break;
@@ -1797,16 +1804,16 @@ QStringList QFontDatabase::styles(const QString &family) const
for (int k = 0; k < foundry->count; k++) {
QtFontStyle::Key ke(foundry->styles[k]->key);
ke.stretch = 0;
- allStyles.style(ke, true);
+ allStyles.style(ke, foundry->styles[k]->styleName, true);
}
}
}
for (int i = 0; i < allStyles.count; i++) {
- l.append(allStyles.styles[i]->key.styleName.isEmpty() ?
+ l.append(allStyles.styles[i]->styleName.isEmpty() ?
styleStringHelper(allStyles.styles[i]->key.weight,
(QFont::Style)allStyles.styles[i]->key.style) :
- allStyles.styles[i]->key.styleName);
+ allStyles.styles[i]->styleName);
}
return l;
}
@@ -1865,7 +1872,9 @@ bool QFontDatabase::isBitmapScalable(const QString &family,
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- if ((style.isEmpty() || foundry->styles[k]->key == styleKey)
+ if ((style.isEmpty() ||
+ foundry->styles[k]->styleName == style ||
+ foundry->styles[k]->key == styleKey)
&& foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
bitmapScalable = true;
goto end;
@@ -1904,7 +1913,9 @@ bool QFontDatabase::isSmoothlyScalable(const QString &family, const QString &sty
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
+ if ((style.isEmpty() ||
+ foundry->styles[k]->styleName == style ||
+ foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
smoothScalable = true;
goto end;
}
@@ -1937,12 +1948,12 @@ bool QFontDatabase::isScalable(const QString &family,
\sa smoothSizes(), standardSizes()
*/
QList<int> QFontDatabase::pointSizes(const QString &family,
- const QString &style)
+ const QString &styleName)
{
#if defined(Q_WS_WIN)
// windows and macosx are always smoothly scalable
Q_UNUSED(family);
- Q_UNUSED(style);
+ Q_UNUSED(styleName);
return standardSizes();
#else
bool smoothScalable = false;
@@ -1953,7 +1964,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
QT_PREPEND_NAMESPACE(load)(familyName);
- QtFontStyle::Key styleKey(style);
+ QtFontStyle::Key styleKey(styleName);
QList<int> sizes;
@@ -1970,7 +1981,7 @@ QList<int> QFontDatabase::pointSizes(const QString &family,
for (int j = 0; j < fam->count; j++) {
QtFontFoundry *foundry = fam->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
- QtFontStyle *style = foundry->style(styleKey);
+ QtFontStyle *style = foundry->style(styleKey, styleName);
if (!style) continue;
if (style->smoothScalable) {
@@ -2021,25 +2032,21 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- allStyles.style(foundry->styles[k]->key, true);
+ allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
- QtFontStyle *s = bestStyle(&allStyles, styleKey);
+ QtFontStyle *s = bestStyle(&allStyles, styleKey, style);
if (!s) // no styles found?
return QGuiApplication::font();
- if (s->key.styleName.isEmpty()) {
- QFont fnt(family, pointSize, s->key.weight);
- fnt.setStyle((QFont::Style)s->key.style);
- return fnt;
- } else {
- // found a perfect match
- QFont fnt(family, pointSize);
- fnt.setStyleName(s->key.styleName);
- return fnt;
- }
+
+ QFont fnt(family, pointSize, s->key.weight);
+ fnt.setStyle((QFont::Style)s->key.style);
+ if (!s->styleName.isEmpty())
+ fnt.setStyleName(s->styleName);
+ return fnt;
}
@@ -2052,11 +2059,11 @@ QFont QFontDatabase::font(const QString &family, const QString &style,
\sa pointSizes(), standardSizes()
*/
QList<int> QFontDatabase::smoothSizes(const QString &family,
- const QString &style)
+ const QString &styleName)
{
#ifdef Q_WS_WIN
Q_UNUSED(family);
- Q_UNUSED(style);
+ Q_UNUSED(styleName);
return QFontDatabase::standardSizes();
#else
bool smoothScalable = false;
@@ -2067,7 +2074,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
QT_PREPEND_NAMESPACE(load)(familyName);
- QtFontStyle::Key styleKey(style);
+ QtFontStyle::Key styleKey(styleName);
QList<int> sizes;
@@ -2084,7 +2091,7 @@ QList<int> QFontDatabase::smoothSizes(const QString &family,
for (int j = 0; j < fam->count; j++) {
QtFontFoundry *foundry = fam->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
- QtFontStyle *style = foundry->style(styleKey);
+ QtFontStyle *style = foundry->style(styleKey, styleName);
if (!style) continue;
if (style->smoothScalable) {
@@ -2151,12 +2158,12 @@ bool QFontDatabase::italic(const QString &family, const QString &style) const
QtFontFoundry *foundry = f->foundries[j];
if (foundryName.isEmpty() || foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- allStyles.style(foundry->styles[k]->key, true);
+ allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
- QtFontStyle *s = allStyles.style(styleKey);
+ QtFontStyle *s = allStyles.style(styleKey, style);
return s && s->key.style == QFont::StyleItalic;
}
@@ -2186,12 +2193,12 @@ bool QFontDatabase::bold(const QString &family,
if (foundryName.isEmpty() ||
foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- allStyles.style(foundry->styles[k]->key, true);
+ allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
- QtFontStyle *s = allStyles.style(styleKey);
+ QtFontStyle *s = allStyles.style(styleKey, style);
return s && s->key.weight >= QFont::Bold;
}
@@ -2222,12 +2229,12 @@ int QFontDatabase::weight(const QString &family,
if (foundryName.isEmpty() ||
foundry->name.compare(foundryName, Qt::CaseInsensitive) == 0) {
for (int k = 0; k < foundry->count; k++)
- allStyles.style(foundry->styles[k]->key, true);
+ allStyles.style(foundry->styles[k]->key, foundry->styles[k]->styleName, true);
}
}
QtFontStyle::Key styleKey(style);
- QtFontStyle *s = allStyles.style(styleKey);
+ QtFontStyle *s = allStyles.style(styleKey, style);
return s ? s->key.weight : -1;
}
diff --git a/src/gui/text/qfontdatabase_qpa.cpp b/src/gui/text/qfontdatabase_qpa.cpp
index d2adf7c6b4..c0392e798b 100644
--- a/src/gui/text/qfontdatabase_qpa.cpp
+++ b/src/gui/text/qfontdatabase_qpa.cpp
@@ -73,7 +73,7 @@ Q_GUI_EXPORT void qt_registerFont(const QString &familyName, const QString &fou
}
QtFontFoundry *foundry = f->foundry(foundryname, true);
- QtFontStyle *fontStyle = foundry->style(styleKey, true);
+ QtFontStyle *fontStyle = foundry->style(styleKey, QString(), true);
fontStyle->smoothScalable = scalable;
fontStyle->antialiased = antialiased;
QtFontSize *size = fontStyle->pixelSize(pixelSize?pixelSize:SMOOTH_SCALABLE, true);
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index a488c13156..08b6e0bf14 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -2711,7 +2711,7 @@ void QTextHtmlExporter::emitBlock(const QTextBlock &block)
html += QLatin1Char('>');
if (block.begin().atEnd())
- html += "<br />";
+ html += QLatin1String("<br />");
QTextBlock::Iterator it = block.begin();
if (fragmentMarkers && !it.atEnd() && block == doc->begin())
diff --git a/src/network/access/qhttpnetworkconnectionchannel_p.h b/src/network/access/qhttpnetworkconnectionchannel_p.h
index 8400f62ab9..c159f1a0c5 100644
--- a/src/network/access/qhttpnetworkconnectionchannel_p.h
+++ b/src/network/access/qhttpnetworkconnectionchannel_p.h
@@ -163,8 +163,6 @@ public:
bool isSocketWaiting() const;
bool isSocketReading() const;
- friend class QNetworkAccessHttpBackend;
-
protected slots:
void _q_receiveReply();
void _q_bytesWritten(qint64 bytes); // proceed sending
diff --git a/src/network/access/qnetworkaccesshttpbackend.cpp b/src/network/access/qnetworkaccesshttpbackend.cpp
deleted file mode 100644
index 64a22aa0e8..0000000000
--- a/src/network/access/qnetworkaccesshttpbackend.cpp
+++ /dev/null
@@ -1,1189 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-//#define QNETWORKACCESSHTTPBACKEND_DEBUG
-
-#include "qnetworkaccesshttpbackend_p.h"
-#include "qnetworkaccessmanager_p.h"
-#include "qnetworkaccesscache_p.h"
-#include "qabstractnetworkcache.h"
-#include "qnetworkrequest.h"
-#include "qnetworkreply.h"
-#include "QtNetwork/private/qnetworksession_p.h"
-#include "qnetworkrequest_p.h"
-#include "qnetworkcookie_p.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qelapsedtimer.h"
-#include "QtNetwork/qsslconfiguration.h"
-#include "qhttpthreaddelegate_p.h"
-#include "qthread.h"
-
-#ifndef QT_NO_HTTP
-
-#include <string.h> // for strchr
-
-Q_DECLARE_METATYPE(QSharedPointer<char>)
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkProxy;
-
-static inline bool isSeparator(register char c)
-{
- static const char separators[] = "()<>@,;:\\\"/[]?={}";
- return isLWS(c) || strchr(separators, c) != 0;
-}
-
-// ### merge with nextField in cookiejar.cpp
-static QHash<QByteArray, QByteArray> parseHttpOptionHeader(const QByteArray &header)
-{
- // The HTTP header is of the form:
- // header = #1(directives)
- // directives = token | value-directive
- // value-directive = token "=" (token | quoted-string)
- QHash<QByteArray, QByteArray> result;
-
- int pos = 0;
- while (true) {
- // skip spaces
- pos = nextNonWhitespace(header, pos);
- if (pos == header.length())
- return result; // end of parsing
-
- // pos points to a non-whitespace
- int comma = header.indexOf(',', pos);
- int equal = header.indexOf('=', pos);
- if (comma == pos || equal == pos)
- // huh? Broken header.
- return result;
-
- // The key name is delimited by either a comma, an equal sign or the end
- // of the header, whichever comes first
- int end = comma;
- if (end == -1)
- end = header.length();
- if (equal != -1 && end > equal)
- end = equal; // equal sign comes before comma/end
- QByteArray key = QByteArray(header.constData() + pos, end - pos).trimmed().toLower();
- pos = end + 1;
-
- if (uint(equal) < uint(comma)) {
- // case: token "=" (token | quoted-string)
- // skip spaces
- pos = nextNonWhitespace(header, pos);
- if (pos == header.length())
- // huh? Broken header
- return result;
-
- QByteArray value;
- value.reserve(header.length() - pos);
- if (header.at(pos) == '"') {
- // case: quoted-string
- // quoted-string = ( <"> *(qdtext | quoted-pair ) <"> )
- // qdtext = <any TEXT except <">>
- // quoted-pair = "\" CHAR
- ++pos;
- while (pos < header.length()) {
- register char c = header.at(pos);
- if (c == '"') {
- // end of quoted text
- break;
- } else if (c == '\\') {
- ++pos;
- if (pos >= header.length())
- // broken header
- return result;
- c = header.at(pos);
- }
-
- value += c;
- ++pos;
- }
- } else {
- // case: token
- while (pos < header.length()) {
- register char c = header.at(pos);
- if (isSeparator(c))
- break;
- value += c;
- ++pos;
- }
- }
-
- result.insert(key, value);
-
- // find the comma now:
- comma = header.indexOf(',', pos);
- if (comma == -1)
- return result; // end of parsing
- pos = comma + 1;
- } else {
- // case: token
- // key is already set
- result.insert(key, QByteArray());
- }
- }
-}
-
-QNetworkAccessBackend *
-QNetworkAccessHttpBackendFactory::create(QNetworkAccessManager::Operation op,
- const QNetworkRequest &request) const
-{
- // check the operation
- switch (op) {
- case QNetworkAccessManager::GetOperation:
- case QNetworkAccessManager::PostOperation:
- case QNetworkAccessManager::HeadOperation:
- case QNetworkAccessManager::PutOperation:
- case QNetworkAccessManager::DeleteOperation:
- case QNetworkAccessManager::CustomOperation:
- break;
-
- default:
- // no, we can't handle this request
- return 0;
- }
-
- QUrl url = request.url();
- QString scheme = url.scheme().toLower();
- if (scheme == QLatin1String("http") || scheme == QLatin1String("https"))
- return new QNetworkAccessHttpBackend;
-
- return 0;
-}
-
-QNetworkAccessHttpBackend::QNetworkAccessHttpBackend()
- : QNetworkAccessBackend()
- , statusCode(0)
- , pendingDownloadDataEmissions(new QAtomicInt())
- , pendingDownloadProgressEmissions(new QAtomicInt())
- , loadingFromCache(false)
- , usingZerocopyDownloadBuffer(false)
-#ifndef QT_NO_OPENSSL
- , pendingSslConfiguration(0), pendingIgnoreAllSslErrors(false)
-#endif
- , resumeOffset(0)
-{
-}
-
-QNetworkAccessHttpBackend::~QNetworkAccessHttpBackend()
-{
- // This will do nothing if the request was already finished or aborted
- emit abortHttpRequest();
-
-#ifndef QT_NO_OPENSSL
- delete pendingSslConfiguration;
-#endif
-}
-
-/*
- For a given httpRequest
- 1) If AlwaysNetwork, return
- 2) If we have a cache entry for this url populate headers so the server can return 304
- 3) Calculate if response_is_fresh and if so send the cache and set loadedFromCache to true
- */
-bool QNetworkAccessHttpBackend::loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest)
-{
- QNetworkRequest::CacheLoadControl CacheLoadControlAttribute =
- (QNetworkRequest::CacheLoadControl)request().attribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork).toInt();
- if (CacheLoadControlAttribute == QNetworkRequest::AlwaysNetwork) {
- // If the request does not already specify preferred cache-control
- // force reload from the network and tell any caching proxy servers to reload too
- if (!request().rawHeaderList().contains("Cache-Control")) {
- httpRequest.setHeaderField("Cache-Control", "no-cache");
- httpRequest.setHeaderField("Pragma", "no-cache");
- }
- return false;
- }
-
- // The disk cache API does not currently support partial content retrieval.
- // That is why we don't use the disk cache for any such requests.
- if (request().hasRawHeader("Range"))
- return false;
-
- QAbstractNetworkCache *nc = networkCache();
- if (!nc)
- return false; // no local cache
-
- QNetworkCacheMetaData metaData = nc->metaData(url());
- if (!metaData.isValid())
- return false; // not in cache
-
- if (!metaData.saveToDisk())
- return false;
-
- QNetworkHeadersPrivate cacheHeaders;
- QNetworkHeadersPrivate::RawHeadersList::ConstIterator it;
- cacheHeaders.setAllRawHeaders(metaData.rawHeaders());
-
- it = cacheHeaders.findRawHeader("etag");
- if (it != cacheHeaders.rawHeaders.constEnd())
- httpRequest.setHeaderField("If-None-Match", it->second);
-
- QDateTime lastModified = metaData.lastModified();
- if (lastModified.isValid())
- httpRequest.setHeaderField("If-Modified-Since", QNetworkHeadersPrivate::toHttpDate(lastModified));
-
- it = cacheHeaders.findRawHeader("Cache-Control");
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second);
- if (cacheControl.contains("must-revalidate"))
- return false;
- }
-
- QDateTime currentDateTime = QDateTime::currentDateTime();
- QDateTime expirationDate = metaData.expirationDate();
-
-#if 0
- /*
- * age_value
- * is the value of Age: header received by the cache with
- * this response.
- * date_value
- * is the value of the origin server's Date: header
- * request_time
- * is the (local) time when the cache made the request
- * that resulted in this cached response
- * response_time
- * is the (local) time when the cache received the
- * response
- * now
- * is the current (local) time
- */
- int age_value = 0;
- it = cacheHeaders.findRawHeader("age");
- if (it != cacheHeaders.rawHeaders.constEnd())
- age_value = it->second.toInt();
-
- QDateTime dateHeader;
- int date_value = 0;
- it = cacheHeaders.findRawHeader("date");
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- dateHeader = QNetworkHeadersPrivate::fromHttpDate(it->second);
- date_value = dateHeader.toTime_t();
- }
-
- int now = currentDateTime.toUTC().toTime_t();
- int request_time = now;
- int response_time = now;
-
- // Algorithm from RFC 2616 section 13.2.3
- int apparent_age = qMax(0, response_time - date_value);
- int corrected_received_age = qMax(apparent_age, age_value);
- int response_delay = response_time - request_time;
- int corrected_initial_age = corrected_received_age + response_delay;
- int resident_time = now - response_time;
- int current_age = corrected_initial_age + resident_time;
-
- // RFC 2616 13.2.4 Expiration Calculations
- if (!expirationDate.isValid()) {
- if (lastModified.isValid()) {
- int diff = currentDateTime.secsTo(lastModified);
- expirationDate = lastModified;
- expirationDate.addSecs(diff / 10);
- if (httpRequest.headerField("Warning").isEmpty()) {
- QDateTime dt;
- dt.setTime_t(current_age);
- if (dt.daysTo(currentDateTime) > 1)
- httpRequest.setHeaderField("Warning", "113");
- }
- }
- }
-
- // the cache-saving code below sets the expirationDate with date+max_age
- // if "max-age" is present, or to Expires otherwise
- int freshness_lifetime = dateHeader.secsTo(expirationDate);
- bool response_is_fresh = (freshness_lifetime > current_age);
-#else
- bool response_is_fresh = currentDateTime.secsTo(expirationDate) >= 0;
-#endif
-
- if (!response_is_fresh)
- return false;
-
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "response_is_fresh" << CacheLoadControlAttribute;
-#endif
- return sendCacheContents(metaData);
-}
-
-static QHttpNetworkRequest::Priority convert(const QNetworkRequest::Priority& prio)
-{
- switch (prio) {
- case QNetworkRequest::LowPriority:
- return QHttpNetworkRequest::LowPriority;
- case QNetworkRequest::HighPriority:
- return QHttpNetworkRequest::HighPriority;
- case QNetworkRequest::NormalPriority:
- default:
- return QHttpNetworkRequest::NormalPriority;
- }
-}
-
-void QNetworkAccessHttpBackend::postRequest()
-{
- QThread *thread = 0;
- if (isSynchronous()) {
- // A synchronous HTTP request uses its own thread
- thread = new QThread();
- QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
- thread->start();
- } else if (!manager->httpThread) {
- // We use the manager-global thread.
- // At some point we could switch to having multiple threads if it makes sense.
- manager->httpThread = new QThread();
- QObject::connect(manager->httpThread, SIGNAL(finished()), manager->httpThread, SLOT(deleteLater()));
- manager->httpThread->start();
-#ifndef QT_NO_NETWORKPROXY
- qRegisterMetaType<QNetworkProxy>("QNetworkProxy");
-#endif
-#ifndef QT_NO_OPENSSL
- qRegisterMetaType<QList<QSslError> >("QList<QSslError>");
- qRegisterMetaType<QSslConfiguration>("QSslConfiguration");
-#endif
- qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >("QList<QPair<QByteArray,QByteArray> >");
- qRegisterMetaType<QHttpNetworkRequest>("QHttpNetworkRequest");
- qRegisterMetaType<QNetworkReply::NetworkError>("QNetworkReply::NetworkError");
- qRegisterMetaType<QSharedPointer<char> >("QSharedPointer<char>");
-
- thread = manager->httpThread;
- } else {
- // Asynchronous request, thread already exists
- thread = manager->httpThread;
- }
-
- QUrl url = request().url();
- httpRequest.setUrl(url);
-
- bool ssl = url.scheme().toLower() == QLatin1String("https");
- setAttribute(QNetworkRequest::ConnectionEncryptedAttribute, ssl);
- httpRequest.setSsl(ssl);
-
-
-#ifndef QT_NO_NETWORKPROXY
- QNetworkProxy transparentProxy, cacheProxy;
-
- foreach (const QNetworkProxy &p, proxyList()) {
- // use the first proxy that works
- // for non-encrypted connections, any transparent or HTTP proxy
- // for encrypted, only transparent proxies
- if (!ssl
- && (p.capabilities() & QNetworkProxy::CachingCapability)
- && (p.type() == QNetworkProxy::HttpProxy ||
- p.type() == QNetworkProxy::HttpCachingProxy)) {
- cacheProxy = p;
- transparentProxy = QNetworkProxy::NoProxy;
- break;
- }
- if (p.isTransparentProxy()) {
- transparentProxy = p;
- cacheProxy = QNetworkProxy::NoProxy;
- break;
- }
- }
-
- // check if at least one of the proxies
- if (transparentProxy.type() == QNetworkProxy::DefaultProxy &&
- cacheProxy.type() == QNetworkProxy::DefaultProxy) {
- // unsuitable proxies
- QMetaObject::invokeMethod(this, "error", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection,
- Q_ARG(QNetworkReply::NetworkError, QNetworkReply::ProxyNotFoundError),
- Q_ARG(QString, tr("No suitable proxy found")));
- QMetaObject::invokeMethod(this, "finished", isSynchronous() ? Qt::DirectConnection : Qt::QueuedConnection);
- return;
- }
-#endif
-
-
- bool loadedFromCache = false;
- httpRequest.setPriority(convert(request().priority()));
-
- switch (operation()) {
- case QNetworkAccessManager::GetOperation:
- httpRequest.setOperation(QHttpNetworkRequest::Get);
- loadedFromCache = loadFromCacheIfAllowed(httpRequest);
- break;
-
- case QNetworkAccessManager::HeadOperation:
- httpRequest.setOperation(QHttpNetworkRequest::Head);
- loadedFromCache = loadFromCacheIfAllowed(httpRequest);
- break;
-
- case QNetworkAccessManager::PostOperation:
- invalidateCache();
- httpRequest.setOperation(QHttpNetworkRequest::Post);
- createUploadByteDevice();
- break;
-
- case QNetworkAccessManager::PutOperation:
- invalidateCache();
- httpRequest.setOperation(QHttpNetworkRequest::Put);
- createUploadByteDevice();
- break;
-
- case QNetworkAccessManager::DeleteOperation:
- invalidateCache();
- httpRequest.setOperation(QHttpNetworkRequest::Delete);
- break;
-
- case QNetworkAccessManager::CustomOperation:
- invalidateCache(); // for safety reasons, we don't know what the operation does
- httpRequest.setOperation(QHttpNetworkRequest::Custom);
- createUploadByteDevice();
- httpRequest.setCustomVerb(request().attribute(
- QNetworkRequest::CustomVerbAttribute).toByteArray());
- break;
-
- default:
- break; // can't happen
- }
-
- if (loadedFromCache) {
- // commented this out since it will be called later anyway
- // by copyFinished()
- //QNetworkAccessBackend::finished();
- return; // no need to send the request! :)
- }
-
- QList<QByteArray> headers = request().rawHeaderList();
- if (resumeOffset != 0) {
- if (headers.contains("Range")) {
- // Need to adjust resume offset for user specified range
-
- headers.removeOne("Range");
-
- // We've already verified that requestRange starts with "bytes=", see canResume.
- QByteArray requestRange = request().rawHeader("Range").mid(6);
-
- int index = requestRange.indexOf('-');
-
- quint64 requestStartOffset = requestRange.left(index).toULongLong();
- quint64 requestEndOffset = requestRange.mid(index + 1).toULongLong();
-
- requestRange = "bytes=" + QByteArray::number(resumeOffset + requestStartOffset) +
- '-' + QByteArray::number(requestEndOffset);
-
- httpRequest.setHeaderField("Range", requestRange);
- } else {
- httpRequest.setHeaderField("Range", "bytes=" + QByteArray::number(resumeOffset) + '-');
- }
- }
-
- foreach (const QByteArray &header, headers)
- httpRequest.setHeaderField(header, request().rawHeader(header));
-
- if (request().attribute(QNetworkRequest::HttpPipeliningAllowedAttribute).toBool() == true)
- httpRequest.setPipeliningAllowed(true);
-
- if (static_cast<QNetworkRequest::LoadControl>
- (request().attribute(QNetworkRequest::AuthenticationReuseAttribute,
- QNetworkRequest::Automatic).toInt()) == QNetworkRequest::Manual)
- httpRequest.setWithCredentials(false);
-
-
- // Create the HTTP thread delegate
- QHttpThreadDelegate *delegate = new QHttpThreadDelegate;
-#ifndef Q_NO_BEARERMANAGEMENT
- QVariant v(property("_q_networksession"));
- if (v.isValid())
- delegate->networkSession = qvariant_cast<QSharedPointer<QNetworkSession> >(v);
-#endif
-
- // For the synchronous HTTP, this is the normal way the delegate gets deleted
- // For the asynchronous HTTP this is a safety measure, the delegate deletes itself when HTTP is finished
- connect(thread, SIGNAL(finished()), delegate, SLOT(deleteLater()));
-
- // Set the properties it needs
- delegate->httpRequest = httpRequest;
-#ifndef QT_NO_NETWORKPROXY
- delegate->cacheProxy = cacheProxy;
- delegate->transparentProxy = transparentProxy;
-#endif
- delegate->ssl = ssl;
-#ifndef QT_NO_OPENSSL
- if (ssl)
- delegate->incomingSslConfiguration = request().sslConfiguration();
-#endif
-
- // Do we use synchronous HTTP?
- delegate->synchronous = isSynchronous();
-
- // The authentication manager is used to avoid the BlockingQueuedConnection communication
- // from HTTP thread to user thread in some cases.
- delegate->authenticationManager = manager->authenticationManager;
-
- if (!isSynchronous()) {
- // Tell our zerocopy policy to the delegate
- delegate->downloadBufferMaximumSize =
- request().attribute(QNetworkRequest::MaximumDownloadBufferSizeAttribute).toLongLong();
-
- // These atomic integers are used for signal compression
- delegate->pendingDownloadData = pendingDownloadDataEmissions;
- delegate->pendingDownloadProgress = pendingDownloadProgressEmissions;
-
- // Connect the signals of the delegate to us
- connect(delegate, SIGNAL(downloadData(QByteArray)),
- this, SLOT(replyDownloadData(QByteArray)),
- Qt::QueuedConnection);
- connect(delegate, SIGNAL(downloadFinished()),
- this, SLOT(replyFinished()),
- Qt::QueuedConnection);
- connect(delegate, SIGNAL(downloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)),
- this, SLOT(replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64)),
- Qt::QueuedConnection);
- connect(delegate, SIGNAL(downloadProgress(qint64,qint64)),
- this, SLOT(replyDownloadProgressSlot(qint64,qint64)),
- Qt::QueuedConnection);
- connect(delegate, SIGNAL(error(QNetworkReply::NetworkError,QString)),
- this, SLOT(httpError(QNetworkReply::NetworkError, const QString)),
- Qt::QueuedConnection);
-#ifndef QT_NO_OPENSSL
- connect(delegate, SIGNAL(sslConfigurationChanged(QSslConfiguration)),
- this, SLOT(replySslConfigurationChanged(QSslConfiguration)),
- Qt::QueuedConnection);
-#endif
- // Those need to report back, therefire BlockingQueuedConnection
- connect(delegate, SIGNAL(authenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
- this, SLOT(httpAuthenticationRequired(QHttpNetworkRequest,QAuthenticator*)),
- Qt::BlockingQueuedConnection);
-#ifndef QT_NO_NETWORKPROXY
- connect (delegate, SIGNAL(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
- this, SLOT(proxyAuthenticationRequired(QNetworkProxy,QAuthenticator*)),
- Qt::BlockingQueuedConnection);
-#endif
-#ifndef QT_NO_OPENSSL
- connect(delegate, SIGNAL(sslErrors(QList<QSslError>,bool*,QList<QSslError>*)),
- this, SLOT(replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *)),
- Qt::BlockingQueuedConnection);
-#endif
- // This signal we will use to start the request.
- connect(this, SIGNAL(startHttpRequest()), delegate, SLOT(startRequest()));
- connect(this, SIGNAL(abortHttpRequest()), delegate, SLOT(abortRequest()));
-
- if (uploadByteDevice) {
- QNonContiguousByteDeviceThreadForwardImpl *forwardUploadDevice =
- new QNonContiguousByteDeviceThreadForwardImpl(uploadByteDevice->atEnd(), uploadByteDevice->size());
- if (uploadByteDevice->isResetDisabled())
- forwardUploadDevice->disableReset();
- forwardUploadDevice->setParent(delegate); // needed to make sure it is moved on moveToThread()
- delegate->httpRequest.setUploadByteDevice(forwardUploadDevice);
-
- // From main thread to user thread:
- QObject::connect(this, SIGNAL(haveUploadData(QByteArray, bool, qint64)),
- forwardUploadDevice, SLOT(haveDataSlot(QByteArray, bool, qint64)), Qt::QueuedConnection);
- QObject::connect(uploadByteDevice.data(), SIGNAL(readyRead()),
- forwardUploadDevice, SIGNAL(readyRead()),
- Qt::QueuedConnection);
-
- // From http thread to user thread:
- QObject::connect(forwardUploadDevice, SIGNAL(wantData(qint64)),
- this, SLOT(wantUploadDataSlot(qint64)));
- QObject::connect(forwardUploadDevice, SIGNAL(processedData(qint64)),
- this, SLOT(sentUploadDataSlot(qint64)));
- connect(forwardUploadDevice, SIGNAL(resetData(bool*)),
- this, SLOT(resetUploadDataSlot(bool*)),
- Qt::BlockingQueuedConnection); // this is the only one with BlockingQueued!
- }
- } else if (isSynchronous()) {
- connect(this, SIGNAL(startHttpRequestSynchronously()), delegate, SLOT(startRequestSynchronously()), Qt::BlockingQueuedConnection);
-
- if (uploadByteDevice) {
- // For the synchronous HTTP use case the use thread (this one here) is blocked
- // so we cannot use the asynchronous upload architecture.
- // We therefore won't use the QNonContiguousByteDeviceThreadForwardImpl but directly
- // use the uploadByteDevice provided to us by the QNetworkReplyImpl.
- // The code that is in QNetworkReplyImplPrivate::setup() makes sure it is safe to use from a thread
- // since it only wraps a QRingBuffer
- delegate->httpRequest.setUploadByteDevice(uploadByteDevice.data());
- }
- }
-
-
- // Move the delegate to the http thread
- delegate->moveToThread(thread);
- // This call automatically moves the uploadDevice too for the asynchronous case.
-
- // Send an signal to the delegate so it starts working in the other thread
- if (isSynchronous()) {
- emit startHttpRequestSynchronously(); // This one is BlockingQueuedConnection, so it will return when all work is done
-
- if (delegate->incomingErrorCode != QNetworkReply::NoError) {
- replyDownloadMetaData
- (delegate->incomingHeaders,
- delegate->incomingStatusCode,
- delegate->incomingReasonPhrase,
- delegate->isPipeliningUsed,
- QSharedPointer<char>(),
- delegate->incomingContentLength);
- httpError(delegate->incomingErrorCode, delegate->incomingErrorDetail);
- } else {
- replyDownloadMetaData
- (delegate->incomingHeaders,
- delegate->incomingStatusCode,
- delegate->incomingReasonPhrase,
- delegate->isPipeliningUsed,
- QSharedPointer<char>(),
- delegate->incomingContentLength);
- replyDownloadData(delegate->synchronousDownloadData);
- }
-
- // End the thread. It will delete itself from the finished() signal
- thread->quit();
-
- finished();
- } else {
- emit startHttpRequest(); // Signal to the HTTP thread and go back to user.
- }
-}
-
-void QNetworkAccessHttpBackend::invalidateCache()
-{
- QAbstractNetworkCache *nc = networkCache();
- if (nc)
- nc->remove(url());
-}
-
-void QNetworkAccessHttpBackend::open()
-{
- postRequest();
-}
-
-void QNetworkAccessHttpBackend::closeDownstreamChannel()
-{
- // FIXME Maybe we can get rid of this whole architecture part
-}
-
-void QNetworkAccessHttpBackend::downstreamReadyWrite()
-{
- // FIXME Maybe we can get rid of this whole architecture part
-}
-
-void QNetworkAccessHttpBackend::setDownstreamLimited(bool b)
-{
- Q_UNUSED(b);
- // We know that readBuffer maximum size limiting is broken since quite a while.
- // The task to fix this is QTBUG-15065
-}
-
-void QNetworkAccessHttpBackend::replyDownloadData(QByteArray d)
-{
- int pendingSignals = (int)pendingDownloadDataEmissions->fetchAndAddAcquire(-1) - 1;
-
- if (pendingSignals > 0) {
- // Some more signal emissions to this slot are pending.
- // Instead of writing the downstream data, we wait
- // and do it in the next call we get
- // (signal comppression)
- pendingDownloadData.append(d);
- return;
- }
-
- pendingDownloadData.append(d);
- d.clear();
- // We need to usa a copy for calling writeDownstreamData as we could
- // possibly recurse into this this function when we call
- // appendDownstreamDataSignalEmissions because the user might call
- // processEvents() or spin an event loop when this occur.
- QByteDataBuffer pendingDownloadDataCopy = pendingDownloadData;
- pendingDownloadData.clear();
- writeDownstreamData(pendingDownloadDataCopy);
-}
-
-void QNetworkAccessHttpBackend::replyFinished()
-{
- // We are already loading from cache, we still however
- // got this signal because it was posted already
- if (loadingFromCache)
- return;
-
- finished();
-}
-
-void QNetworkAccessHttpBackend::checkForRedirect(const int statusCode)
-{
- switch (statusCode) {
- case 301: // Moved Permanently
- case 302: // Found
- case 303: // See Other
- case 307: // Temporary Redirect
- // What do we do about the caching of the HTML note?
- // The response to a 303 MUST NOT be cached, while the response to
- // all of the others is cacheable if the headers indicate it to be
- QByteArray header = rawHeader("location");
- QUrl url = QUrl::fromEncoded(header);
- if (!url.isValid())
- url = QUrl(QLatin1String(header));
- redirectionRequested(url);
- }
-}
-
-void QNetworkAccessHttpBackend::replyDownloadMetaData
- (QList<QPair<QByteArray,QByteArray> > hm,
- int sc,QString rp,bool pu,
- QSharedPointer<char> db,
- qint64 contentLength)
-{
- statusCode = sc;
- reasonPhrase = rp;
-
- // Download buffer
- if (!db.isNull()) {
- reply->setDownloadBuffer(db, contentLength);
- usingZerocopyDownloadBuffer = true;
- } else {
- usingZerocopyDownloadBuffer = false;
- }
-
- setAttribute(QNetworkRequest::HttpPipeliningWasUsedAttribute, pu);
-
- // reconstruct the HTTP header
- QList<QPair<QByteArray, QByteArray> > headerMap = hm;
- QList<QPair<QByteArray, QByteArray> >::ConstIterator it = headerMap.constBegin(),
- end = headerMap.constEnd();
- QByteArray header;
-
- for (; it != end; ++it) {
- QByteArray value = rawHeader(it->first);
- if (!value.isEmpty()) {
- if (qstricmp(it->first.constData(), "set-cookie") == 0)
- value += '\n';
- else
- value += ", ";
- }
- value += it->second;
- setRawHeader(it->first, value);
- }
-
- setAttribute(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
- setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, reasonPhrase);
-
- // is it a redirection?
- checkForRedirect(statusCode);
-
- if (statusCode >= 500 && statusCode < 600) {
- QAbstractNetworkCache *nc = networkCache();
- if (nc) {
- QNetworkCacheMetaData metaData = nc->metaData(url());
- QNetworkHeadersPrivate cacheHeaders;
- cacheHeaders.setAllRawHeaders(metaData.rawHeaders());
- QNetworkHeadersPrivate::RawHeadersList::ConstIterator it;
- it = cacheHeaders.findRawHeader("Cache-Control");
- bool mustReValidate = false;
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- QHash<QByteArray, QByteArray> cacheControl = parseHttpOptionHeader(it->second);
- if (cacheControl.contains("must-revalidate"))
- mustReValidate = true;
- }
- if (!mustReValidate && sendCacheContents(metaData))
- return;
- }
- }
-
- if (statusCode == 304) {
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "Received a 304 from" << url();
-#endif
- QAbstractNetworkCache *nc = networkCache();
- if (nc) {
- QNetworkCacheMetaData oldMetaData = nc->metaData(url());
- QNetworkCacheMetaData metaData = fetchCacheMetaData(oldMetaData);
- if (oldMetaData != metaData)
- nc->updateMetaData(metaData);
- if (sendCacheContents(metaData))
- return;
- }
- }
-
-
- if (statusCode != 304 && statusCode != 303) {
- if (!isCachingEnabled())
- setCachingEnabled(true);
- }
-
- metaDataChanged();
-}
-
-void QNetworkAccessHttpBackend::replyDownloadProgressSlot(qint64 received, qint64 total)
-{
- // we can be sure here that there is a download buffer
-
- int pendingSignals = (int)pendingDownloadProgressEmissions->fetchAndAddAcquire(-1) - 1;
- if (pendingSignals > 0) {
- // Let's ignore this signal and look at the next one coming in
- // (signal comppression)
- return;
- }
-
- // Now do the actual notification of new bytes
- writeDownstreamDataDownloadBuffer(received, total);
-}
-
-void QNetworkAccessHttpBackend::httpAuthenticationRequired(const QHttpNetworkRequest &,
- QAuthenticator *auth)
-{
- authenticationRequired(auth);
-}
-
-void QNetworkAccessHttpBackend::httpError(QNetworkReply::NetworkError errorCode,
- const QString &errorString)
-{
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "http error!" << errorCode << errorString;
-#endif
-
- error(errorCode, errorString);
-}
-
-#ifndef QT_NO_OPENSSL
-void QNetworkAccessHttpBackend::replySslErrors(
- const QList<QSslError> &list, bool *ignoreAll, QList<QSslError> *toBeIgnored)
-{
- // Go to generic backend
- sslErrors(list);
- // Check if the callback set any ignore and return this here to http thread
- if (pendingIgnoreAllSslErrors)
- *ignoreAll = true;
- if (!pendingIgnoreSslErrorsList.isEmpty())
- *toBeIgnored = pendingIgnoreSslErrorsList;
-}
-
-void QNetworkAccessHttpBackend::replySslConfigurationChanged(const QSslConfiguration &c)
-{
- // Receiving the used SSL configuration from the HTTP thread
- if (pendingSslConfiguration)
- *pendingSslConfiguration = c;
- else if (!c.isNull())
- pendingSslConfiguration = new QSslConfiguration(c);
-}
-#endif
-
-// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
-void QNetworkAccessHttpBackend::resetUploadDataSlot(bool *r)
-{
- *r = uploadByteDevice->reset();
-}
-
-// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
-void QNetworkAccessHttpBackend::sentUploadDataSlot(qint64 amount)
-{
- uploadByteDevice->advanceReadPointer(amount);
-}
-
-// Coming from QNonContiguousByteDeviceThreadForwardImpl in HTTP thread
-void QNetworkAccessHttpBackend::wantUploadDataSlot(qint64 maxSize)
-{
- // call readPointer
- qint64 currentUploadDataLength = 0;
- char *data = const_cast<char*>(uploadByteDevice->readPointer(maxSize, currentUploadDataLength));
- // Let's make a copy of this data
- QByteArray dataArray(data, currentUploadDataLength);
-
- // Communicate back to HTTP thread
- emit haveUploadData(dataArray, uploadByteDevice->atEnd(), uploadByteDevice->size());
-}
-
-/*
- A simple web page that can be used to test us: http://www.procata.com/cachetest/
- */
-bool QNetworkAccessHttpBackend::sendCacheContents(const QNetworkCacheMetaData &metaData)
-{
- setCachingEnabled(false);
- if (!metaData.isValid())
- return false;
-
- QAbstractNetworkCache *nc = networkCache();
- Q_ASSERT(nc);
- QIODevice *contents = nc->data(url());
- if (!contents) {
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "Can not send cache, the contents are 0" << url();
-#endif
- return false;
- }
- contents->setParent(this);
-
- QNetworkCacheMetaData::AttributesMap attributes = metaData.attributes();
- int status = attributes.value(QNetworkRequest::HttpStatusCodeAttribute).toInt();
- if (status < 100)
- status = 200; // fake it
-
- setAttribute(QNetworkRequest::HttpStatusCodeAttribute, status);
- setAttribute(QNetworkRequest::HttpReasonPhraseAttribute, attributes.value(QNetworkRequest::HttpReasonPhraseAttribute));
- setAttribute(QNetworkRequest::SourceIsFromCacheAttribute, true);
-
- QNetworkCacheMetaData::RawHeaderList rawHeaders = metaData.rawHeaders();
- QNetworkCacheMetaData::RawHeaderList::ConstIterator it = rawHeaders.constBegin(),
- end = rawHeaders.constEnd();
- for ( ; it != end; ++it)
- setRawHeader(it->first, it->second);
-
- checkForRedirect(status);
-
- // This needs to be emitted in the event loop because it can be reached at
- // the direct code path of qnam.get(...) before the user has a chance
- // to connect any signals.
- QMetaObject::invokeMethod(this, "metaDataChanged", Qt::QueuedConnection);
- qRegisterMetaType<QIODevice*>("QIODevice*");
- QMetaObject::invokeMethod(this, "writeDownstreamData", Qt::QueuedConnection, Q_ARG(QIODevice*, contents));
-
-
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- qDebug() << "Successfully sent cache:" << url() << contents->size() << "bytes";
-#endif
-
- // Set the following flag so we can ignore some signals from HTTP thread
- // that would still come
- loadingFromCache = true;
- return true;
-}
-
-void QNetworkAccessHttpBackend::copyFinished(QIODevice *dev)
-{
- delete dev;
- finished();
-}
-
-#ifndef QT_NO_OPENSSL
-void QNetworkAccessHttpBackend::ignoreSslErrors()
-{
- pendingIgnoreAllSslErrors = true;
-}
-
-void QNetworkAccessHttpBackend::ignoreSslErrors(const QList<QSslError> &errors)
-{
- // the pending list is set if QNetworkReply::ignoreSslErrors(const QList<QSslError> &errors)
- // is called before QNetworkAccessManager::get() (or post(), etc.)
- pendingIgnoreSslErrorsList = errors;
-}
-
-void QNetworkAccessHttpBackend::fetchSslConfiguration(QSslConfiguration &config) const
-{
- if (pendingSslConfiguration)
- config = *pendingSslConfiguration;
- else
- config = request().sslConfiguration();
-}
-
-void QNetworkAccessHttpBackend::setSslConfiguration(const QSslConfiguration &newconfig)
-{
- // Setting a SSL configuration on a reply is not supported. The user needs to set
- // her/his QSslConfiguration on the QNetworkRequest.
- Q_UNUSED(newconfig);
-}
-#endif
-
-QNetworkCacheMetaData QNetworkAccessHttpBackend::fetchCacheMetaData(const QNetworkCacheMetaData &oldMetaData) const
-{
- QNetworkCacheMetaData metaData = oldMetaData;
-
- QNetworkHeadersPrivate cacheHeaders;
- cacheHeaders.setAllRawHeaders(metaData.rawHeaders());
- QNetworkHeadersPrivate::RawHeadersList::ConstIterator it;
-
- QList<QByteArray> newHeaders = rawHeaderList();
- foreach (QByteArray header, newHeaders) {
- QByteArray originalHeader = header;
- header = header.toLower();
- bool hop_by_hop =
- (header == "connection"
- || header == "keep-alive"
- || header == "proxy-authenticate"
- || header == "proxy-authorization"
- || header == "te"
- || header == "trailers"
- || header == "transfer-encoding"
- || header == "upgrade");
- if (hop_by_hop)
- continue;
-
- // we are currently not using the date header to determine the expiration time of a page,
- // but only the "Expires", "max-age" and "s-maxage" headers, see
- // QNetworkAccessHttpBackend::validateCache() and below ("metaData.setExpirationDate()").
- if (header == "date")
- continue;
-
- // Don't store Warning 1xx headers
- if (header == "warning") {
- QByteArray v = rawHeader(header);
- if (v.length() == 3
- && v[0] == '1'
- && v[1] >= '0' && v[1] <= '9'
- && v[2] >= '0' && v[2] <= '9')
- continue;
- }
-
- it = cacheHeaders.findRawHeader(header);
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- // Match the behavior of Firefox and assume Cache-Control: "no-transform"
- if (header == "content-encoding"
- || header == "content-range"
- || header == "content-type")
- continue;
-
- // For MS servers that send "Content-Length: 0" on 304 responses
- // ignore this too
- if (header == "content-length")
- continue;
- }
-
-#if defined(QNETWORKACCESSHTTPBACKEND_DEBUG)
- QByteArray n = rawHeader(header);
- QByteArray o;
- if (it != cacheHeaders.rawHeaders.constEnd())
- o = (*it).second;
- if (n != o && header != "date") {
- qDebug() << "replacing" << header;
- qDebug() << "new" << n;
- qDebug() << "old" << o;
- }
-#endif
- cacheHeaders.setRawHeader(originalHeader, rawHeader(header));
- }
- metaData.setRawHeaders(cacheHeaders.rawHeaders);
-
- bool checkExpired = true;
-
- QHash<QByteArray, QByteArray> cacheControl;
- it = cacheHeaders.findRawHeader("Cache-Control");
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- cacheControl = parseHttpOptionHeader(it->second);
- QByteArray maxAge = cacheControl.value("max-age");
- if (!maxAge.isEmpty()) {
- checkExpired = false;
- QDateTime dt = QDateTime::currentDateTime();
- dt = dt.addSecs(maxAge.toInt());
- metaData.setExpirationDate(dt);
- }
- }
- if (checkExpired) {
- it = cacheHeaders.findRawHeader("expires");
- if (it != cacheHeaders.rawHeaders.constEnd()) {
- QDateTime expiredDateTime = QNetworkHeadersPrivate::fromHttpDate(it->second);
- metaData.setExpirationDate(expiredDateTime);
- }
- }
-
- it = cacheHeaders.findRawHeader("last-modified");
- if (it != cacheHeaders.rawHeaders.constEnd())
- metaData.setLastModified(QNetworkHeadersPrivate::fromHttpDate(it->second));
-
- bool canDiskCache;
- // only cache GET replies by default, all other replies (POST, PUT, DELETE)
- // are not cacheable by default (according to RFC 2616 section 9)
- if (httpRequest.operation() == QHttpNetworkRequest::Get) {
-
- canDiskCache = true;
- // 14.32
- // HTTP/1.1 caches SHOULD treat "Pragma: no-cache" as if the client
- // had sent "Cache-Control: no-cache".
- it = cacheHeaders.findRawHeader("pragma");
- if (it != cacheHeaders.rawHeaders.constEnd()
- && it->second == "no-cache")
- canDiskCache = false;
-
- // HTTP/1.1. Check the Cache-Control header
- if (cacheControl.contains("no-cache"))
- canDiskCache = false;
- else if (cacheControl.contains("no-store"))
- canDiskCache = false;
-
- // responses to POST might be cacheable
- } else if (httpRequest.operation() == QHttpNetworkRequest::Post) {
-
- canDiskCache = false;
- // some pages contain "expires:" and "cache-control: no-cache" field,
- // so we only might cache POST requests if we get "cache-control: max-age ..."
- if (cacheControl.contains("max-age"))
- canDiskCache = true;
-
- // responses to PUT and DELETE are not cacheable
- } else {
- canDiskCache = false;
- }
-
- metaData.setSaveToDisk(canDiskCache);
- QNetworkCacheMetaData::AttributesMap attributes;
- if (statusCode != 304) {
- // update the status code
- attributes.insert(QNetworkRequest::HttpStatusCodeAttribute, statusCode);
- attributes.insert(QNetworkRequest::HttpReasonPhraseAttribute, reasonPhrase);
- } else {
- // this is a redirection, keep the attributes intact
- attributes = oldMetaData.attributes();
- }
- metaData.setAttributes(attributes);
- return metaData;
-}
-
-bool QNetworkAccessHttpBackend::canResume() const
-{
- // Only GET operation supports resuming.
- if (operation() != QNetworkAccessManager::GetOperation)
- return false;
-
- // Can only resume if server/resource supports Range header.
- QByteArray acceptRangesheaderName("Accept-Ranges");
- if (!hasRawHeader(acceptRangesheaderName) || rawHeader(acceptRangesheaderName) == "none")
- return false;
-
- // We only support resuming for byte ranges.
- if (request().hasRawHeader("Range")) {
- QByteArray range = request().rawHeader("Range");
- if (!range.startsWith("bytes="))
- return false;
- }
-
- // If we're using a download buffer then we don't support resuming/migration
- // right now. Too much trouble.
- if (usingZerocopyDownloadBuffer)
- return false;
-
- return true;
-}
-
-void QNetworkAccessHttpBackend::setResumeOffset(quint64 offset)
-{
- resumeOffset = offset;
-}
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
diff --git a/src/network/access/qnetworkaccesshttpbackend_p.h b/src/network/access/qnetworkaccesshttpbackend_p.h
deleted file mode 100644
index 7d4ea56260..0000000000
--- a/src/network/access/qnetworkaccesshttpbackend_p.h
+++ /dev/null
@@ -1,169 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
-**
-** This file is part of the QtNetwork module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** GNU Lesser General Public License Usage
-** This file may be used under the terms of the GNU Lesser General Public
-** License version 2.1 as published by the Free Software Foundation and
-** appearing in the file LICENSE.LGPL included in the packaging of this
-** file. Please review the following information to ensure the GNU Lesser
-** General Public License version 2.1 requirements will be met:
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Nokia gives you certain additional
-** rights. These rights are described in the Nokia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** 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.
-**
-** Other Usage
-** Alternatively, this file may be used in accordance with the terms and
-** conditions contained in a signed written agreement between you and Nokia.
-**
-**
-**
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef QNETWORKACCESSHTTPBACKEND_P_H
-#define QNETWORKACCESSHTTPBACKEND_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists for the convenience
-// of the Network Access API. This header file may change from
-// version to version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include "qhttpnetworkconnection_p.h"
-#include "qnetworkaccessbackend_p.h"
-#include "qnetworkrequest.h"
-#include "qnetworkreply.h"
-#include "qabstractsocket.h"
-
-#include "QtCore/qpointer.h"
-#include "QtCore/qdatetime.h"
-#include "QtCore/qsharedpointer.h"
-#include "qatomic.h"
-
-#ifndef QT_NO_HTTP
-
-QT_BEGIN_NAMESPACE
-
-class QNetworkAccessCachedHttpConnection;
-
-class QNetworkAccessHttpBackendIODevice;
-
-class QNetworkAccessHttpBackend: public QNetworkAccessBackend
-{
- Q_OBJECT
-public:
- QNetworkAccessHttpBackend();
- virtual ~QNetworkAccessHttpBackend();
-
- virtual void open();
- virtual void closeDownstreamChannel();
-
- virtual void downstreamReadyWrite();
- virtual void setDownstreamLimited(bool b);
-
- virtual void copyFinished(QIODevice *);
-#ifndef QT_NO_OPENSSL
- virtual void ignoreSslErrors();
- virtual void ignoreSslErrors(const QList<QSslError> &errors);
-
- virtual void fetchSslConfiguration(QSslConfiguration &configuration) const;
- virtual void setSslConfiguration(const QSslConfiguration &configuration);
-#endif
- QNetworkCacheMetaData fetchCacheMetaData(const QNetworkCacheMetaData &metaData) const;
-
- // we return true since HTTP needs to send PUT/POST data again after having authenticated
- bool needsResetableUploadData() { return true; }
-
- bool canResume() const;
- void setResumeOffset(quint64 offset);
-
-signals:
- // To HTTP thread:
- void startHttpRequest();
- void abortHttpRequest();
-
- void startHttpRequestSynchronously();
-
- void haveUploadData(QByteArray dataArray, bool dataAtEnd, qint64 dataSize);
-private slots:
- // From HTTP thread:
- void replyDownloadData(QByteArray);
- void replyFinished();
- void replyDownloadMetaData(QList<QPair<QByteArray,QByteArray> >,int,QString,bool,QSharedPointer<char>,qint64);
- void replyDownloadProgressSlot(qint64,qint64);
- void httpAuthenticationRequired(const QHttpNetworkRequest &request, QAuthenticator *auth);
- void httpError(QNetworkReply::NetworkError error, const QString &errorString);
-#ifndef QT_NO_OPENSSL
- void replySslErrors(const QList<QSslError> &, bool *, QList<QSslError> *);
- void replySslConfigurationChanged(const QSslConfiguration&);
-#endif
-
- // From QNonContiguousByteDeviceThreadForwardImpl in HTTP thread:
- void resetUploadDataSlot(bool *r);
- void wantUploadDataSlot(qint64);
- void sentUploadDataSlot(qint64);
-
- bool sendCacheContents(const QNetworkCacheMetaData &metaData);
-
-private:
- QHttpNetworkRequest httpRequest; // There is also a copy in the HTTP thread
- int statusCode;
- QString reasonPhrase;
- // Will be increased by HTTP thread:
- QSharedPointer<QAtomicInt> pendingDownloadDataEmissions;
- QSharedPointer<QAtomicInt> pendingDownloadProgressEmissions;
- bool loadingFromCache;
- QByteDataBuffer pendingDownloadData;
- bool usingZerocopyDownloadBuffer;
-
-#ifndef QT_NO_OPENSSL
- QSslConfiguration *pendingSslConfiguration;
- bool pendingIgnoreAllSslErrors;
- QList<QSslError> pendingIgnoreSslErrorsList;
-#endif
-
- quint64 resumeOffset;
-
- bool loadFromCacheIfAllowed(QHttpNetworkRequest &httpRequest);
- void invalidateCache();
- void postRequest();
- void readFromHttp();
- void checkForRedirect(const int statusCode);
-};
-
-class QNetworkAccessHttpBackendFactory : public QNetworkAccessBackendFactory
-{
-public:
- virtual QNetworkAccessBackend *create(QNetworkAccessManager::Operation op,
- const QNetworkRequest &request) const;
-};
-
-QT_END_NAMESPACE
-
-#endif // QT_NO_HTTP
-
-#endif
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 0b51f7255b..eba5880352 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -50,7 +50,6 @@
#include "QtNetwork/qnetworksession.h"
#include "QtNetwork/private/qsharednetworksession_p.h"
-#include "qnetworkaccesshttpbackend_p.h"
#include "qnetworkaccessftpbackend_p.h"
#include "qnetworkaccessfilebackend_p.h"
#include "qnetworkaccessdebugpipebackend_p.h"
diff --git a/src/network/access/qnetworkaccessmanager.h b/src/network/access/qnetworkaccessmanager.h
index ea295dbe97..8ce6080d3a 100644
--- a/src/network/access/qnetworkaccessmanager.h
+++ b/src/network/access/qnetworkaccessmanager.h
@@ -159,7 +159,6 @@ protected:
private:
friend class QNetworkReplyImplPrivate;
- friend class QNetworkAccessHttpBackend;
friend class QNetworkReplyHttpImpl;
Q_DECLARE_PRIVATE(QNetworkAccessManager)
diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp
index 7f61ef9239..21b1d84a78 100644
--- a/src/network/access/qnetworkrequest.cpp
+++ b/src/network/access/qnetworkrequest.cpp
@@ -105,6 +105,10 @@ QT_BEGIN_NAMESPACE
header and contains a QList<QNetworkCookie> representing the
cookies sent by the server to be stored locally.
+ \value UserAgentHeader The User-Agent header sent by HTTP clients.
+
+ \value ServerHeader The Server header received by HTTP clients.
+
\sa header(), setHeader(), rawHeader(), setRawHeader()
*/
@@ -650,6 +654,12 @@ static QByteArray headerName(QNetworkRequest::KnownHeaders header)
case QNetworkRequest::ContentDispositionHeader:
return "Content-Disposition";
+ case QNetworkRequest::UserAgentHeader:
+ return "User-Agent";
+
+ case QNetworkRequest::ServerHeader:
+ return "Server";
+
// no default:
// if new values are added, this will generate a compiler warning
}
@@ -663,6 +673,8 @@ static QByteArray headerValue(QNetworkRequest::KnownHeaders header, const QVaria
case QNetworkRequest::ContentTypeHeader:
case QNetworkRequest::ContentLengthHeader:
case QNetworkRequest::ContentDispositionHeader:
+ case QNetworkRequest::UserAgentHeader:
+ case QNetworkRequest::ServerHeader:
return value.toByteArray();
case QNetworkRequest::LocationHeader:
@@ -745,6 +757,13 @@ static QNetworkRequest::KnownHeaders parseHeaderName(const QByteArray &headerNam
case 's':
if (qstricmp(headerName.constData(), "set-cookie") == 0)
return QNetworkRequest::SetCookieHeader;
+ else if (qstricmp(headerName.constData(), "server") == 0)
+ return QNetworkRequest::ServerHeader;
+ break;
+
+ case 'u':
+ if (qstricmp(headerName.constData(), "user-agent") == 0)
+ return QNetworkRequest::UserAgentHeader;
break;
}
@@ -778,6 +797,8 @@ static QVariant parseHeaderValue(QNetworkRequest::KnownHeaders header, const QBy
{
// header is always a valid value
switch (header) {
+ case QNetworkRequest::UserAgentHeader:
+ case QNetworkRequest::ServerHeader:
case QNetworkRequest::ContentTypeHeader:
// copy exactly, convert to QString
return QString::fromLatin1(value);
diff --git a/src/network/access/qnetworkrequest.h b/src/network/access/qnetworkrequest.h
index eedb0f6592..aa86007127 100644
--- a/src/network/access/qnetworkrequest.h
+++ b/src/network/access/qnetworkrequest.h
@@ -66,7 +66,9 @@ public:
LastModifiedHeader,
CookieHeader,
SetCookieHeader,
- ContentDispositionHeader // added for QMultipartMessage
+ ContentDispositionHeader, // added for QMultipartMessage
+ UserAgentHeader,
+ ServerHeader
};
enum Attribute {
HttpStatusCodeAttribute,
diff --git a/src/network/kernel/qhostinfo.cpp b/src/network/kernel/qhostinfo.cpp
index df7766e2c5..d42c2598f8 100644
--- a/src/network/kernel/qhostinfo.cpp
+++ b/src/network/kernel/qhostinfo.cpp
@@ -527,6 +527,7 @@ void QHostInfoRunnable::run()
iterator.remove();
hostInfo.setLookupId(postponed->id);
postponed->resultEmitter.emitResultsReady(hostInfo);
+ delete postponed;
}
}
}
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 7403590f8c..839a253b99 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -128,7 +128,7 @@
QT_BEGIN_NAMESPACE
// forward declaration
-static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name);
+static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name);
/*!
Constructs a QSslCertificate by reading \a format encoded data
@@ -297,19 +297,19 @@ QByteArray QSslCertificate::digest(QCryptographicHash::Algorithm algorithm) cons
return QCryptographicHash::hash(toDer(), algorithm);
}
-static QString _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
+static QByteArray _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
{
- QString str;
+ QByteArray str;
switch (info) {
- case QSslCertificate::Organization: str = QLatin1String("O"); break;
- case QSslCertificate::CommonName: str = QLatin1String("CN"); break;
- case QSslCertificate::LocalityName: str = QLatin1String("L"); break;
- case QSslCertificate::OrganizationalUnitName: str = QLatin1String("OU"); break;
- case QSslCertificate::CountryName: str = QLatin1String("C"); break;
- case QSslCertificate::StateOrProvinceName: str = QLatin1String("ST"); break;
- case QSslCertificate::DistinguishedNameQualifier: str = QLatin1String("dnQualifier"); break;
- case QSslCertificate::SerialNumber: str = QLatin1String("serialNumber"); break;
- case QSslCertificate::EmailAddress: str = QLatin1String("emailAddress"); break;
+ case QSslCertificate::Organization: str = QByteArray("O"); break;
+ case QSslCertificate::CommonName: str = QByteArray("CN"); break;
+ case QSslCertificate::LocalityName: str = QByteArray("L"); break;
+ case QSslCertificate::OrganizationalUnitName: str = QByteArray("OU"); break;
+ case QSslCertificate::CountryName: str = QByteArray("C"); break;
+ case QSslCertificate::StateOrProvinceName: str = QByteArray("ST"); break;
+ case QSslCertificate::DistinguishedNameQualifier: str = QByteArray("dnQualifier"); break;
+ case QSslCertificate::SerialNumber: str = QByteArray("serialNumber"); break;
+ case QSslCertificate::EmailAddress: str = QByteArray("emailAddress"); break;
}
return str;
}
@@ -334,20 +334,20 @@ QStringList QSslCertificate::issuerInfo(SubjectInfo info) const
}
/*!
- Returns the issuer information for \a tag from the certificate,
- or an empty string if there is no information for \a tag in the
+ Returns the issuer information for \a attribute from the certificate,
+ or an empty string if there is no information for \a attribute in the
certificate.
\sa subjectInfo()
*/
-QStringList QSslCertificate::issuerInfo(const QByteArray &tag) const
+QStringList QSslCertificate::issuerInfo(const QByteArray &attribute) const
{
// lazy init
if (d->issuerInfo.isEmpty() && d->x509)
d->issuerInfo =
_q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
- return d->issuerInfo.values(QString::fromLatin1(tag));
+ return d->issuerInfo.values(attribute);
}
/*!
@@ -370,19 +370,57 @@ QStringList QSslCertificate::subjectInfo(SubjectInfo info) const
}
/*!
- Returns the subject information for \a tag, or an empty string if
- there is no information for \a tag in the certificate.
+ Returns the subject information for \a attribute, or an empty string if
+ there is no information for \a attribute in the certificate.
\sa issuerInfo()
*/
-QStringList QSslCertificate::subjectInfo(const QByteArray &tag) const
+QStringList QSslCertificate::subjectInfo(const QByteArray &attribute) const
{
// lazy init
if (d->subjectInfo.isEmpty() && d->x509)
d->subjectInfo =
_q_mapFromX509Name(q_X509_get_subject_name(d->x509));
- return d->subjectInfo.values(QString::fromLatin1(tag));
+ return d->subjectInfo.values(attribute);
+}
+
+/*!
+ Returns a list of the attributes that have values in the subject
+ information of this certificate. The information associated
+ with a given attribute can be accessed using the subjectInfo()
+ method. Note that this list may include the OIDs for any
+ elements that are not known by the SSL backend.
+
+ \sa subjectInfo()
+*/
+QList<QByteArray> QSslCertificate::subjectInfoAttributes() const
+{
+ // lazy init
+ if (d->subjectInfo.isEmpty() && d->x509)
+ d->subjectInfo =
+ _q_mapFromX509Name(q_X509_get_subject_name(d->x509));
+
+ return d->subjectInfo.uniqueKeys();
+}
+
+/*!
+ Returns a list of the attributes that have values in the issuer
+ information of this certificate. The information associated
+ with a given attribute can be accessed using the issuerInfo()
+ method. Note that this list may include the OIDs for any
+ elements that are not known by the SSL backend.
+
+ \sa subjectInfo()
+*/
+QList<QByteArray> QSslCertificate::issuerInfoAttributes() const
+{
+ // lazy init
+ if (d->issuerInfo.isEmpty() && d->x509)
+ d->issuerInfo =
+ _q_mapFromX509Name(q_X509_get_issuer_name(d->x509));
+
+ return d->issuerInfo.uniqueKeys();
}
/*!
@@ -706,17 +744,32 @@ QByteArray QSslCertificatePrivate::text_from_X509(X509 *x509)
return result;
}
-static QMap<QString, QString> _q_mapFromX509Name(X509_NAME *name)
+QByteArray QSslCertificatePrivate::asn1ObjectName(ASN1_OBJECT *object)
{
- QMap<QString, QString> info;
+ int nid = q_OBJ_obj2nid(object);
+ if (nid != NID_undef)
+ return QByteArray(q_OBJ_nid2sn(nid));
+
+ // This is used for unknown info so we get the OID as text
+ char buf[80];
+ q_i2t_ASN1_OBJECT(buf, sizeof(buf), object);
+
+ return QByteArray(buf);
+}
+
+static QMap<QByteArray, QString> _q_mapFromX509Name(X509_NAME *name)
+{
+ QMap<QByteArray, QString> info;
for (int i = 0; i < q_X509_NAME_entry_count(name); ++i) {
X509_NAME_ENTRY *e = q_X509_NAME_get_entry(name, i);
- const char *obj = q_OBJ_nid2sn(q_OBJ_obj2nid(q_X509_NAME_ENTRY_get_object(e)));
+
+ QByteArray name = QSslCertificatePrivate::asn1ObjectName(q_X509_NAME_ENTRY_get_object(e));
unsigned char *data = 0;
int size = q_ASN1_STRING_to_UTF8(&data, q_X509_NAME_ENTRY_get_data(e));
- info.insertMulti(QString::fromUtf8(obj), QString::fromUtf8((char*)data, size));
+ info.insertMulti(name, QString::fromUtf8((char*)data, size));
q_CRYPTO_free(data);
}
+
return info;
}
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index 8abaa3f73e..4de84dd4ba 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -100,9 +100,11 @@ public:
QByteArray serialNumber() const;
QByteArray digest(QCryptographicHash::Algorithm algorithm = QCryptographicHash::Md5) const;
QStringList issuerInfo(SubjectInfo info) const;
- QStringList issuerInfo(const QByteArray &tag) const;
+ QStringList issuerInfo(const QByteArray &attribute) const;
QStringList subjectInfo(SubjectInfo info) const;
- QStringList subjectInfo(const QByteArray &tag) const;
+ QStringList subjectInfo(const QByteArray &attribute) const;
+ QList<QByteArray> subjectInfoAttributes() const;
+ QList<QByteArray> issuerInfoAttributes() const;
QMultiMap<QSsl::AlternateNameEntryType, QString> alternateSubjectNames() const;
QDateTime effectiveDate() const;
QDateTime expiryDate() const;
diff --git a/src/network/ssl/qsslcertificate_p.h b/src/network/ssl/qsslcertificate_p.h
index eb192968c5..3cfcef7b57 100644
--- a/src/network/ssl/qsslcertificate_p.h
+++ b/src/network/ssl/qsslcertificate_p.h
@@ -83,8 +83,8 @@ public:
QByteArray versionString;
QByteArray serialNumberString;
- QMap<QString, QString> issuerInfo;
- QMap<QString, QString> subjectInfo;
+ QMap<QByteArray, QString> issuerInfo;
+ QMap<QByteArray, QString> subjectInfo;
QDateTime notValidAfter;
QDateTime notValidBefore;
@@ -92,6 +92,7 @@ public:
void init(const QByteArray &data, QSsl::EncodingFormat format);
+ static QByteArray asn1ObjectName(ASN1_OBJECT *object);
static QByteArray QByteArray_from_X509(X509 *x509, QSsl::EncodingFormat format);
static QByteArray text_from_X509(X509 *x509);
static QSslCertificate QSslCertificate_from_X509(X509 *x509);
diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp
index f191ed9324..294e2508d8 100644
--- a/src/network/ssl/qsslsocket.cpp
+++ b/src/network/ssl/qsslsocket.cpp
@@ -1599,6 +1599,27 @@ bool QSslSocket::supportsSsl()
}
/*!
+ Returns the version number of the SSL library in use. Note that
+ this is the version of the library in use at run-time not compile
+ time. If no SSL support is available then this will return an
+ undefined value.
+*/
+long QSslSocket::sslLibraryVersionNumber()
+{
+ return QSslSocketPrivate::sslLibraryVersionNumber();
+}
+
+/*!
+ Returns the version string of the SSL library in use. Note that
+ this is the version of the library in use at run-time not compile
+ time. If no SSL support is available then this will return an empty value.
+*/
+QString QSslSocket::sslLibraryVersionString()
+{
+ return QSslSocketPrivate::sslLibraryVersionString();
+}
+
+/*!
Starts a delayed SSL handshake for a client connection. This
function can be called when the socket is in the \l ConnectedState
but still in the \l UnencryptedMode. If it is not yet connected,
diff --git a/src/network/ssl/qsslsocket.h b/src/network/ssl/qsslsocket.h
index f175ffd946..803e79e0c4 100644
--- a/src/network/ssl/qsslsocket.h
+++ b/src/network/ssl/qsslsocket.h
@@ -176,6 +176,9 @@ public:
QList<QSslError> sslErrors() const;
static bool supportsSsl();
+ static long sslLibraryVersionNumber();
+ static QString sslLibraryVersionString();
+
void ignoreSslErrors(const QList<QSslError> &errors);
public Q_SLOTS:
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 479a6bd60e..c7e938a705 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -602,6 +602,23 @@ void QSslSocketPrivate::ensureInitialized()
ensureCiphersAndCertsLoaded();
}
+long QSslSocketPrivate::sslLibraryVersionNumber()
+{
+ return q_SSLeay();
+}
+
+QString QSslSocketPrivate::sslLibraryVersionString()
+{
+ if (!supportsSsl())
+ return QString();
+
+ const char *versionString = q_SSLeay_version(SSLEAY_VERSION);
+ if (!versionString)
+ return QString();
+
+ return QString::fromLatin1(versionString);
+}
+
/*!
\internal
diff --git a/src/network/ssl/qsslsocket_openssl_symbols.cpp b/src/network/ssl/qsslsocket_openssl_symbols.cpp
index b652833b45..31afab003f 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols.cpp
+++ b/src/network/ssl/qsslsocket_openssl_symbols.cpp
@@ -133,6 +133,10 @@ DEFINEFUNC(EVP_PKEY *, EVP_PKEY_new, DUMMYARG, DUMMYARG, return 0, return)
DEFINEFUNC(int, EVP_PKEY_type, int a, a, return NID_undef, return)
DEFINEFUNC2(int, i2d_X509, X509 *a, a, unsigned char **b, b, return -1, return)
DEFINEFUNC(const char *, OBJ_nid2sn, int a, a, return 0, return)
+DEFINEFUNC(const char *, OBJ_nid2ln, int a, a, return 0, return)
+DEFINEFUNC3(int, i2t_ASN1_OBJECT, char *a, a, int b, b, ASN1_OBJECT *c, c, return -1, return)
+
+
DEFINEFUNC(int, OBJ_obj2nid, const ASN1_OBJECT *a, a, return NID_undef, return)
#ifdef SSLEAY_MACROS
DEFINEFUNC6(void *, PEM_ASN1_read_bio, d2i_of_void *a, a, const char *b, b, BIO *c, c, void **d, d, pem_password_cb *e, e, void *f, f, return 0, return)
@@ -276,6 +280,7 @@ DEFINEFUNC(void, OPENSSL_add_all_algorithms_noconf, void, DUMMYARG, return, DUMM
DEFINEFUNC(void, OPENSSL_add_all_algorithms_conf, void, DUMMYARG, return, DUMMYARG)
DEFINEFUNC3(int, SSL_CTX_load_verify_locations, SSL_CTX *ctx, ctx, const char *CAfile, CAfile, const char *CApath, CApath, return 0, return)
DEFINEFUNC(long, SSLeay, void, DUMMYARG, return 0, return)
+DEFINEFUNC(const char *, SSLeay_version, int a, a, return 0, return)
#ifdef Q_OS_SYMBIAN
#define RESOLVEFUNC(func, ordinal, lib) \
@@ -687,6 +692,8 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(EVP_PKEY_new)
RESOLVEFUNC(EVP_PKEY_type)
RESOLVEFUNC(OBJ_nid2sn)
+ RESOLVEFUNC(OBJ_nid2ln)
+ RESOLVEFUNC(i2t_ASN1_OBJECT)
RESOLVEFUNC(OBJ_obj2nid)
#ifdef SSLEAY_MACROS // ### verify
RESOLVEFUNC(PEM_ASN1_read_bio)
@@ -788,6 +795,7 @@ bool q_resolveOpenSslSymbols()
RESOLVEFUNC(OPENSSL_add_all_algorithms_conf)
RESOLVEFUNC(SSL_CTX_load_verify_locations)
RESOLVEFUNC(SSLeay)
+ RESOLVEFUNC(SSLeay_version)
#endif // Q_OS_SYMBIAN
symbolsResolved = true;
delete libs.first;
diff --git a/src/network/ssl/qsslsocket_openssl_symbols_p.h b/src/network/ssl/qsslsocket_openssl_symbols_p.h
index 658aa144a7..cd3aa07bc0 100644
--- a/src/network/ssl/qsslsocket_openssl_symbols_p.h
+++ b/src/network/ssl/qsslsocket_openssl_symbols_p.h
@@ -237,6 +237,8 @@ int q_EVP_PKEY_type(int a);
EVP_PKEY *q_EVP_PKEY_new();
int q_i2d_X509(X509 *a, unsigned char **b);
const char *q_OBJ_nid2sn(int a);
+const char *q_OBJ_nid2ln(int a);
+int q_i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *obj);
int q_OBJ_obj2nid(const ASN1_OBJECT *a);
#ifdef SSLEAY_MACROS
// ### verify
@@ -426,6 +428,7 @@ void q_OPENSSL_add_all_algorithms_noconf();
void q_OPENSSL_add_all_algorithms_conf();
int q_SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, const char *CApath);
long q_SSLeay();
+const char *q_SSLeay_version(int type);
// Helper function
class QDateTime;
diff --git a/src/network/ssl/qsslsocket_p.h b/src/network/ssl/qsslsocket_p.h
index 86ecba07ce..b1dc656e88 100644
--- a/src/network/ssl/qsslsocket_p.h
+++ b/src/network/ssl/qsslsocket_p.h
@@ -116,6 +116,8 @@ public:
bool allowRootCertOnDemandLoading;
static bool supportsSsl();
+ static long sslLibraryVersionNumber();
+ static QString sslLibraryVersionString();
static void ensureInitialized();
static void deinitialize();
static QList<QSslCipher> defaultCiphers();
diff --git a/src/plugins/bearer/connman/qofonoservice_linux.cpp b/src/plugins/bearer/connman/qofonoservice_linux.cpp
index 7c0a255c17..d862456ddc 100644
--- a/src/plugins/bearer/connman/qofonoservice_linux.cpp
+++ b/src/plugins/bearer/connman/qofonoservice_linux.cpp
@@ -57,8 +57,6 @@
#ifndef QT_NO_DBUS
QT_BEGIN_NAMESPACE
-static QDBusConnection dbusConnection = QDBusConnection::systemBus();
-
QOfonoManagerInterface::QOfonoManagerInterface( QObject *parent)
: QDBusAbstractInterface(QLatin1String(OFONO_SERVICE),
@@ -106,7 +104,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
QLatin1String(OFONO_MANAGER_PATH),
QLatin1String(OFONO_MANAGER_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -256,7 +254,7 @@ void QOfonoModemInterface::connectNotify(const char *signal)
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_MODEM_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -379,7 +377,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_NETWORK_REGISTRATION_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -477,7 +475,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_NETWORK_OPERATOR_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -580,7 +578,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_SIM_MANAGER_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -669,7 +667,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_DATA_CONNECTION_MANAGER_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -788,7 +786,7 @@ if (QLatin1String(signal) == SIGNAL(propertyChanged(QString,QDBusVariant))) {
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_DATA_CONTEXT_INTERFACE),
QLatin1String("PropertyChanged"),
@@ -870,7 +868,7 @@ void QOfonoSmsInterface::connectNotify(const char *signal)
QOfonoDBusHelper *helper;
helper = new QOfonoDBusHelper(this);
- dbusConnection.connect(QLatin1String(OFONO_SERVICE),
+ QDBusConnection::systemBus().connect(QLatin1String(OFONO_SERVICE),
this->path(),
QLatin1String(OFONO_SMS_MANAGER_INTERFACE),
QLatin1String("PropertyChanged"),
diff --git a/src/plugins/platforms/uikit/README b/src/plugins/platforms/uikit/README
index a101a3ac0b..f878cce50e 100644
--- a/src/plugins/platforms/uikit/README
+++ b/src/plugins/platforms/uikit/README
@@ -18,11 +18,11 @@ After configuring and building Qt you need to also build src/plugins/platforms/u
Simulator:
----------
-configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+configure -qpa -xplatform qws/macx-iphonesimulator-g++ -arch i386 -developer-build -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake docs -nomake examples -nomake translations
Device:
-------
-configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake demos -nomake docs -nomake examples -nomake translations
+configure -qpa -xplatform qws/macx-iphonedevice-g++ -arch armv7 -developer-build -release -opengl es1 -no-accessibility -no-qt3support -no-multimedia -no-phonon -no-phonon-backend -no-svg -no-webkit -no-scripttools -no-openssl -no-sql-mysql -no-sql-odbc -no-cups -no-iconv -no-dbus -static -nomake tools -nomake docs -nomake examples -nomake translations
2) XCode setup:
- there are examples in the examples subdirectory of the platform plugin
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
index 9bf857d734..320113f58d 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.cpp
@@ -48,6 +48,8 @@
#include "wayland-xcomposite-client-protocol.h"
#include <X11/extensions/Xcomposite.h>
+#include "qwaylandxcompositeeglintegration.h"
+#include "windowmanager_integration/qwaylandwindowmanagerintegration.h"
#include <QtCore/QDebug>
@@ -147,3 +149,12 @@ void QWaylandXCompositeEGLWindow::sync_function(void *data)
QWaylandXCompositeEGLWindow *that = static_cast<QWaylandXCompositeEGLWindow *>(data);
that->m_waitingForSync = false;
}
+
+void QWaylandXCompositeEGLWindow::requestActivateWindow()
+{
+#ifdef QT_WAYLAND_WINDOWMANAGER_SUPPORT
+ mDisplay->windowManagerIntegration()->authenticateWithToken();
+#endif
+
+ QWaylandWindow::requestActivateWindow();
+}
diff --git a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
index 535498a722..b2f8fbe6c4 100644
--- a/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
+++ b/src/plugins/platforms/wayland/gl_integration/xcomposite_egl/qwaylandxcompositeeglwindow.h
@@ -55,6 +55,7 @@ public:
WindowType windowType() const;
void setGeometry(const QRect &rect);
+ void requestActivateWindow();
EGLSurface eglSurface() const;
diff --git a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
index 7390c52740..60b0a5605e 100644
--- a/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
+++ b/src/plugins/platforms/wayland/windowmanager_integration/qwaylandwindowmanagerintegration.cpp
@@ -99,19 +99,18 @@ void QWaylandWindowManagerIntegration::authenticateWithToken(const QByteArray &t
QByteArray authToken = token;
if (authToken.isEmpty())
authToken = qgetenv("WL_AUTHENTICATION_TOKEN");
- if (mWaylandWindowManager)
+
+ if (mWaylandWindowManager && !authToken.isEmpty()) {
wl_windowmanager_authenticate_with_token(mWaylandWindowManager, authToken.constData());
+ }
}
void QWaylandWindowManagerIntegration::wlHandleOnScreenVisibilityChange(void *data, struct wl_windowmanager *wl_windowmanager, int visible)
{
Q_UNUSED(data);
Q_UNUSED(wl_windowmanager);
- QEvent evt(visible != 0 ? QEvent::ApplicationActivated : QEvent::ApplicationDeactivated);
-
+ QEvent evt(visible != 0 ? QEvent::ApplicationActivate : QEvent::ApplicationDeactivate);
QCoreApplication::sendEvent(QCoreApplication::instance(), &evt);
-
- qDebug() << "OnScreenVisibility" << (visible != 0);
}
void QWaylandWindowManagerIntegration::wlHandleScreenOrientationChange(void *data, struct wl_windowmanager *wl_windowmanager, int screenOrientation)
diff --git a/src/sql/kernel/qsql.h b/src/sql/kernel/qsql.h
index 5a1c32381d..f23b518bfb 100644
--- a/src/sql/kernel/qsql.h
+++ b/src/sql/kernel/qsql.h
@@ -56,10 +56,6 @@ namespace QSql
{
BeforeFirstRow = -1,
AfterLastRow = -2
-#ifdef QT3_SUPPORT
- , BeforeFirst = BeforeFirstRow,
- AfterLast = AfterLastRow
-#endif
};
enum ParamTypeFlag
@@ -87,21 +83,6 @@ namespace QSql
HighPrecision = 0
};
-
-#ifdef QT3_SUPPORT
- enum Op {
- None = -1,
- Insert = 0,
- Update = 1,
- Delete = 2
- };
-
- enum Confirm {
- Cancel = -1,
- No = 0,
- Yes = 1
- };
-#endif
}
Q_DECLARE_OPERATORS_FOR_FLAGS(QSql::ParamType)
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index c5eac194f5..cd36d5d591 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -1434,26 +1434,6 @@ bool QSqlDatabase::isValid() const
return d->driver && d->driver != d->shared_null()->driver;
}
-#ifdef QT3_SUPPORT
-/*!
- Use query.record() instead.
-*/
-QSqlRecord QSqlDatabase::record(const QSqlQuery& query) const
-{ return query.record(); }
-
-/*!
- Use query.record() instead.
-*/
-QSqlRecord QSqlDatabase::recordInfo(const QSqlQuery& query) const
-{ return query.record(); }
-
-/*!
- \fn QSqlRecord QSqlDatabase::recordInfo(const QString& tablename) const
-
- Use record() instead.
-*/
-#endif
-
/*!
Clones the database connection \a other and and stores it as \a
connectionName. All the settings from the original database, e.g.
diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h
index c8cde8557e..72c5694ceb 100644
--- a/src/sql/kernel/qsqldatabase.h
+++ b/src/sql/kernel/qsqldatabase.h
@@ -44,9 +44,6 @@
#include <QtCore/qstring.h>
#include <QtSql/qsql.h>
-#ifdef QT3_SUPPORT
-#include <QtSql/qsqlrecord.h>
-#endif
QT_BEGIN_HEADER
@@ -92,12 +89,6 @@ public:
QStringList tables(QSql::TableType type = QSql::Tables) const;
QSqlIndex primaryIndex(const QString& tablename) const;
QSqlRecord record(const QString& tablename) const;
-#ifdef QT3_SUPPORT
- QT3_SUPPORT QSqlRecord record(const QSqlQuery& query) const;
- inline QT3_SUPPORT QSqlRecord recordInfo(const QString& tablename) const
- { return record(tablename); }
- QT3_SUPPORT QSqlRecord recordInfo(const QSqlQuery& query) const;
-#endif
QSqlQuery exec(const QString& query = QString()) const;
QSqlError lastError() const;
bool isValid() const;
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 479d3ac990..ee1e52538a 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -46,9 +46,6 @@
#include <QtCore/qstring.h>
#include <QtCore/qstringlist.h>
#include <QtSql/qsql.h>
-#ifdef QT3_SUPPORT
-#include <QtSql/qsqlquery.h>
-#endif
QT_BEGIN_HEADER
@@ -93,17 +90,6 @@ public:
virtual QStringList tables(QSql::TableType tableType) const;
virtual QSqlIndex primaryIndex(const QString &tableName) const;
virtual QSqlRecord record(const QString &tableName) const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT QSqlRecord record(const QSqlQuery& query) const
- { return query.record(); }
- inline QT3_SUPPORT QSqlRecord recordInfo(const QString& tablename) const
- { return record(tablename); }
- inline QT3_SUPPORT QSqlRecord recordInfo(const QSqlQuery& query) const
- { return query.record(); }
- inline QT3_SUPPORT QString nullText() const { return QLatin1String("NULL"); }
- inline QT3_SUPPORT QString formatValue(const QSqlField *field, bool trimStrings = false) const
- { return field ? formatValue(*field, trimStrings) : QString(); }
-#endif
virtual QString formatValue(const QSqlField& field, bool trimStrings = false) const;
virtual QString escapeIdentifier(const QString &identifier, IdentifierType type) const;
diff --git a/src/sql/kernel/qsqlerror.h b/src/sql/kernel/qsqlerror.h
index 87136ecda9..fea3ca8526 100644
--- a/src/sql/kernel/qsqlerror.h
+++ b/src/sql/kernel/qsqlerror.h
@@ -59,13 +59,6 @@ public:
StatementError,
TransactionError,
UnknownError
-#ifdef QT3_SUPPORT
- , None = NoError,
- Connection = ConnectionError,
- Statement = StatementError,
- Transaction = TransactionError,
- Unknown = UnknownError
-#endif
};
QSqlError( const QString& driverText = QString(),
const QString& databaseText = QString(),
diff --git a/src/sql/kernel/qsqlfield.h b/src/sql/kernel/qsqlfield.h
index 182b5318e2..93992ea9d4 100644
--- a/src/sql/kernel/qsqlfield.h
+++ b/src/sql/kernel/qsqlfield.h
@@ -98,10 +98,6 @@ public:
bool isGenerated() const;
bool isValid() const;
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT void setNull() { clear(); }
-#endif
-
private:
void detach();
QVariant val;
diff --git a/src/sql/kernel/qsqlindex.cpp b/src/sql/kernel/qsqlindex.cpp
index 33e3c1ce34..764e93a678 100644
--- a/src/sql/kernel/qsqlindex.cpp
+++ b/src/sql/kernel/qsqlindex.cpp
@@ -164,60 +164,6 @@ void QSqlIndex::setDescending(int i, bool desc)
sorts[i] = desc;
}
-#ifdef QT3_SUPPORT
-
-/*!
- Returns a comma-separated list of all the index's field names as a
- string. This string is suitable, for example, for generating a
- SQL SELECT statement. Only generated fields are included in the
- list (see \l{isGenerated()}). If a \a prefix is specified, e.g. a
- table name, it is prepended before all field names in the form:
-
- "\a{prefix}.<fieldname>"
-
- If \a sep is specified, each field is separated by \a sep. If \a
- verbose is true (the default), each field contains a suffix
- indicating an ASCending or DESCending sort order.
-*/
-
-QString QSqlIndex::toString(const QString& prefix, const QString& sep, bool verbose) const
-{
- QString s;
- bool comma = false;
- for (int i = 0; i < count(); ++i) {
- if(comma)
- s += sep + QLatin1Char(' ');
- s += createField(i, prefix, verbose);
- comma = true;
- }
- return s;
-}
-
-/*!
- Returns a list of all the index's field names. Only generated
- fields are included in the list (see \l{isGenerated()}). If a \a
- prefix is specified, e.g. a table name, all fields are prefixed in
- the form:
-
- "\a{prefix}.<fieldname>"
-
- If \a verbose is true (the default), each field contains a suffix
- indicating an ASCending or DESCending sort order.
-
- Note that if you want to iterate over the list, you should iterate
- over a copy, e.g.
- \snippet doc/src/snippets/code/src_sql_kernel_qsqlindex.cpp 0
-
-*/
-QStringList QSqlIndex::toStringList(const QString& prefix, bool verbose) const
-{
- QStringList s;
- for (int i = 0; i < count(); ++i)
- s += createField(i, prefix, verbose);
- return s;
-}
-#endif
-
/*! \internal
Creates a string representing the field number \a i using prefix \a
diff --git a/src/sql/kernel/qsqlindex.h b/src/sql/kernel/qsqlindex.h
index 97874e24f6..c88e30603f 100644
--- a/src/sql/kernel/qsqlindex.h
+++ b/src/sql/kernel/qsqlindex.h
@@ -70,14 +70,6 @@ public:
bool isDescending(int i) const;
void setDescending(int i, bool desc);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT QString toString(const QString &prefix = QString(),
- const QString &sep = QLatin1String(","),
- bool verbose = true) const;
- QT3_SUPPORT QStringList toStringList(const QString& prefix = QString(),
- bool verbose = true) const;
-#endif
-
private:
QString createField(int i, const QString& prefix, bool verbose) const;
QString cursor;
diff --git a/src/sql/kernel/qsqlquery.h b/src/sql/kernel/qsqlquery.h
index e82380956c..bd498f344a 100644
--- a/src/sql/kernel/qsqlquery.h
+++ b/src/sql/kernel/qsqlquery.h
@@ -94,9 +94,6 @@ public:
bool seek(int i, bool relative = false);
bool next();
bool previous();
-#ifdef QT3_SUPPORT
- inline QT3_SUPPORT bool prev() { return previous(); }
-#endif
bool first();
bool last();
diff --git a/src/sql/kernel/qsqlrecord.cpp b/src/sql/kernel/qsqlrecord.cpp
index dfeb3e0622..944f2fc9bc 100644
--- a/src/sql/kernel/qsqlrecord.cpp
+++ b/src/sql/kernel/qsqlrecord.cpp
@@ -244,34 +244,6 @@ int QSqlRecord::indexOf(const QString& name) const
return -1;
}
-#ifdef QT3_SUPPORT
-/*!
- \obsolete
- Use field() instead
-*/
-const QSqlField* QSqlRecord::fieldPtr(int index) const
-{
- if (!d->contains(index))
- return 0;
-
- return &d->fields.at(index);
-}
-
-/*!
- \obsolete
- Use field() instead
-*/
-
-const QSqlField* QSqlRecord::fieldPtr(const QString& name) const
-{
- int i = indexOf(name);
- if (!d->contains(i))
- return 0;
-
- return &d->fields.at(i);
-}
-#endif //QT3_SUPPORT
-
/*!
Returns the field at position \a index. If the position is out of
range, an empty field is returned.
@@ -496,49 +468,6 @@ bool QSqlRecord::isGenerated(int index) const
return d->fields.value(index).isGenerated();
}
-#ifdef QT3_SUPPORT
-/*!
- Returns a list of all the record's field names as a string
- separated by \a sep.
-
- In the unlikely event that you used this function in Qt 3, you
- can simulate it using the rest of the QSqlRecord public API.
-*/
-
-QString QSqlRecord::toString(const QString& prefix, const QString& sep) const
-{
- QString pflist;
- bool comma = false;
- for (int i = 0; i < count(); ++i) {
- if (!d->fields.value(i).isGenerated()) {
- if (comma)
- pflist += sep + QLatin1Char(' ');
- pflist += d->createField(i, prefix);
- comma = true;
- }
- }
- return pflist;
-}
-
-/*!
- Returns a list of all the record's field names, each having the
- prefix \a prefix.
-
- In the unlikely event that you used this function in Qt 3, you
- can simulate it using the rest of the QSqlRecord public API.
-*/
-
-QStringList QSqlRecord::toStringList(const QString& prefix) const
-{
- QStringList s;
- for (int i = 0; i < count(); ++i) {
- if (!d->fields.value(i).isGenerated())
- s += d->createField(i, prefix);
- }
- return s;
-}
-#endif // QT3_SUPPORT
-
/*!
Returns the number of fields in the record.
diff --git a/src/sql/kernel/qsqlrecord.h b/src/sql/kernel/qsqlrecord.h
index e697e8e170..8c7a17ab1d 100644
--- a/src/sql/kernel/qsqlrecord.h
+++ b/src/sql/kernel/qsqlrecord.h
@@ -87,15 +87,6 @@ public:
void setGenerated(const QString& name, bool generated);
void setGenerated(int i, bool generated);
-#ifdef QT3_SUPPORT
- QT3_SUPPORT const QSqlField* fieldPtr(int i) const;
- QT3_SUPPORT const QSqlField* fieldPtr(const QString& name) const;
- inline QT3_SUPPORT int position(const QString& name) const { return indexOf(name); }
- QT3_SUPPORT QString toString(const QString& prefix = QString(),
- const QString& sep = QLatin1String(",")) const;
- QT3_SUPPORT QStringList toStringList(const QString& prefix = QString()) const;
-#endif
-
void append(const QSqlField& field);
void replace(int pos, const QSqlField& field);
void insert(int pos, const QSqlField& field);
diff --git a/src/sql/kernel/qsqlresult.h b/src/sql/kernel/qsqlresult.h
index 58b19c193d..984bd5e03f 100644
--- a/src/sql/kernel/qsqlresult.h
+++ b/src/sql/kernel/qsqlresult.h
@@ -74,10 +74,6 @@ protected:
enum BindingSyntax {
PositionalBinding,
NamedBinding
-#ifdef QT3_SUPPORT
- , BindByPosition = PositionalBinding,
- BindByName = NamedBinding
-#endif
};
explicit QSqlResult(const QSqlDriver * db);
diff --git a/src/widgets/platforms/mac/qfontdatabase_mac.cpp b/src/widgets/platforms/mac/qfontdatabase_mac.cpp
index b7335d684e..e1e59b79eb 100644
--- a/src/widgets/platforms/mac/qfontdatabase_mac.cpp
+++ b/src/widgets/platforms/mac/qfontdatabase_mac.cpp
@@ -113,7 +113,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QtFontFoundry *foundry = family->foundry(foundry_name, true);
QtFontStyle::Key styleKey;
- styleKey.styleName = style_name;
+ QString styleName = style_name;
if(QCFType<CFDictionaryRef> styles = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)) {
if(CFNumberRef weight = (CFNumberRef)CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
Q_ASSERT(CFNumberIsFloatType(weight));
@@ -134,7 +134,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
}
}
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, styleName, true);
style->smoothScalable = true;
if(QCFType<CFNumberRef> size = (CFNumberRef)CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
//qDebug() << "WHEE";
@@ -207,7 +207,7 @@ if (QSysInfo::MacintoshVersion >= QSysInfo::MV_10_5) {
QtFontFamily *family = db->family(familyName, true);
QtFontFoundry *foundry = family->foundry(QString(), true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->pixelSize(0, true);
style->smoothScalable = true;
diff --git a/src/widgets/platforms/mac/qfontengine_coretext.mm b/src/widgets/platforms/mac/qfontengine_coretext.mm
index a68a1551d9..303da8d363 100644
--- a/src/widgets/platforms/mac/qfontengine_coretext.mm
+++ b/src/widgets/platforms/mac/qfontengine_coretext.mm
@@ -492,17 +492,6 @@ void QCoreTextFontEngine::init()
avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize);
} else
avgCharWidth = QFontEngine::averageCharWidth();
-
- ctMaxCharWidth = ctMinLeftBearing = ctMinRightBearing = 0;
- QByteArray hheaTable = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));
- if (hheaTable.size() >= 16) {
- quint16 width = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 10));
- ctMaxCharWidth = width * fontDef.pixelSize / emSize;
- qint16 bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 12));
- ctMinLeftBearing = bearing * fontDef.pixelSize / emSize;
- bearing = qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(hheaTable.constData() + 14));
- ctMinRightBearing = bearing * fontDef.pixelSize / emSize;
- }
}
bool QCoreTextFontEngine::stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs,
@@ -599,20 +588,17 @@ QFixed QCoreTextFontEngine::averageCharWidth() const
qreal QCoreTextFontEngine::maxCharWidth() const
{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? qRound(ctMaxCharWidth) : ctMaxCharWidth;
+ return 0;
}
qreal QCoreTextFontEngine::minLeftBearing() const
{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? qRound(ctMinLeftBearing) : ctMinLeftBearing;
+ return 0;
}
qreal QCoreTextFontEngine::minRightBearing() const
{
- return (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
- ? qRound(ctMinRightBearing) : ctMinLeftBearing;
+ return 0;
}
void QCoreTextFontEngine::draw(CGContextRef ctx, qreal x, qreal y, const QTextItemInt &ti, int paintDeviceHeight)
diff --git a/src/widgets/platforms/mac/qfontengine_coretext_p.h b/src/widgets/platforms/mac/qfontengine_coretext_p.h
index b531856a27..d8a3033be6 100644
--- a/src/widgets/platforms/mac/qfontengine_coretext_p.h
+++ b/src/widgets/platforms/mac/qfontengine_coretext_p.h
@@ -107,9 +107,6 @@ private:
int synthesisFlags;
CGAffineTransform transform;
QFixed avgCharWidth;
- qreal ctMaxCharWidth;
- qreal ctMinLeftBearing;
- qreal ctMinRightBearing;
friend class QCoreTextFontEngineMulti;
};
diff --git a/src/widgets/platforms/s60/qfontdatabase_s60.cpp b/src/widgets/platforms/s60/qfontdatabase_s60.cpp
index eea075fc47..cfa405dbc1 100644
--- a/src/widgets/platforms/s60/qfontdatabase_s60.cpp
+++ b/src/widgets/platforms/s60/qfontdatabase_s60.cpp
@@ -508,7 +508,7 @@ static bool registerScreenDeviceFont(int screenDeviceFontIndex,
QtFontFamily *family = privateDb()->family(familyName, true);
family->fixedPitch = faceAttrib.IsMonoWidth();
QtFontFoundry *foundry = family->foundry(QString(), true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = typefaceSupport.iIsScalable;
style->pixelSize(0, true);
diff --git a/src/widgets/platforms/win/qfontdatabase_win.cpp b/src/widgets/platforms/win/qfontdatabase_win.cpp
index 20f945a6c9..788eb307c3 100644
--- a/src/widgets/platforms/win/qfontdatabase_win.cpp
+++ b/src/widgets/platforms/win/qfontdatabase_win.cpp
@@ -284,7 +284,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
family->english_name = getEnglishName(familyName);
QtFontFoundry *foundry = family->foundry(foundryName, true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
@@ -292,14 +292,14 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
if (styleKey.weight <= QFont::DemiBold) {
QtFontStyle::Key key(styleKey);
key.weight = QFont::Bold;
- QtFontStyle *style = foundry->style(key, true);
+ QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}
if (styleKey.style != QFont::StyleItalic) {
QtFontStyle::Key key(styleKey);
key.style = QFont::StyleItalic;
- QtFontStyle *style = foundry->style(key, true);
+ QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}
@@ -307,7 +307,7 @@ void addFontToDatabase(QString familyName, const QString &scriptName,
QtFontStyle::Key key(styleKey);
key.weight = QFont::Bold;
key.style = QFont::StyleItalic;
- QtFontStyle *style = foundry->style(key, true);
+ QtFontStyle *style = foundry->style(key, QString(), true);
style->smoothScalable = scalable;
style->pixelSize( size, TRUE);
}
diff --git a/src/widgets/platforms/x11/qfontdatabase_x11.cpp b/src/widgets/platforms/x11/qfontdatabase_x11.cpp
index ed94fa6be1..922a97f3aa 100644
--- a/src/widgets/platforms/x11/qfontdatabase_x11.cpp
+++ b/src/widgets/platforms/x11/qfontdatabase_x11.cpp
@@ -680,7 +680,7 @@ static void loadXlfds(const char *reqFamily, int encoding_id)
family->fontFileIndex = -1;
family->symbol_checked = true;
QtFontFoundry *foundry = family->foundry(QLatin1String(foundryName), true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
delete [] style->weightName;
style->weightName = qstrdup(tokens[Weight]);
@@ -1145,7 +1145,7 @@ static void loadFontConfig()
family->fontFileIndex = index_value;
QtFontStyle::Key styleKey;
- styleKey.styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
+ QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
styleKey.style = (slant_value == FC_SLANT_ITALIC)
? QFont::StyleItalic
: ((slant_value == FC_SLANT_OBLIQUE)
@@ -1160,7 +1160,7 @@ static void loadFontConfig()
QtFontFoundry *foundry
= family->foundry(foundry_value ? QString::fromUtf8((const char *)foundry_value) : QString(), true);
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, styleName, true);
if (spacing_value < FC_MONO)
family->fixedPitch = false;
@@ -1212,7 +1212,7 @@ static void loadFontConfig()
for (int i = 0; i < 4; ++i) {
styleKey.style = (i%2) ? QFont::StyleNormal : QFont::StyleItalic;
styleKey.weight = (i > 1) ? QFont::Bold : QFont::Normal;
- QtFontStyle *style = foundry->style(styleKey, true);
+ QtFontStyle *style = foundry->style(styleKey, QString(), true);
style->smoothScalable = true;
QtFontSize *size = style->pixelSize(SMOOTH_SCALABLE, true);
QtFontEncoding *enc = size->encodingID(-1, 0, 0, 0, 0, true);
@@ -1360,7 +1360,7 @@ static void initializeDb()
if (equiv) continue;
// let's fake one...
- equiv = foundry->style(key, true);
+ equiv = foundry->style(key, QString(), true);
equiv->smoothScalable = true;
QtFontSize *equiv_size = equiv->pixelSize(SMOOTH_SCALABLE, true);
diff --git a/src/xml/sax/qxml.cpp b/src/xml/sax/qxml.cpp
index 2f5384b902..671adafcbd 100644
--- a/src/xml/sax/qxml.cpp
+++ b/src/xml/sax/qxml.cpp
@@ -1324,29 +1324,6 @@ QXmlInputSource::QXmlInputSource(QIODevice *dev)
d->inputDevice->setTextModeEnabled(false);
}
-#ifdef QT3_SUPPORT
-/*!
- Use the QXmlInputSource(QIODevice *) constructor instead, with
- the device used by \a stream.
-
- \sa QTextStream::device()
-*/
-QXmlInputSource::QXmlInputSource(QTextStream& stream)
-{
- init();
- d->inputStream = &stream;
-}
-
-/*!
- Use QXmlInputSource(&\a file) instead.
-*/
-QXmlInputSource::QXmlInputSource(QFile& file)
-{
- init();
- d->inputDevice = &file;
-}
-#endif
-
/*!
Destructor.
*/
diff --git a/src/xml/sax/qxml.h b/src/xml/sax/qxml.h
index 8b402dfedb..52eea6ce76 100644
--- a/src/xml/sax/qxml.h
+++ b/src/xml/sax/qxml.h
@@ -172,11 +172,6 @@ public:
static const ushort EndOfData;
static const ushort EndOfDocument;
-#ifdef QT3_SUPPORT
- QT3_SUPPORT_CONSTRUCTOR QXmlInputSource(QFile& file);
- QT3_SUPPORT_CONSTRUCTOR QXmlInputSource(QTextStream& stream);
-#endif
-
protected:
virtual QString fromRawData(const QByteArray &data, bool beginning = false);