⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kazip.pas

📁 Complete Zip Program
💻 PAS
📖 第 1 页 / 共 5 页
字号:
var
  Buffer: array[1..8192] of Byte;
  I, ReadCount: Integer;
  TempResult: Longword;
begin
  TempResult := $FFFFFFFF;
  while (Stream.Position <> Stream.Size) do begin
    ReadCount := Stream.Read(Buffer, SizeOf(Buffer));
    for I := 1 to ReadCount do
      TempResult := ((TempResult shr 8) and $FFFFFF) xor CRCTable[(TempResult xor Longword(Buffer[I])) and $FF];
  end;
  Result := not TempResult;
end;

Function TKAZipEntries.RemoveRootName(FileName, RootName : String):String;
Var
  P : Integer;
Begin
  Result := FileName;
  P      := Pos(AnsiLowerCase(RootName),AnsiLowerCase(FileName));
  if P=1 Then System.Delete(Result,1,Length(RootName));
End;

Procedure TKAZipEntries.SortList(List : TList);
Var
  X        : Integer;
  I1       : Cardinal;
  I2       : Cardinal;
  NoChange : Boolean;
Begin
  if List.Count=1 Then Exit;
  Repeat
    NoChange := True;
    For X := 0 To List.Count-2 Do
      Begin
        I1 := Integer(List.Items[X]);
        I2 := Integer(List.Items[X+1]);
        if I1 > I2 Then
           Begin
             List.Exchange(X,X+1);
             NoChange := False;
           End;
      End;
  Until NoChange;
End;




function TKAZipEntries.FileTime2DateTime(FileTime: TFileTime): TDateTime;
var
   LocalFileTime: TFileTime;
   SystemTime: TSystemTime;
begin
   FileTimeToLocalFileTime(FileTime, LocalFileTime) ;
   FileTimeToSystemTime(LocalFileTime, SystemTime) ;
   Result := SystemTimeToDateTime(SystemTime) ;
end;

function TKAZipEntries.GetHeaderEntry(Index: Integer): TKAZipEntriesEntry;
begin
  Result := TKAZipEntriesEntry(Inherited Items[Index]);
end;

procedure TKAZipEntries.SetHeaderEntry(Index: Integer; const Value: TKAZipEntriesEntry);
begin
  Inherited Items[Index] := TCollectionItem(Value);
end;

Function TKAZipEntries.ReadBA(MS: TStream; Sz, Poz:Integer): TBytes;
Begin
  SetLength(Result,SZ);
  MS.Position := Poz;
  MS.Read(Result[0],SZ);
End;

function TKAZipEntries.FindCentralDirectory(MS: TStream): Boolean;
Var
  SeekStart : Integer;
  Poz       : Integer;
  BR        : Integer;
  Byte_     : Array[0..3] of Byte;

begin
  Result     := False;
  if MS.Size < 22 Then Exit;
  if MS.Size < 256 Then
     SeekStart := MS.Size
  Else
     SeekStart := 256;
  Poz       := MS.Size-22;
  BR        := SeekStart;
  Repeat
    MS.Position := Poz;
    MS.Read(Byte_,4);
    If Byte_[0]=$50 Then
       Begin
         if  (Byte_[1]=$4B)
         And (Byte_[2]=$05)
         And (Byte_[3]=$06) Then
             Begin
               MS.Position                  := Poz;
               FParent.FEndOfCentralDirPos  := MS.Position;
               MS.Read(FParent.FEndOfCentralDir,SizeOf(FParent.FEndOfCentralDir));
               FParent.FZipCommentPos       := MS.Position;
               FParent.FZipComment.Clear;
               Result  := True;
             End
         Else
             Begin
               Dec(Poz,4);
               Dec(BR ,4);
             End;
       End
    Else
       Begin
         Dec(Poz);
         Dec(BR)
       End;
    if BR < 0 Then
       Begin
         Case SeekStart of
               256   : Begin
                        SeekStart := 1024;
                        Poz       := MS.Size-(256+22);
                        BR        := SeekStart;
                      End;
              1024  : Begin
                        SeekStart := 65536;
                        Poz       := MS.Size-(1024+22);
                        BR        := SeekStart;
                      End;
              65536 : Begin
                        SeekStart := -1;
                      End;
         End;
       End;
    if BR < 0              Then SeekStart := -1;
    if MS.Size < SeekStart Then SeekStart := -1;
  Until (Result) or (SeekStart=-1);
