Я использую QDataStream для сериализации некоторых uint-переменных. Несколько примеров значений и соответствующего результата:
quint32 i;
i = 99
[0,0,0,99]
i = 255
[0,0,0,255]
i = 256
[0,0,1,0]
i = 510
[0,0,1,254]
i = 512
[0,0,2,0]
i = 1024
[0,0,4,0]
Как делается это преобразование?
Вот что я использовал для вывода вывода.
QByteArray barr;
QDataStream stream(&barr,QIODevice::WriteOnly);
stream.setVersion(QDataStream::Qt_4_8);
quint32 i32 = 512;
stream << i32;
QList<int> valueList;
for(int i = 0 ; i < barr.count() ; ++i)
valueList.append(QChar(barr.at(i)).unicode());
qDebug() << valueList;
Похоже на стандартное великодушно представление. Вот как целые числа фактически разбиваются на байты в памяти компьютера. Например:
510 = 0 * (1 << 24) + 0 * (1 << 16) + 1 * (1 << 8) + 254
Обратный порядок байтов, little-endian, более популярен в наши дни. Вы делаете выбор с помощью QDataStream.setByteOrder().
Вот код, который разбивает 32-битное целое число на байты:
void putUint32BigEndian(quint32 x)
{
putByte(x >> 24);
putByte((x >> 16) & 0xff);
putByte((x >> 8) & 0xff);
putByte(x & 0xff);
}
Отредактировано:
По всей видимости
xi = (quint8 )(X >> (8*i))
Где X
- исходный quint32
, i
- индекс байта и xi
- i-я цифра в выведенном вами выводе. Сериализация, которую они выполняют, так же проста, как и
quint8* data = (quint8*)(&X);
или
unsigned char* data = (unsigned char*)(&X);
xi = data[i]
Сериализация зависит от сущности. Поэтому QDataStream
обладает такими свойствами, как
QDataStream::ByteOrder
QDataStream::FloatingPointPrecision
>>
сдвигается битами, а не байтами. Во-вторых, обработка int как байтового массива дает разные результаты в зависимости от порядка байтов.
Это похоже на кодировку на основе индекса, умноженную на 256 добавленных вниз. Я покажу вам "большие" цифры из списка.
i = 510
[0,0,1,254]
510 = 1 * 256 + 254
i = 512
[0,0,2,0]
512 = 2* 256 + 0
Следуя логике, легко увидеть шаблон...