Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QDataStream detect unsupported newer version.

QDataStream detect unsupported newer version.

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 6 Posters 2.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J.HilkJ J.Hilk

    hi @VRonin ,
    interessting situation. Have you read through the Versioning section of the QDataStream docu?
    http://doc.qt.io/qt-5/qdatastream.html#versioning

    from 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.

    VRoninV Offline
    VRoninV Offline
    VRonin
    wrote on last edited by VRonin
    #3

    @J.Hilk said in QDataStream detect unsupported newer version.:

    only for complex structs

    Yep, that's why I used QMap<QString,int> above, as I think it changed in from different versions (moved from a skip list to a red-black tree)

    "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
    ~Napoleon Bonaparte

    On a crusade to banish setIndexWidget() from the holy land of Qt

    J.HilkJ 1 Reply Last reply
    0
    • VRoninV VRonin

      @J.Hilk said in QDataStream detect unsupported newer version.:

      only for complex structs

      Yep, that's why I used QMap<QString,int> above, as I think it changed in from different versions (moved from a skip list to a red-black tree)

      J.HilkJ Online
      J.HilkJ Online
      J.Hilk
      Moderators
      wrote on last edited by J.Hilk
      #4

      @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 and QT_VERSION come to mind. Or, as you'll need it at runtime qVersion()


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      2
      • VRoninV VRonin

        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 read map 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?

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by raven-worx
        #5

        @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!

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        3
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #6

          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

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          raven-worxR JonBJ 2 Replies Last reply
          0
          • VRoninV VRonin

            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

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by raven-worx
            #7

            @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 :)

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            VRoninV 1 Reply Last reply
            0
            • VRoninV VRonin

              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

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by JonB
              #8

              @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...?

              1 Reply Last reply
              1
              • raven-worxR raven-worx

                @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 :)

                VRoninV Offline
                VRoninV Offline
                VRonin
                wrote on last edited by VRonin
                #9

                @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 the QDataStream::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?

                @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!

                "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                ~Napoleon Bonaparte

                On a crusade to banish setIndexWidget() from the holy land of Qt

                aha_1980A raven-worxR 2 Replies Last reply
                0
                • VRoninV VRonin

                  @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 the QDataStream::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?

                  @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!

                  aha_1980A Offline
                  aha_1980A Offline
                  aha_1980
                  Lifetime Qt Champion
                  wrote on last edited by
                  #10

                  @VRonin

                  then the easiest solution is to use a feature introduced in Qt 5.11, so neither re-linking nor compiling against older versions give a working program ;)

                  Qt has to stay free or it will die.

                  1 Reply Last reply
                  0
                  • VRoninV VRonin

                    @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 the QDataStream::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?

                    @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!

                    raven-worxR Offline
                    raven-worxR Offline
                    raven-worx
                    Moderators
                    wrote on last edited by
                    #11

                    @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()

                    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                    If you have a question please use the forum so others can benefit from the solution in the future

                    1 Reply Last reply
                    0
                    • VRoninV VRonin

                      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 read map 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?

                      kshegunovK Offline
                      kshegunovK Offline
                      kshegunov
                      Moderators
                      wrote on last edited by kshegunov
                      #12

                      @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;
                      

                      Read and abide by the Qt Code of Conduct

                      1 Reply Last reply
                      1

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved