PDA

View Full Version : C++ -> Delphi convertion problem



CynicRus
12-08-2014, 07:26 AM
Hello guys. I have a few problems with convertion the C++ code to Delphi.

1)
C++:


typedef struct _HashRecord_ {
unsigned value1;
unsigned value2;
} HashRecord;
...
void BSARecord::calculateHash() {
unsigned l = (len>>1);
unsigned sum, off, temp, i, n;

for(sum = off = i = 0; i < l; i++) {
sum ^= (((unsigned)(name[i]))<<(off&0x1F));
off += 8;
}
hash.value1 = sum;

for(sum = off = 0; i < len; i++) {
temp = (((unsigned)(name[i]))<<(off&0x1F));
sum ^= temp;
n = temp & 0x1F;
sum = (sum << (32-n)) | (sum >> n); // binary "rotate right"
off += 8;
}
hash.value2 = sum;
}

I've converted this code as:


procedure TMorrowindWorker.GenHash(Data: TAbstractFile);
var
Name: AnsiString;
len, sum, off, i, temp, n,l: cardinal;
begin
Name:=AnsiString(Data.Directory + Data.Name);
len := Length(Name);
l:=0;
l:= len shr 1;
sum := 0;
off := 0;
for i:=1 to l do
begin
sum := sum xor (Cardinal(Name[i]) shl (off and $1F));
off := off + 8;
end;
Data.Hash1:=sum;

sum:=0;
off:=0;
temp:=0;
n:=0;
while I < len do
begin
temp := (Cardinal(Name[i]) shl (off and $1F));
sum := sum xor temp;
n := temp and $1F;
sum := (sum shl (32 - n)) or (sum shr n);
off := off + 8;
Inc(i);
end;
Data.Hash2:=sum;
end;


Where Data.Hash fileds is Cardinal. But sometimes I got the different results on same strings! What I do wrong?

2) I have the sort code on C++:


int BSARecord::CompareByHash(const void *pElem1, const void *pElem2) {
BSARecord *elem1 = (BSARecord *)pElem1;
BSARecord *elem2 = (BSARecord *)pElem2;
int result;

if ( (elem1->hash.value1) < (elem2->hash.value1) ) {
return -1;
}
else if ( (elem1->hash.value1) > (elem2->hash.value1) ) {
return 1;
}
else if ( (elem1->hash.value2) < (elem2->hash.value2) ) {
return -1;
}
else if ( (elem1->hash.value2) > (elem2->hash.value2) ) {
return 1;
}

return stricmp(elem1->name, elem2->name);
}

int BSARecord::CompareByName(const void *pElem1, const void *pElem2) {
BSARecord *elem1 = (BSARecord *)pElem1;
BSARecord *elem2 = (BSARecord *)pElem2;

return stricmp(elem1->name, elem2->name);
}


I've converted it as:

function CompareByHash(P1, P2: Pointer): Integer;
var
AFile1, AFile2: TAbstractFile;
begin
AFile1 := TAbstractFile(P1);
AFile2 := TAbstractFile(P2);
// result := StrIComp(PChar(AFile1.Name), PChar(AFile2.Name));
if ((AFile1.Hash1) < (AFile2.Hash1)) then
result := -1
else if ((AFile1.Hash1) > (AFile2.Hash1)) then
result := 1
else if ((AFile1.Hash2 ) < (AFile2.Hash2)) then
result := -1
else if ((AFile1.Hash2) > (AFile2.Hash2)) then
result := 1
else
result := StrComp(PAnsiChar(AFile1.Directory + AFile1.Name), PAnsiChar(AFile2.Directory +AFile2.Name));
end;
function CompareByName(P1,P2: Pointer):Integer;
var
AFile1,AFile2: TAbstractFile;
begin
AFile1:=TAbstractFile(P1);
AFile2:=TAbstractFile(P2);
result:= StrComp(PChar(AFile1.Directory + AFile1.Name),PChar(AFile2.Directory + AFile2.Name));
end;


And I have the same problem: the results is sometimes is different on the same strings. how I can the convert this code to Delphi is much accuracy? Thank you.


PS: Brandon; maybe you can help me with this?

CynicRus
12-08-2014, 09:56 AM
Lol:) Fixed:) Delphi string's have #0 at the end:)


var
Name: AnsiString;
len, sum, off, i, temp, n,l: cardinal;
begin
Name:=AnsiString(TrimLeft(Data.Directory + Data.Name));
len := Length(Name)-1;
l:=0;
l:= len shr 1;
sum := 0;
off := 0;
for i:=1 to l do
begin
sum := sum xor (Cardinal(Name[i]) shl (off and $1F));
off := off + 8;
end;
Data.Hash1:=sum;

sum:=0;
off:=0;
temp:=0;
n:=0;
while I <= len do
begin
temp := (Cardinal(Name[i]) shl (off and $1F));
sum := sum xor temp;
n := temp and $1F;
sum := (sum shl (32 - n)) or (sum shr n);
off := off + 8;
Inc(i);
end;
Data.Hash2:=sum;
end;

Brandon
12-08-2014, 02:51 PM
Delphi string's have #0 at the end


C/C++ strings do as well (have '\0' at the end). The difference is actually the for-loop.


for (int i = 0; i < len; ++i)


is the same as:


for I := 0 To Len - 1 do



notice the "-1". I had the same problem when making the tesseract plugin (very annoying.. Took me long enough to actually spot the first time around).

Example:

C/C++: http://ideone.com/UcOObf
Pascal/Delphi: http://ideone.com/mycTq4


Glad you solved it though :) +1.