PDA

View Full Version : Reading binary into QVector



stathis.stefanidis
11th December 2009, 11:03
Hi,
I am trying to read binary data into a QVector. Each chunk is represented as 2 Bytes (unsigned int).

The follow code works:

QDataStream in(m_tcpSocket);
if (m_tcpSocket->bytesAvailable() < m_dataLength ) return;

qint16 a;
QVector<double> dataVector;

for(int i=0; i<m_dataLength; i++)
{
in >> a;
dataVector.push_back(a);
}

The first five values that I get from this code are what I expect:
0 3 0 16384 -7460 -7483

But I want to avoid the loop and I'd like to get the pointer to the beginning of the data and to the end of the data and then transfer this into the memory and put it into a vector.
I tried the following:

char *s = new char[ 5 * sizeof(qint16)]; //Get only the first 8 bytes
in.readRawData( s , 5*sizeof(qint16) );

QVector<qint16> vector;
qint16 *vdata = vector.data();
vdata = (qint16*)s;

If I print out the first 5 values of the vector I get:
-21589 -21589 -21589 -21589 0

Has anyone done this before?
I'd appreciate any contribution.

faldzip
11th December 2009, 11:59
QVector<qint16> vector;
qint16 *vdata = vector.data();
vdata = (qint16*)s;

Hmm this is NOT going to work :]
You create vdata pointer that points to vector data. But then you make it pointing to the s array. So how the vector data can be changed, if there is even no line making any change to it.
Moreover, I think all your method is not going to work. You can try with memcpy to copy data to the memory pointed with vector.data() pointer, but there is great chance you do some segmentation fault (hmm what is the size of reserved memory for vector, which you get by vector.data() method?).

So either stay with QVector (or QList) and with a loop or just do everything with low level C arrays and do some harcore memcpys and other stuff, and don't mess vector internal structures :P

tanderson
11th December 2009, 17:55
I agree with faldzip, but just for fun I would try.

QVector<qint16> vector;
vector.reserve(6);//one extra for safety.
in.readRawData((char*)vector.data() , 5*sizeof(qint16) );

sizeof might be redundant here. from qt assistant:

typedef qint16
Typedef for signed short. This type is guaranteed to be 16-bit on all platforms supported by Qt.

stathis.stefanidis
14th December 2009, 10:19
Thanks both for your replies.
I tried the following

QVector<qint16> vector;
vector.reserve(6);
in.readRawData((char*)vector.data(), 5*sizeof(qint16) );
for(int i=0; i<5; i++)
{
qDebug()<<vector[i];
}

And now I get:
0 768 0 64 -8990

where I should get:
0 3 0 16384 -7460

There must be a conversion problem I think. As you see I can get the zeros and the sign but not the correct number.. Is there a possibility the bytes to be read the inverse order?
Thanks

tanderson
15th December 2009, 00:35
this seems to be working:



//setup
QVector<qint16> inVect;
inVect << 0 << 3 << 0 << 16384 << -7460;
QByteArray storage;
QDataStream storageIn(&storage, QIODevice::WriteOnly);
storageIn.writeRawData((const char*)inVect.data(), 10);
//read back
QDataStream storageOut(&storage, QIODevice::ReadOnly);
QVector<qint16> outVect;
outVect.resize(5);
storageOut.readRawData((char*)outVect.data(), 10);
foreach (qint16 current, outVect)
qDebug() << current;

output is:
Starting .../QtConsoleTest...
0
3
0
16384
-7460

.../QtConsoleTest exited with code 0

dbzhang800
15th December 2009, 01:50
this seems to be working:



//setup
QVector<qint16> inVect;
inVect << 0 << 3 << 0 << 16384 << -7460;
QByteArray storage;
QDataStream storageIn(&storage, QIODevice::WriteOnly);
storageIn.writeRawData((const char*)inVect.data(), 10);
//read back
QDataStream storageOut(&storage, QIODevice::ReadOnly);
QVector<qint16> outVect;
outVect.resize(5);
storageOut.readRawData((char*)outVect.data(), 10);
foreach (qint16 current, outVect)
qDebug() << current;

output is:
Starting .../QtConsoleTest...
0
3
0
16384
-7460

.../QtConsoleTest exited with code 0

You can try this:

QVector<qint16> inVect;
inVect << 0 << 3 << 0 << 16384 << -7460;
qDebug()<<QByteArray((const char*)inVect.data(), 10).toHex();
inVect.clear();
inVect << 0 << 768 << 0 << 64 << -8990;
qDebug()<<QByteArray((const char*)inVect.data(), 10).toHex();
output:

"0000030000000040dce2"
"0000000300004000e2dc"

stathis.stefanidis
16th December 2009, 15:55
I finally made it work using the idea by tanderson..
Thanks to all for contributing!