PDA

View Full Version : QDataStream question...



grellsworth
18th April 2008, 20:13
Is it permissible to mix serialization of data and readRawData/writeRawData to a QDataStream?

In other words, imagine I have information stored in a class that I'd like to transfer over the network using QDataStream, and imagine I have a pointer to that object:



myClass *myObject = new myClass;


Would it be OK to do something like this:



... // assume 'out' is a QDataStream object.
out << (quint16)0; // Initialize "bytes of data" to 0
out.writeRawData((char *)myObject, myObject->sizeInBytes()); // put binary data into stream
out.device()->seek(0); // seek back to beginning of stream
out << (quint16)(out.size() - sizeof(quint16)); // set the "bytes of data"


Or would it confuse Qt?

Same question for input of binary data using readRawData() ...

Thanks,

Gordon E.

wysota
18th April 2008, 20:46
Qt won't mind, but you might be unable to retrieve the object back on the other side of the connection. Can't you do the proper serialization?

grellsworth
19th April 2008, 15:16
Qt won't mind, but you might be unable to retrieve the object back on the other side of the connection.
Why do you say that?

Can't you do the proper serialization?
You mean something like this:


out << (char *)myObject;


???

I didn't think that would work.

I don't know... do you have any other suggestions for transferring that data?

Gordon E.

wysota
19th April 2008, 18:12
Why do you say that?
Because the application running on the other end of connection might be compiled with a different compiler and/or for a different platform (including 32/64 bit and little/big endian differences).


You mean something like this:


out << (char *)myObject;


???
No, I mean serialize.

I don't know what your object consists of, but you need to represent it with a string. For instance:


struct MyStruct {
int x;
int y;
QString txt;
QDataStream &operator<<(QDataStream &stream) const {
stream << x << y << txt;
return stream;
}
QDataStream &operator>>(QDataStream &stream){
stream >> x >> y >> txt;
return stream;
}
};

The last two operators should allow you to serialize this class' instances using QDataStream.

grellsworth
20th April 2008, 21:14
Because the application running on the other end of connection might be compiled with a different compiler and/or for a different platform (including 32/64 bit and little/big endian differences).


No, I mean serialize.

I don't know what your object consists of, but you need to represent it with a string. For instance:


struct MyStruct {
int x;
int y;
QString txt;
QDataStream &operator<<(QDataStream &stream) const {
stream << x << y << txt;
return stream;
}
QDataStream &operator>>(QDataStream &stream){
stream >> x >> y >> txt;
return stream;
}
};

The last two operators should allow you to serialize this class' instances using QDataStream.

Ahh, I agree with you about the first part... That's a good point.

The way you've got it to serialize would work pretty well, too... but it would be tedious if a class contained a lot of members (say 100 or more). It's definitely something to think about, thank you very much for your input.

I'm just curious, if I did the serialization operators as you recommend, and then include this class as a member of another class (which also has serialization operators), would the parent class serialize the child correctly?

(I know I'm using parent/child incorrectly here, usually we only use those terms for classes that inherit other classes, but I'm not sure what other term to use.)

wysota
20th April 2008, 21:33
I'm just curious, if I did the serialization operators as you recommend, and then include this class as a member of another class (which also has serialization operators), would the parent class serialize the child correctly?
Yes, of course. Just as I'm serializing QString in the example above although I did not implement redirect operators for it myself.

stevey
21st April 2008, 02:11
The way you've got it to serialize would work pretty well, too... but it would be tedious if a class contained a lot of members (say 100 or more).

Something to consider would be a code generator of some sort.
I personally use "CodeSmith Tools".
In that you could list all your members in a flat text file, then write a small amount of CodeSmith scripting to dump a Class with your << and >> all filled out and ready to go.

Actualyl it's something I've been meaning to do for ages. I'll whip up a template tonight and upload it to the forum.

wysota
21st April 2008, 08:57
You could enter the contest (http://contest.qtcentre.org) with it.

stevey
21st April 2008, 12:28
Maybe, although the Image Format one that's almost complete might be a better candidate.

wysota
21st April 2008, 12:57
Who stops you from entering in more than one category?

stevey
21st April 2008, 13:17
Here's the first cut. I wrote this with CodeSmith Tools 4.1
Get it from http://www.codesmithtools.com/
It requires .NET 2 (sorry to linux only people but hey, it was the quickest way to get the job done).

The process is:
1. Install CodeSmith Tools.
2. Open the .cst file I've provided in CodeSmith Tools.
3. "Build" the template. A properties list will appear to the right.
4. There should be some default values, if you want a class, set the "GenerateClass" property to True.
5. Set the name for the struct / class
6. The struct / class will have members set based on the content of the "SourceFile" property value. Ie, in the Members.txt file is list of members and their types in this format <Type>,<Name>. Follow the format shown for your own members.
7. Press F5 to run the template.
8. Copy and paste the generated code into your source file in your IDE / text editor.

Let me know if you want anything added.
This is totally free, do whatever you want with it, or ask for additions and I'll provide if I can.

Stevey