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. Serializing std::string over QDataStream

Serializing std::string over QDataStream

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 6 Posters 4.1k 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.
  • D Offline
    D Offline
    DRoscoe
    wrote on last edited by
    #1

    My apologies in advance is this is a silly question. I thought this would be easy, but its turning out to be anything but, so maybe I am missing something.

    I am converting a lot of legacy message classes to use QDataStream for serialization/deserialization. As you would expect, the legacy messages contain many non-Qt data structures, the most ubiquitous of which is std::string. In my message base class I want to define a global overload of QDataStream's streaming operators to deal with std::strings. This is what I have:

    Serialization

    QDataStream& operator <<(QDataStream& out, const std::string& in)
    {
      out << in.c_str(); // serializing as const char*
      return out;
    }
    

    Deserialization

    QDataStream& operator >>(QDataStream& in, std::string& out)
    {
      quint32 size;
      in >> size;
      char* data = new char[size];
      in >> data;
      out.append(data, size);
      delete[] data;
      return in;
    }
    

    Am I doing that correctly? I supposed I could have constructed a QString in the original serialization and simply deserialized into a QString and then constructed a new std::string:

    Serialization

    QDataStream& operator <<(QDataStream& out, const std::string& in)
    {
      QString temp(in.c_str());
      out << temp;
      return out;
    }
    

    Deserialization

    QDataStream& operator >>(QDataStream& in, std::string& out)
    {
      QString temp;
      in >> temp;
      out = temp.toStdString();
      return in;
    }
    

    As usual, I am looking at best practices to avoid propagating bad examples throughout my code for future developers

    1 Reply Last reply
    0
    • Chris KawaC Offline
      Chris KawaC Offline
      Chris Kawa
      Lifetime Qt Champion
      wrote on last edited by
      #2

      That's not correct. See the docs. You should not manually read the size or allocate the buffer. Qt will do that. You need only to delete it:

      QDataStream& operator >>(QDataStream& in, std::string& out)
      {
        char* data;
        in >> data;
        if (data)
           out = data;
        delete[] data;
        return in;
      }
      
      1 Reply Last reply
      4
      • D Offline
        D Offline
        DRoscoe
        wrote on last edited by
        #3

        @Chris-Kawa Ok, thanks. It was not obvious (to me) from reading the documentation that I was not responsible for allocating the memory myself, especially since I am responsible for deleting it. I used the "Serializing Qt Data Types" link to derive the solution I posted.

        kshegunovK 1 Reply Last reply
        0
        • VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by
          #4

          Honestly, I'd go the QString way, a lot safer as you do not have to remember to handle the memory
          you can use QString::fromStdString()

          "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

          1 Reply Last reply
          3
          • BuckwheatB Offline
            BuckwheatB Offline
            Buckwheat
            wrote on last edited by
            #5

            @DRoscoe
            I agree with @VRonin on this. The most maintainable is the best practice in most cases. I also look at.. "when in Rome..." or in this case Qt, use Qt and give the outside world what it wants. Unless this is some kind of real-time I/O then the miniscule amount of time for the copy to take place is worth the safety.

            Dave Fileccia

            1 Reply Last reply
            2
            • D DRoscoe

              @Chris-Kawa Ok, thanks. It was not obvious (to me) from reading the documentation that I was not responsible for allocating the memory myself, especially since I am responsible for deleting it. I used the "Serializing Qt Data Types" link to derive the solution I posted.

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

              I'm with the Ronin. And one preference/advice: I'd go with QString::fromStdString always instead of through char *, it just keeps type-safety and is why the methods exist in the first place. ;)

              EDIT:
              And it is binary-safe! Which may be a big deal if you have a stray NULL in the string ...

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              2
              • D Offline
                D Offline
                DRoscoe
                wrote on last edited by
                #7

                Thanks all!

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  RoyBellingan
                  wrote on last edited by
                  #8

                  Another option is

                  QDataStream& operator<<(QDataStream& out, const std::string& rhs) {
                  	QByteArray raw;
                  	raw.setRawData(rhs.data(), rhs.size());
                  	out << raw;
                  	return out;
                  }
                  

                  Which not only is safe but will not allocate too.

                  1 Reply Last reply
                  0

                  • Login

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