PDA

View Full Version : Cant 'connect' an internal char array to a qdatastream



tonnot
17th November 2011, 13:51
I have :

mybuffer = new char[265536]();

QByteArray data = QByteArray::fromRawData(mybuffer, sizeof(mybuffer));
the_qstream = new QDataStream(&data , QIODevice::ReadWrite);
the_qstream->setVersion(QDataStream::Qt_4_6);
QDebug()<<" size buffer"<< the_qstream->device()->size();

Ok, first I have 4 for the size buffer ???
And the_qstream<<a_float; fails at
inline int QByteArray::size() const { return d->size; }

Any help ? What am I doing bad ?

d_stranz
18th November 2011, 00:14
myBuffer is a pointer to an array of 265536 chars. sizeof( char * ) == 4 on your system.

And you are setting the QDataStream with a QByteArray, not a QIODevice, so the call to QDataStream::device() returns a NULL pointer. Read the docs!

ChrisW67
18th November 2011, 02:58
Actually QDataStream::device() returns a pointer to the internally created QBuffer in this case. A quick test has size() returning the correct value, just not what Tonnot is expecting, and no issue streaming a float.


float a_float = 0.0;
QByteArray buf;
QDataStream stream(&buf, QIODevice::WriteOnly);
stream << qint32(0) << a_float;
qDebug() << stream.device() << stream.device()->size();
// Outputs: QBuffer(0x2533720) 12

tonnot
18th November 2011, 08:13
Finally this code works :
qbytearray = new QByteArray(265536,0);
the_qstream = new QDataStream(qbytearray , QIODevice::ReadWrite);
the_qstream->setVersion(QDataStream::Qt_4_6);
the_qstream->setFloatingPointPrecision(QDataStream::DoublePreci sion);
the_qstream->setByteOrder(QDataStream::LittleEndian);

I'm going to use liitteendian, because I think my 80% of users are going to be windows- 'pc' users.

A last question, using qdatastream, writing a float with 4, 8 for double, using litteendian, are going to means a file with 12 bytes. Knowing this information, the data coulde be recovered using another languaje ins't ?. Or could not ?
Thanks

ChrisW67
18th November 2011, 09:02
If the receiving program is not a Qt program then you need to be careful that you stream only intrinsic types or the data received may not be what you expect. For example streaming a QByteArray containing 10 bytes to a QDataStream will generate a 14 byte stream, the C-string "Hello" generates another 10.

As for using another language's integer type, well, that might work if the integers are the same size and endian-ness. Floating point will only be binary compatible if the two ends use the same encoding, usually IEEE 754, and the same variant where several exist. Four-byte floats may not exist in some languages.

tonnot
18th November 2011, 09:28
By now, I'm talking at file level (I also am uising the data at memory level)
The need of QTdatastream for reading the data could be interesting for me. That is, it would be very difficult to read my file.

But In case of need, I could document my data structure ? :
"read 4 bytes : reserved
read 10 : whatever
read 4 : float
read 8 : double
etc...
Endian : liitle-endian."

Thanks Chrish

d_stranz
18th November 2011, 16:53
Actually QDataStream::device() returns a pointer to the internally created QBuffer in this case. A quick test has size() returning the correct value, just not what Tonnot is expecting, and no issue streaming a float.


I believe you, but the documentation is misleading:


QIODevice * QDataStream::device () const
Returns the I/O device currently set, or 0 if no device is currently set.

The QByteArray form of the constructor does say that an internal QBuffer will be created, but it isn't obvious that this would be returned as the QIODevice pointer. So apparently only in the case of an instance created through the default constructor will the QIODevice pointer be null.