151 lines
3.9 KiB
ObjectPascal

////////////////////////////////////////////////////////////////////////////////
//
// ****************************************************************************
// * Project : FWZip
// * Unit Name : FWZipCrc32
// * Purpose : Íàáîð ôóíêöèé äëÿ ðàññ÷åòà êîíòðîëüíîé ñóììû áëîêà äàííûõ
// * : Êëàññ TFWZipCRC32Stream èñïîëüçóåòñÿ â êà÷åñòâå ïîñðåäíèêà
// * : ìåæäó äâóìÿ ñòðèìàìè è ïðåäíàçíà÷åí äëÿ áàñòðîãî
// * : ðàññ÷åòà êîíòðîëüíîé ñóììû ïåðåäàâàåìûõ áëîêîâ äàííûõ
// * Author : Àëåêñàíäð (Rouse_) Áàãåëü
// * Copyright : © Fangorn Wizards Lab 1998 - 2023.
// * Version : 2.0.0
// * Home Page : http://rouse.drkb.ru
// * Home Blog : http://alexander-bagel.blogspot.ru
// ****************************************************************************
// * Stable Release : http://rouse.drkb.ru/components.php#fwzip
// * Latest Source : https://github.com/AlexanderBagel/FWZip
// ****************************************************************************
//
// Èñïîëüçóåìûå èñòî÷íèêè:
// ftp://ftp.info-zip.org/pub/infozip/doc/appnote-iz-latest.zip
// https://zlib.net/zlib-1.2.13.tar.gz
// http://www.base2ti.com/
//
unit FWZipCrc32;
{$IFDEF FPC}
{$MODE Delphi}
{$H+}
{$ENDIF}
interface
uses
Classes,
SysUtils,
FWZipConsts;
type
TFWZipCRC32Stream = class(TStream)
private
FOwner: TStream;
FCRC32: Cardinal;
protected
function GetSize: Int64; override;
public
constructor Create(AOwner: TStream);
function Seek(Offset: Longint; Origin: Word): Longint; overload; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; overload; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function CRC32: Cardinal;
end;
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal; overload;
function FileCRC32(const FileName: string): Cardinal;
implementation
function CRC32Calc(CurrCRC: Cardinal;
Buffer: PByte; const BufferLen: Int64): Cardinal;
var
I: Integer;
begin
Result := CurrCRC;
for I := 0 to BufferLen - 1 do
begin
Result := ((Result shr 8) and $00FFFFFF) xor
CRC32Table[(Result xor Buffer^) and $FF];
Inc(Buffer);
end;
end;
function CRC32Calc(Buffer: PByte; const BufferLen: Int64): Cardinal;
begin
Result := CRC32Calc($FFFFFFFF, Buffer, BufferLen) xor $FFFFFFFF;
end;
function FileCRC32(const FileName: string): Cardinal;
var
Buff: Pointer;
F: TFileStream;
Size: Integer;
begin
Result := $FFFFFFFF;
GetMem(Buff, $FFFF);
try
F := TFileStream.Create(FileName, fmOpenRead);
try
Size := 1;
while Size > 0 do
begin
Size := F.Read(Buff^, $FFFF);
Result := CRC32Calc(Result, Buff, Size);
end;
finally
F.Free;
end;
finally
FreeMem(Buff);
end;
Result := Result xor $FFFFFFFF;
end;
{ TFWZipCRC32Stream }
function TFWZipCRC32Stream.CRC32: Cardinal;
begin
Result := FCRC32 xor $FFFFFFFF;
end;
constructor TFWZipCRC32Stream.Create(AOwner: TStream);
begin
FOwner := AOwner;
FCRC32 := $FFFFFFFF;
end;
function TFWZipCRC32Stream.GetSize: Int64;
begin
Result := FOwner.Size;
end;
function TFWZipCRC32Stream.Read(var Buffer; Count: Integer): Longint;
begin
Result := FOwner.Read(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
function TFWZipCRC32Stream.Seek(Offset: Integer; Origin: Word): Longint;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Seek(const Offset: Int64;
Origin: TSeekOrigin): Int64;
begin
Result := FOwner.Seek(Offset, Origin);
end;
function TFWZipCRC32Stream.Write(const Buffer; Count: Integer): Longint;
begin
Result := FOwner.Write(Buffer, Count);
FCRC32 := CRC32Calc(FCRC32, @Buffer, Result);
end;
end.