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

📄 chieflz.pas

📁 delhpi下lzss加密算法源码及例子
💻 PAS
📖 第 1 页 / 共 5 页
字号:
{$else Windows}
  INT $21
{$endif Windows}
  POP DS
  JC @Fail
{
  The file handle refers to an OPEN file; close it so we can open it
  the Pascal way ...
}
  MOV BX, AX
  MOV AH, $3E
{$ifdef Windows}
  CALL DOS3Call
{$else Windows}
  INT $21
{$endif Windows}
{
  Return True if successful, False otherwise ...
}
@Fail:
{$ifdef Delphi}
  DB $0F, $93, $C0  (* setnc al *)
{$else Delphi}
  MOV AL, False
  JC @End
  INC AX
@End:
{$endif Delphi}
end;

{$endif Win32}

{/////////////////////////////////////////////////////////}
{///// is this an LZ compressed file using this unit? ////}
Function IsMyLZFile(Var InFile:file; Var f:TLZHeader):boolean;
var
  OldPos:  LongInt;
  NumRead: Integer;
begin
  OldPos := FilePos(InFile);
  Seek(InFile,0);
  BlockRead(InFile, f, SizeOf(f), NumRead);
  IsMyLZFile := (NumRead = SizeOf(f))
                  and (Length(f.FName) <> 0)
                  and (f.Signature = ChiefLZSig);
  Seek(InFile,OldPos)
end;

{/////////////////////////////////////////////////////////}
{////: normal file copy if not LZ file}
const LZ_UNKNOWN_LENGTH = -1;

type TReporting = (doReportOnRead, doReportOnWrite);

Function MyFCopy(var InFile, OutFile: file;
                 const CopyLength: LongInt;
                 const doReport:   TReporting): LongInt;
{$ifndef Win32} far; {$endif}
Var
p: PBufType;
{
  Turn the enumerated type doReport into a Boolean:
    doReportOnRead  -> False
    doReportOnWrite -> True

  Decompression routines will call MyFCopy() using doReportOnWrite,
  whereas Compression routines will call using doReportOnRead
}
var
ReportingOnWrite: Boolean absolute doReport;

{$ifdef Win32}
NumRead:integer;
BRead:  integer;
{$else}
BRead:  word;
NumRead:word;
NumWrit:word;
{$endif}
{$ifndef Delphi}
Result: LongInt;
{$endif}

begin

{$IFDEF Debug}
   if CopyLength < LZ_UNKNOWN_LENGTH then
   {$ifdef Win32}
     raise EChiefLZDebug.Create('Negative copy-length passed to MyFCopy')
       at AddrOfCaller        
   {$else Win32}
     RunErrorMessageAt('Negative copy-length passed to MyFCopy',
                        AddrOfCaller)
   {$endif Win32};
{$ENDIF}
   Result := 0;
   New(p);
 {$ifdef Win32}
   try {finally}
 {$else Win32}
   if p = nil then
     begin
     {$ifndef Delphi}
       MyFCopy := 0;
     {$endif}
       Exit  { ERROR !!! Failed Memory Allocation! }
     end;
 {$endif Win32}

   repeat
     if CopyLength <> LZ_UNKNOWN_LENGTH then
       BRead := Min(CopyLength-Result, SizeOf(p^))
     else
       BRead := SizeOf(p^);
     BlockRead(InFile, p^, BRead, NumRead);

     {compressing - return number of bytes read}
     if Assigned(LZReportProc) and not ReportingOnWrite then
       LZReportProc(BlankRec, NumRead);
{
  If CopyLength <> LZ_UNKNOWN_LENGTH, we know how many bytes we EXPECT
  to be able to read from this file. If BRead <> NumRead, then the
  file must be corrupt ...
}
   {$ifdef Win32}
     if (CopyLength <> LZ_UNKNOWN_LENGTH) and (BRead <> NumRead) then
       RaiseIOError(SEndOfFile,100); { Will exit via `finally...end' }
   {$endif}
{
  This is the EOF condition for when we DON'T know how long the copy is ...
}
     if NumRead = 0 then
       break;
{
  Without the NumWrit parameter, BlockWrite will cause an IO-Error if the disc
  doesn't have room for SizeOf(p) bytes. This is good in Win32, as an exception
  will then be raised.
}
     BlockWrite(OutFile,p^,NumRead {$ifndef Win32}, NumWrit {$endif});
{
  If Win32 version gets this far, then all NumRead chars must have
  been written ...
}
     inc(Result, {$ifdef Win32} NumRead {$else} NumWrit {$endif});

     {de-compressing - return number of bytes written}
     if Assigned(LZReportProc) and ReportingOnWrite then
       LZReportProc(BlankRec, {$ifdef Win32} NumRead {$else} NumWrit {$endif})

   until {$ifndef Win32} (NumWrit<>NumRead) or {$endif}
         ( (CopyLength <> LZ_UNKNOWN_LENGTH) and
           (Result >= CopyLength) );
 {$ifndef Delphi}
   MyFCopy := Result;
 {$endif}
 {$ifdef Win32}
   finally
 {$endif}
     Dispose(p);
 {$ifdef Win32}
   end;
 {$endif}
end;

{/////////////////////////////////////////////////////////}
Function MyReadProc(var ReadBuf): TLZSSWord; {$ifndef Win32} far; {$endif}
{to read from files}
{$ifndef Delphi}
var
  Result: TLZSSWord;
{$endif}

Begin
  BlockRead(InFile, ReadBuf, LZRWBufSize, Result);
  Inc(aRead, Result);

 {compressing - return bytes read}
  if Assigned(LZReportProc) and not Decompressing then
    LZReportProc(BlankRec, Result);

{$ifndef Delphi}
  MyReadProc := Result
{$endif}
End; { MyReadProc }

{/////////////////////////////////////////////////////////}
Function MyWriteProc(var WriteBuf; Count: TLZSSWord): TLZSSWord;
{$ifndef Win32} far; {$endif Win32}
{$ifndef Delphi}
var
  Result: TLZSSWord;
{$endif}
{to write to files}
Begin
  BlockWrite(OutFile, WriteBuf, Count, Result);
  Inc(aWrite, Result);

 {de-compressing - return bytes written}
  if Assigned(LZReportProc) and Decompressing then
    LZReportProc(BlankRec, Result);

{$ifndef Delphi}
  MyWriteProc := Result
{$endif}
End; { MyWriteProc }

{/////////////////////////////////////////////////////////}
Function GetDirIndex(aDir: TLZPathStr; Const DirList: PLZDirArray;
                                       Const Max: TLZSSWord): LongInt;
{find the index of a directory within an array}
Var
  i: TLZSSWord;
begin
{$ifndef Win32}
  aDir := UpperCase(aDir);
{$endif Win32}
  for i := 0 to Max do
    if {$ifdef Win32} AnsiCompareText(aDir, DirList^[i]) = 0
       {$else Win32}  aDir = DirList^[i]^
       {$endif Win32} then
      begin
        GetDirIndex := i;
        Exit
      end;
  GetDirIndex := -1
end;

{/////////////////////////////////////////////////////////}
function CreatePath(Path: TLZPathStr): Integer;
{Iteratively create a directory path}
var
  i:      Integer;
  NewDir: TLZPathStr;
{$ifndef Delphi}
{$ifdef Windows}
  P:      array[0..79] of Char;
{$endif Windows}
  Result: Integer;
{$endif Delphi}
begin
{$ifdef Delphi}
  Path := ExpandFileName(Path);
{$else Delphi}
  {$ifdef Windows}
  FileExpand(P, Str2PChar(Path));
  Path := StrPas(p);
  {$else Windows}
  Path := FExpand(Path);
  {$endif Windows}
{$endif Delphi}

  i := 3;
  Result := 0;

  repeat
    repeat
      Inc(i)
    until (i > Length(Path)) or (Path[i] = '\');
    NewDir := Copy(Path,1,i-1);
    if not DirectoryExists(NewDir) then
      begin
        MkDir(NewDir);         { Win32 throws an exception and exits... }
        {$ifndef Win32}        { We shall catch and handle this     }
        If IOResult <> 0 then  { exception in the calling function. }
          begin
            CreatePath := -1;
            Exit
          end;
       {$endif Win32}
        Inc(Result)
      end
  until i > Length(Path);
{$ifndef Delphi}
  CreatePath := Result;
{$endif}
end;

{/////////////////////////////////////////////////////////}
function GetFullLZName(const     X: TChiefLZArchiveHeader;
                             Index: Integer): string;
{$ifdef aDLL} {$ifdef Win32} stdcall
              {$else Win32}  export
              {$endif Win32}; {$endif aDLL}
{$ifndef Delphi}
var
  Result: string;
{$endif}
begin
  Result := '';
  repeat
    with X.Files[Index] do
      begin
        Result := Names + '\' + Result;
        if not IsDir then
          Index := DirID
        else
          Index := ParentDir
      end
  until Index = 0;
{$ifdef Win32}
  SetLength(Result, Pred(Length(Result)));
{$else Win32}
  Dec(Result[0]);
{$endif Win32}
{$ifndef Delphi}
  GetFullLZName := Result;
{$endif Delphi}
end;

Function GetFileVersion({$ifdef Win32} Const
                        {$endif} fName: String): TLZVerStr;
{$ifndef DPMI}
{$ifdef TPW}
Var
Result: TLZVerStr;
{$endif TPW}
{$endif DPMI}
Begin
  {$ifdef DPMI}
    GetFileVersion := '0'
  {$else DPMI}
  {$ifdef Windows}
  {$ifdef Win32}
    Result := FileVersionInfo(fName, 'FileVersion');
  {$else Win32}
    Result := FileVersionInfo(Str2PChar(fName), 'FileVersion');
  {$endif Win32}
    if Length(Result) = 0 then
      GetFileVersion := '0'
  {$ifndef Delphi}
    else
      GetFileVersion := Result
  {$endif Delphi}
  {$else Windows}
    GetFileVersion := '0'
  {$endif Windows}
  {$endif DPMI}
End;

{/////////////////////////////////////////////////////////}
function GetLZMarkedName(const FName: string): string;
var
  i:   Integer;
  Ext: TLZExtStr;
begin
  Ext := ExtractFileExt(FName);
  i := Length(Ext);
  if i < 2 then             { Ext is either '' or '.' }
    Ext := '.' + MyLZMarker
  else
    Ext[i] := MyLZMarker;
  GetLZMarkedName := ChangeFileExt(FName, Ext)
end;

{/////////////////////////////////////////////////////////}
{/////////////////////////////////////////////////////////}
{
  These are the LZ functions exported from the unit
}
{/////////////////////////////////////////////////////////}
{/////////////////////////////////////////////////////////}
Function IsChiefLZArchive(const fName: {$ifdef Win32} string
                                       {$else}        PChar
                                       {$endif} ):boolean;
{$ifdef aDLL} {$ifdef Win32} stdcall
              {$else Win32}  export
              {$endif Win32};
{$endif aDLL}
Var
f:file;
NumRead: TLZSSWord;
{$ifndef Win32}
OldFMode: byte;
{$endif}

Hed : TLZArchiveHeader;

Begin
     IsChiefLZArchive := False;

     if {$ifdef Win32} Length(fName)
        {$else}        StrLen(fName)
        {$endif} = 0 then
       Exit;

  {$ifdef Win32}

    AssignFile(f, fName);
    FileMode := fmOpenRead; { Win32 only allows 0 <= FileMode <= 2 }
  {$I-}                     { However, share access is FILE_SHARE_READ }
    Reset(f, 1);
  {$I+}
    if IOResult = 0 then
      begin
        BlockRead(f, Hed, SizeOf(Hed), NumRead); // No IO-Error; uses NumRead
        CloseFile(f);
        IsChiefLZArchive := (NumRead = SizeOf(Hed)) and
                            (Hed.Signature = MyLZSignature) and
                            (Hed.Count <> 0)
                 // If haven't read SizeOf(Hed) bytes, CAN'T be LZ Archive
      end

   {$else}

    Assign(f, StrPas(fName));
    OldFMode := FileMode;
{
  Open file: we need Read-access, don't need Write-access and *INSIST*
  that no one else can write to it (i.e. corrupt it) until we're done.
}
    FileMode := (fmOpenRead or fmShareDenyWrite);
    Reset(f,1);
    FileMode := OldFMode;
    if IOResult = 0 then
      begin
        BlockRead(f, Hed, SizeOf(Hed), NumRead);
        Close(f);
        IsChiefLZArchive := (NumRead = SizeOf(Hed)) and
                            (Hed.Signature = MyLZSignature) and
                            (Hed.Count <> 0)
      end
   {$endif}
end;

{/////////////////////////////////////////////////////////}
{$ifdef Win32}
Function GetChiefLZFileName(const fName: string): string;
{$ifdef aDLL} stdcall; {$endif aDLL}
var
f: file;
h: TLZHeader;
begin
  AssignFile(f, fName);
  FileMode := fmOpenRead; { Win32 only allows 0 <= FileMode <= 2 }
  Reset(f,1);             { However, share access is FILE_SHARE_READ }
  try
    if IsMyLZFile(f,h) then
      SetString(Result, PChar(@h.fName[1]), Length(h.fName))
    else
      Result := fName
  finally
    CloseFile(f)
  end
end;
{$else}

⌨️ 快捷键说明

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