diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2009-09-30 10:41:58 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2009-09-30 10:46:00 (GMT) |
commit | 5170432e7cb2d0d1adf7ac2ec1ece627c75470f3 (patch) | |
tree | e9cca0ad6ba6c59ce1c0477542808e0f063dd7ac /tests/auto/qdatastream | |
parent | 45d5832a504516219167f0205901c56035118944 (diff) | |
download | Qt-5170432e7cb2d0d1adf7ac2ec1ece627c75470f3.zip Qt-5170432e7cb2d0d1adf7ac2ec1ece627c75470f3.tar.gz Qt-5170432e7cb2d0d1adf7ac2ec1ece627c75470f3.tar.bz2 |
Fix floating point precision when using qreal with QDataStream
A frequent bug when using QDataStream across platforms where the size
of qreal is different (such as any desktop platform and an ARM device)
is that you end up using different overloads for streaming the value
in and out (e.g. operator>>(double) on desktop and operator<<(float) on
ARM.)
This can leads to crashes and data corruption. To avoid the problem,
we define a single floating point precision for the entire data stream
and allow this to be set by the user. The default is to use 64-bit
precision for all floating point numbers.
Reviewed-by: Samuel
Reviewed-by: Thiago
Diffstat (limited to 'tests/auto/qdatastream')
-rw-r--r-- | tests/auto/qdatastream/tst_qdatastream.cpp | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/tests/auto/qdatastream/tst_qdatastream.cpp b/tests/auto/qdatastream/tst_qdatastream.cpp index 4f7b34e..add0945 100644 --- a/tests/auto/qdatastream/tst_qdatastream.cpp +++ b/tests/auto/qdatastream/tst_qdatastream.cpp @@ -204,6 +204,8 @@ private slots: void streamRealDataTypes(); + void floatingPointPrecision(); + #ifdef QT3_SUPPORT void task_224283(); #endif @@ -288,7 +290,8 @@ static int NColorRoles[] = { QPalette::AlternateBase + 1, // Qt_4_3 QPalette::ToolTipText + 1, // Qt_4_4 QPalette::ToolTipText + 1, // Qt_4_5 - 0 // add the correct value for Qt_4_6 here later + QPalette::ToolTipText + 1, // Qt_4_6 + 0 // add the correct value for Qt_4_7 here later }; // Testing get/set functions @@ -2538,9 +2541,12 @@ void tst_QDataStream::skipRawData() QFETCH(QByteArray, littleEndianData); \ QFETCH(int, expectedStatus); \ QFETCH(double, expectedValue); \ + \ + QDataStream::FloatingPointPrecision prec = sizeof(T) == sizeof(double) ? QDataStream::DoublePrecision : QDataStream::SinglePrecision; \ \ { \ QDataStream stream(&bigEndianData, QIODevice::ReadOnly); \ + stream.setFloatingPointPrecision(prec); \ T i; \ stream >> i; \ QCOMPARE((int) stream.status(), expectedStatus); \ @@ -2549,6 +2555,7 @@ void tst_QDataStream::skipRawData() { \ QDataStream stream(&littleEndianData, QIODevice::ReadOnly); \ stream.setByteOrder(QDataStream::LittleEndian); \ + stream.setFloatingPointPrecision(prec); \ T i; \ stream >> i; \ QCOMPARE((int) stream.status(), expectedStatus); \ @@ -3359,6 +3366,55 @@ void tst_QDataStream::compatibility_Qt2() QVERIFY(in_palette.color(QPalette::Light) == Qt::green); } +void tst_QDataStream::floatingPointPrecision() +{ + QByteArray ba; + { + QDataStream stream(&ba, QIODevice::WriteOnly); + QCOMPARE(QDataStream::DoublePrecision, stream.floatingPointPrecision()); + + float f = 123.0f; + stream << f; + QCOMPARE(ba.size(), int(sizeof(double))); + + double d = 234.0; + stream << d; + QCOMPARE(ba.size(), int(sizeof(double)*2)); + + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + + f = 123.0f; + stream << f; + QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float))); + + d = 234.0; + stream << d; + QCOMPARE(ba.size(), int(sizeof(double)*2 + sizeof(float)*2)); + } + + { + QDataStream stream(ba); + + float f = 0.0f; + stream >> f; + QCOMPARE(123.0f, f); + + double d = 0.0; + stream >> d; + QCOMPARE(234.0, d); + + f = 0.0f; + stream.setFloatingPointPrecision(QDataStream::SinglePrecision); + stream >> f; + QCOMPARE(123.0f, f); + + d = 0.0; + stream >> d; + QCOMPARE(234.0, d); + } + +} + QTEST_MAIN(tst_QDataStream) #include "tst_qdatastream.moc" |