summaryrefslogtreecommitdiffstats
path: root/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/corelib/global/qtendian/tst_qtendian.cpp')
-rw-r--r--tests/auto/corelib/global/qtendian/tst_qtendian.cpp176
1 files changed, 173 insertions, 3 deletions
diff --git a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
index 6934818dcf..2345bb39c1 100644
--- a/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
+++ b/tests/auto/corelib/global/qtendian/tst_qtendian.cpp
@@ -39,9 +39,17 @@ class tst_QtEndian: public QObject
private slots:
void fromBigEndian();
void fromLittleEndian();
+ void fromBigEndianRegion_data();
+ void fromBigEndianRegion();
+ void fromLittleEndianRegion_data() { fromBigEndianRegion_data(); }
+ void fromLittleEndianRegion();
void toBigEndian();
void toLittleEndian();
+ void toBigEndianRegion_data() { fromBigEndianRegion_data(); }
+ void toBigEndianRegion();
+ void toLittleEndianRegion_data() { fromBigEndianRegion_data(); }
+ void toLittleEndianRegion();
void endianIntegers_data();
void endianIntegers();
@@ -56,18 +64,58 @@ struct TestData
quint16 data16;
quint8 data8;
+ float dataFloat;
+ double dataDouble;
+
quint8 reserved;
};
+template <typename T> T getData(const TestData &d);
+template <> quint8 getData(const TestData &d) { return d.data8; }
+template <> quint16 getData(const TestData &d) { return d.data16; }
+template <> quint32 getData(const TestData &d) { return d.data32; }
+template <> quint64 getData(const TestData &d) { return d.data64; }
+template <> float getData(const TestData &d) { return d.dataFloat; }
+
union RawTestData
{
uchar rawData[sizeof(TestData)];
TestData data;
};
-static const TestData inNativeEndian = { Q_UINT64_C(0x0123456789abcdef), 0x00c0ffee, 0xcafe, 0xcf, '\0' };
-static const RawTestData inBigEndian = { "\x01\x23\x45\x67\x89\xab\xcd\xef" "\x00\xc0\xff\xee" "\xca\xfe" "\xcf" };
-static const RawTestData inLittleEndian = { "\xef\xcd\xab\x89\x67\x45\x23\x01" "\xee\xff\xc0\x00" "\xfe\xca" "\xcf" };
+template <typename Float>
+Float int2Float(typename QIntegerForSizeof<Float>::Unsigned i)
+{
+ Float result = 0;
+ memcpy(reinterpret_cast<char *>(&result), reinterpret_cast<const char *>(&i), sizeof (Float));
+ return result;
+}
+
+static const TestData inNativeEndian = {
+ Q_UINT64_C(0x0123456789abcdef),
+ 0x00c0ffee,
+ 0xcafe,
+ 0xcf,
+ int2Float<float>(0x00c0ffeeU),
+ int2Float<double>(Q_UINT64_C(0x0123456789abcdef)),
+ '\0'
+};
+static const RawTestData inBigEndian = {
+ "\x01\x23\x45\x67\x89\xab\xcd\xef"
+ "\x00\xc0\xff\xee"
+ "\xca\xfe"
+ "\xcf"
+ "\x00\xc0\xff\xee"
+ "\x01\x23\x45\x67\x89\xab\xcd\xef"
+};
+static const RawTestData inLittleEndian = {
+ "\xef\xcd\xab\x89\x67\x45\x23\x01"
+ "\xee\xff\xc0\x00"
+ "\xfe\xca"
+ "\xcf"
+ "\xee\xff\xc0\x00"
+ "\xef\xcd\xab\x89\x67\x45\x23\x01"
+};
#define EXPAND_ENDIAN_TEST(endian) \
do { \
@@ -108,6 +156,106 @@ void tst_QtEndian::fromLittleEndian()
#undef ENDIAN_TEST
+template <typename T>
+void transformRegion_template(T (*transformOne)(T), void (*transformRegion)(const void *, qsizetype, void *))
+{
+ enum { Size = 64 };
+ T source[Size];
+ T dest[Size];
+ T expected = transformOne(getData<T>(inNativeEndian));
+ std::fill_n(source, +Size, getData<T>(inNativeEndian));
+ memset(dest, 0, sizeof(dest));
+
+ auto checkBounds = [&](int from) {
+ for ( ; from < Size; ++from)
+ QCOMPARE(dest[from], T(0));
+ };
+
+ transformRegion(source, 1, dest);
+ QCOMPARE(dest[0], expected);
+ checkBounds(1);
+ memset(dest, 0, sizeof(T));
+
+ transformRegion(source, 2, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ checkBounds(2);
+ memset(dest, 0, sizeof(T) * 2);
+
+ transformRegion(source, 3, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ QCOMPARE(dest[2], expected);
+ checkBounds(3);
+ memset(dest, 0, sizeof(T) * 3);
+
+ transformRegion(source, 4, dest);
+ QCOMPARE(dest[0], expected);
+ QCOMPARE(dest[1], expected);
+ QCOMPARE(dest[2], expected);
+ QCOMPARE(dest[3], expected);
+ checkBounds(4);
+ memset(dest, 0, sizeof(T) * 4);
+
+ transformRegion(source, 8, dest);
+ for (int i = 0; i < 8; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(8);
+ memset(dest, 0, sizeof(T) * 8);
+
+ transformRegion(source, 16, dest);
+ for (int i = 0; i < 16; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(16);
+ memset(dest, 0, sizeof(T) * 16);
+
+ transformRegion(source, 32, dest);
+ for (int i = 0; i < 32; ++i)
+ QCOMPARE(dest[i], expected);
+ checkBounds(32);
+ memset(dest, 0, sizeof(T) * 32);
+
+ transformRegion(source, 64, dest);
+ for (int i = 0; i < 64; ++i)
+ QCOMPARE(dest[i], expected);
+
+ // check transforming in-place
+ memcpy(dest, source, sizeof(dest));
+ transformRegion(dest, 64, dest);
+ for (int i = 0; i < 64; ++i)
+ QCOMPARE(dest[i], expected);
+}
+
+void tst_QtEndian::fromBigEndianRegion_data()
+{
+ QTest::addColumn<int>("size");
+ QTest::newRow("1") << 1;
+ QTest::newRow("2") << 2;
+ QTest::newRow("4") << 4;
+ QTest::newRow("8") << 8;
+}
+
+void tst_QtEndian::fromBigEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qFromBigEndian<quint8>, qFromBigEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qFromBigEndian<quint16>, qFromBigEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qFromBigEndian<quint32>, qFromBigEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qFromBigEndian<quint64>, qFromBigEndian<quint64>);
+ }
+}
+
+void tst_QtEndian::fromLittleEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qFromLittleEndian<quint8>, qFromLittleEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qFromLittleEndian<quint16>, qFromLittleEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qFromLittleEndian<quint32>, qFromLittleEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qFromLittleEndian<quint64>, qFromLittleEndian<quint64>);
+ }
+}
#define ENDIAN_TEST(endian, type, size) \
do { \
@@ -135,6 +283,28 @@ void tst_QtEndian::toLittleEndian()
#undef ENDIAN_TEST
+void tst_QtEndian::toBigEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qToBigEndian<quint8>, qToBigEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qToBigEndian<quint16>, qToBigEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qToBigEndian<quint32>, qToBigEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qToBigEndian<quint64>, qToBigEndian<quint64>);
+ }
+}
+
+void tst_QtEndian::toLittleEndianRegion()
+{
+ QFETCH(int, size);
+ switch (size) {
+ case 1: return transformRegion_template<quint8>(qToLittleEndian<quint8>, qToLittleEndian<quint8>);
+ case 2: return transformRegion_template<quint16>(qToLittleEndian<quint16>, qToLittleEndian<quint16>);
+ case 4: return transformRegion_template<quint32>(qToLittleEndian<quint32>, qToLittleEndian<quint32>);
+ case 8: return transformRegion_template<quint64>(qToLittleEndian<quint64>, qToLittleEndian<quint64>);
+ }
+}
+
void tst_QtEndian::endianIntegers_data()
{
QTest::addColumn<int>("val");