QDataStream detect unsupported newer version.
-
Say I compile an app that uses
QDataStream
to save some stuff like below with Qt 5.11// QMap<QString,int> map; QDataStream stream(device); const qint32 oldVersion = stream.version(); stream.setVersion(QDataStream::Qt_5_0); stream<< oldVersion; stream.setVersion(oldVersion); stream << map;
The first
qint32
in the device is now 17 (QDataStream::Qt_5_11
).Say I now compile the same app using Qt 5.0 and need to read that data back
qint32 oldVersion; QDataStream stream(device); stream.setVersion(QDataStream::Qt_5_0); stream >> oldVersion; stream.setVersion(oldVersion); stream >> map;
Inside Qt I only saw
version()<
checks so this code will try to readmap
with the most recent version available and it might crash or just contain gibberish.How do I detect the fact that
oldVersion
here contains a value that is too new to my current Qt version? -
hi @VRonin ,
interessting situation. Have you read through theVersioning
section of the QDataStream docu?
http://doc.qt.io/qt-5/qdatastream.html#versioningfrom that I would guess, that writing raw values like
out << (quint32)0xA0B0C0D0;
out << (qint32)123;are done independently, and the different versions matter only for complex structs, enums etc.
-
-
@VRonin
I'm sorry,
I totaly missunderstood your question.Your issue is, that the read Datastream version may be higher than the QDatstream reading it, may support!
I think you could potentially work around that with some QT-Macros.
QT_VERSION_CHECK
andQT_VERSION
come to mind. Or, as you'll need it at runtimeqVersion()
-
@VRonin said in QDataStream detect unsupported newer version.:
How do I detect the fact that oldVersion here contains a value that is too new to my current Qt version?
thats what exactly the versioning paragraph mentions (with an example)?
Write a magic number (or composed Qt-version if you want) as a primitive data-type and then set the version correspondingly.If thats Qt-version-magic number is higher than the compiled Qt version you won't be able to read it.
Edit:
I should have read @J.Hilk's previous post more clearly! -
The problem is not writing and reading the version number it's know what's the most recent
QDataStream
that my program is dynamically linking to. If you distribute anything GPL compatible you have little to no control over the version of Qt used (unless you want to bring in draconic restrictions to linking just because of this).Even #ifdef-ing using Qt version, as @J-Hilk suggested, does not work as a program linked to Qt 5.11 should be binary compatible to Qt 5.0 libraries so the user has the liberty of swapping (dynamic) Qt libraries to the earlier version without ever recompiling, in that case my ifdef would still think it's in Qt5.11 land
-
@VRonin said in QDataStream detect unsupported newer version.:
The problem is not writing and reading the version number it's know what's the most recent QDataStream that my program is dynamically linking to.
Then compare against
QDataStream::Qt_DefaultCompiledVersion
But this is whats returned by default anyway when you call QDataStream::version() (before overwriting it with an explicit setVersion() call)But i am afraid i still don't understand whats your problem is. Either one of us is thinking to complicated :)
-
@VRonin said in QDataStream detect unsupported newer version.:
The problem is not writing and reading the version number it's know what's the most recent QDataStream that my program is dynamically linking to.
If that is indeed what your problem/question is ('coz you two keep arguing about that :) ), and you're saying that is dynamic not compile-time, why not have your app create its own temporary
QDataStream
initially, read it back, and see what the version is? If I've understood correctly....Mind you, won't that just be
QDataStream::Qt_DefaultCompiledVersion
...? -
@raven-worx said in QDataStream detect unsupported newer version.:
Then compare against QDataStream::Qt_DefaultCompiledVersion
That's an enum so as far as I'm aware it's resolved at compile-time
@raven-worx said in QDataStream detect unsupported newer version.:
But i am afraid i still don't understand what your problem is.
- let's pretend for a second that
QMap
had a massive change in how it was serialised in Qt 5.5 - I have some code, that is linking to Q 5.11 that serialises a
qint32
with theQDataStream::Version
that I'm using and the QMap, it will obviously use the new, post-Qt5.5, algorithm - Now I have some other code that reads the QMap back. It was built with Qt 5.11 but the user decided to use Qt5.0 dlls (not a problem, they are binary compatible)
- The new code will read the first
qint32
and should be able to detect that the Qt version linked will not be able to de-serialise the QMap correctly because the Qt5.0 dlls don't have that algorithm. My question is how?
- The new code will read the first
@JonB said in QDataStream detect unsupported newer version.:
create its own temporary QDataStream initially, read it back, and see what the version is?
This is the closest to a solution I have at the moment, it looks ugly though!
- let's pretend for a second that
-
@VRonin said in QDataStream detect unsupported newer version.:
That's an enum so as far as I'm aware it's resolved at compile-time
anyway, as i said. It's the initial default value of QDataStream::version()
-
@VRonin said in QDataStream detect unsupported newer version.:
How do I detect the fact that oldVersion here contains a value that is too new to my current Qt version?
QDataStream stream(device); int currentVersion = stream.version(); // Latest possible stream.setVersion(QDataStream::Qt_5_0); stream >> dataVersion; if (currentVersion < dataVersion) return; // Ooops I did it again stream.setVersion(oldVersion); stream >> map;