summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2013-10-10 19:43:22 -0700
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-12-13 09:30:04 +0100
commitee7536876cee007efef4b8d7e861721f88af1a19 (patch)
tree2f66aba902d93d3ff2d35cd20a45a0a39406418a /src/corelib/tools
parent8892e3d0fc8258975f27aa90bef741fb4254ce7e (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.cpp30
-rw-r--r--src/corelib/tools/qstring.h3
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);