PDA

View Full Version : QDataStream>>(int) skipping one byte?



Khaine
15th March 2016, 20:13
I have a problem with reading binary file. File was written using standard C++ fwrite functions, and now I want to read it using QDataStream. Yet I have problem that I cannot explain.


//dataset description
fileStream>>(int)tempInt; //length of description, this is correctly loaded, int = 121
fileStream.readRawData(charBuffer,tempInt); // this is correctly loaded too

qDebug() << "Dataset descr length: " << tempInt;

for (int i=0; i<tempInt; i++){
dataSetDescription += charBuffer[i]; // it works too
}

//signals count
fileStream>>(int)signalsCount; //and it doesn't work there, it should read int=13, yet it reads 16777216


IT'S NOT ENDIANESS PROBLEM! One byte is simply skipped for whatever reason.

http://s11.postimg.org/tp2xi4hz5/hex.png

Take a look at this binary file. Whole name of dataset is loaded correctly and ended with . sign. After this . sign I want to read 4 bytes in little endian being number of signals. As you can see it should read 0D000000, which is 13. YET it totally skips 0D byte and proceeds further, and reads 00000010 which means 16777216 in little endian hex. I just have no clue what is happening here. You can see, that there is nothing in code that would order it to move this one byte further. Also same algorithm you see is used in reading many things before signals count and it skips no bytes, and all chars are converted to strings correctly. Any ideas?

jefftee
16th March 2016, 02:41
QDataStream reads and writes in encoded format, which includes the QDataStream version to ensure compatibility when reading/writing the data. Since your data was not written using QDataStream, your issue is likely due to the format of data written using fwrite doesn't contain the exact format expected by QDataStream.

The x'0D' following your string is likely a carriage return. From the docs:


To take one example, a char * string is written as a 32-bit integer equal to the length of the string including the '\0' byte, followed by all the characters of the string including the '\0' byte. When reading a char * string, 4 bytes are read to create the 32-bit length value, then that many characters for the char * string including the '\0' terminator are read.
So when you write your file using fwrite, does the 32-bit integer length include the carriage return and trailing '\0' byte in its length?

Edit: QDataSteam also encodes a version number into the stream, which could also be where you're getting tripped up since your file wasn't written with QDataStream.

mynamebilalzahid
16th March 2016, 07:12
may be if there is a option to add watch then -> add watch from the 1st statement and then compile it line by line, i am sure you will recover your problem with reading this.

Good Luck !

Khaine
16th March 2016, 12:36
And what can I do when



//dataset description
fileStream>>(int)tempInt; //length of description
fileStream.readRawData(charBuffer,tempInt);

qDebug() << "Dataset descr length: " << tempInt;

for (int i=0; i<tempInt; i++){
dataSetDescription += charBuffer[i];
}

fileStream.readRawData(charBuffer,4);
memcpy(&signalsCount, charBuffer, 4);


does the same? 0D is still missed.



//dataset description
fileStream>>(int)tempInt; //length of description
fileStream.readRawData(charBuffer,tempInt+4);

qDebug() << "Dataset descr length: " << tempInt;

for (int i=0; i<tempInt; i++){
dataSetDescription += charBuffer[i];
}

memcpy(&signalsCount, charBuffer+(tempInt*sizeof(char)), 4);


Even this misses 0D byte. It's just impossible what is happening here.

anda_skoa
16th March 2016, 14:08
You are using two incompatible methods of writing and reading.

Just don't use QDataStream and you should be fine.

Cheers,
_

jefftee
16th March 2016, 23:01
It's just impossible what is happening here.
Clearly not impossible, because it is happening! As @anda_skoa pointed out more clearly than I did, the format you're writing the data clearly isn't compatible with trying to read the data back in with QDataStream. You can keep struggling and not understanding why, or you can abandon QDataStream unless the data you're trying to read is *also* written using QDataStream.

Khaine
17th March 2016, 15:50
I figured it out. QIODevice::Text was accidentally set. So it treated this sign as end line probably.