From 5c2ff22ba117f295718c529198ab42ee4646d90c Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
Date: Tue, 26 Apr 2016 16:40:37 -0700
Subject: [PATCH] Use void instead of uchar in the endian-swapping function
 parameters

This allows us to pass pointers to storage that is not an array of
uchar, which it hardly ever is.

Change-Id: Ifea6e497f11a461db432ffff14490d2c2df21906
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
---
 src/corelib/global/qendian.h                  | 57 ++++++++++---------
 src/corelib/global/qendian.qdoc               | 20 +++++--
 src/corelib/json/qjson.cpp                    |  2 +-
 src/corelib/json/qjsonparser.cpp              |  2 +-
 src/corelib/mimetypes/qmimemagicrule.cpp      |  2 +-
 src/corelib/plugin/qelfparser_p.h             |  4 +-
 src/gui/text/qfontengine_qpf2.cpp             |  2 +-
 src/gui/text/qfontsubset.cpp                  |  2 +-
 src/network/access/qspdyprotocolhandler.cpp   | 20 +++----
 .../fontdatabases/mac/qfontengine_coretext.mm |  4 +-
 src/plugins/generic/tuiotouch/qoscbundle.cpp  |  4 +-
 src/plugins/generic/tuiotouch/qoscmessage.cpp |  4 +-
 src/plugins/platforms/xcb/qxcbxsettings.cpp   |  4 +-
 13 files changed, 68 insertions(+), 59 deletions(-)

diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h
index 34bb015a2fa..c2028289a7e 100644
--- a/src/corelib/global/qendian.h
+++ b/src/corelib/global/qendian.h
@@ -58,25 +58,26 @@ QT_BEGIN_NAMESPACE
 /*
  * ENDIAN FUNCTIONS
 */
-inline void qbswap_helper(const uchar *src, uchar *dest, int size)
+inline void qbswap_helper(const void *src, void *dest, int size)
 {
-    for (int i = 0; i < size ; ++i) dest[i] = src[size - 1 - i];
+    for (int i = 0; i < size ; ++i)
+        static_cast<uchar *>(dest)[i] = static_cast<const uchar *>(src)[size - 1 - i];
 }
 
 /*
- * qbswap(const T src, const uchar *dest);
+ * qbswap(const T src, const void *dest);
  * Changes the byte order of \a src from big endian to little endian or vice versa
  * and stores the result in \a dest.
  * There is no alignment requirements for \a dest.
 */
-template <typename T> inline void qbswap(const T src, uchar *dest)
+template <typename T> inline void qbswap(const T src, void *dest)
 {
-    qbswap_helper(reinterpret_cast<const uchar *>(&src), dest, sizeof(T));
+    qbswap_helper(&src, dest, sizeof(T));
 }
 
 // Used to implement a type-safe and alignment-safe copy operation
 // If you want to avoid the memcpy, you must write specializations for these functions
-template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, uchar *dest)
+template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, void *dest)
 {
     // Using sizeof(T) inside memcpy function produces internal compiler error with
     // MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T.
@@ -89,7 +90,7 @@ template <typename T> Q_ALWAYS_INLINE void qToUnaligned(const T src, uchar *dest
             (dest, &src, size);
 }
 
-template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const uchar *src)
+template <typename T> Q_ALWAYS_INLINE T qFromUnaligned(const void *src)
 {
     T dest;
     const size_t size = sizeof(T);
@@ -122,11 +123,11 @@ template <> inline quint32 qbswap<quint32>(quint32 source)
     return __builtin_bswap32(source);
 }
 
-template <> inline void qbswap<quint64>(quint64 source, uchar *dest)
+template <> inline void qbswap<quint64>(quint64 source, void *dest)
 {
     qToUnaligned<quint64>(__builtin_bswap64(source), dest);
 }
-template <> inline void qbswap<quint32>(quint32 source, uchar *dest)
+template <> inline void qbswap<quint32>(quint32 source, void *dest)
 {
     qToUnaligned<quint32>(__builtin_bswap32(source), dest);
 }
@@ -158,7 +159,7 @@ template <> inline quint16 qbswap<quint16>(quint16 source)
 {
     return __builtin_bswap16(source);
 }
-template <> inline void qbswap<quint16>(quint16 source, uchar *dest)
+template <> inline void qbswap<quint16>(quint16 source, void *dest)
 {
     qToUnaligned<quint16>(__builtin_bswap16(source), dest);
 }