end;


function TKAZipEntries.ParseCentralHeaders(MS: TStream): Boolean;
Var
  X                 : Integer;
  Entry             : TKAZipEntriesEntry;
  CDFile            : TCentralDirectoryFile;
begin
  Result            := False;
  Try
    MS.Position     := FParent.FEndOfCentralDir.OffsetOfStartOfCentralDirectory;
    For X := 0 To FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk-1 do
        Begin
          FillChar(CDFile,SizeOf(TCentralDirectoryFile),0);
          MS.Read(CDFile,SizeOf(TCentralDirectoryFile)-3*SizeOf(String));
          Entry                       := TKAZipEntriesEntry.Create(Self);
          Entry.FDate                 := FileDateToDateTime(CDFile.LastModFileTimeDate);
          if (CDFile.GeneralPurposeBitFlag And 1) > 0 Then
              Entry.FIsEncrypted := True
          Else
              Entry.FIsEncrypted := False;
          If CDFile.FilenameLength > 0 Then
             Begin
               SetLength(CDFile.FileName,CDFile.FilenameLength);
               MS.Read(CDFile.FileName[1],   CDFile.FilenameLength)
             End;
          If CDFile.ExtraFieldLength > 0 Then
             Begin
               SetLength(CDFile.ExtraField,CDFile.ExtraFieldLength);
               MS.Read(CDFile.ExtraField[1], CDFile.ExtraFieldLength);
             End;
          If CDFile.FileCommentLength > 0 Then
             Begin
               SetLength(CDFile.FileComment,CDFile.FileCommentLength);
               MS.Read(CDFile.FileComment[1],CDFile.FileCommentLength);
             End;
          Entry.FIsFolder          := (CDFile.ExternalFileAttributes and faDirectory) > 0;

          Entry.FCompressionType   := ctUnknown;
          if (CDFile.CompressionMethod=8) or (CDFile.CompressionMethod=9) Then
             Begin
               Case CDFile.GeneralPurposeBitFlag AND 6 of
                    0 : Entry.FCompressionType := ctNormal;
                    2 : Entry.FCompressionType := ctMaximum;
                    4 : Entry.FCompressionType := ctFast;
                    6 : Entry.FCompressionType := ctSuperFast
               End;
             End;
          Entry.FCentralDirectoryFile := CDFile;
        End;
   Except
     Exit;
   End;
   Result := Count=FParent.FEndOfCentralDir.TotalNumberOfEntriesOnThisDisk;
end;


procedure TKAZipEntries.ParseZip(MS: TStream);
begin
  FIsZipFile := False;
  Clear;
  if FindCentralDirectory(MS) Then
    Begin
      if ParseCentralHeaders(MS) Then
         Begin
           FIsZipFile := True;
           LoadLocalHeaders(MS);
         End;
    End;
end;


function TKAZipEntries.GetLocalEntry(MS: TStream; Offset : Integer; HeaderOnly : Boolean): TLocalFile;
Var
  Byte_             : Array[0..4] of Byte;
  DataDescriptor    : TDataDescriptor;
