PDA

View Full Version : QDataStream reading to C++ vectors



pdoria
23rd July 2009, 15:27
Hi,

I have this vector defined:

vector<char> payload;
and re-sized it to the appropriate size with:

payload.resize(size_packet_data+2);

and some QDataStream object like 'mybytes'...

and, as expected I can't do


mybytes >> payload.

So, quick question is:
What the best way to read (len) bytes from a QDataStream to a vector?

TIA,
Pedro.

mcosta
23rd July 2009, 15:43
You can write code like


...
char ch;
for (int i = 0; i < size_packet_data; ++i)
{
mybytes >> ch;
payload.push_back(ch);
}
...

pdoria
23rd July 2009, 16:00
Thank you mcosta!

First thing:

It'd only compile if :

mybytes >> (char *&) ch;

Secondly I'm wondering if there's a more optimized way to do it beyond a for...next loop ;)

TY,
Pedro

wysota
23rd July 2009, 16:02
and, as expected I can't do


mybytes >> payload.
This semantics means "read a vector of items from the stream"

The stream contains something else, I presume, so this will obviously fail.


So, quick question is:
What the best way to read (len) bytes from a QDataStream to a vector?

Having a vector of chars is... well... strange. What you want is QByteArray. Then if you write a byte array to the stream at one end, you can read it on the other:

QByteArray array;
stream >> array;

Also note QDataStream is not a general purpose binary stream but a (de)serialization mechanism. So if you didn't write a byte array at one end, you can't read it on the other. For that you can use readRawData() or simply QFile API.

pdoria
23rd July 2009, 16:12
Thank you wysota! (as always to the rescue! :) )

Let me expose my code:

the structure:

//! \brief Fleet Management Protocol
//! \note All packets related to the fleet management protocol use packet ID 161.
typedef struct {
quint8 DLE; // =16;
quint8 packet_id; // =161
quint8 size_packet_data; // size of fleet_management_payload + 2
quint16 fleet_management_packet_id; // see #defines below
vector<char> fleet_management_payload; // 0 to 253 bytes
quint8 checksum; // compute this BEFORE sending the packet!
quint8 DLE_end; // =16
quint8 ETX; // =3
} fleet_management_packet_data_type;

the function (so far):

//! \brief Process Fleet Management packets
//! \param records QDataStream raw data
//! \note First two bytes of the packet have already been read by TeltonikaUnit::parseFM4GarminRecs
void processFleetManagement ( QDataStream & records ) {
fleet_management_packet_data_type packet;
bool debug = true;

records >> packet.size_packet_data;
records >> packet.fleet_management_packet_id;
packet.fleet_management_payload.resize(packet.size _packet_data+2);

// get the payload in a byte at a time...
char ch;
for (int i = 0; i < packet.size_packet_data; ++i)
{
records >> (char*&) ch;
packet.fleet_management_payload.push_back(ch);
}
records >> packet.checksum;
records >> packet.DLE_end;
records >> packet.ETX;

}

So, as you can see, I'm trying to read packet.size_packet_data bytes from the data stream.
Your suggestion for using a QByteArray is perfectly valid but I'd like to stick with a vector, hence the question in the first place... :)

TIA,
Pedro.

wysota
23rd July 2009, 17:13
How was the data written to the device the DataStream operates on?

mcosta
24th July 2009, 20:34
You can use



mybytes >> (qint8) ch;