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

📄 abgztyp.pas

📁 Lazarus is a free and open source development tool for the FreePascal Compiler. The purpose of the p
💻 PAS
📖 第 1 页 / 共 3 页
字号:
(* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is TurboPower Abbrevia * * The Initial Developer of the Original Code is * TurboPower Software * * Portions created by the Initial Developer are Copyright (C) 1997-2002 * the Initial Developer. All Rights Reserved. * * Contributor(s): * * ***** END LICENSE BLOCK ***** *){*********************************************************}{* ABBREVIA: AbGzTyp.pas 3.05                            *}{*********************************************************}{* ABBREVIA: TAbGzipArchive, TAbGzipItem classes         *}{*********************************************************}{* Misc. constants, types, and routines for working      *}{* with GZip files                                       *}{* See: RFC 1952                                         *}{* "GZIP file format specification version 4.3"          *}{* for more information on GZip                          *}{*********************************************************}{$I AbDefine.inc}unit AbGzTyp;interfaceuses  {$IFDEF MSWINDOWS}  Windows,  {$ENDIF}  {$IFDEF LINUX}  {$IFNDEF NOQT}  QDialogs,  {$ENDIF}  {$ENDIF}  SysUtils, Classes,  AbConst, AbExcept, AbUtils, AbArcTyp, AbTarTyp,   AbDfBase, AbDfDec, AbDfEnc, AbVMStrm, AbBitBkt, AbSpanSt;type  { pre-defined "operating system" (really more FILE system)    types for the Gzip header }  TAbGzFileSystem =    (osFat, osAmiga, osVMS, osUnix, osVM_CMS, osAtariTOS,    osHPFS, osMacintosh, osZSystem, osCP_M, osTOPS20,    osNTFS, osQDOS, osAcornRISCOS, osUnknown, osUndefined);type  PAbGzHeader = ^TAbGzHeader;  TAbGzHeader = packed record  { SizeOf(TGzHeader) = 10}    ID1        : Byte;  { ID Byte, should always be $1F}    ID2        : Byte;  { ID Byte, should always be $8B}    CompMethod : Byte;  { compression method used}    { 0..7 reserved, 8 = deflate, others undefined as of this writing (4/27/2001)}    Flags      : Byte; { misc flags}      { Bit 0: FTEXT    compressed file contains text, can be used for}                      { cross platform line termination translation}      { Bit 1: FHCRC    header data includes CRC16 for header after}                      { Extra Data, FileName, and Comment, if any}      { Bit 2: FEXTRA   header data contains Extra Data, starts immediately}                      { after header proper}      { Bit 3: FNAME    header data contains FileName, null terminated}                      { string starting immediately after Extra Data (if any)}      { Bit 4: FCOMMENT header data contains Comment, null terminated string}                      { starting immediately after FileName (if any)}      { Bits 5..7 are undefined and reserved as of this writing (4/27/2001)}    ModTime    : LongInt; { File Modification (Creation) time,}                          { UNIX cdate format}    XtraFlags  : Byte;   { additional flags}      { XtraFlags = 2  -- Deflate compressor used maximum compression algorithm}      { XtraFlags = 4  -- Deflate compressor used fastest algorithm}    OS         : Byte; { Operating system that created file,}                       { see GZOsToStr routine for values}  end;  TAbGzTailRec = packed record    CRC32 : LongInt;  { crc for uncompressed data }    ISize : LongInt;  { size of uncompressed data }  end;type  TAbGzipItem = class(TAbArchiveItem)  private    FCRC32: LongInt;  protected {private}    FGZHeader : TAbGzHeader;    FIsText : Boolean;    FCRC16 : ShortInt;    FXLen  : ShortInt;    FExtraField, FFileComment : string;    FIncludeHeaderCrc: Boolean;  protected    function GetExtraField: string;    function GetFileSystem: TAbGzFileSystem;    function GetFileComment: string;    function GetHeaderCRC: Word;    function GetHasExtraField: Boolean;    function GetHasFileComment: Boolean;    function GetHasHeaderCRC: Boolean;    function GetHasFileName: Boolean;    function GetIsText: Boolean;    procedure SetExtraField(const Value: string);    procedure SetFileComment(Value : string);    procedure SetFileSystem(const Value: TAbGzFileSystem);    procedure SetIsText(const Value: Boolean);    function GetCompressedSize : LongInt; override;    function GetExternalFileAttributes : LongInt; override;    function GetIsEncrypted : Boolean; override;    function GetLastModFileDate : Word; override;    function GetLastModFileTime : Word; override;    function GetUncompressedSize : LongInt; override;    procedure SetCompressedSize(const Value : LongInt); override;    procedure SetExternalFileAttributes( Value : LongInt ); override;    procedure SetFileName(Value : string); override;    procedure SetIsEncrypted(Value : Boolean); override;    procedure SetLastModFileDate(const Value : Word); override;    procedure SetLastModFileTime(const Value : Word); override;    procedure SetUncompressedSize(const Value : LongInt); override;    procedure SaveGzHeaderToStream(AStream : TStream);    procedure LoadGzHeaderFromStream(AStream : TStream);  public    property CRC32 : LongInt      read FCRC32 write FCRC32;    property CompressionMethod : Byte      read FGZHeader.CompMethod write FGZHeader.CompMethod;    property ExtraFlags : Byte {Default: 2}      read FGZHeader.XtraFlags write FGZHeader.XtraFlags;    property Flags : Byte      read FGZHeader.Flags write FGZHeader.Flags;    property FileComment : string      read GetFileComment write SetFileComment;    property FileSystem : TAbGzFileSystem {Default: osFat (Windows); osUnix (Linux)}      read GetFileSystem write SetFileSystem;    property ExtraField : string      read GetExtraField write SetExtraField;    property HeaderCRC : Word      read GetHeaderCRC;    property IsEncrypted : Boolean      read GetIsEncrypted;    property HasExtraField : Boolean      read GetHasExtraField;    property HasFileName : Boolean      read GetHasFileName;    property HasFileComment : Boolean      read GetHasFileComment;    property HasHeaderCRC : Boolean      read GetHasHeaderCRC;    property IsText : Boolean      read GetIsText write SetIsText;    property GZHeader : TAbGzHeader      read FGZHeader write FGZHeader;    property IncludeHeaderCrc : Boolean      read FIncludeHeaderCrc write FIncludeHeaderCrc;    constructor Create;  end;  TAbGzipStreamHelper = class(TAbArchiveStreamHelper)  private    function GetGzCRC: LongInt;    function GetFileSize: LongInt;  protected {private}    FItem : TAbGzipItem;    FTail : TAbGzTailRec;  public    constructor Create(AStream : TStream);    destructor Destroy; override;    procedure ExtractItemData(AStream : TStream); override;    function FindFirstItem : Boolean; override;    function FindNextItem : Boolean; override;    function SeekItem(Index : Integer): Boolean; override;    procedure SeekToItemData;    procedure WriteArchiveHeader; override;    procedure WriteArchiveItem(AStream : TStream); override;    procedure WriteArchiveTail; override;    function GetItemCount : Integer; override;    procedure ReadHeader; override;    procedure ReadTail; override;    property CRC : LongInt      read GetGzCRC;    property FileSize : LongInt      read GetFileSize;    property TailCRC : LongInt      read FTail.CRC32;    property TailSize : LongInt      read FTail.ISize;  end;  TAbGzipArchiveState = (gsGzip, gsTar);  TAbGzipArchive = class(TAbTarArchive)  private    FGZStream  : TStream;        { stream for GZip file}    FGZItem    : TAbArchiveList; { item in Gzip (only one, but need polymorphism of class)}    FTarStream : TStream;        { stream for possible contained Tar }    FTarList   : TAbArchiveList; { items in possible contained Tar }    FTarAutoHandle: Boolean;    FTarLoaded : Boolean;    FState     : TAbGzipArchiveState;    FIsGzippedTar : Boolean;    procedure SetTarAutoHandle(const Value: Boolean);    function GetIsGzippedTar: Boolean;    procedure SwapToGzip;    procedure SwapToTar;  protected    function CreateItem(const FileSpec : string): TAbArchiveItem;      override;    procedure ExtractItemAt(Index : Integer; const NewName : string);      override;    procedure ExtractItemToStreamAt(Index : Integer; aStream : TStream);      override;    procedure LoadArchive;      override;    procedure SaveArchive;      override;    procedure TestItemAt(Index : Integer);      override;    function FixName(Value : string) : string;      override;    function GetItem(Index: Integer): TAbGzipItem;                  {!!.03}    procedure PutItem(Index: Integer; const Value: TAbGzipItem);    {!!.03}  public {methods}    constructor Create(FileName : string; Mode : Word);      override;    destructor  Destroy;      override;    procedure DoSpanningMediaRequest(Sender : TObject; ImageNumber : Integer;      var ImageName : string; var Abort : Boolean); override;    property TarAutoHandle : Boolean      read FTarAutoHandle write SetTarAutoHandle;    property IsGzippedTar : Boolean      read GetIsGzippedTar write FIsGzippedTar;    property Items[Index : Integer] : TAbGzipItem                    {!!.03}      read GetItem                                                   {!!.03}      write PutItem; default;                                        {!!.03}  end;function VerifyGZip(Strm : TStream) : TAbArchiveType;function GZOsToStr(OS: Byte) : string;implementationconst  { Header Signature Values}  AB_GZ_HDR_ID1 = $1F;  AB_GZ_HDR_ID2 = $8B;  { Test bits for TGzHeader.Flags field }  AB_GZ_FLAG_FTEXT    = $01;  AB_GZ_FLAG_FHCRC    = $02;  AB_GZ_FLAG_FEXTRA   = $04;  AB_GZ_FLAG_FNAME    = $08;  AB_GZ_FLAG_FCOMMENT = $10;  { GZip OS source flags }  AB_GZ_OS_ID_FAT         = 0;  AB_GZ_OS_ID_Amiga       = 1;  AB_GZ_OS_ID_VMS         = 2;  AB_GZ_OS_ID_Unix        = 3;  AB_GZ_OS_ID_VM_CMS      = 4;  AB_GZ_OS_ID_AtariTOS    = 5;  AB_GZ_OS_ID_HPFS        = 6;  AB_GZ_OS_ID_Macintosh   = 7;  AB_GZ_OS_ID_Z_System    = 8;  AB_GZ_OS_ID_CP_M        = 9;  AB_GZ_OS_ID_TOPS20      = 10;  AB_GZ_OS_ID_NTFS        = 11;  AB_GZ_OS_ID_QDOS        = 12;  AB_GZ_OS_ID_AcornRISCOS = 13;  AB_GZ_OS_ID_unknown     = 255;function GZOsToStr(OS: Byte) : string;{Return a descriptive string for TGzHeader.OS field}begin  case OS of    AB_GZ_OS_ID_FAT         : Result := AbGzOsFat;    AB_GZ_OS_ID_Amiga       : Result := AbGzOsAmiga;    AB_GZ_OS_ID_VMS         : Result := AbGzOsVMS;    AB_GZ_OS_ID_Unix        : Result := AbGzOsUnix;    AB_GZ_OS_ID_VM_CMS      : Result := AbGzOsVM_CMS;    AB_GZ_OS_ID_AtariTOS    : Result := AbGzOsAtari;    AB_GZ_OS_ID_HPFS        : Result := AbGzOsHPFS;    AB_GZ_OS_ID_Macintosh   : Result := AbGzOsMacintosh;    AB_GZ_OS_ID_Z_System    : Result := AbGzOsZ_System;    AB_GZ_OS_ID_CP_M        : Result := AbGzOsCP_M;    AB_GZ_OS_ID_TOPS20      : Result := AbGzOsTOPS_20;    AB_GZ_OS_ID_NTFS        : Result := AbGzOsNTFS;    AB_GZ_OS_ID_QDOS        : Result := AbGzOsQDOS;    AB_GZ_OS_ID_AcornRISCOS : Result := AbGzOsAcornRISCOS;    AB_GZ_OS_ID_unknown     : Result := AbGzOsunknown;  else    Result := AbGzOsUndefined;  end;end;function VerifyHeader(Header : TAbGzHeader) : Boolean;begin  { check id fields and if deflated (only handle deflate anyway)}  Result := (Header.ID1 = AB_GZ_HDR_ID1) and     (Header.ID2 = AB_GZ_HDR_ID2) and     (Header.CompMethod = 8 {deflate});end;function VerifyGZip(Strm : TStream) : TAbArchiveType;var{  Hdr : TAbGzHeader; }  GHlp : TAbGzipStreamHelper;  Hlpr : TAbDeflateHelper;  PartialTarData : TMemoryStream;  CurPos : LongInt;begin  Result := atUnknown;  CurPos := Strm.Position;  Strm.Seek(0, soFromBeginning);  {prepare for the try..finally}  Hlpr := nil;  PartialTarData := nil;  GHlp := TAbGzipStreamHelper.Create(Strm);  try    {create the stream helper and read the item header}    GHlp.ReadHeader;    { check id fields and if deflated (only handle deflate anyway)}    if VerifyHeader(GHlp.FItem.FGZHeader) then begin      Result := atGZip; { provisional }      { check if is actually a Gzipped Tar }      { partial extract contents, verify vs. Tar }      PartialTarData := TMemoryStream.Create;      GHlp.SeekToItemData;      Hlpr := TAbDeflateHelper.Create;      Hlpr.PartialSize := 512;      PartialTarData.SetSize(512 * 2);      Inflate(Strm, PartialTarData, Hlpr);      {set to beginning of extracted data}      PartialTarData.Position := 0;      if (VerifyTar(PartialTarData) = atTar) then        Result := atGZippedTar;    end;  finally    GHlp.Free;    Hlpr.Free;    PartialTarData.Free;        Strm.Position := CurPos;  end;end;{ TAbGzipStreamHelper }constructor TAbGzipStreamHelper.Create(AStream : TStream);begin  inherited Create(AStream);  FItem := TAbGzipItem.Create;end;destructor TAbGzipStreamHelper.Destroy;begin  FItem.Free;  inherited;end;procedure SeekToStringEndInStream(AStream: TStream);{locate next instance of a null character in a streamleaves stream positioned just past that,or at end of stream if not found or null is last byte in stream.}const  BuffSiz = 1024;var  Buff   : array [0..BuffSiz-1] of AnsiChar;  Len, StartPos, DataRead, TotalRead : LongInt;  Done : Boolean;begin{ basically what this is supposed to do is...}{  repeat    AStream.Read(C, 1);  until (AStream.Position = AStream.Size) or (C = #0);}  StartPos := AStream.Position;  Done := False;  TotalRead := 0;  while not Done do begin    DataRead := AStream.Read(Buff, BuffSiz - 1);    if DataRead = 0 then      Done := True    else begin      Buff[DataRead] := #0;      Len := StrLen(Buff);      if Len < DataRead then begin        Done := True;        AStream.Seek(StartPos + TotalRead + Len + 1, soFromBeginning);      end else        TotalRead := TotalRead + DataRead;    end;  end;end;procedure TAbGzipStreamHelper.SeekToItemData;{find end of header data, including FileName etc.}begin  {** Seek to Compressed Data **}  FStream.Seek(0, soFromBeginning);  FItem.LoadGzHeaderFromStream(FStream);end;procedure TAbGzipStreamHelper.ExtractItemData(AStream: TStream);var  Helper : TAbDeflateHelper;begin  Helper := TAbDeflateHelper.Create;  try    SeekToItemData;    if (AStream is TAbBitBucketStream) then      Helper.Options := Helper.Options or dfc_TestOnly;    FItem.CRC32 := Inflate(FStream, AStream, Helper);    FItem.UncompressedSize := AStream.Size{Helper.NormalSize};  finally    Helper.Free;  end;end;function TAbGzipStreamHelper.FindFirstItem: Boolean;var

⌨️ 快捷键说明

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