begin
  FillChar(Result,SizeOf(Result),0);
  MS.Position := Offset;
  MS.Read(Byte_,4);
  if  (Byte_[0]  = $50)
  And (Byte_[1]  = $4B)
  And (Byte_[2]  = $03)
  And (Byte_[3]  = $04) Then
    Begin
      MS.Position := Offset;
      MS.Read(Result,SizeOf(Result)-3*SizeOf(AnsiString));
      if Result.FilenameLength > 0 Then
         Begin
           SetLength(Result.FileName,Result.FilenameLength);
           MS.Read(Result.FileName[1],Result.FilenameLength);
         End;
      if Result.ExtraFieldLength > 0 Then
         Begin
           SetLength(Result.ExtraField,Result.ExtraFieldLength);
           MS.Read(Result.ExtraField[1],Result.ExtraFieldLength);
         End;
      if (Result.GeneralPurposeBitFlag And (1 SHL 3)) > 0 Then
         Begin
           MS.Read(DataDescriptor,SizeOf(TDataDescriptor));
           Result.Crc32            := DataDescriptor.Crc32;
           Result.CompressedSize   := DataDescriptor.CompressedSize;
           Result.UnCompressedSize := DataDescriptor.UnCompressedSize;
         End;
      if Not HeaderOnly Then
         Begin
           if Result.CompressedSize > 0 Then
              Begin
                SetLength(Result.CompressedData,Result.CompressedSize);
                MS.Read(Result.CompressedData[1],Result.CompressedSize);
              End;
         End;
    End;
end;

procedure TKAZipEntries.LoadLocalHeaders(MS: TStream);
Var
  X : Integer;
begin
  For X := 0 To Count-1 do
      Begin
        Items[X].FLocalFile := GetLocalEntry(MS,Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader,True);
      End;
end;

function TKAZipEntries.ParseLocalHeaders(MS: TStream): Boolean;
Var
  Poz               : Integer;
  Byte_             : Array[0..4] of Byte;
  LocalFile         : TLocalFile;
  DataDescriptor    : TDataDescriptor;
  NoMore            : Boolean;
begin
  Result := False;
  Try
      Poz    := 0;
      Repeat
        NoMore      := True;
        MS.Position := Poz;
        MS.Read(Byte_,4);
        if  (Byte_[0]  = $50)
        And (Byte_[1]  = $4B)
        And (Byte_[2]  = $03)
        And (Byte_[3]  = $04) Then
            Begin
              NoMore      := False;
              MS.Position := Poz;
              MS.Read(LocalFile,SizeOf(TLocalFile)-3*SizeOf(String));
              if LocalFile.FilenameLength > 0 Then
                 Begin
                   SetLength(LocalFile.FileName,LocalFile.FilenameLength);
                   MS.Read(LocalFile.FileName[1],LocalFile.FilenameLength);
                 End;
              if LocalFile.ExtraFieldLength > 0 Then
                 Begin
                   SetLength(LocalFile.ExtraField,LocalFile.ExtraFieldLength);
                   MS.Read(LocalFile.ExtraField[1],LocalFile.ExtraFieldLength);
                 End;
              if (LocalFile.GeneralPurposeBitFlag And (1 SHL 3)) > 0 Then
                 Begin
                   MS.Read(DataDescriptor,SizeOf(TDataDescriptor));
                   LocalFile.Crc32            := DataDescriptor.Crc32;
                   LocalFile.CompressedSize   := DataDescriptor.CompressedSize;
                   LocalFile.UncompressedSize := DataDescriptor.UncompressedSize;
                 End;
              MS.Position := MS.Position+LocalFile.CompressedSize;
              Poz         := MS.Position;
            End;
      Until NoMore;
  Except
    Exit;
  End;
  Result := True;
end;

procedure TKAZipEntries.Remove(ItemIndex: Integer);
Var
  TempStream          : TFileStream;
  TempFileName        : String;
  BUF                 : String;
  ZipComment          : String;
  OSL                 : Cardinal;
  //*********************************************
  X                   : Integer;
  TargetPos           : Cardinal;
  Border              : Cardinal;
begin
 TargetPos          := Items[ItemIndex].FCentralDirectoryFile.RelativeOffsetOfLocalHeader;
 Border             := TargetPos;
 Delete(ItemIndex);
 if (FParent.FZipSaveMethod=FastSave) And (Count > 0) Then
    Begin
       ZipComment := FParent.Comment.Text;
       For X := 0 to Count-1 do
           Begin
             if Items[X].FCentralDirectoryFile.RelativeOffsetOfLocalHeader > Border Then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -