PDA

View Full Version : Porting from C# to Qt4



Sölve
13th May 2011, 19:01
Hello.
I'm porting some code from C# to Qt4 and I met some problems.
The program opens a binary file and retrieves some data from it.

This is code in C#:


string scriptName = args[0];
Encoding jis = Encoding.GetEncoding(932);
using(BinaryReader script = new BinaryReader(scriptFile.OpenRead(), jis))
{
script.BaseStream.Seek(0x020, SeekOrigin.Begin);
uint opcode = script.ReadUInt32();
uint codeSize = script.ReadUInt32();

script.BaseStream.Seek(0, SeekOrigin.Begin);
byte[] scriptBuffer = script.ReadBytes((int)codeSize);

for(int dwptr = 0; dwptr < codeSize; dwptr += 4)
{
uint currentDw = scriptBuffer[dwptr];
if(currentDw != 0x03 && currentDw != 0x07F)
continue;

dwptr += 4;
currentDw = ToUInt32(scriptBuffer, dwptr);
}
}

and reimplemented ToUInt32 (in C#):

static uint ToUInt32(byte[] array, int beginOfs)
{
return(uint)((array[beginOfs+3] << 24) | (array[beginOfs+2] << 16) | (array[beginOfs+1] << 8) | (array[beginOfs]));
}

I ported this code to:


QFile cScript(fPath+"/"+fName);
cScript.open(QIODevice::ReadOnly);

QDataStream cData(&cScript);
cData.setByteOrder(QDataStream::LittleEndian);

cScript.seek(0x020);

quint32 opcode;
quint32 codeSize;

cData >> opcode;
cData >> codeSize;

cScript.seek(0);
QByteArray fragment = cScript.read(codeSize);

for(quint32 dwptr = 0; dwptr < codeSize; dwptr += 4)
{
quint32 curr = fragment[dwptr];
if(curr != 0x03 && curr != 0x07F)
continue;

dwptr +=4;
curr = toUint32(fragment, dwptr);
}

and toUint32 function:


quint32 EustiaTools::toUint32(QByteArray array, uint offStart)
{
return(quint32)((array[offStart+3] << 24) | (array[offStart+2] << 16) | (array[offStart+1] << 8) | (array[offStart]));
}

My problem probably lies in this line:


quint32 curr = fragment[dwptr];

And in function toUint32 too.
I checked and my curr before for loop equals 4294967272 when currentDw from C# equals 232.
I changed type of curr from quint32 to int and then curr equals -24.

How to repair that?

Sorry for my bad english.
Thanks in advance.

wysota
13th May 2011, 21:36
Your problem lies in the use of QDataStream. It's not an equivalent of BinaryReader but rather a serialization mechanism. Use QFile only and forget about QDataStream.

Sölve
14th May 2011, 01:16
Thank you for your reply.
I replaced getting data from QDataStream by memcpy and changed line:

quint32 curr = fragment[dwptr];
to:

quint32 curr;
memcpy(&curr, QByteArray(1, fragment[dwptr]).constData(), 4);

Now my code looks like that:

QFile cScript(fPath+"/"+fName);
cScript.open(QIODevice::ReadOnly);

quint32 opcode;
quint32 codeSize;

cScript.seek(0x020);
memcpy(&opcode, cScript.read(4).constData(), 4);
memcpy(&codeSize, cScript.read(4).constData(), 4);

cScript.seek(0);
QByteArray fragment = cScript.read(codeSize);

for(quint32 dwptr = 0; dwptr < codeSize; dwptr += 4)
{
quint32 curr;
memcpy(&curr, QByteArray(1, fragment[dwptr]).constData(), 4);
qDebug() << curr;

if(curr != 0x03 && curr != 0x07F)
continue;

dwptr +=4;
curr = toUint32(fragment, dwptr);
}

Now I've got bad first value of curr, but rest of values are ok.
First value = 3342352, but I need 16.
Is it related to memcpy() function?

wysota
14th May 2011, 08:35
My guess is you want to read a single byte and not 32 bits, that's what you seem to be doing in your original code. QByteArray::at() will return a single byte for you.

Sölve
15th May 2011, 11:02
Okay, I rewrote code and changed quint32 to quint8 which fits to value returned by QByteArray::at(). Thanks for help, topic solved.