Reputation: 991
I need to process streamed binary data (QDataStream) of defined structure created by another non-Qt program. I wonder what is the best practice to interpret that data. Let's say the data is structured (struct definition provided) in telegrams as follows and cannot be changed by myself:
4 bytes header | 2 bytes sequence number | 1 byte checksum | 10 bytes data
I see the following possibilities to handle the data in a "Telegram" class:
return (array.at(4)<<8) + array.at(5)
for the sequence number, with is not very elegant.telegramstruct.squenceNumber
I see potential problems with this method like endianness and padding.QString strHeader
. When reading the telegrams from the stream, data is stored directly in these variables. Reading is done with readRawData or with the operator>> for basic types. The code should be as fast as possible since there is a lot of data to process. I am using Qt 5.0.1 on Windows with MinGW.
My questions:
Thanks a lot for your opinions and hints.
Chris
Upvotes: 1
Views: 2587
Reputation: 4085
Well, sorry dont have that much time to write code examples, but will try to give a brief hints. 1) Performance issue. As soon as you have performance constrains first thing to optimise is an amounts of actual reads from the stream from where data are coming. Whatever it's File/Socket/etc it's anyway QIODevice. So first thing to do is to maintain some kind of QByteArray where you adding all data available on a QIODevice on every ready attempt/handling data received notification. So below I assume there is certain QByteArray m_rawData which holds currently unprocessed bytes, which can be some amount of Telegrams + last telegram which can be received partially.
2) I would make a class like Telegram which holds telegram data, roughly saying
class Telegram {
QString header;
int sequenceNumber;
unsigned char checkSum;
QByteArray data;
...
bool checkSumOK(); // check is checksum is OK for provided data
}
with constructors and operators on your taste (you can implement copy constructor/etc).. Then I would extend this class with ( <<, >>) operators to support QDataStream which operates on temporary buffer mentioned in part 1).
So general concept is that you read data from the stream to temporary buffer as soon as possible and after read is done you fetch from resulted buffer as many Telegram's instances as possible. Then you work with QDataSteam applied on a QByteArray you can safely use read 4 bytes, read 1 byte etc calls without having that much performance impact because in general it's mostly about shifting pointers.
3) Of course if you talking about extreme condition.. you can think of unions (as being mentioned in previous answer) to make direct copy of raw data on top of a aligned structure but that way requires much more careful programming (especially taking in consideration x32/x64 archs as well as big/little endians platforms)
Upvotes: 3