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.
Qt 6.11 is out! See what's new in the release blog

QDataStream detect unsupported newer version.

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 6 Posters 4.0k Views 3 Watching
  • 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.
  • 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?

    J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #2

    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.


    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.

    VRoninV 1 Reply Last reply
    0
    • 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 Offline
        J.HilkJ Offline
        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