2008-10-07 3 views
3

Я пытаюсь распаковать некоторые данные, созданные в VB6, используя API zlib.Как преобразовать число в bytearray в порядке бит в конец

Я прочитал это возможно с помощью функции qUncompress: http://doc.trolltech.com/4.4/qbytearray.html#qUncompress

Я прочитал данные в из QDataStream через readRawBytes в символ массив, который я затем преобразуется в QByteArray для декомпрессии. I имеют сжатую длину и ожидаемую декомпрессированную длину, но я не получаю что-нибудь из qUncompress.

Однако мне нужно добавить ожидаемую декомпрессированную длину в формате большой буквы. Кто-нибудь сделал это и привел пример?

ответ

2

Я не использовал VB6 в возрастов, так что я надеюсь, что это примерно правильно. I думаю это vb6 б/у() для индексирования массива. Если у меня что-то не так, сообщите мне.

Если вы посмотрите на qUncompress docs, вы должны поместить свои данные в свой QByteArray, начиная с байта 5 (я собираюсь предположить, что вы оставили базу данных массива, установленную для этого примера 1).

Скажем, массив имеет имя qArr, а ожидаемый несжатый размер - это размер. В представлении «big-endian» первый байт находится по первому адресу.

qArr(1) = int(Size/(256*256*256)) 
qArr(2) = 255 And int(Size/256*256) 
qArr(3) = 255 And int(Size/256) 
qArr(4) = 255 And int(Size) 

Это имеет смысл?

Если вам нужен маленький конец, вы можете просто изменить порядок индексов (qArr (4) - qArr (1)) и оставить вычисления одинаковыми.

0

Похоже, вы хотите кусок кода C, который сжимает некоторые сжатые данные zlib. В этом случае вы можете использовать zlib и просто передавать данные zlib. Домашняя страница zlib: http://www.zlib.net/.

Если я ошибаюсь, можете ли вы указать, какой язык следует использовать для разжатия данных и почему zlib не будет выбором?

+0

qCompress/qUncompress просто оберткой Zlib. – 2008-10-07 12:48:47

0
//int length; 
byte[] bigEndianBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(length)) 

И наоборот:

//byte[] bigEndianBytes; 
int length = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(bigEndianBytes)) 
+0

Доступны ли BitConverter и IPAddress в vb6? – 2008-10-07 11:33:41

1

Это, как я могу преобразовать данные из произвольных одного формата в другой.

Private Type LongByte 
    H1 As Byte 
    H2 As Byte 
    L1 As Byte 
    L2 As Byte 
End Type 

Private Type LongType 
    L As Long 
End Type 

Function SwapEndian(ByVal LongData as Long) as Long 
    Dim TempL As LongType 
    Dim TempLB As LongByte 
    Dim TempVar As Long 

    TempL.L = LongData 
    LSet TempLB = TempL 
'Swap is a subroutine I wrote to swap two variables 
    Swap TempLB.H1, TempLB.L2 
    Swap TempLB.H2, TempLB.L1 
    LSet TempL = TempLB 
    TempVar = TempL.L 

    SwapEndian = TempVar 
End Function 

Если вы имеете дело с FileIO, то вы можете использовать Byte поле TempLB

Уловка с помощью LSet безвестных команд из VB6

Если вы используете .NET, то делает процесс намного проще. Здесь трюк использует MemoryStream для извлечения и установки отдельных байтов. Теперь вы можете сделать математику для int16/int32/int64. Но если вы имеете дело с данными с плавающей запятой, использование LSET или MemoryStream намного яснее и легче отлаживать.

Если вы используете версию Framework 1.1 или более позднюю, то у вас есть класс BitConvertor, который использует массивы байтов.

Private Structure Int32Byte 
    Public H1 As Byte 
    Public H2 As Byte 
    Public L1 As Byte 
    Public L2 As Byte 
    Public Function Convert() As Integer 
     Dim M As New MemoryStream() 
     Dim bR As IO.BinaryReader 
     Dim bW As New IO.BinaryWriter(M) 
     Swap(H1, L2) 
     Swap(H2, L1) 
     bW.Write(H1) 
     bW.Write(H2) 
     bW.Write(L1) 
     bW.Write(L2) 
     M.Seek(0, SeekOrigin.Begin) 
     bR = New IO.BinaryReader(M) 
     Convert = bR.ReadInt32() 
    End Function 
End Structure 
0

Это не было для меня ясно из вашего вопроса, хотите ли вы предварять длину в VB, так что она пригодна для непосредственного использования qUncompress, или же вы хотите использовать VB были получены данные, как сейчас и добавьте длину в C++ перед вызовом qUncompress.

Mike G имеет posted решение VB. Если вы хотите сделать это на C++, у вас есть два варианта: либо добавьте длину в начале QByteArray, либо сразу вызовите zlib. В обоих случаях источник Qt для qCompress и qUncompress (corelib/tools/qbytearray.cpp) является хорошей ссылкой.

Это как qCompress добавляет длину (число-байт) в bazip, сжатые данные:

bazip[0] = (nbytes & 0xff000000) >> 24; 
bazip[1] = (nbytes & 0x00ff0000) >> 16; 
bazip[2] = (nbytes & 0x0000ff00) >> 8; 
bazip[3] = (nbytes & 0x000000ff); 

где bazip является результатом QByteArray

В качестве альтернативы, если вы хотите позвонить распаковывать непосредственно, вместо того, чтобы использовать qUncompress обертка вызов он использует это

baunzip.resize(len); 
res = ::uncompress((uchar*)baunzip.data(), &len, 
         (uchar*)data+4, nbytes-4); 

где baunzip является QByteArray. В вашем случае вы потеряете +4 и -4, так как ваши данные не имеют длины, предшествующей этому.

0

Благодарим за оказанную помощь, это было полезно.

Я получил код, работающий с:

 char slideStr[currentCompressedLen]; 
     int slideByteRead = in.readRawData(slideStr, currentCompressedLen); 
     QByteArray aInCompBytes = QByteArray(slideStr, slideByteRead); 
     aInCompBytesPlusLen = aInCompBytes; 
     aInCompBytesPlusLen.prepend(QByteArray::number(currentUnCompressedLen)); 
     aInUnCompBytes.resize(currentUnCompressedLen); 
     aInUnCompBytes = qUncompress(aInCompBytesPlusLen); 

 Смежные вопросы

  • Нет связанных вопросов^_^