Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Qt have a way of converting bytes to int and vice versa?

Tags:

c++

qt

I'm trying to find a Qt function that can convert bytes to int with the same endianness that I'm using below. I feel like I'm definitely reinventing the wheel here, and that there must be something in the Qt libs to do this already. Does it exist?

// TODO: qt must have a built in way of converting bytes to int.
int IpcReader::bytesToInt(const char *buffer, int size)
{
    if (size == 2) {
        return
            (((unsigned char)buffer[0]) << 8) +
              (unsigned char)buffer[1];
    }
    else if (size == 4) {
        return
            (((unsigned char)buffer[0]) << 24) +
            (((unsigned char)buffer[1]) << 16) +
            (((unsigned char)buffer[2]) << 8) +
              (unsigned char)buffer[3];
    }
    else {
        // TODO: other sizes, if needed.
        return 0;
    }
}

// TODO: qt must have a built in way of converting int to bytes.
void IpcClient::intToBytes(int value, char *buffer, int size)
{
    if (size == 2) {
        buffer[0] = (value >> 8) & 0xff;
        buffer[1] = value & 0xff;
    }
    else {
        // TODO: other sizes, if needed.
    }
}

Edit: The data is always big endian (no matter what OS), so for example 101 would be [0, 0, 0, 101] and 78000 is [0, 1, 48, 176].

like image 250
Nick Bolton Avatar asked Jul 06 '12 22:07

Nick Bolton


3 Answers

The following functions seems to fit your needs :

  • qFromBigEndian()

  • qToBigEndian()

From : #include <QtEndian>

like image 108
miko53 Avatar answered Nov 12 '22 03:11

miko53


Your code is pretty simple and easy to follow but you could use Qt's QByteArray like so (note: I didn't try compiling this):

int IpcReader::bytesToInt(const char *buffer, int size)
{
  QByteArray b(buffer, size);
  return b.toInt();
}

void IpcClient::intToBytes(int value, char *buffer, int size)
{
  QByteArray b = QByteArray::number(value);
  strncpy(buffer, (const char*)b, size);
}

Note that the endianness is going to be the same as the machine it is run on.

like image 20
syplex Avatar answered Nov 12 '22 02:11

syplex


Wouldn't be a QByteArray with a QDataStream sufficient?

int IpcReader::bytesToInt(const char *buffer, int size)
{
    QByteArray byteArr(buffer,size);
    QDataStream ds(&byteArr,QIODevice::ReadOnly);

    if(little_endian_usage) // little endian check or something similar here
         ds.setByteOrder(QDataStream::LittleEndian);
    else
         ds.setByteOrder(QDataStream::BigEndian);

    int ret;
    if(size == 2){
        qint16 tmp;
        ds >> tmp;
        ret = tmp;
    } else if(size == 4){
        qint32 tmp;
        ds >> tmp;
        ret = tmp;
    } else if(size == 1){
        qint8 tmp;
        ds >> tmp;
        ret = tmp;
    }
    return ret;
}

If you don't want to create a copy of your buffered data you can use QByteArray byteArr =QByteArray::fromRawData(buffer, size). You can also use a QDataStream to write an int back into a QByteArray or a raw buffer (use QByteArray::fromRawData() for the latter).

like image 1
Zeta Avatar answered Nov 12 '22 01:11

Zeta