diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2013-10-10 19:43:22 -0700 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-12-13 09:30:04 +0100 |
commit | ee7536876cee007efef4b8d7e861721f88af1a19 (patch) | |
tree | 2f66aba902d93d3ff2d35cd20a45a0a39406418a /src/corelib/tools | |
parent | 8892e3d0fc8258975f27aa90bef741fb4254ce7e (diff) |
Add the UTF16-to-Latin1 in-place converter
This is only possible for two important reasons:
1) QString and QByteArray d pointers are both done with QArrayData and
that class does not care that the alignof(T) changes from 2 to 1,
so we can give the pointer from QString to QByteArray
(after adapting the allocated size, which is now double)
2) conversion from UTF16 to Latin1 always has fewer bytes (exactly half)
Change-Id: I17b2690c910f3de8db55156c6d6b5f55be06d827
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
Diffstat (limited to 'src/corelib/tools')
-rw-r--r-- | src/corelib/tools/qstring.cpp | 30 | ||||
-rw-r--r-- | src/corelib/tools/qstring.h | 3 |
2 files changed, 32 insertions, 1 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1b07e31c89..18c96c0b38 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -4020,6 +4020,36 @@ QByteArray QString::toLatin1_helper(const QChar *data, int length) return ba; } +QByteArray QString::toLatin1_helper_inplace(QString &s) +{ + if (!s.isDetached()) + return s.toLatin1(); + + // We can return our own buffer to the caller. + // Conversion to Latin-1 always shrinks the buffer by half. + const ushort *data = reinterpret_cast<const ushort *>(s.constData()); + uint length = s.size(); + + // Swap the d pointers. + // Kids, avert your eyes. Don't try this at home. + QArrayData *ba_d = s.d; + + // multiply the allocated capacity by sizeof(ushort) + ba_d->alloc *= sizeof(ushort); + + // reset ourselves to QString() + s.d = QString().d; + + // do the in-place conversion + uchar *dst = reinterpret_cast<uchar *>(ba_d->data()); + QT_PREPEND_NAMESPACE(toLatin1_helper)(dst, data, length); + dst[length] = '\0'; + + QByteArrayDataPtr badptr = { ba_d }; + return QByteArray(badptr); +} + + /*! \fn QByteArray QString::toLatin1() const diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 943d7c266e..460afb00f4 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -481,7 +481,7 @@ public: QByteArray toLatin1() const & Q_REQUIRED_RESULT { return toLatin1_helper(*this); } QByteArray toLatin1() && Q_REQUIRED_RESULT - { return toLatin1_helper(reinterpret_cast<const ushort *>(constData()), size()); } + { return toLatin1_helper_inplace(*this); } QByteArray toUtf8() const & Q_REQUIRED_RESULT { return toUtf8_helper(*this); } QByteArray toUtf8() && Q_REQUIRED_RESULT @@ -751,6 +751,7 @@ private: static QString fromLocal8Bit_helper(const char *, int size); static QByteArray toLatin1_helper(const QString &); static QByteArray toLatin1_helper(const QChar *data, int size); + static QByteArray toLatin1_helper_inplace(QString &); static QByteArray toUtf8_helper(const QString &); static QByteArray toLocal8Bit_helper(const QChar *data, int size); static int toUcs4_helper(const ushort *uc, int length, uint *out); |