read / write on byte array by QDataStream - c++

i have byte image array i want to write this byte array to another byte array with add some another value on second byte array , i'm using this code but i think something is wrong
QByteArray byteArray;
QDataStream ds(&byteArray,QIODevice::ReadWrite);
ds<<(qint32)20;
ds<<bArray;
qint32 code;
ds>>code;
when i trace ds>>code it is always have 0 value but in fact it must have 20 value and i used ds.resetStatus(); but it return 0 value again

I suspect that QDataStream::operator<< functions sets some sort of pointer/iterator/index to point to the next location where they can start inserting data when the next call is made. QDataStream::operator>> probably starts to read from the same location.
QDataStream::resetStatus() does not change the position from where the object reads/writes. It merely resets the status to QDataStream::Ok to allow you to read from the stream after an error has occurred.
You can use two QDataStream objects -- one for writing to the QByteArray and the other for reading from the same QByteArray.
QByteArray byteArray;
QDataStream ds_w(&byteArray,QIODevice::WriteOnly);
QDataStream ds_r(&byteArray,QIODevice::ReadOnly);
ds_w << (qint32)20;
ds_w << bArray;
qint32 code;
ds_r >> code;

Related

Weird QByteArray with QDataStream behaviour

QByteArray byteArray;
QDataStream dataStream(&byteArray, QIODevice::WriteOnly);
dataStream << (quint8)22;
dataStream << "test2";
qInfo() << byteArray;
Result: \x16\x00\x00\x00\x06test2\x00
Why is it using 4 bytes instead of 1? I explicitly say that I want it to be unsigned char. Is there some memory aligning behind the scenes? Can I turn it off?
EDIT: It seems to happen only when I write char* it adds 3 bytes on the beginning from nowhere.
\x16\x00\x00\x00\x06test2\x00
\x16 is you uint8.
\x00\x00\x00\x06 is a fixed size, four byte header of the string length (apparently including the null).
Then your string, followed by a terminating null.

Fill QByteArray from QAudioBuffer

My goal is to save a QAudioRecorder recording into memory. From my research it seems the best way to store the recording is to use a QByteArray. My audio recorder is probed using a QAudioProbe.
From the audioBufferProbed signal I try to append the data to the byte array using this slot method.
QByteArray *byteArr;
void AudioRecorder::processBuffer(const QAudioBuffer &buffer)
{
byteArr->append(buffer.constData<char>());
qDebug() << buffer.byteCount();
qDebug() << byteArr->size();
}
However that doesn't seem to work considering buffer.byteCount(); returns 4092 constantly which seems normal but byteArr->size(); returns weird and irregular increments starting off usually with 2, 4, 6, 7, 189.
The data also usually only ends up being around 18kb in size which also leads me to believe that the data is not being appended into the byte array correctly.
According to the QByteArray::size() docs size() should give how many bytes are in the array. Along with QAudioBuffer::byteCount() which also should give the amount of bytes in the current buffer, shouldn't the full 4092 from the buffer be copied to the array?
I am also open to another solution that doesn't use QByteArray if there is a better way to store the data.
You have a QByteArray pointer, but have not set it to anything.
You need to set it to a QByteArray, in your case you can use QByteArray(const char * data, int size):
byteArr = new QByteArray(buffer.constData<char>(), buffer.byteCount());
But to be honest, I am not sure why you are using a pointer.
You could just do:
QByteArray byteArr; // Your global declaration
:
:
byteArr.append(buffer.constData<char>(), buffer.byteCount());
You might want to try printing like this if you are using binary data...:
qDebug() << byteArr.toHex();
You are using method QByteArray::append which does something else than you expect. This overload of append you are using appends bytes until zero is encountered. This API should be used for c-strings!
So fix code like this:
QByteArray byteArr; // there is no point of create this on heap
byteArr.reserve(8*1024*1024); // reserve 8 MB - it will improve performance
void AudioRecorder::processBuffer(const QAudioBuffer &buffer)
{
byteArr.append(buffer.constData<char>(), buffer.size());
qDebug() << buffer.byteCount();
qDebug() << byteArr.size();
}

Inserting an integer into QByteArray

