[Development] Weird offseting in QDataStream

Eskil Abrahamsen Blomfeldt eskil.abrahamsen-blomfeldt at digia.com
Fri Nov 8 11:20:42 CET 2013


On 11/08/2013 11:03 AM, André Somers wrote:
> Olivier Goffart schreef op 8-11-2013 10:57:
>> On Friday 08 November 2013 10:42:16 Yves Bailly wrote:
>>
>>> I can understand this for high-level Qt objects, but what about lower-level
>>> data? Does this mean I can't use QDataStream to read a file written by
>>> some other program, and/or can't use it to *write* a file which could be
>>> read back by some other program? Again, only using low-level data, ints,
>>> floats, and so on.
>>>
>>> If that is true, then it's a huge step backward in the ease of use provided
>>> by Qt in the realm of reading/writing binary files.
>>>
>>> Just to give a context, the goal here is to read and write binary
>>> STL (stereolithography) or PLY files. I have old Qt3 code which works like a
>>> charm, reading and writing files usable to and from other soft (e.g.
>>> Blender). Now moving that old code to Qt5 it seems to not work as expected,
>>> despite using only basic, low-level data types.
>> You can use
>>
>> stream.setVersion(QDataStream::Qt_3_3);
>>
>> To get back to the Qt3 behaviour.
>>
>> Else, yes, you will have to change the floating point precision before every
>> call.  It was changed in Qt 4.6 for compatibility with  qreal  that can be
>> float or double depending on the platform.
>> Perhaps one could add a QDataStream::FloatingPointPrecision::AutoPrecision,
>> that would not be a bad idea.
>>
> What would that mode do, exactly? Isn't the whole point that qreal may
> be defined as float or double, and thus you don't know how it will be
> stored in QDataStream? You cannot detect which meaning of qreal was used
> when the file was written... Or do you mean that it should be something
> like MixedPrecision or TypePrecision that would always use 4 bytes for
> float and 8 for double again (and wreck havoc if you try to use qReal
> for reading or writing)? That indeed would be good, I think. I think
> it's a bit weird that in order to support streaming qreal, you basicaly
> stop supporting reading and writing floats or doubles.

QDataStream supports reading and writing floats and doubles, but it 
might use more bytes than necessary to represent them in the stream.

The main use case of QDataStream is to serialize Qt data in a portable, 
binary form with the convenience that the code used to write and read 
the file are inverses of each other. One objective is that you get 
predictable results when moving your existing code and data to new 
platforms, and this was not at all the case before we standardized on a 
floating point precision for all floating point values in QDataStream 
for Qt 4.6. (For the same reason, QDataStream also assumes a particular 
endianness of the input data, and this also might have to be overridden 
manually if you want to read data that is not written by QDataStream.)

It's pretty easy to read four bytes from a QIODevice if you do not worry 
about portability.

Personally, having MixedPrecision/AutoPrecision seems unnecessary, since 
you would still have to be aware of the issue before you can make the 
decision to set this mode, and once you are aware of the issue, you can 
use setFloatingPointPrecision() to achieve the results you want and your 
code will still be cross-platform.

-- Eskil



More information about the Development mailing list