Solved Writing Raw Data through a QDataStream
-
Ok, simple example here where I want to write a 0xC2 unsigned char value out through a QDataStream. All avenues seem to require a (char *) cast and then my 0xC2 is 0x3F. You can see various attempts below and typical C file works as expected. Any thoughts?
Output:int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); unsigned char uc[] = { 194 }; unsigned char uc1[] = { '\x7F' }; quint8 uc2[] = { 195 }; char c3[] = { '\xC2' }; QByteArray ba = QByteArray::fromHex("C2"); char delim[] = { '\x55' }; FILE *binFile = fopen("file1.dat","wb"); fwrite(uc,sizeof(unsigned char),sizeof(unsigned char), binFile); fwrite(uc1,sizeof(unsigned char),sizeof(unsigned char), binFile); fwrite(uc2,sizeof(unsigned char),sizeof(unsigned char), binFile); fwrite(c3,sizeof(unsigned char),sizeof(unsigned char), binFile); fclose(binFile); QFile file("file.dat"); try{ file.open(QIODevice::WriteOnly); QDataStream out(&file); out << quint8(uc[0]); out << quint8(uc1[0]); out << quint8(uc2[0]); out << quint8(c3[0]); out << quint8(delim[0]); out.writeRawData((char *)&uc[0], 1); out.writeRawData((char *)&uc1[0], 1); out.writeRawData((char *)&uc2[0], 1); out.writeRawData((char *)&c3[0], 1); out << quint8(delim[0]); out.device()->write((char *)&uc[0], 1); out.device()->write((char *)&uc1[0], 1); out.device()->write((char *)&uc2[0], 1); out.device()->write((char *)&c3[0], 1); out << quint8(delim[0]); out << uc[0]; out << quint8(delim[0]); out << uc1[0]; out << quint8(delim[0]); out << uc2[0]; out << quint8(delim[0]); // extra 3f3f3f in this one section out << c3[0]; out << quint8(delim[0]); // byte array out.writeRawData(ba.data(), ba.size()); out << quint8(delim[0]); QDataStream str(ba); out << str; out << quint8(delim[0]); out << (quint8)0xC2; } catch (...) { file.close(); } file.close(); return a.exec(); }
-
Event serialization using things like this fail:
float f = -199.5;out << quint8(delim[0]); out << (quint32)(*(uint32_t*)&f); out << quint8(delim[0]); out << (quint32)(*(int32_t*)&f);
If the byte is >0x73 it seems to wriate a 0x3F! I have not idea why.
Thanks,
-Rich -
Ok, I think this is a bug in 5.12.5....in 5.9.8
float f = -199.5; out << quint8(uc[0]); out << quint8(uc1[0]); out << quint8(uc2[0]); out << quint8(c3[0]); out << quint8(delim[0]); out << f;
yields:
You'll note f comes out in 64-bit vs. 32-bit though which should be 32-bit in my mind per the float definition. But at least there are no 0x3F question marks.
Does anyone know if there has been a bug report on this?
Thanks,
Rich -
I tested it with 5.9.7 (MinGW 32bit), 5.12.6 (MinGW 64bit), 5.13.2 ((MinGW 64bit) and 5.13.x and dev (Linux, 64 Bit) - all produce the same output.
-
Weird. 5.12.5 GCC is what fails for me. I was given a hint that '?' might be part of a UTF8 encoding error but still investigating as this is a binary file I'm writing.
Thanks,
-Rich -
@Rich-Bair What editor do you use to display the file?
-
Yeah, I was using VIM in this case and I just downloaded another hex editor and I don't see the issue. It also seems to have gone away once I started a new session of VIM. The one picture has two files in the same instance of VIM with one working (C file) and one not (QDataStream file) but perhaps VIM has encoding per buffer...not sure. At any rate, thanks very much for the response but all is well now. I can take a:
union myflt { char ch[sizeof(float)]; float f; quint32 i; };
and then do a:
out.writeRawData(&f.ch[0], 4);
which is what I needed to do to match a binary file format output. I wish I knew exactly what went wrong but at this time I'm thinking a VIM encoding oddity. Not sure.
-
@Rich-Bair: VIM is no hex editor - it's a text editor (and opens the file as text, not as binary) - use "hexdump -C" when you're on linux.
/edit: and please forget to mark the topic as solved.