Ah, I see! Keep in mind that reading the whole file is usually a slow process. Most likely that is where most of the time is lost. As for calculating the check sum, I see two issues:
1- Add const before CsumData: array of word in the procedure signature.
2- Order is not important when doing xor operations. Use PtrUInt type instead or word to benefit from the CPU (32 or 64) bits, excluding the last few odd bytes. This way you do (2 or 4) xor operations at the same time, at the end merge the result back to word.
What file sizes are you dealing with?
Edit:
Here is one way to calculate the checksum:
procedure CheckSumCalc(var CsumValue: word; const CsumData: array of word; const vSize: PtrInt; var errorflag: integer); overload;
var
j, CPUTimes, Odd: PtrInt;
cs: PtrUInt;
p: PPtrUInt;
pw: PWord;
begin
{ Start with zero checksums }
CsumValue := 0;
cs := 0;
{ Calculate loop length based on PtrUInt }
CPUTimes := (vSize * 2) div SizeOf(PtrUInt);
{ Calculte left over loop length }
Odd := vSize - (SizeOf(PtrUInt)*CPUTimes div 2);
{ Point at the beginning of data past left over }
p := @CsumData[Odd];
{ Do main calculation }
for j := 0 to CPUTimes - 1 do
cs := cs xor p[j];
{ Do left over calculation }
for j := 0 to Odd - 1 do
CsumValue := CsumValue xor CsumData[j];
{ Merge calculations back to word }
pw := @cs;
for j := 0 to SizeOf(PtrUInt) div 2 - 1 do
CsumValue := CsumValue xor pw[j];
end;
procedure CheckSumCalc(var CsumValue: word; const CsumData: array of word; var errorflag: integer); overload;
begin
CheckSumCalc(CsumValue, CsumData, Length(CsumData), errorflag);
end;
procedure CheckSumCalc(var CsumValue: word; const vStream: TStream; var errorflag: integer); overload;
const
BufSize = 1024*4;
var
BufByte: array[0..BufSize-1] of byte;
Buf: array[0..BufSize div 2 - 1] of word absolute BufByte;
size: Int64;
RemainingSize: Int64;
cs: word;
begin
{ Start with zero checksums }
cs := 0;
CsumValue := 0;
{ Exclude 2 bytes - original checksum }
RemainingSize := vStream.Size - 2;
{ Do calculations in chunks }
while RemainingSize>0 do
begin
{ Read a chunk }
if RemainingSize>Length(BufByte) then
size := vStream.Read(Buf[0], Length(BufByte))
else
size := vStream.Read(Buf[0], RemainingSize);
{ Do the real checksum calculation for this chunk }
CheckSumCalc(cs, Buf[0], Size div 2, errorflag);
{ Merge the result with previous ones }
CsumValue := CsumValue xor cs;
Dec(RemainingSize, size);
end;
end;
And to use it:
m_stream.Position:=0;
CheckSumCalc(chksum, m_stream, errorflg);
WriteLn('chksum: ',IntToHex(chksum, 4));
or
f_stream := TFileStream.Create('C:\Path\SomeBigFile.imi', fmOpenRead);
f_stream.Position:=0;
CheckSumCalc(chksum, f_stream, errorflg);
WriteLn('checksum: ',IntToHex(chksum, 4));
f_stream.Free;