@@ -187,17 +188,17 @@ template <> inline qint16 qbswap<qint16>(qint16 source)
     return qbswap<quint16>(quint16(source));
 }
 
-template <> inline void qbswap<qint64>(qint64 source, uchar *dest)
+template <> inline void qbswap<qint64>(qint64 source, void *dest)
 {
     qbswap<quint64>(quint64(source), dest);
 }
 
-template <> inline void qbswap<qint32>(qint32 source, uchar *dest)
+template <> inline void qbswap<qint32>(qint32 source, void *dest)
 {
     qbswap<quint32>(quint32(source), dest);
 }
 
-template <> inline void qbswap<qint16>(qint16 source, uchar *dest)
+template <> inline void qbswap<qint16>(qint16 source, void *dest)
 {
     qbswap<quint16>(quint16(source), dest);
 }
@@ -212,9 +213,9 @@ template <typename T> inline T qToLittleEndian(T source)
 { return qbswap<T>(source); }
 template <typename T> inline T qFromLittleEndian(T source)
 { return qbswap<T>(source); }
-template <typename T> inline void qToBigEndian(T src, uchar *dest)
+template <typename T> inline void qToBigEndian(T src, void *dest)
 { qToUnaligned<T>(src, dest); }
-template <typename T> inline void qToLittleEndian(T src, uchar *dest)
+template <typename T> inline void qToLittleEndian(T src, void *dest)
 { qbswap<T>(src, dest); }
 #else // Q_LITTLE_ENDIAN
 
@@ -226,9 +227,9 @@ template <typename T> inline T qToLittleEndian(T source)
 { return source; }
 template <typename T> inline T qFromLittleEndian(T source)
 { return source; }
-template <typename T> inline void qToBigEndian(T src, uchar *dest)
+template <typename T> inline void qToBigEndian(T src, void *dest)
 { qbswap<T>(src, dest); }
-template <typename T> inline void qToLittleEndian(T src, uchar *dest)
+template <typename T> inline void qToLittleEndian(T src, void *dest)
 { qToUnaligned<T>(src, dest); }
 
 #endif // Q_BYTE_ORDER == Q_BIG_ENDIAN
@@ -243,34 +244,34 @@ template <> inline qint8 qbswap<qint8>(qint8 source)
     return source;
 }
 
-/* T qFromLittleEndian(const uchar *src)
+/* T qFromLittleEndian(const void *src)
  * This function will read a little-endian encoded value from \a src
  * and return the value in host-endian encoding.
  * There is no requirement that \a src must be aligned.
 */
-template <typename T> inline T qFromLittleEndian(const uchar *src)
+template <typename T> inline T qFromLittleEndian(const void *src)
 {
     return qFromLittleEndian(qFromUnaligned<T>(src));
 }
 
-template <> inline quint8 qFromLittleEndian<quint8>(const uchar *src)
-{ return static_cast<quint8>(src[0]); }
-template <> inline qint8 qFromLittleEndian<qint8>(const uchar *src)
-{ return static_cast<qint8>(src[0]); }
+template <> inline quint8 qFromLittleEndian<quint8>(const void *src)
+{ return static_cast<const quint8 *>(src)[0]; }
+template <> inline qint8 qFromLittleEndian<qint8>(const void *src)
+{ return static_cast<const qint8 *>(src)[0]; }
 
 /* This function will read a big-endian (also known as network order) encoded value from \a src
  * and return the value in host-endian encoding.
  * There is no requirement that \a src must be aligned.
 */
-template <class T> inline T qFromBigEndian(const uchar *src)
+template <class T> inline T qFromBigEndian(const void *src)
 {
     return qFromBigEndian(qFromUnaligned<T>(src));
 }
 
-template <> inline quint8 qFromBigEndian<quint8>(const uchar *src)
-{ return static_cast<quint8>(src[0]); }
-template <> inline qint8 qFromBigEndian<qint8>(const uchar *src)
-{ return static_cast<qint8>(src[0]); }
+template <> inline quint8 qFromBigEndian<quint8>(const void *src)
+{ return static_cast<const quint8 *>(src)[0]; }
+template <> inline qint8 qFromBigEndian<qint8>(const void *src)
+{ return static_cast<const qint8 *>(src)[0]; }
 
 QT_END_NAMESPACE
 
diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.qdoc
index 3b22dcec875..9ce9dbdb0e5 100644
--- a/src/corelib/global/qendian.qdoc
+++ b/src/corelib/global/qendian.qdoc
@@ -35,7 +35,7 @@
 
 /*!
     \internal
-    \fn T qFromUnaligned(const uchar *ptr)
+    \fn T qFromUnaligned(const void *ptr)
     \since 5.5
 
     Loads a \c{T} from address \a ptr, which may be misaligned.
@@ -46,7 +46,7 @@
 
 /*!
     \internal
-    \fn void qToUnaligned(T t, uchar *ptr)
+    \fn void qToUnaligned(T t, void *ptr)
     \since 4.5
 
     Stores \a t to address \a ptr, which may be misaligned.
@@ -57,7 +57,7 @@
 
 
 /*!
-    \fn T qFromBigEndian(const uchar *src)
+    \fn T qFromBigEndian(const void *src)
     \since 4.3
     \relates <QtEndian>
 
@@ -69,6 +69,8 @@
     \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of
     integers, e.g., qlong, are not applicable.
 
+    \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
+
     There are no data alignment constraints for \a src.
 
     \sa qFromLittleEndian()
@@ -88,7 +90,7 @@
     unmodified.
 */
 /*!
-    \fn T qFromLittleEndian(const uchar *src)
+    \fn T qFromLittleEndian(const void *src)
     \since 4.3
     \relates <QtEndian>
 
@@ -100,6 +102,8 @@
     \note Template type \c{T} can either be a qint16, qint32 or qint64. Other types of
     integers, e.g., qlong, are not applicable.
 
+    \note Since Qt 5.7, the type of the \a src parameter is a void pointer.
+
     There are no data alignment constraints for \a src.
 
     \sa qFromBigEndian()
@@ -119,7 +123,7 @@
     unmodified.
 */
 /*!
-    \fn void qToBigEndian(T src, uchar *dest)
+    \fn void qToBigEndian(T src, void *dest)
     \since 4.3
     \relates <QtEndian>
 
@@ -130,6 +134,8 @@
 
     There are no data alignment constraints for \a dest.
 
+    \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
+
     \sa qFromBigEndian()
     \sa qFromLittleEndian()
     \sa qToLittleEndian()
@@ -147,7 +153,7 @@
     unmodified.
 */
 /*!
-    \fn void qToLittleEndian(T src, uchar *dest)
+    \fn void qToLittleEndian(T src, void *dest)
     \since 4.3
     \relates <QtEndian>
 
@@ -158,6 +164,8 @@
 
     There are no data alignment constraints for \a dest.
 
+    \note Since Qt 5.7, the type of the \a dest parameter is a void pointer.
+
     \sa qFromBigEndian()
     \sa qFromLittleEndian()
     \sa qToBigEndian()
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp
index bb98e25fa57..4b98ef076ca 100644
--- a/src/corelib/json/qjson.cpp
+++ b/src/corelib/json/qjson.cpp
@@ -435,7 +435,7 @@ void Value::copyData(const QJsonValue &v, char *dest, bool compressed)
     switch (v.t) {
     case QJsonValue::Double:
         if (!compressed) {
-            qToLittleEndian(v.ui, (uchar *)dest);
+            qToLittleEndian(v.ui, dest);
         }
         break;
     case QJsonValue::String: {
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 2926adf10ae..6a3d1de99a6 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -738,7 +738,7 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset)
     }
 
     int pos = reserveSpace(sizeof(double));
-    qToLittleEndian(ui, reinterpret_cast<uchar *>(data + pos));
+    qToLittleEndian(ui, data + pos);
     if (current - baseOffset >= Value::MaxSize) {
         lastError = QJsonParseError::DocumentTooLarge;
         return false;
diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp
index 8461bf7130e..7e07f8acb9e 100644
--- a/src/corelib/mimetypes/qmimemagicrule.cpp
+++ b/src/corelib/mimetypes/qmimemagicrule.cpp
@@ -163,7 +163,7 @@ bool QMimeMagicRule::matchNumber(const QByteArray &data) const
     const char *p = data.constData() + m_startPos;
     const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), m_endPos + 1);
     for ( ; p <= e; ++p) {
-        if ((qFromUnaligned<T>(reinterpret_cast<const uchar *>(p)) & mask) == (value & mask))
+        if ((qFromUnaligned<T>(p) & mask) == (value & mask))
             return true;
     }
 
diff --git a/src/corelib/plugin/qelfparser_p.h b/src/corelib/plugin/qelfparser_p.h
index 2ecdc4e7861..145f00df434 100644
--- a/src/corelib/plugin/qelfparser_p.h
+++ b/src/corelib/plugin/qelfparser_p.h
@@ -89,9 +89,9 @@ public:
     T read(const char *s)
     {
         if (m_endian == ElfBigEndian)
-            return qFromBigEndian<T>(reinterpret_cast<const uchar *>(s));
+            return qFromBigEndian<T>(s);
         else
-            return qFromLittleEndian<T>(reinterpret_cast<const uchar *>(s));
+            return qFromLittleEndian<T>(s);
     }
 
     const char *parseSectionHeader(const char* s, ElfSectionHeader *sh);
diff --git a/src/gui/text/qfontengine_qpf2.cpp b/src/gui/text/qfontengine_qpf2.cpp
index c3a911fc55a..2e4af09550c 100644
--- a/src/gui/text/qfontengine_qpf2.cpp
+++ b/src/gui/text/qfontengine_qpf2.cpp
@@ -533,7 +533,7 @@ void QPF2Generator::writeHeader()
     {
         const QByteArray head = fe->getSfntTable(MAKE_TAG('h', 'e', 'a', 'd'));
         if (head.size() >= 4) {
-            const quint32 revision = qFromBigEndian<quint32>(reinterpret_cast<const uchar *>(head.constData()));
+            const quint32 revision = qFromBigEndian<quint32>(head.constData());
             writeTaggedUInt32(QFontEngineQPF2::Tag_FontRevision, revision);
         }
     }
diff --git a/src/gui/text/qfontsubset.cpp b/src/gui/text/qfontsubset.cpp
index f591b4333c2..c8f0393084c 100644
--- a/src/gui/text/qfontsubset.cpp
+++ b/src/gui/text/qfontsubset.cpp
@@ -1145,7 +1145,7 @@ static QByteArray bindFont(const QVector<QTtfTable>& _tables)
 
     // calculate the fonts checksum and qToBigEndian into 'head's checksum_adjust
     quint32 checksum_adjust = 0xB1B0AFBA - checksum(font);
-    qToBigEndian(checksum_adjust, (uchar *)font.data() + head_offset + 8);
+    qToBigEndian(checksum_adjust, font.data() + head_offset + 8);
 
     return font;
 }
diff --git a/src/network/access/qspdyprotocolhandler.cpp b/src/network/access/qspdyprotocolhandler.cpp
index e4e058b7727..413b03cc22f 100644
--- a/src/network/access/qspdyprotocolhandler.cpp
+++ b/src/network/access/qspdyprotocolhandler.cpp
@@ -364,43 +364,43 @@ void QSpdyProtocolHandler::_q_readyRead()
 
 static qint16 twoBytesToInt(const char *bytes)
 {
-    return qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(bytes));
+    return qFromBigEndian<qint16>(bytes);
 }
 
 static qint32 threeBytesToInt(const char *bytes)
 {
-    return qFromBigEndian<qint32>(reinterpret_cast<const uchar *>(bytes)) >> 8;
+    return qFromBigEndian<qint32>(bytes) >> 8;
 }
 
 static qint32 fourBytesToInt(const char *bytes)
 {
-    return qFromBigEndian<qint32>(reinterpret_cast<const uchar *>(bytes));
+    return qFromBigEndian<qint32>(bytes);
 }
 
 static void appendIntToThreeBytes(char *output, qint32 number)
 {
-    qToBigEndian<qint16>(number, reinterpret_cast<uchar *>(output + 1));
-    qToBigEndian<qint8>(number >> 16, reinterpret_cast<uchar *>(output));
+    qToBigEndian<qint16>(number, output + 1);
+    qToBigEndian<qint8>(number >> 16, output);
 }
 
 static void appendIntToFourBytes(char *output, qint32 number)
 {
-    qToBigEndian<qint32>(number, reinterpret_cast<uchar *>(output));
+    qToBigEndian<qint32>(number, output);
 }
 
 static QByteArray intToFourBytes(qint32 number) // ### try to use appendIntToFourBytes where possible
 {
-    uchar data[4];
+    char data[4];
     qToBigEndian<qint32>(number, data);
-    QByteArray ret(reinterpret_cast<char *>(data), 4);
+    QByteArray ret(data, 4);
     return ret;
 }
 
 static QByteArray intToThreeBytes(qint32 number)
 {
-    uchar data[4];
+    char data[4];
     qToBigEndian<qint32>(number << 8, data);
-    QByteArray ret(reinterpret_cast<char *>(data), 3);
+    QByteArray ret(data, 3);
     return ret;
 }
 
diff --git a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
index 3d214b6f392..942bb6c6bb2 100644
--- a/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
+++ b/src/platformsupport/fontdatabases/mac/qfontengine_coretext.mm
@@ -251,9 +251,9 @@ void QCoreTextFontEngine::init()
     QByteArray os2Table = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
     unsigned emSize = CTFontGetUnitsPerEm(ctfont);
     if (os2Table.size() >= 10) {
-        fsType = qFromBigEndian<quint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 8));
+        fsType = qFromBigEndian<quint16>(os2Table.constData() + 8);
         // qAbs is a workaround for weird fonts like Lucida Grande
-        qint16 width = qAbs(qFromBigEndian<qint16>(reinterpret_cast<const uchar *>(os2Table.constData() + 2)));
+        qint16 width = qAbs(qFromBigEndian<qint16>(os2Table.constData() + 2));
         avgCharWidth = QFixed::fromReal(width * fontDef.pixelSize / emSize);
     } else
         avgCharWidth = QFontEngine::averageCharWidth();
diff --git a/src/plugins/generic/tuiotouch/qoscbundle.cpp b/src/plugins/generic/tuiotouch/qoscbundle.cpp
index 26dabebd23b..6ddca9b09d2 100644
--- a/src/plugins/generic/tuiotouch/qoscbundle.cpp
+++ b/src/plugins/generic/tuiotouch/qoscbundle.cpp
@@ -89,9 +89,9 @@ QOscBundle::QOscBundle(const QByteArray &data)
     // (editor's note: one may wonder how a 64bit big-endian number can also be
     // two 32bit numbers, without specifying in which order they occur or
     // anything, and one may indeed continue to wonder.)
-    quint32 oscTimeEpoch = qFromBigEndian<quint32>((const uchar*)data.constData() + parsedBytes);
+    quint32 oscTimeEpoch = qFromBigEndian<quint32>(data.constData() + parsedBytes);
     parsedBytes += sizeof(quint32);
-    quint32 oscTimePico = qFromBigEndian<quint32>((const uchar*)data.constData() + parsedBytes);
+    quint32 oscTimePico = qFromBigEndian<quint32>(data.constData() + parsedBytes);
     parsedBytes += sizeof(quint32);
 
     bool isImmediate = false;
diff --git a/src/plugins/generic/tuiotouch/qoscmessage.cpp b/src/plugins/generic/tuiotouch/qoscmessage.cpp
index 30cf117767d..6f82cd784bc 100644
--- a/src/plugins/generic/tuiotouch/qoscmessage.cpp
+++ b/src/plugins/generic/tuiotouch/qoscmessage.cpp
@@ -95,7 +95,7 @@ QOscMessage::QOscMessage(const QByteArray &data)
             if (parsedBytes > (quint32)data.size() || data.size() - parsedBytes < sizeof(quint32))
                 return;
 
-            quint32 anInt = qFromBigEndian<quint32>((const uchar*)data.constData() + parsedBytes);
+            quint32 anInt = qFromBigEndian<quint32>(data.constData() + parsedBytes);
             parsedBytes += sizeof(quint32);
 
             // TODO: is int32 in OSC signed, or unsigned?
@@ -109,7 +109,7 @@ QOscMessage::QOscMessage(const QByteArray &data)
                 quint32 u;
                 float f;
             } value;
-            value.u = qFromBigEndian<quint32>((const uchar*)data.constData() + parsedBytes);
+            value.u = qFromBigEndian<quint32>(data.constData() + parsedBytes);
             parsedBytes += sizeof(quint32);
             arguments.append(value.f);
         } else {
diff --git a/src/plugins/platforms/xcb/qxcbxsettings.cpp b/src/plugins/platforms/xcb/qxcbxsettings.cpp
index 899dc0158a2..401eb8043c7 100644
--- a/src/plugins/platforms/xcb/qxcbxsettings.cpp
+++ b/src/plugins/platforms/xcb/qxcbxsettings.cpp
@@ -158,8 +158,8 @@ public:
 
 #define ADJUST_BO(b, t, x) \
         ((b == LSBFirst) ?                          \
-         qFromLittleEndian<t>((const uchar *)(x)) : \
-         qFromBigEndian<t>((const uchar *)(x)))
+         qFromLittleEndian<t>(x) : \
+         qFromBigEndian<t>(x))
 #define VALIDATE_LENGTH(x)    \
         if ((size_t)xSettings.length() < (offset + local_offset + 12 + x)) { \
             qWarning("Length %d runs past end of data", x); \
-- 
GitLab