2

I have data which comes from tcp socket as raw data (i have a specified format) and then create an object based on that data. Format is like this: 24 bytes of header [size of data and some other info] and then amount of data specified in header.

I would like to just read it as an object (object has a buffer for data inside with dynamic size where data is put). Is it possible to somehow override QDataStream or do it some other way to elegantly wrap it? I would like to take advantage of transactions methods to read whole packets of data and not taking care of assembling them if they come in pieces (half header, or just not full amount of data).

So basically I would want to do sth like this:

Event event;          // my custom class
QDataStream dataStream(tcpSocket);

dataStream >> event;
dataStream.commit();
Voider
  • 83
  • 9

1 Answers1

1

I am believe it is the case for operator overloading. I made a small demonstrative example:

class Test
{
public:
    int i;
    float f;
    double d;

    char empty[4];
    int ii[3];

    QString s;

public:
    friend QDataStream& operator>>(QDataStream& in, Test& test);
    friend QDataStream& operator<<(QDataStream& out, const Test& test);
};

QDataStream& operator>>(QDataStream& in, Test& test)
{
    in >> test.i;

    in.setFloatingPointPrecision(QDataStream::SinglePrecision);
    in >> test.f;

    in.setFloatingPointPrecision(QDataStream::DoublePrecision);
    in >> test.d;

    in.skipRawData(sizeof test.empty);
    in.readRawData(reinterpret_cast<char*>(test.ii), sizeof test.ii);

    in >> test.s;

    return in;
}

QDataStream& operator<<(QDataStream& out, const Test& test)
{
    out << test.i;

    out.setFloatingPointPrecision(QDataStream::SinglePrecision);
    out << test.f;

    out.setFloatingPointPrecision(QDataStream::DoublePrecision);
    out << test.d;

    out.writeRawData(reinterpret_cast<const char*>(test.empty), sizeof test.empty);
    out.writeRawData(reinterpret_cast<const char*>(test.ii), sizeof test.ii);
    out << test.s;

    return out;
}

Then you can do:

 outputStream
        << test1
        << test2
        << test3;

// ...

inputStream.startTransaction();
inputStream
        >> test11
        >> test22
        >> test33;
inputStream.commitTransaction();

Also these operators are predefined for Qt fundamental containers (QVector, QList, QSet etc.)

WindyFields
  • 2,697
  • 1
  • 18
  • 21