diff options
author | Olivier Goffart <ogoffart@trolltech.com> | 2010-02-20 01:07:32 (GMT) |
---|---|---|
committer | Olivier Goffart <olivier.goffart@nokia.com> | 2011-04-01 10:59:41 (GMT) |
commit | 2365b2dfd57770875b6eefb165ec27f3bf65dd0c (patch) | |
tree | 50910e3040885973b26c52000619ca55baa930f8 /src | |
parent | 9660d056a7040798c61f64cfb609181ead72f0c3 (diff) | |
download | Qt-2365b2dfd57770875b6eefb165ec27f3bf65dd0c.zip Qt-2365b2dfd57770875b6eefb165ec27f3bf65dd0c.tar.gz Qt-2365b2dfd57770875b6eefb165ec27f3bf65dd0c.tar.bz2 |
QStringBuilder now support building QByteArray
This breaks source compatibility if one made its own QConcatenable
as it nows require a Prefered type.
And also sometimes if QT_USE_FAST_OPERATOR_PLUS was used, and
the result of an addition between two QByteArray is used directly
Reviewed-by: Denis
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/tools/qbytearray.h | 8 | ||||
-rw-r--r-- | src/corelib/tools/qstringbuilder.cpp | 26 | ||||
-rw-r--r-- | src/corelib/tools/qstringbuilder.h | 175 |
3 files changed, 175 insertions, 34 deletions
diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 70d865a..6957022 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -548,6 +548,8 @@ inline bool operator>=(const QByteArray &a1, const char *a2) { return qstrcmp(a1, a2) >= 0; } inline bool operator>=(const char *a1, const QByteArray &a2) { return qstrcmp(a1, a2) >= 0; } +#ifndef QT_USE_FAST_OPERATOR_PLUS +# ifndef QT_USE_FAST_CONCATENATION inline const QByteArray operator+(const QByteArray &a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(const QByteArray &a1, const char *a2) @@ -558,6 +560,8 @@ inline const QByteArray operator+(const char *a1, const QByteArray &a2) { return QByteArray(a1) += a2; } inline const QByteArray operator+(char a1, const QByteArray &a2) { return QByteArray(&a1, 1) += a2; } +# endif // QT_USE_FAST_CONCATENATION +#endif // QT_USE_FAST_OPERATOR_PLUS inline QBool QByteArray::contains(const char *c) const { return QBool(indexOf(c) != -1); } inline QByteArray &QByteArray::replace(char before, const char *c) @@ -600,4 +604,8 @@ QT_END_NAMESPACE QT_END_HEADER +#ifdef QT_USE_FAST_CONCATENATION +#include <QtCore/qstring.h> +#endif + #endif // QBYTEARRAY_H diff --git a/src/corelib/tools/qstringbuilder.cpp b/src/corelib/tools/qstringbuilder.cpp index 7d75de7..a5dff88 100644 --- a/src/corelib/tools/qstringbuilder.cpp +++ b/src/corelib/tools/qstringbuilder.cpp @@ -40,6 +40,7 @@ ****************************************************************************/ #include "qstringbuilder.h" +#include <QtCore/qtextcodec.h> QT_BEGIN_NAMESPACE @@ -146,7 +147,9 @@ QT_BEGIN_NAMESPACE Converts the \c QLatin1Literal into a \c QString object. */ -/*! \internal */ +/*! \internal + Note: The len contains the ending \0 + */ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out) { #ifndef QT_NO_TEXTCODEC @@ -166,4 +169,25 @@ void QAbstractConcatenable::convertFromAscii(const char *a, int len, QChar *&out } } +/*! \internal */ +void QAbstractConcatenable::convertToAscii(const QChar* a, int len, char*& out) +{ +#ifndef QT_NO_TEXTCODEC + if (QString::codecForCStrings) { + QByteArray tmp = QString::codecForCStrings->fromUnicode(a, len); + memcpy(out, tmp.constData(), tmp.size()); + out += tmp.length(); + return; + } +#endif + if (len == -1) { + while (a->unicode()) + convertToLatin1(*a++, out); + } else { + for (int i = 0; i < len; ++i) + convertToLatin1(a[i], out); + } +} + + QT_END_NAMESPACE diff --git a/src/corelib/tools/qstringbuilder.h b/src/corelib/tools/qstringbuilder.h index d230d67..614346c 100644 --- a/src/corelib/tools/qstringbuilder.h +++ b/src/corelib/tools/qstringbuilder.h @@ -43,6 +43,7 @@ #define QSTRINGBUILDER_H #include <QtCore/qstring.h> +#include <QtCore/qbytearray.h> #if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) # if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ == 0) @@ -78,7 +79,7 @@ struct Q_CORE_EXPORT QAbstractConcatenable { protected: static void convertFromAscii(const char *a, int len, QChar *&out); - + static void convertToAscii(const QChar *a, int len, char *&out); static inline void convertFromAscii(char a, QChar *&out) { #ifndef QT_NO_TEXTCODEC @@ -88,6 +89,21 @@ protected: #endif *out++ = QLatin1Char(a); } + + static inline void convertToAscii(QChar a, char *&out) + { +#ifndef QT_NO_TEXTCODEC + if (QString::codecForCStrings) + *out++ = a.toAscii(); //### + else +#endif + convertToLatin1(a, out); + } + + static inline void convertToLatin1(QChar a, char *&out) + { + *out++ = a.unicode() > 0xff ? '?' : char(a.unicode()); + } }; template <typename T> struct QConcatenable {}; @@ -97,14 +113,16 @@ class QStringBuilder { public: QStringBuilder(const A &a_, const B &b_) : a(a_), b(b_) {} - - operator QString() const +private: + friend class QByteArray; + friend class QString; + template <typename T> T convertTo() const { const uint size = QConcatenable< QStringBuilder<A, B> >::size(*this); - QString s(size, Qt::Uninitialized); + T s(size, Qt::Uninitialized); - QChar *d = s.data(); - const QChar * const start = d; + typename T::iterator d = s.data(); + typename T::const_iterator const start = d; QConcatenable< QStringBuilder<A, B> >::appendTo(*this, d); if (!QConcatenable< QStringBuilder<A, B> >::ExactSize && int(size) != d - start) { @@ -114,7 +132,14 @@ public: } return s; } - QByteArray toLatin1() const { return QString(*this).toLatin1(); } + + typedef QConcatenable<QStringBuilder<A, B> > Concatenable; + typedef typename Concatenable::ConvertTo ConvertTo; +public: + operator ConvertTo() const { return convertTo<ConvertTo>(); } + + QByteArray toLatin1() const { return convertTo<QString>().toLatin1(); } + int size() const { return Concatenable::size(*this); } const A &a; const B &b; @@ -134,53 +159,80 @@ class QStringBuilder <QString, QString> const QString &b; }; +template <> +class QStringBuilder <QByteArray, QByteArray> +{ + public: + QStringBuilder(const QByteArray &a_, const QByteArray &b_) : a(a_), b(b_) {} + + operator QByteArray() const + { QByteArray r(a); r += b; return r; } + + const QByteArray &a; + const QByteArray &b; +}; + + template <> struct QConcatenable<char> : private QAbstractConcatenable { typedef char type; + typedef QByteArray ConvertTo; enum { ExactSize = true }; static int size(const char) { return 1; } - static inline void appendTo(const char c, QChar *&out) +#ifndef QT_NO_CAST_FROM_ASCII + static inline QT_ASCII_CAST_WARN void appendTo(const char c, QChar *&out) { QAbstractConcatenable::convertFromAscii(c, out); } +#endif + static inline void appendTo(const char c, char *&out) + { *out++ = c; } }; template <> struct QConcatenable<QLatin1Char> { typedef QLatin1Char type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QLatin1Char) { return 1; } static inline void appendTo(const QLatin1Char c, QChar *&out) - { - *out++ = c; - } + { *out++ = c; } + static inline void appendTo(const QLatin1Char c, char *&out) + { *out++ = c.toLatin1(); } }; -template <> struct QConcatenable<QChar> +template <> struct QConcatenable<QChar> : private QAbstractConcatenable { typedef QChar type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QChar) { return 1; } static inline void appendTo(const QChar c, QChar *&out) - { - *out++ = c; - } + { *out++ = c; } +#ifndef QT_NO_CAST_TO_ASCII + static inline QT_ASCII_CAST_WARN void appendTo(const QChar c, char *&out) + { convertToAscii(c, out); } +#endif }; -template <> struct QConcatenable<QCharRef> +template <> struct QConcatenable<QCharRef> : private QAbstractConcatenable { typedef QCharRef type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QCharRef &) { return 1; } static inline void appendTo(const QCharRef &c, QChar *&out) - { - *out++ = QChar(c); - } + { *out++ = QChar(c); } +#ifndef QT_NO_CAST_TO_ASCII + static inline QT_ASCII_CAST_WARN void appendTo(const QCharRef &c, char *&out) + { convertToAscii(c, out); } +#endif }; template <> struct QConcatenable<QLatin1String> { typedef QLatin1String type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QLatin1String &a) { return qstrlen(a.latin1()); } static inline void appendTo(const QLatin1String &a, QChar *&out) @@ -188,12 +240,17 @@ template <> struct QConcatenable<QLatin1String> 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) @@ -201,11 +258,17 @@ template <> struct QConcatenable<QLatin1Literal> for (const char *s = a.data(); *s; ) *out++ = QLatin1Char(*s++); } + static inline void appendTo(const QLatin1Literal &a, char *&out) + { + for (const char *s = a.data(); *s; ) + *out++ = *s++; + } }; -template <> struct QConcatenable<QString> +template <> struct QConcatenable<QString> : private QAbstractConcatenable { typedef QString type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QString &a) { return a.size(); } static inline void appendTo(const QString &a, QChar *&out) @@ -214,81 +277,127 @@ template <> struct QConcatenable<QString> memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n); out += n; } +#ifndef QT_NO_CAST_TO_ASCII + static inline QT_ASCII_CAST_WARN void appendTo(const QString &a, char *&out) + { convertToAscii(a.constData(), a.length(), out); } +#endif }; -template <> struct QConcatenable<QStringRef> +template <> struct QConcatenable<QStringRef> : private QAbstractConcatenable { typedef QStringRef type; + typedef QString ConvertTo; enum { ExactSize = true }; static int size(const QStringRef &a) { return a.size(); } - static inline void appendTo(QStringRef a, QChar *&out) + static inline void appendTo(const QStringRef &a, QChar *&out) { const int n = a.size(); memcpy(out, reinterpret_cast<const char*>(a.constData()), sizeof(QChar) * n); out += n; } +#ifndef QT_NO_CAST_TO_ASCII + static inline QT_ASCII_CAST_WARN void appendTo(const QStringRef &a, char *&out) + { convertToAscii(a.constData(), a.length(), out); } +#endif + }; -#ifndef QT_NO_CAST_FROM_ASCII template <int N> struct QConcatenable<char[N]> : private QAbstractConcatenable { typedef char type[N]; + typedef QByteArray ConvertTo; enum { ExactSize = false }; - static int size(const char[N]) + static int size(const char[N]) { return N - 1; } +#ifndef QT_NO_CAST_FROM_ASCII + static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out) { - return N - 1; + QAbstractConcatenable::convertFromAscii(a, N, out); } - static inline void appendTo(const char a[N], QChar *&out) +#endif + static inline void appendTo(const char a[N], char *&out) { - QAbstractConcatenable::convertFromAscii(a, N, out); + while (*a) + *out++ = *a++; } }; template <int N> struct QConcatenable<const char[N]> : private QAbstractConcatenable { typedef const char type[N]; + typedef QByteArray ConvertTo; enum { ExactSize = false }; static int size(const char[N]) { return N - 1; } - static inline void appendTo(const char a[N], QChar *&out) +#ifndef QT_NO_CAST_FROM_ASCII + static inline void QT_ASCII_CAST_WARN appendTo(const char a[N], QChar *&out) { QAbstractConcatenable::convertFromAscii(a, N, out); } +#endif + static inline void appendTo(const char a[N], char *&out) + { + while (*a) + *out++ = *a++; + } }; template <> struct QConcatenable<const char *> : private QAbstractConcatenable { typedef char const *type; + typedef QByteArray ConvertTo; enum { ExactSize = false }; static int size(const char *a) { return qstrlen(a); } - static inline void appendTo(const char *a, QChar *&out) +#ifndef QT_NO_CAST_FROM_ASCII + static inline void QT_ASCII_CAST_WARN appendTo(const char *a, QChar *&out) + { QAbstractConcatenable::convertFromAscii(a, -1, out); } +#endif + static inline void appendTo(const char *a, char *&out) { - QAbstractConcatenable::convertFromAscii(a, -1, out); + while (*a) + *out++ = *a++; } }; template <> struct QConcatenable<QByteArray> : private QAbstractConcatenable { typedef QByteArray type; + typedef QByteArray ConvertTo; enum { ExactSize = false }; static int size(const QByteArray &ba) { return ba.size(); } +#ifndef QT_NO_CAST_FROM_ASCII static inline void appendTo(const QByteArray &ba, QChar *&out) { // adding 1 because convertFromAscii expects the size including the null-termination QAbstractConcatenable::convertFromAscii(ba.constData(), ba.size() + 1, out); } -}; #endif + static inline void appendTo(const QByteArray &ba, char *&out) + { + const char *a = ba.constData(); + const char * const end = ba.end(); + while (a != end) + *out++ = *a++; + } +}; + +namespace QtStringBuilder { + template <typename A, typename B> struct ConvertToTypeHelper + { typedef A ConvertTo; }; + template <typename T> struct ConvertToTypeHelper<T, QString> + { typedef QString ConvertTo; }; +}; + template <typename A, typename B> struct QConcatenable< QStringBuilder<A, B> > { typedef QStringBuilder<A, B> type; + typedef typename QtStringBuilder::ConvertToTypeHelper<typename QConcatenable<A>::ConvertTo, typename QConcatenable<B>::ConvertTo>::ConvertTo ConvertTo; enum { ExactSize = QConcatenable<A>::ExactSize && QConcatenable<B>::ExactSize }; static int size(const type &p) { return QConcatenable<A>::size(p.a) + QConcatenable<B>::size(p.b); } - static inline void appendTo(const QStringBuilder<A, B> &p, QChar *&out) + template<typename T> static inline void appendTo(const type &p, T *&out) { QConcatenable<A>::appendTo(p.a, out); QConcatenable<B>::appendTo(p.b, out); |