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.
Forum Updated to NodeBB v4.3 + New Features

QDataStream detect unsupported newer version.

Scheduled Pinned Locked Moved Solved General and Desktop
12 Posts 6 Posters 2.4k 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.
  • V Offline
    V Offline
    VRonin
    wrote on 13 Jul 2018, 10:15 last edited by VRonin
    #1

    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?

    "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 R K 3 Replies Last reply 13 Jul 2018, 10:43
    0
    • V VRonin
      13 Jul 2018, 10:15

      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 Offline
      J Offline
      J.Hilk
      Moderators
      wrote on 13 Jul 2018, 10:43 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.

      V 1 Reply Last reply 13 Jul 2018, 10:59
      0
      • J J.Hilk
        13 Jul 2018, 10:43

        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.

        V Offline
        V Offline
        VRonin
        wrote on 13 Jul 2018, 10:59 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 1 Reply Last reply 13 Jul 2018, 11:09
        0
        • V VRonin
          13 Jul 2018, 10:59

          @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 Offline
          J Offline
          J.Hilk
          Moderators
          wrote on 13 Jul 2018, 11:09 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
          • V VRonin
            13 Jul 2018, 10:15

            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?

            R Offline
            R Offline
            raven-worx
            Moderators
            wrote on 13 Jul 2018, 11:25 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
            • V Offline
              V Offline
              VRonin
              wrote on 13 Jul 2018, 12:44 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

              R JonBJ 2 Replies Last reply 13 Jul 2018, 12:59
              0
              • V VRonin
                13 Jul 2018, 12:44

                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

                R Offline
                R Offline
                raven-worx
                Moderators
                wrote on 13 Jul 2018, 12:59 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

                V 1 Reply Last reply 13 Jul 2018, 14:32
                0
                • V VRonin
                  13 Jul 2018, 12:44

                  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 13 Jul 2018, 13:48 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
                  • R raven-worx
                    13 Jul 2018, 12:59

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

                    V Offline
                    V Offline
                    VRonin
                    wrote on 13 Jul 2018, 14:32 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 R 2 Replies Last reply 13 Jul 2018, 15:29
                    0
                    • V VRonin
                      13 Jul 2018, 14:32

                      @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 13 Jul 2018, 15:29 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
                      • V VRonin
                        13 Jul 2018, 14:32

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

                        R Offline
                        R Offline
                        raven-worx
                        Moderators
                        wrote on 13 Jul 2018, 16:28 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
                        • V VRonin
                          13 Jul 2018, 10:15

                          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?

                          K Offline
                          K Offline
                          kshegunov
                          Moderators
                          wrote on 14 Jul 2018, 00:04 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

                          1/12

                          13 Jul 2018, 10:15

                          • Login

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