压缩流

支持DELPHI7及以上版本。

unit zip;

interface

{$if CompilerVersion>= 21}
  {$define NEWZLib}
{$IFEND}

uses
  Classes, Zlib, SysUtils;

type
{$if CompilerVersion< 18.5}
  TBytes = array of Byte;
{$IFEND}

  TZip = class(TObject)
  public
    /// <summary>
    ///   解压
    /// </summary>
    class procedure UnZipStream(const pvInStream, pvOutStream: TStream);

    /// <summary>
    ///   压缩
    /// </summary>
    class procedure ZipStream(const pvInStream, pvOutStream: TStream);


    class function verifyData(const buf; len:Cardinal): Cardinal;
    class function verifyStream(pvStream:TStream; len:Cardinal): Cardinal;
  end;

implementation

class procedure TZip.UnZipStream(const pvInStream, pvOutStream: TStream);
var
  l:Integer;

{$IFDEF POSIX}
var
  lvBytes, lvOutBytes:TBytes;
{$ELSE}
var
  lvBytes:TBytes;
  OutBuf: Pointer;
  OutBytes: Integer;
{$ENDIF}
begin
  if pvInStream= nil then exit;
  l := pvInStream.Size;
  if l = 0 then Exit;
{$IFDEF POSIX}
  SetLength(lvBytes, l);
  pvInStream.Position := 0;
  pvInStream.Read(lvBytes[0], pvInStream.Size);
  ZLib.ZDecompress(lvBytes, lvOutBytes);  //POSIX下,只支持该方式
  pvOutStream.Size := Length(lvOutBytes);
  pvOutStream.Position := 0;
  pvOutStream.Write(lvOutBytes[0], Length(lvOutBytes));
{$ELSE}
  setLength(lvBytes, l);
  pvInStream.Position := 0;
  pvInStream.ReadBuffer(lvBytes[0], l);
  {$if defined(NEWZLib)}
  ZLib.ZDecompress(@lvBytes[0], l, OutBuf, OutBytes);
  {$ELSE}
  Zlib.DecompressBuf(@lvBytes[0], l, 0, OutBuf, OutBytes);
  {$ifend}
  try
    pvOutStream.Size := OutBytes;
    pvOutStream.Position := 0;
    pvOutStream.WriteBuffer(OutBuf^, OutBytes);
  finally
    FreeMem(OutBuf, OutBytes);
  end;
{$ENDIF}
end;

class function TZip.verifyData(const buf; len: Cardinal): Cardinal;
var
  i:Cardinal;
  p:PByte;
begin
  i := 0;
  Result := 0;
  p := PByte(@buf);
  while i < len do
  begin
    Result := Result + p^;
    Inc(p);
    Inc(i);
  end;
end;

class function TZip.verifyStream(pvStream:TStream; len:Cardinal):
    Cardinal;
var
  l, j:Cardinal;
  lvBytes:TBytes;
begin
  SetLength(lvBytes, 1024);

  if len = 0 then
  begin
    j := pvStream.Size - pvStream.Position;
  end else
  begin
    j := len;
  end;

  Result := 0;

  while j > 0 do
  begin
    if j <1024 then l := j else l := 1024;

    pvStream.ReadBuffer(lvBytes[0], l);

    Result := Result + verifyData(lvBytes[0], l);
    Dec(j, l);
  end;
end;

class procedure TZip.ZipStream(const pvInStream, pvOutStream: TStream);
{$IFDEF POSIX}
var
  lvBytes, lvOutBytes:TBytes;
{$ELSE}
var
  lvInBuf: TBytes;
  OutBuf: Pointer;
  OutBytes: Integer;
{$ENDIF}
var
  l: Integer;
begin
  if pvInStream= nil then exit;
  l := pvInStream.Size;
  if l = 0 then Exit;

{$IFDEF POSIX}
  SetLength(lvBytes, pvInStream.Size);
  pvInStream.Position := 0;
  pvInStream.Read(lvBytes[0], pvInStream.Size);
  ZLib.ZCompress(lvBytes, lvOutBytes);                 // POSIX下只支持该中方式的压缩
  pvOutStream.Size := Length(lvOutBytes);
  pvOutStream.Position := 0;
  pvOutStream.Write(lvOutBytes[0], Length(lvOutBytes));
{$ELSE}
  SetLength(lvInBuf, l);
  pvInStream.Position := 0;
  pvInStream.ReadBuffer(lvInBuf[0], l);
  {$if defined(NEWZLib)}
  ZLib.ZCompress(@lvInBuf[0], l, OutBuf, OutBytes);
  {$ELSE}
  ZLib.CompressBuf(@lvInBuf[0], l, OutBuf, OutBytes);
  {$ifend}
  try
    pvOutStream.Size := OutBytes;
    pvOutStream.Position := 0;
    pvOutStream.WriteBuffer(OutBuf^, OutBytes);
  finally
    FreeMem(OutBuf, OutBytes);
  end;
{$ENDIF}


end;

end.

  

01-03 18:23