[Qt-interest] Adding quint32 to a QByteArray

Francisco Gonzalez Morell gzmorell at gmail.com
Wed Sep 8 19:37:46 CEST 2010


Thanks, a lot

I have made some test:

//-----Code
#include <QtCore/QCoreApplication>
#include <QByteArray>
#include <QDataStream>
#include <QtEndian>
#include <QDebug>
#include <QTime>
#include <QDateTime>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QByteArray array(400000,0x00);
    QDataStream stream(&array,QIODevice::ReadWrite);
    QTime time;

    int duration;
    quint32 number = 0xffffffff;
    const int MAXNUMBER = 100000;
    stream.setByteOrder(QDataStream::LittleEndian);
    stream.device()->seek(0);
    int mySize = sizeof(number);
    qsrand(QDateTime::currentDateTime().toTime_t());

    //Sequential Writing

    time.start();
    for (int i=0;i<MAXNUMBER;++i)
        stream << number;
    duration = time.elapsed();
    qDebug()<< "Stream Sequential Write Time: " << duration << " ms.";

    time.start();
    for (int i=0;i<MAXNUMBER;++i)
        qToLittleEndian<quint32>( quint32(number), reinterpret_cast<uchar 
*>(array.data() + i*mySize) );
    duration = time.elapsed();
    qDebug()<< "Array Sequential Write Time: " << duration << " ms.";

    //Random Writing
    time.start();
    for (int i=0;i<MAXNUMBER;++i)
    {
        stream.device()->seek(qrand()%MAXNUMBER);
        stream << number;
    }
    duration=time.elapsed();
    qDebug()<<"Stream random write time: " << duration << " ms.";

    time.start();
    for (int i=0;i<MAXNUMBER;++i)
    {
        qToLittleEndian<quint32>( quint32(number), reinterpret_cast<uchar 
*>(array.data() + (qrand()%MAXNUMBER)*mySize) );
    }
    duration=time.elapsed();
    qDebug()<<"Array random write time: " << duration << " ms.";

    //Sequential Read
    time.start();
    for (int i=0;i<MAXNUMBER;++i)
        stream >> number;
    duration = time.elapsed();
    qDebug()<< "Stream Sequential Read Time: " << duration << " ms.";

    time.start();
    for (int i=0;i<MAXNUMBER;++i)
        number = qFromLittleEndian<quint32>(reinterpret_cast<uchar 
*>(array.data() + i*mySize) );
    duration = time.elapsed();
    qDebug()<< "Array Sequential Read Time: " << duration << " ms.";

    //Random Read
    time.start();
    for (int i=0;i<MAXNUMBER;++i)
    {
        stream.device()->seek(qrand()%MAXNUMBER);
        stream >> number;
    }
    duration=time.elapsed();
    qDebug()<<"Stream random read time: " << duration << " ms.";

    time.start();
    for (int i=0;i<MAXNUMBER;++i)
    {
        number = qFromLittleEndian<quint32>(reinterpret_cast<uchar 
*>(array.data() + (qrand()%MAXNUMBER)*mySize) );
    }
    duration=time.elapsed();
    qDebug()<<"Array random read time: " << duration << " ms.";

    /* Not implemented
    qreal realnumber = 10.3;
    qToLittleEndian<qreal>( qreal(realnumber), reinterpret_cast<uchar 
*>(array.data() + 10 ));
    realnumber = qFromLittleEndian<qreal>(reinterpret_cast<uchar 
*>(array.data() + 10 ));
    */

    //return a.exec();
}
// end code------------------

With this results:
Stream Sequential Write Time:  6  ms. 
Array Sequential Write Time:  3  ms. 
Stream random write time:  14 ms.
Array random write time:  9 ms.
Stream Sequential Read Time:  6  ms. 
Array Sequential Read Time:  2  ms. 
Stream random read time:  134 ms.
Array random read time:  9 ms.

So it seems to be a better solution. 
Unfortunatelly this have not been implemented for qreal.

Francisco

On Miércoles 08 Septiembre 2010 09:54:12 Stephen Bryant escribió:
> Hi,
> 
> On 07/09/2010 20:24, Francisco Gonzalez wrote:
> > Hello,
> > Afaik QByteArray class have not a function to add a quint32 data
> > directly at some position, (nor any other integer, float or doble types)
> > in a platform independent manner.
> > Instead it is possible to do:
> > 
> > quint32 number = anyNumber;
> > qint64 position = anyPositionNumber;
> > QByteArray array;
> > QDataStream stream(QByteArray& array, QIODevice::ReadWrite);
> > stream.setByteOrder(QDataStream::LittleEndian); // The endian type you
> > want stream.device()->seek(position);
> > stream << number;
> > 
> > Is there any other option to get this directly to a QByteArray in a
> > platform independent way?
> 
> There is a quite simple way.  You have to ensure the byte array has a
> suitable size yourself though, but you can overwrite data in the middle.
> 
> #include <QtEndian>
> 
> quint32 number = anyNumber;
> qint64 position = anyPositionNumber;
> QByteArray array;
> 
> array.resize( anyPositionNumber + sizeof number );
> qToLittleEndian<quint32>( anyNumber, array.data() + anyPositionNumber );
> 
> There is also qToBigEndian<>() and qFrom...
> 
> Be aware: you've used a qint64 for the position, but a QByteArray is
> limited to 2GB.  It uses a signed (!) int (normally 32 bits) for its
> size type.
> 
> Steve
> _______________________________________________
> Qt-interest mailing list
> Qt-interest at trolltech.com
> http://lists.trolltech.com/mailman/listinfo/qt-interest




More information about the Qt-interest-old mailing list