I am trying to read a binary data file using QDataStream and QByteArray, make some changes, and save off as a new file.
I have the following:
QDataStream in_datastream(&file);
QByteArray fileByteArray = file.readAll();
//find my insertion point
int pos = fileByteArray.indexOf(magic_num, 0);
//move to insertion point, minus 4 bytes (size of an integer)
file.seek(pos-4);
int current_val;
//check what the value is here
in_datastream >> current_val;
//now, I want to replace that value..but how?
I have tried several things at this point, but can't seem to figure out how to make it work. I want to insert the integer 5000 at (pos-4) in the QByteArray.
//remove 4 bytes..this seems to work
fileByteArray.remove(pos-4, 4);
//actually inserts garbage.
fileByteArray.insert(pos-4, newInteger);
If I try to insert a 4 character string "TEST", they all get inserted properly. I think I am having some type conversion problems trying to put an integer in there.
First of all, integer may have size not only 4, but 8 bytes, so you should use sizeof(integer) instead of 4. Then you can convert integer to string with Qstring::number(newInteger). QString can be converted to bytearray with QString::toLatin1()

Append a QByteArray to QDataStream?

I have to populate a QByteArray with different data. So I'm using the QDataStream.
QByteArray buffer;
QDataStream stream(&buffer, QIODevice::WriteOnly);
qint8 dataHex= 0x04;
qint8 dataChar = 'V';
stream << dataHex<< dataChar;
qDebug() << buffer.toHex(); // "0456" This is what I want
However, I would also like to append a QByteArray to the buffer.
QByteArray buffer;
QDataStream stream(&buffer, QIODevice::WriteOnly);
qint8 dataHex= 0x04;
qint8 dataChar = 'V';
QByteArray moreData = QByteArray::fromHex("ff");
stream << dataHex<< dataChar << moreData.data(); // char * QByteArray::data ()
qDebug() << buffer.toHex(); // "045600000002ff00" I would like "0456ff"
What am I missing?
when a char* is appended it assumes \0 termination and serializes with writeBytes which also writes out the size first (as uint32)
writeBytes' doc:
Writes the length specifier len and the buffer s to the stream and
returns a reference to the stream.
The len is serialized as a quint32, followed by len bytes from s. Note
that the data is not encoded.
you can use writeRawData to circumvent it:
stream << dataHex<< dataChar;
stream.writeRawData(moreData.data(), moreDate.size());
The 00000002 is the size of the char array, which is written to the stream.
What you are missing is, QDataStream is not raw data. It has its own simple serialization format. It is most suitable for use cases where data is both written (serialized) and read back (deserialized) with QDataStream, and using a reliable QIODevice (QBuffer or QFile for example).
If you want to add raw data to a QBuffer, you could use a suitable overload of write method. But then you might as well just append to the QByteArray directly.

Is it possible to mix QTextStream and QDataStream?

Needing to read a mixed text/binary file I thought using both QTextStream and QDataStream together would be the most effective.
The file looks like this:
Some line of text Another line of text 42 <100 bytes of
binary data> 12 <100 bytes of binary data> ... etc. (an
int in a line, then 100 bytes of binary data in a line, and so on)
Here is the initialization, variables etc.:
// a QFile named in is already opened successfully as binary (without QIODevice::Text)
QTextStream stream(&in);
QDataStream data(&in);
int nr;
int nr_bytes;
char buffer[200];
First I tested whether reading from one stream advances the other. If I read 10 bytes with data.readRawData() from the file, then stream.readLine() will read "of text", so it works!
However, if I do the following, from the beginning of the example file:
stream.readLine();
stream.readLine();
for (/*...*/)
{
stream >> nr;
stream.readLine();
nr_bytes = data.readRawData(buffer, 100);
stream.readLine();
}
it does not work, and the buffer remains empty. Strangely, the numbers (42, 12, etc.) are read correctly into nr, no matter how many bytes I read with data.readRawData(). It can be 1000 bytes, it still does not seem to read anything. The value in nr_bytes, however, indicates that the bytes are successfully read! Still strange, that the last readLine in the loop actually reads the binary data (at least until it encounters a zero, a line feed or other special characters). This means, that data.readRawData() did not read anything at all, but it still has the number of required bytes in its return value.
Does this mean I cannot use QTextStream and QDataStream together, or am I doing something else wrong?