Стартовый пул

This commit is contained in:
2024-04-02 08:46:59 +03:00
parent fd57fffd3a
commit 3bb34d000b
5591 changed files with 3291734 additions and 0 deletions

2153
Abbrevia/source/AbArcTyp.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,70 @@
(* ***** 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: AbBase.pas *}
{*********************************************************}
{* ABBREVIA: Base component class *}
{*********************************************************}
unit AbBase;
{$I AbDefine.inc}
interface
uses
Classes;
type
TAbBaseComponent = class(TComponent)
protected {methods}
function GetVersion : string;
procedure SetVersion(const Value : string);
protected {properties}
property Version : string
read GetVersion
write SetVersion
stored False;
end;
implementation
uses
AbConst;
{ -------------------------------------------------------------------------- }
function TAbBaseComponent.GetVersion : string;
begin
Result := AbVersionS;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseComponent.SetVersion(const Value : string);
begin
{NOP}
end;
end.

View File

@@ -0,0 +1,241 @@
(* ***** 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: AbBitBkt.pas *}
{*********************************************************}
{* ABBREVIA: Bit bucket memory stream class *}
{*********************************************************}
unit AbBitBkt;
{$I AbDefine.inc}
interface
uses
Classes,
AbUtils;
type
TAbBitBucketStream = class(TStream)
private
FBuffer : {$IFDEF UNICODE}PByte{$ELSE}PAnsiChar{$ENDIF};
FBufSize : longint;
FBufPosn : longint;
FPosn : Int64;
FSize : Int64;
FTail : longint;
protected
public
constructor Create(aBufSize : cardinal);
destructor Destroy; override;
function Read(var Buffer; Count : Longint) : Longint; override;
function Write(const Buffer; Count : Longint) : Longint; override;
function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;
procedure ForceSize(aSize : Int64);
end;
implementation
uses
Math, SysUtils, AbExcept;
{Notes: The buffer is a circular queue without a head pointer; FTail
is where data is next going to be written and it wraps
indescriminately. The buffer can never be empty--it is always
full (initially it is full of binary zeros.
The class is designed to act as a bit bucket for the test
feature of Abbrevia's zip code; it is not intended as a
complete class with many possible applications. It is designed
to be written to in a steady progression with some reading
back in the recently written stream (the buffer size details
how far back the Seek method will work). Seeking outside this
buffer will result in exceptions being generated.
For testing deflated files, the buffer size should be 32KB,
for imploded files, either 8KB or 4KB. The Create constructor
limits the buffer size to these values.}
{===TAbBitBucketStream===============================================}
constructor TAbBitBucketStream.Create(aBufSize : cardinal);
begin
inherited Create;
if (aBufSize <> 4096) and
(aBufSize <> 8192) and
(aBufSize <> 32768) then
FBufSize := 32768
else
FBufSize := aBufSize;
{add a 1KB leeway}
inc(FBufSize, 1024);
GetMem(FBuffer, FBufSize);
end;
{--------}
destructor TAbBitBucketStream.Destroy;
begin
if (FBuffer <> nil) then
FreeMem(FBuffer, FBufSize);
inherited Destroy;
end;
{--------}
procedure TAbBitBucketStream.ForceSize(aSize : Int64);
begin
FSize := aSize;
end;
{--------}
function TAbBitBucketStream.Read(var Buffer; Count : Longint) : Longint;
var
Chunk2Size : longint;
Chunk1Size : longint;
OutBuffer : PByte;
begin
OutBuffer := @Buffer;
{we cannot read more bytes than there is buffer}
if (Count > FBufSize) then
raise EAbBBSReadTooManyBytes.Create(Count);
{calculate the size of the chunks}
if (FBufPosn <= FTail) then begin
Chunk1Size := FTail - FBufPosn;
if (Chunk1Size > Count) then
Chunk1Size := Count;
Chunk2Size := 0;
end
else begin
Chunk1Size := FBufSize - FBufPosn;
if (Chunk1Size > Count) then begin
Chunk1Size := Count;
Chunk2Size := 0;
end
else begin
Chunk2Size := FTail;
if (Chunk2Size > (Count - Chunk1Size)) then
Chunk2Size := Count - Chunk1Size;
end
end;
{we cannot read more bytes than there are available}
if (Count > (Chunk1Size + Chunk2Size)) then
raise EAbBBSReadTooManyBytes.Create(Count);
{perform the read}
if (Chunk1Size > 0) then begin
Move(FBuffer[FBufPosn], OutBuffer^, Chunk1Size);
inc(FBufPosn, Chunk1Size);
inc(FPosn, Chunk1Size);
end;
if (Chunk2Size > 0) then begin
{we've wrapped}
Move(FBuffer[0], PByte(PtrInt(OutBuffer) + PtrInt(Chunk1Size))^, Chunk2Size);
FBufPosn := Chunk2Size;
inc(FPosn, Chunk2Size);
end;
Result := Count;
end;
{--------}
function TAbBitBucketStream.Write(const Buffer; Count : Longint) : Longint;
var
Chunk2Size : longint;
Chunk1Size : longint;
InBuffer : PByte;
Overage : longint;
begin
Result := Count;
InBuffer := @Buffer;
{we cannot write more bytes than there is buffer}
while Count > FBufSize do begin
Overage := Min(FBufSize, Count - FBufSize);
Write(InBuffer^, Overage);
Inc(PtrInt(InBuffer), Overage);
Dec(Count, Overage);
end;
{calculate the size of the chunks}
Chunk1Size := FBufSize - FTail;
if (Chunk1Size > Count) then begin
Chunk1Size := Count;
Chunk2Size := 0;
end
else begin
Chunk2Size := Count - Chunk1Size;
end;
{write the first chunk}
if (Chunk1Size > 0) then begin
Move(InBuffer^, FBuffer[FTail], Chunk1Size);
inc(FTail, Chunk1Size);
end;
{if the second chunk size is not zero, write the second chunk; note
that we have wrapped}
if (Chunk2Size > 0) then begin
Move(PByte(PtrInt(InBuffer) + PtrInt(Chunk1Size))^, FBuffer[0], Chunk2Size);
FTail := Chunk2Size;
end;
{the stream size and position have changed}
inc(FSize, Count);
FPosn := FSize;
FBufPosn := FTail;
end;
{--------}
function TAbBitBucketStream.Seek(const Offset : Int64; Origin : TSeekOrigin): Int64;
var
Posn : Int64;
BytesBack : longint;
begin
{calculate the new position}
case Origin of
soBeginning :
Posn := Offset;
soCurrent :
Posn := FPosn + Offset;
soEnd :
if (Offset = 0) then begin
{special case: position at end of stream}
FBufPosn := FTail;
FPosn := FSize;
Result := FSize;
Exit;
end
else begin
Posn := FSize + Offset;
end;
else
raise EAbBBSInvalidOrigin.Create;
end;
{calculate whether the new position is within the buffer; if not,
raise exception}
if (Posn > FSize) or
(Posn <= (FSize - FBufSize)) then
raise EAbBBSSeekOutsideBuffer.Create;
{set the internal fields for the new position}
FPosn := Posn;
BytesBack := FSize - Posn;
if (BytesBack <= FTail) then
FBufPosn := FTail - BytesBack
else
FBufPosn := longint(FTail) + FBufSize - BytesBack;
{return the new position}
Result := Posn;
end;
{====================================================================}
end.

View File

@@ -0,0 +1,602 @@
(* ***** 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: AbBrowse.pas *}
{*********************************************************}
{* ABBREVIA: Base Browser Component *}
{*********************************************************}
unit AbBrowse;
{$I AbDefine.inc}
interface
uses
Classes,
AbBase,
AbUtils,
AbArcTyp;
type
IAbProgressMeter = interface
['{4B766704-FD20-40BF-BA40-2EC2DD77B178}']
procedure DoProgress(Progress : Byte);
procedure Reset;
end;
TAbBaseBrowser = class(TAbBaseComponent)
public
FArchive : TAbArchive;
protected {private}
FSpanningThreshold : Longint;
FItemProgressMeter : IAbProgressMeter;
FArchiveProgressMeter : IAbProgressMeter;
FBaseDirectory : string;
FFileName : string;
FLogFile : string;
FLogging : Boolean;
FOnArchiveProgress : TAbArchiveProgressEvent;
FOnArchiveItemProgress : TAbArchiveItemProgressEvent;
FOnChange : TNotifyEvent;
FOnConfirmProcessItem : TAbArchiveItemConfirmEvent;
FOnLoad : TAbArchiveEvent;
FOnProcessItemFailure : TAbArchiveItemFailureEvent;
FOnRequestImage : TAbRequestImageEvent;
FTempDirectory : string;
{ detected compression type }
FArchiveType : TAbArchiveType;
FForceType : Boolean;
protected {private methods}
function GetCount : Integer;
function GetItem(Value : Longint) : TAbArchiveItem;
function GetSpanned : Boolean;
function GetStatus : TAbArchiveStatus;
procedure ResetMeters; virtual;
procedure SetArchiveProgressMeter(const Value: IAbProgressMeter);
procedure SetCompressionType(const Value: TAbArchiveType);
procedure SetBaseDirectory(const Value : string);
procedure SetItemProgressMeter(const Value: IAbProgressMeter);
procedure SetSpanningThreshold(Value : Longint);
procedure SetLogFile(const Value : string);
procedure SetLogging(Value : Boolean);
procedure SetTempDirectory(const Value : string);
procedure Loaded; override;
procedure Notification(Component: TComponent;
Operation: TOperation); override;
protected {virtual methods}
procedure DoArchiveItemProgress(Sender : TObject;
Item : TAbArchiveItem;
Progress : Byte;
var Abort : Boolean); virtual;
procedure DoArchiveProgress(Sender : TObject;
Progress : Byte;
var Abort : Boolean); virtual;
procedure DoChange; virtual;
procedure DoConfirmProcessItem(Sender : TObject;
Item : TAbArchiveItem;
ProcessType : TAbProcessType;
var Confirm : Boolean); virtual;
procedure DoLoad(Sender : TObject); virtual;
procedure DoProcessItemFailure(Sender : TObject;
Item : TAbArchiveItem;
ProcessType : TAbProcessType;
ErrorClass : TAbErrorClass;
ErrorCode : Integer); virtual;
procedure SetOnRequestImage(Value : TAbRequestImageEvent); virtual;
procedure InitArchive; virtual;
{This method must be defined in descendent classes}
procedure SetFileName(const aFileName : string); virtual; abstract;
protected {properties}
property Archive : TAbArchive
read FArchive;
property ArchiveProgressMeter : IAbProgressMeter
read FArchiveProgressMeter
write SetArchiveProgressMeter;
property BaseDirectory : string
read FBaseDirectory
write SetBaseDirectory;
property FileName : string
read FFileName
write SetFileName;
property SpanningThreshold : Longint
read FSpanningThreshold
write SetSpanningThreshold
default 0;
property ItemProgressMeter : IAbProgressMeter
read FItemProgressMeter
write SetItemProgressMeter;
property LogFile : string
read FLogFile
write SetLogFile;
property Logging : Boolean
read FLogging
write SetLogging
default False;
property Spanned : Boolean
read GetSpanned;
property TempDirectory : string
read FTempDirectory
write SetTempDirectory;
protected {events}
property OnArchiveProgress : TAbArchiveProgressEvent
read FOnArchiveProgress
write FOnArchiveProgress;
property OnArchiveItemProgress : TAbArchiveItemProgressEvent
read FOnArchiveItemProgress
write FOnArchiveItemProgress;
property OnConfirmProcessItem : TAbArchiveItemConfirmEvent
read FOnConfirmProcessItem
write FOnConfirmProcessItem;
property OnProcessItemFailure : TAbArchiveItemFailureEvent
read FOnProcessItemFailure
write FOnProcessItemFailure;
property OnRequestImage : TAbRequestImageEvent
read FOnRequestImage
write SetOnRequestImage;
public {methods}
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
procedure ClearTags;
{Clear all tags from the archive}
function FindItem(aItem : TAbArchiveItem) : Integer;
function FindFile(const aFileName : string) : Integer;
procedure TagItems(const FileMask : string);
{tag all items that match the mask}
procedure UnTagItems(const FileMask : string);
{clear tags for all items that match the mask}
procedure CloseArchive;
{closes the archive by setting FileName to ''}
procedure OpenArchive(const aFileName : string);
{opens the archive}
public {properties}
property Count : Integer
read GetCount;
property Items[Index : Integer] : TAbArchiveItem
read GetItem; default;
property Status : TAbArchiveStatus
read GetStatus;
property ArchiveType : TAbArchiveType
read FArchiveType
write SetCompressionType
default atUnknown;
property ForceType : Boolean
read FForceType
write FForceType
default False;
public {events}
property OnChange : TNotifyEvent
read FOnChange
write FOnChange;
property OnLoad : TAbArchiveEvent
read FOnLoad
write FOnLoad;
end;
function AbDetermineArcType(const FN : string; AssertType : TAbArchiveType) : TAbArchiveType; overload;
function AbDetermineArcType(aStream: TStream) : TAbArchiveType; overload;
implementation
uses
SysUtils,
AbExcept,
{$IFDEF MSWINDOWS}
AbCabTyp,
{$ENDIF}
AbZipTyp,
AbTarTyp,
AbGzTyp,
AbBzip2Typ;
{ TAbBaseBrowser implementation ======================================= }
{ -------------------------------------------------------------------------- }
constructor TAbBaseBrowser.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
FLogFile := '';
FLogging := False;
FSpanningThreshold := 0;
FArchiveType := atUnknown;
FForceType := False;
end;
{ -------------------------------------------------------------------------- }
destructor TAbBaseBrowser.Destroy;
begin
FArchive.Free;
FArchive := nil;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.ClearTags;
{Clear all tags from the archive}
begin
if Assigned(FArchive) then
FArchive.ClearTags
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.CloseArchive;
{closes the archive by setting FileName to ''}
begin
if FFileName <> '' then
FileName := '';
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoArchiveItemProgress(Sender : TObject;
Item : TAbArchiveItem;
Progress : Byte;
var Abort : Boolean);
begin
Abort := False;
if Assigned(FItemProgressMeter) then
FItemProgressMeter.DoProgress(Progress);
if Assigned(FOnArchiveItemProgress) then
FOnArchiveItemProgress(Self, Item, Progress, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoArchiveProgress(Sender : TObject;
Progress : Byte;
var Abort : Boolean);
begin
Abort := False;
if Assigned(FArchiveProgressMeter) then
FArchiveProgressMeter.DoProgress(Progress);
if Assigned(FOnArchiveProgress) then
FOnArchiveProgress(Self, Progress, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoChange;
begin
if Assigned(FOnChange) then begin
FOnChange(Self);
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoConfirmProcessItem(Sender : TObject;
Item : TAbArchiveItem;
ProcessType : TAbProcessType;
var Confirm : Boolean);
begin
Confirm := True;
if Assigned(FItemProgressMeter) then
FItemProgressMeter.Reset;
if Assigned(FOnConfirmProcessItem) then
FOnConfirmProcessItem(Self, Item, ProcessType, Confirm);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoLoad(Sender : TObject);
begin
if Assigned(FOnLoad) then
FOnLoad(Self);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.DoProcessItemFailure(Sender : TObject;
Item : TAbArchiveItem;
ProcessType : TAbProcessType;
ErrorClass : TAbErrorClass;
ErrorCode : Integer);
begin
if Assigned(FOnProcessItemFailure) then
FOnProcessItemFailure(Self, Item, ProcessType, ErrorClass, ErrorCode);
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.FindItem(aItem : TAbArchiveItem) : Integer;
begin
if Assigned(FArchive) then
Result := FArchive.FindItem(aItem)
else
Result := -1;
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.FindFile(const aFileName : string) : Integer;
begin
if Assigned(FArchive) then
Result := FArchive.FindFile(aFileName)
else
Result := -1;
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.GetSpanned : Boolean;
begin
if Assigned(FArchive) then
Result := FArchive.Spanned
else
Result := False;
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.GetStatus : TAbArchiveStatus;
begin
if Assigned(FArchive) then
Result := FArchive.Status
else
Result := asInvalid;
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.GetCount : Integer;
begin
if Assigned(FArchive) then
Result := FArchive.Count
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TAbBaseBrowser.GetItem(Value : Longint) : TAbArchiveItem;
begin
if Assigned(FArchive) then
Result := FArchive.ItemList[Value]
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.InitArchive;
begin
ResetMeters;
if Assigned(FArchive) then begin
{properties}
FArchive.SpanningThreshold := FSpanningThreshold;
FArchive.LogFile := FLogFile;
FArchive.Logging := FLogging;
FArchive.TempDirectory := FTempDirectory;
SetBaseDirectory(FBaseDirectory);
{events}
FArchive.OnArchiveProgress := DoArchiveProgress;
FArchive.OnArchiveItemProgress := DoArchiveItemProgress;
FArchive.OnConfirmProcessItem := DoConfirmProcessItem;
FArchive.OnLoad := DoLoad;
FArchive.OnProcessItemFailure := DoProcessItemFailure;
FArchive.OnRequestImage := FOnRequestImage;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.Loaded;
begin
inherited Loaded;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.Notification(Component: TComponent;
Operation: TOperation);
begin
inherited Notification(Component, Operation);
if (Operation = opRemove) then begin
if Assigned(ItemProgressMeter) and Component.IsImplementorOf(ItemProgressMeter) then
ItemProgressMeter := nil;
if Assigned(ArchiveProgressMeter) and Component.IsImplementorOf(ArchiveProgressMeter) then
ArchiveProgressMeter := nil;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.OpenArchive(const aFileName : string);
{opens the archive}
begin
FileName := AFileName;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.ResetMeters;
begin
if Assigned(FArchiveProgressMeter) then
FArchiveProgressMeter.Reset;
if Assigned(FItemProgressMeter) then
FItemProgressMeter.Reset;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetBaseDirectory(const Value : string);
begin
if Assigned(FArchive) then begin
FArchive.BaseDirectory := Value;
FBaseDirectory := FArchive.BaseDirectory;
end else
FBaseDirectory := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetSpanningThreshold(Value : Longint);
begin
FSpanningThreshold := Value;
if Assigned(FArchive) then
FArchive.SpanningThreshold := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetLogFile(const Value : string);
begin
FLogFile := Value;
if (csDesigning in ComponentState) then
Exit;
if Assigned(FArchive) then
FArchive.LogFile := Value;
SetLogging(Value <> '');
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetLogging(Value : Boolean);
begin
FLogging := Value;
if (csDesigning in ComponentState) then
Exit;
if Assigned(FArchive) then
FArchive.Logging:= Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetOnRequestImage(Value : TAbRequestImageEvent);
begin
FOnRequestImage := Value;
if Assigned(FArchive) then
FArchive.OnRequestImage := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetTempDirectory(const Value : string);
begin
FTempDirectory := Value;
if Assigned(FArchive) then
FArchive.TempDirectory := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.TagItems(const FileMask : string);
{tag all items that match the mask}
begin
if Assigned(FArchive) then
FArchive.TagItems(FileMask)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.UnTagItems(const FileMask : string);
{clear tags for all items that match the mask}
begin
if Assigned(FArchive) then
FArchive.UnTagItems(FileMask)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetCompressionType(const Value: TAbArchiveType);
begin
if not Assigned(FArchive) or (Status <> asInvalid) then
FArchiveType := Value
else
raise EAbArchiveBusy.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetArchiveProgressMeter(const Value: IAbProgressMeter);
begin
ReferenceInterface(FArchiveProgressMeter, opRemove);
FArchiveProgressMeter := Value;
ReferenceInterface(FArchiveProgressMeter, opInsert);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBaseBrowser.SetItemProgressMeter(const Value: IAbProgressMeter);
begin
ReferenceInterface(FItemProgressMeter, opRemove);
FItemProgressMeter := Value;
ReferenceInterface(FItemProgressMeter, opInsert);
end;
{ -------------------------------------------------------------------------- }
function AbDetermineArcType(const FN : string; AssertType : TAbArchiveType) : TAbArchiveType;
var
Ext : string;
FS : TFileStream;
begin
Result := AssertType;
if Result = atUnknown then begin
{ Guess archive type based on it's extension }
Ext := UpperCase(ExtractFileExt(FN));
if (Ext = '.ZIP') or (Ext = '.JAR') then
Result := atZip;
if (Ext = '.EXE') then
Result := atSelfExtZip;
if (Ext = '.TAR') then
Result := atTar;
if (Ext = '.GZ') then
Result := atGzip;
if (Ext = '.TGZ') then
Result := atGzippedTar;
if (Ext = '.CAB') then
Result := atCab;
if (Ext = '.BZ2') then
Result := atBzip2;
if (Ext = '.TBZ') then
Result := atBzippedTar;
end;
{$IFNDEF MSWINDOWS}
if Result = atCab then
Result := atUnknown;
{$ENDIF}
if FileExists(FN) and (AbFileGetSize(FN) > 0) then begin
{ If the file doesn't exist (or is empty) presume to make one, otherwise
guess or verify the contents }
FS := TFileStream.Create(FN, fmOpenRead or fmShareDenyNone);
try
if Result = atUnknown then
Result := AbDetermineArcType(FS)
else begin
case Result of
atZip : begin
Result := VerifyZip(FS);
end;
atSelfExtZip : begin
Result := VerifySelfExtracting(FS);
end;
atTar : begin
Result := VerifyTar(FS);
end;
atGzip, atGzippedTar: begin
Result := VerifyGzip(FS);
end;
{$IFDEF MSWINDOWS}
atCab : begin
Result := VerifyCab(FS);
end;
{$ENDIF}
atBzip2, atBzippedTar: begin
Result := VerifyBzip2(FS);
end;
end;
end;
finally
FS.Free;
end;
end;
end;
{ -------------------------------------------------------------------------- }
function AbDetermineArcType(aStream: TStream): TAbArchiveType;
begin
{ VerifyZip returns true for self-extracting zips too, so test those first }
Result := VerifySelfExtracting(aStream);
if Result = atUnknown then
Result := VerifyZip(aStream);
if Result = atUnknown then
Result := VerifyTar(aStream);
if Result = atUnknown then
Result := VerifyGzip(aStream);
if Result = atUnknown then
Result := VerifyBzip2(aStream);
{$IFDEF MSWINDOWS}
if Result = atUnknown then
Result := VerifyCab(aStream);
{$ENDIF}
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,54 @@
(* ***** 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: AbBaseCLX.pas *}
{*********************************************************}
{* ABBREVIA: Base component class (CLX) *}
{*********************************************************}
unit AbBseCLX;
{$I AbDefine.inc}
interface
uses
Classes,
{$IFNDEF BuildingStub}
QControls,
{$ENDIF BuildingStub}
AbConst,
AbBase;
{$IFNDEF BuildingStub}
type
TAbBaseWinControl = class(TWidgetControl);
{$ENDIF BuildingStub}
implementation
end.

View File

@@ -0,0 +1,53 @@
(* ***** 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: AbBaseVCL.pas *}
{*********************************************************}
{* ABBREVIA: Base component class (VCL) *}
{*********************************************************}
unit AbBseVCL;
{$I AbDefine.inc}
interface
uses
Classes
{$IFNDEF BuildingStub}
, Controls
{$ENDIF BuildingStub}
;
{$IFNDEF BuildingStub}
type
TAbBaseWinControl = class(TWinControl);
{$ENDIF BuildingStub}
implementation
end.

778
Abbrevia/source/AbBzip2.pas Normal file
View File

@@ -0,0 +1,778 @@
(* ***** BEGIN LICENSE BLOCK *****
* This program, "bzip2", the associated library "libbzip2", and all
* documentation, are copyright (C) 1996-2007 Julian R Seward. All
* rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. The origin of this software must not be misrepresented; you must
* not claim that you wrote the original software. If you use this
* software in a product, an acknowledgment in the product
* documentation would be appreciated but is not required.
*
* 3. Altered source versions must be plainly marked as such, and must
* not be misrepresented as being the original software.
*
* 4. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Julian Seward, jseward@bzip.org
* bzip2/libbzip2 version 1.0.5 of 10 December 2007
*
* Pascal wrapper created by Edison Mera, version 1.04
* http://edisonlife.homelinux.com/
*
* Dynamic and runtime linking and Win64/OS X/Linux support by Craig Peterson
* http://tpabbrevia.sourceforge.net/
* ***** END LICENSE BLOCK ***** *)
unit AbBzip2;
{$I AbDefine.inc}
interface
uses
SysUtils, Classes;
type
TAlloc = function(opaque: Pointer; Items, Size: Integer): Pointer; cdecl;
TFree = procedure(opaque, Block: Pointer); cdecl;
// Internal structure. Ignore.
TBZStreamRec = record
next_in: PByte; // next input byte
avail_in: Integer; // number of bytes available at next_in
total_in_lo32: Integer; // total nb of input bytes read so far
total_in_hi32: Integer;
next_out: PByte; // next output byte should be put here
avail_out: Integer; // remaining free space at next_out
total_out_lo32: Integer; // total nb of bytes output so far
total_out_hi32: Integer;
state: Pointer;
bzalloc: TAlloc; // used to allocate the internal state
bzfree: TFree; // used to free the internal state
opaque: Pointer;
end;
// Abstract ancestor class
TCustomBZip2Stream = class(TStream)
private
FStrm: TStream;
FStrmPos: Int64;
FOnProgress: TNotifyEvent;
FBZRec: TBZStreamRec;
FBuffer: array[Word] of Byte;
protected
procedure Progress(Sender: TObject); dynamic;
property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
constructor Create(Strm: TStream);
end;
{ TBZCompressionStream compresses data on the fly as data is written to it, and
stores the compressed data to another stream.
TBZCompressionStream is write-only and strictly sequential. Reading from the
stream will raise an exception. Using Seek to move the stream pointer
will raise an exception.
Output data is cached internally, written to the output stream only when
the internal output buffer is full. All pending output data is flushed
when the stream is destroyed.
The Position property returns the number of uncompressed bytes of
data that have been written to the stream so far.
CompressionRate returns the on-the-fly percentage by which the original
data has been compressed: (1 - (CompressedBytes / UncompressedBytes)) * 100
If raw data size = 100 and compressed data size = 25, the CompressionRate
is 75%
The OnProgress event is called each time the output buffer is filled and
written to the output stream. This is useful for updating a progress
indicator when you are writing a large chunk of data to the compression
stream in a single call.}
TBlockSize100k = (bs1, bs2, bs3, bs4, bs5, bs6, bs7, bs8, bs9);
TBZCompressionStream = class(TCustomBZip2Stream)
private
function GetCompressionRate: Single;
public
constructor Create(BlockSize100k: TBlockSize100k; Dest: TStream);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
property CompressionRate: Single read GetCompressionRate;
property OnProgress;
end;
{ TDecompressionStream decompresses data on the fly as data is read from it.
Compressed data comes from a separate source stream. TDecompressionStream
is read-only and unidirectional; you can seek forward in the stream, but not
backwards. The special case of setting the stream position to zero is
allowed. Seeking forward decompresses data until the requested position in
the uncompressed data has been reached. Seeking backwards, seeking relative
to the end of the stream, requesting the size of the stream, and writing to
the stream will raise an exception.
The Position property returns the number of bytes of uncompressed data that
have been read from the stream so far.
The OnProgress event is called each time the internal input buffer of
compressed data is exhausted and the next block is read from the input stream.
This is useful for updating a progress indicator when you are reading a
large chunk of data from the decompression stream in a single call.}
TBZDecompressionStream = class(TCustomBZip2Stream)
public
constructor Create(Source: TStream);
destructor Destroy; override;
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
property OnProgress;
end;
{ CompressBuf compresses data, buffer to buffer, in one call.
In: InBuf = ptr to compressed data
InBytes = number of bytes in InBuf
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
OutBytes = number of bytes in OutBuf }
procedure BZCompressBuf(const InBuf: Pointer; InBytes: Integer;
out OutBuf: Pointer; out OutBytes: Integer);
{ DecompressBuf decompresses data, buffer to buffer, in one call.
In: InBuf = ptr to compressed data
InBytes = number of bytes in InBuf
OutEstimate = zero, or est. size of the decompressed data
Out: OutBuf = ptr to newly allocated buffer containing decompressed data
OutBytes = number of bytes in OutBuf }
procedure BZDecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
type
EBZip2Error = class(Exception);
EBZCompressionError = class(EBZip2Error);
EBZDecompressionError = class(EBZip2Error);
implementation
// Compile for Win64 using MSVC
// <Path To MSVC>\bin\x86_amd64\cl.exe -c -nologo -GS- -Z7 -wd4086 -Gs32768
// -DBZ_NO_STDIO blocksort.c huffman.c compress.c decompress.c bzlib.c
uses
{$IFDEF Bzip2Runtime}
{$IF DEFINED(FPC)}
dynlibs,
{$ELSEIF DEFINED(MSWINDOWS)}
Windows,
{$IFEND}
{$ENDIF}
AbUtils;
{$IFDEF Bzip2Static}
{$IF DEFINED(WIN32)}
{$L Win32\blocksort.obj}
{$L Win32\huffman.obj}
{$L Win32\compress.obj}
{$L Win32\decompress.obj}
{$L Win32\bzlib.obj}
{$ELSEIF DEFINED(WIN64)}
{$L Win64\blocksort.obj}
{$L Win64\huffman.obj}
{$L Win64\compress.obj}
{$L Win64\decompress.obj}
{$L Win64\bzlib.obj}
{$IFEND}
procedure BZ2_hbMakeCodeLengths; external;
procedure BZ2_blockSort; external;
procedure BZ2_hbCreateDecodeTables; external;
procedure BZ2_hbAssignCodes; external;
procedure BZ2_compressBlock; external;
procedure BZ2_decompress; external;
{$ENDIF}
type
TLargeInteger = record
case Integer of
0: (
LowPart: LongWord;
HighPart: LongWord);
1: (
QuadPart: Int64);
end;
const
BZ_RUN = 0;
BZ_FLUSH = 1;
BZ_FINISH = 2;
BZ_OK = 0;
BZ_RUN_OK = 1;
BZ_FLUSH_OK = 2;
BZ_FINISH_OK = 3;
BZ_STREAM_END = 4;
BZ_SEQUENCE_ERROR = (-1);
BZ_PARAM_ERROR = (-2);
BZ_MEM_ERROR = (-3);
BZ_DATA_ERROR = (-4);
BZ_DATA_ERROR_MAGIC = (-5);
BZ_IO_ERROR = (-6);
BZ_UNEXPECTED_EOF = (-7);
BZ_OUTBUFF_FULL = (-8);
BZ_BLOCK_SIZE_100K = 9;
{$IFDEF Bzip2Static}
BZ2_rNums: array[0..511] of Longint = (
619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
936, 638
);
BZ2_crc32Table: array[0..255] of Longint = (
$00000000, $04C11DB7, $09823B6E, $0D4326D9,
$130476DC, $17C56B6B, $1A864DB2, $1E475005,
$2608EDB8, $22C9F00F, $2F8AD6D6, $2B4BCB61,
$350C9B64, $31CD86D3, $3C8EA00A, $384FBDBD,
$4C11DB70, $48D0C6C7, $4593E01E, $4152FDA9,
$5F15ADAC, $5BD4B01B, $569796C2, $52568B75,
$6A1936C8, $6ED82B7F, $639B0DA6, $675A1011,
$791D4014, $7DDC5DA3, $709F7B7A, $745E66CD,
-$67DC4920, -$631D54A9, -$6E5E7272, -$6A9F6FC7,
-$74D83FC4, -$70192275, -$7D5A04AE, -$799B191B,
-$41D4A4A8, -$4515B911, -$48569FCA, -$4C97827F,
-$52D0D27C, -$5611CFCD, -$5B52E916, -$5F93F4A3,
-$2BCD9270, -$2F0C8FD9, -$224FA902, -$268EB4B7,
-$38C9E4B4, -$3C08F905, -$314BDFDE, -$358AC26B,
-$0DC57FD8, -$09046261, -$044744BA, -$0086590F,
-$1EC1090C, -$1A0014BD, -$17433266, -$13822FD3,
$34867077, $30476DC0, $3D044B19, $39C556AE,
$278206AB, $23431B1C, $2E003DC5, $2AC12072,
$128E9DCF, $164F8078, $1B0CA6A1, $1FCDBB16,
$018AEB13, $054BF6A4, $0808D07D, $0CC9CDCA,
$7897AB07, $7C56B6B0, $71159069, $75D48DDE,
$6B93DDDB, $6F52C06C, $6211E6B5, $66D0FB02,
$5E9F46BF, $5A5E5B08, $571D7DD1, $53DC6066,
$4D9B3063, $495A2DD4, $44190B0D, $40D816BA,
-$535A3969, -$579B24E0, -$5AD80207, -$5E191FB2,
-$405E4FB5, -$449F5204, -$49DC74DB, -$4D1D696E,
-$7552D4D1, -$7193C968, -$7CD0EFBF, -$7811F20A,
-$6656A20D, -$6297BFBC, -$6FD49963, -$6B1584D6,
-$1F4BE219, -$1B8AFFB0, -$16C9D977, -$1208C4C2,
-$0C4F94C5, -$088E8974, -$05CDAFAB, -$010CB21E,
-$39430FA1, -$3D821218, -$30C134CF, -$3400297A,
-$2A47797D, -$2E8664CC, -$23C54213, -$27045FA6,
$690CE0EE, $6DCDFD59, $608EDB80, $644FC637,
$7A089632, $7EC98B85, $738AAD5C, $774BB0EB,
$4F040D56, $4BC510E1, $46863638, $42472B8F,
$5C007B8A, $58C1663D, $558240E4, $51435D53,
$251D3B9E, $21DC2629, $2C9F00F0, $285E1D47,
$36194D42, $32D850F5, $3F9B762C, $3B5A6B9B,
$0315D626, $07D4CB91, $0A97ED48, $0E56F0FF,
$1011A0FA, $14D0BD4D, $19939B94, $1D528623,
-$0ED0A9F2, -$0A11B447, -$075292A0, -$03938F29,
-$1DD4DF2E, -$1915C29B, -$1456E444, -$1097F9F5,
-$28D8444A, -$2C1959FF, -$215A7F28, -$259B6291,
-$3BDC3296, -$3F1D2F23, -$325E09FC, -$369F144D,
-$42C17282, -$46006F37, -$4B4349F0, -$4F825459,
-$51C5045E, -$550419EB, -$58473F34, -$5C862285,
-$64C99F3A, -$6008828F, -$6D4BA458, -$698AB9E1,
-$77CDE9E6, -$730CF453, -$7E4FD28C, -$7A8ECF3D,
$5D8A9099, $594B8D2E, $5408ABF7, $50C9B640,
$4E8EE645, $4A4FFBF2, $470CDD2B, $43CDC09C,
$7B827D21, $7F436096, $7200464F, $76C15BF8,
$68860BFD, $6C47164A, $61043093, $65C52D24,
$119B4BE9, $155A565E, $18197087, $1CD86D30,
$029F3D35, $065E2082, $0B1D065B, $0FDC1BEC,
$3793A651, $3352BBE6, $3E119D3F, $3AD08088,
$2497D08D, $2056CD3A, $2D15EBE3, $29D4F654,
-$3A56D987, -$3E97C432, -$33D4E2E9, -$3715FF60,
-$2952AF5B, -$2D93B2EE, -$20D09435, -$24118984,
-$1C5E343F, -$189F298A, -$15DC0F51, -$111D12E8,
-$0F5A42E3, -$0B9B5F56, -$06D8798D, -$0219643C,
-$764702F7, -$72861F42, -$7FC53999, -$7B042430,
-$6543742B, -$6182699E, -$6CC14F45, -$680052F4,
-$504FEF4F, -$548EF2FA, -$59CDD421, -$5D0CC998,
-$434B9993, -$478A8426, -$4AC9A2FD, -$4E08BF4C
);
procedure bz_internal_error(errcode: Integer); cdecl;
begin
raise EBZip2Error.CreateFmt('Compression Error %d', [errcode]);
end; { _bz_internal_error }
function malloc(size: Integer): Pointer; cdecl;
begin
GetMem(Result, Size);
end; { _malloc }
procedure free(block: Pointer); cdecl;
begin
FreeMem(block);
end; { _free }
{$ENDIF}
const
libbz2 = {$IF DEFINED(MSWINDOWS)}'libbz2.dll'
{$ELSEIF DEFINED(DARWIN)}'libbz2.dylib'
{$ELSE}'libbz2.so.1'{$IFEND};
{$IFDEF Bzip2Runtime}
var
hBzip2: HMODULE;
// deflate compresses data
BZ2_bzCompressInit: function(var strm: TBZStreamRec; blockSize100k: Integer;
verbosity: Integer; workFactor: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzCompress: function(var strm: TBZStreamRec; action: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzCompressEnd: function (var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzBuffToBuffCompress: function(dest: Pointer; var destLen: Integer;
source: Pointer; sourceLen, blockSize100k, verbosity, workFactor: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
// inflate decompresses data
BZ2_bzDecompressInit: function(var strm: TBZStreamRec; verbosity: Integer;
small: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzDecompress: function(var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzDecompressEnd: function(var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
BZ2_bzBuffToBuffDecompress: function(dest: Pointer; var destLen: Integer;
source: Pointer; sourceLen, small, verbosity: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
{$ELSE}
// deflate compresses data
function BZ2_bzCompressInit(var strm: TBZStreamRec; blockSize100k: Integer;
verbosity: Integer; workFactor: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzCompressInit'{$ENDIF};
function BZ2_bzCompress(var strm: TBZStreamRec; action: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzCompress'{$ENDIF};
function BZ2_bzCompressEnd(var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzCompressEnd'{$ENDIF};
function BZ2_bzBuffToBuffCompress(dest: Pointer; var destLen: Integer; source: Pointer;
sourceLen, blockSize100k, verbosity, workFactor: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzBuffToBuffCompress'{$ENDIF};
// inflate decompresses data
function BZ2_bzDecompressInit(var strm: TBZStreamRec; verbosity: Integer;
small: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzDecompressInit'{$ENDIF};
function BZ2_bzDecompress(var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzDecompress'{$ENDIF};
function BZ2_bzDecompressEnd(var strm: TBZStreamRec): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzDecompressEnd'{$ENDIF};
function BZ2_bzBuffToBuffDecompress(dest: Pointer; var destLen: Integer; source: Pointer;
sourceLen, small, verbosity: Integer): Integer;
{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF} external {$IFDEF Bzip2Dynamic}libbz2{$ENDIF}
{$IFDEF DARWIN}name '_BZ2_bzBuffToBuffDecompress'{$ENDIF};
{$ENDIF}
procedure LoadBzip2DLL;
begin
{$IFDEF Bzip2Runtime}
if hBzip2 <> 0 then
Exit;
hBzip2 := LoadLibrary(libbz2);
if hBzip2 = 0 then
raise EBZip2Error.Create('Bzip2 shared library not found');
@BZ2_bzCompressInit := GetProcAddress(hBzip2, 'BZ2_bzCompressInit');
@BZ2_bzCompress := GetProcAddress(hBzip2, 'BZ2_bzCompress');
@BZ2_bzCompressEnd := GetProcAddress(hBzip2, 'BZ2_bzCompressEnd');
@BZ2_bzBuffToBuffCompress := GetProcAddress(hBzip2, 'BZ2_bzBuffToBuffCompress');
@BZ2_bzDecompressInit := GetProcAddress(hBzip2, 'BZ2_bzDecompressInit');
@BZ2_bzDecompress := GetProcAddress(hBzip2, 'BZ2_bzDecompress');
@BZ2_bzDecompressEnd := GetProcAddress(hBzip2, 'BZ2_bzDecompressEnd');
@BZ2_bzBuffToBuffDecompress := GetProcAddress(hBzip2, 'BZ2_bzBuffToBuffDecompress');
{$ENDIF}
end;
function bzip2AllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
begin
GetMem(Result, Items * Size);
end; { bzip2AllocMem }
procedure bzip2FreeMem(AppData, Block: Pointer); cdecl;
begin
FreeMem(Block);
end; { bzip2FreeMem }
function CCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
raise EBZCompressionError.CreateFmt('error %d', [code]); //!!
end; { CCheck }
function DCheck(code: Integer): Integer;
begin
Result := code;
if code < 0 then
raise EBZDecompressionError.CreateFmt('error %d', [code]); //!!
end; { DCheck }
procedure BZCompressBuf(const InBuf: Pointer; InBytes: Integer;
out OutBuf: Pointer; out OutBytes: Integer);
var
strm: TBZStreamRec;
P: Pointer;
begin
LoadBzip2DLL;
FillChar(strm, sizeof(strm), 0);
strm.bzalloc := bzip2AllocMem;
strm.bzfree := bzip2FreeMem;
OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
GetMem(OutBuf, OutBytes);
try
strm.next_in := InBuf;
strm.avail_in := InBytes;
strm.next_out := OutBuf;
strm.avail_out := OutBytes;
CCheck(BZ2_bzCompressInit(strm, 9, 0, 0));
try
while CCheck(BZ2_bzCompress(strm, BZ_FINISH)) <> BZ_STREAM_END do
begin
P := OutBuf;
Inc(OutBytes, 256);
ReallocMem(OutBuf, OutBytes);
strm.next_out := PByte(PtrInt(OutBuf)
+ (PtrInt(strm.next_out) - PtrInt(P)));
strm.avail_out := 256;
end;
finally
CCheck(BZ2_bzCompressEnd(strm));
end;
ReallocMem(OutBuf, strm.total_out_lo32);
OutBytes := strm.total_out_lo32;
except
FreeMem(OutBuf);
raise
end;
end;
procedure BZDecompressBuf(const InBuf: Pointer; InBytes: Integer;
OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
var
strm: TBZStreamRec;
P: Pointer;
BufInc: Integer;
begin
LoadBzip2DLL;
FillChar(strm, sizeof(strm), 0);
strm.bzalloc := bzip2AllocMem;
strm.bzfree := bzip2FreeMem;
BufInc := (InBytes + 255) and not 255;
if OutEstimate = 0 then
OutBytes := BufInc
else
OutBytes := OutEstimate;
GetMem(OutBuf, OutBytes);
try
strm.next_in := InBuf;
strm.avail_in := InBytes;
strm.next_out := OutBuf;
strm.avail_out := OutBytes;
DCheck(BZ2_bzDecompressInit(strm, 0, 0));
try
while DCheck(BZ2_bzDecompress(strm)) <> BZ_STREAM_END do
begin
P := OutBuf;
Inc(OutBytes, BufInc);
ReallocMem(OutBuf, OutBytes);
strm.next_out := PByte(PtrInt(OutBuf) + (PtrInt(strm.next_out) - PtrInt(P)));
strm.avail_out := BufInc;
end;
finally
DCheck(BZ2_bzDecompressEnd(strm));
end;
ReallocMem(OutBuf, strm.total_out_lo32);
OutBytes := strm.total_out_lo32;
except
FreeMem(OutBuf);
raise
end;
end;
// TCustomBZip2Stream
constructor TCustomBZip2Stream.Create(Strm: TStream);
begin
inherited Create;
FStrm := Strm;
FStrmPos := Strm.Position;
FBZRec.bzalloc := bzip2AllocMem;
FBZRec.bzfree := bzip2FreeMem;
end;
procedure TCustomBZip2Stream.Progress(Sender: TObject);
begin
if Assigned(FOnProgress) then FOnProgress(Sender);
end; { TCustomBZip2Stream }
// TBZCompressionStream
constructor TBZCompressionStream.Create(BlockSize100k: TBlockSize100k; Dest: TStream);
const
BlockSizes: array[TBlockSize100k] of ShortInt = (1, 2, 3, 4, 5, 6, 7, 8, 9);
begin
inherited Create(Dest);
LoadBzip2DLL;
FBZRec.next_out := @FBuffer[0];
FBZRec.avail_out := sizeof(FBuffer);
CCheck(BZ2_bzCompressInit(FBZRec, BlockSizes[BlockSize100k], 0, 0));
end;
destructor TBZCompressionStream.Destroy;
begin
if FBZRec.state <> nil then begin
FBZRec.next_in := nil;
FBZRec.avail_in := 0;
try
if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
while (CCheck(BZ2_bzCompress(FBZRec, BZ_FINISH)) <> BZ_STREAM_END)
and (FBZRec.avail_out = 0) do
begin
FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
FBZRec.next_out := @FBuffer[0];
FBZRec.avail_out := sizeof(FBuffer);
end;
if FBZRec.avail_out < sizeof(FBuffer) then
FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FBZRec.avail_out);
finally
BZ2_bzCompressEnd(FBZRec);
end;
end;
inherited Destroy;
end;
function TBZCompressionStream.Read(var Buffer; Count: Longint): Longint;
begin
raise EBZCompressionError.Create('Invalid stream operation');
end; { TBZCompressionStream }
function TBZCompressionStream.Write(const Buffer; Count: Longint): Longint;
begin
FBZRec.next_in := @Buffer;
FBZRec.avail_in := Count;
if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
while (FBZRec.avail_in > 0) do
begin
CCheck(BZ2_bzCompress(FBZRec, BZ_RUN));
if FBZRec.avail_out = 0 then
begin
FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
FBZRec.next_out := @FBuffer[0];
FBZRec.avail_out := sizeof(FBuffer);
FStrmPos := FStrm.Position;
end;
Progress(Self);
end;
Result := Count;
end; { TBZCompressionStream }
function TBZCompressionStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var
conv64 : TLargeInteger;
begin
if (Offset = 0) and (Origin = soCurrent) then begin
conv64.LowPart := FBZRec.total_in_lo32;
conv64.HighPart := FBZRec.total_in_hi32;
Result := conv64.QuadPart
end
else
raise EBZCompressionError.Create('Invalid stream operation');
end; { TBZCompressionStream }
function TBZCompressionStream.GetCompressionRate: Single;
var
conv64In : TLargeInteger;
conv64Out: TLargeInteger;
begin
conv64In.LowPart := FBZRec.total_in_lo32;
conv64In.HighPart := FBZRec.total_in_hi32;
conv64Out.LowPart := FBZRec.total_out_lo32;
conv64Out.HighPart := FBZRec.total_out_hi32;
if conv64In.QuadPart = 0 then
Result := 0
else
Result := (1.0 - (conv64Out.QuadPart / conv64In.QuadPart)) * 100.0;
end; { TBZCompressionStream }
// TDecompressionStream
constructor TBZDecompressionStream.Create(Source: TStream);
begin
inherited Create(Source);
LoadBzip2DLL;
FBZRec.next_in := @FBuffer[0];
FBZRec.avail_in := 0;
DCheck(BZ2_bzDecompressInit(FBZRec, 0, 0));
end;
destructor TBZDecompressionStream.Destroy;
begin
if FBZRec.state <> nil then
BZ2_bzDecompressEnd(FBZRec);
inherited Destroy;
end;
function TBZDecompressionStream.Read(var Buffer; Count: Longint): Longint;
begin
FBZRec.next_out := @Buffer;
FBZRec.avail_out := Count;
if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
while (FBZRec.avail_out > 0) do
begin
if FBZRec.avail_in = 0 then
begin
FBZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
if FBZRec.avail_in = 0 then
begin
Result := Count - FBZRec.avail_out;
Exit;
end;
FBZRec.next_in := @FBuffer[0];
FStrmPos := FStrm.Position;
end;
CCheck(BZ2_bzDecompress(FBZRec));
Progress(Self);
end;
Result := Count;
end; { TBZDecompressionStream }
function TBZDecompressionStream.Write(const Buffer; Count: Longint): Longint;
begin
raise EBZDecompressionError.Create('Invalid stream operation');
end; { TBZDecompressionStream }
function TBZDecompressionStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var
I : Integer;
Buf : array[0..4095] of Char;
conv64: TLargeInteger;
NewOff: Int64;
begin
conv64.LowPart := FBZRec.total_out_lo32;
conv64.HighPart := FBZRec.total_out_hi32;
if (Offset = 0) and (Origin = soBeginning) then
begin
DCheck(BZ2_bzDecompressEnd(FBZRec));
DCheck(BZ2_bzDecompressInit(FBZRec, 0, 0));
FBZRec.next_in := @FBuffer[0];
FBZRec.avail_in := 0;
FStrm.Position := 0;
FStrmPos := 0;
end
else if ((Offset >= 0) and (Origin = soCurrent)) or
(((Offset - conv64.QuadPart) > 0) and (Origin = soBeginning)) then
begin
NewOff := Offset;
if Origin = soBeginning then Dec(NewOff, conv64.QuadPart);
if NewOff > 0 then
begin
for I := 1 to NewOff div sizeof(Buf) do
ReadBuffer(Buf, sizeof(Buf));
ReadBuffer(Buf, NewOff mod sizeof(Buf));
end;
end
else
raise EBZDecompressionError.Create('Invalid stream operation');
Result := conv64.QuadPart;
end; { TBZDecompressionStream }
end.

View File

@@ -0,0 +1,430 @@
(* ***** 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
* Joel Haynie
* Craig Peterson
*
* Portions created by the Initial Developer are Copyright (C) 1997-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbBzip2Typ.pas *}
{*********************************************************}
{* ABBREVIA: TAbBzip2Archive, TAbBzip2Item classes *}
{*********************************************************}
{* Misc. constants, types, and routines for working *}
{* with Bzip2 files *}
{*********************************************************}
unit AbBzip2Typ;
{$I AbDefine.inc}
interface
uses
Classes,
AbArcTyp, AbTarTyp, AbUtils;
const
{ Default Stream Header for Bzip2s is 'BZhX', where X is the block size setting 1-9 in ASCII }
{ Each block has the following header: '1AY&SY', and are in units of 100kilobytes NOT 100kibiBytes }
AB_BZIP2_FILE_HEADER = 'BZh';
AB_BZIP2_BLOCK_SIZE = ['1','2','3','4','5','6','7','8','9'];
AB_BZIP2_BLOCK_HEADER = '1AY&SY'; { Note: $314159265359, BCD for Pi :) }
{ Note that Blocks are bit aligned, as such the only time you will "for sure" see
the block header is on the start of stream/File }
AB_BZIP2_FILE_TAIL =#23#114#36#83#133#9#0; { $1772245385090, BCD for sqrt(Pi) :) }
{ This is odd as the blocks are bit allgned so this is a string that is 13*4 bits = 52 bits }
type
PAbBzip2Header = ^TAbBzip2Header; { File Header }
TAbBzip2Header = packed record { SizeOf(TAbBzip2Header) = 10 }
FileHeader : array[0..2] of AnsiChar;{ 'BZh'; $42,5A,68 }
BlockSize : AnsiChar; { '1'..'9'; $31-$39 }
BlockHeader : array[0..5] of AnsiChar;{ '1AY&SY'; $31,41,59,26,53,59 }
end;
{ The Purpose for this Item is the placeholder for aaAdd and aaDelete Support. }
{ For all intents and purposes we could just use a TAbArchiveItem }
type
TAbBzip2Item = class(TabArchiveItem);
TAbBzip2ArchiveState = (gsBzip2, gsTar);
TAbBzip2Archive = class(TAbTarArchive)
private
FBzip2Stream : TStream; { stream for Bzip2 file}
FBzip2Item : TAbArchiveList; { item in bzip2 (only one, but need polymorphism of class)}
FTarStream : TStream; { stream for possible contained Tar }
FTarList : TAbArchiveList; { items in possible contained Tar }
FTarAutoHandle: Boolean;
FState : TAbBzip2ArchiveState;
FIsBzippedTar : Boolean;
procedure DecompressToStream(aStream: TStream);
procedure SetTarAutoHandle(const Value: Boolean);
procedure SwapToBzip2;
procedure SwapToTar;
protected
{ Inherited Abstract functions }
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 GetSupportsEmptyFolders : Boolean; override;
public {methods}
constructor CreateFromStream(aStream : TStream; const aArchiveName : string); override;
destructor Destroy; override;
procedure DoSpanningMediaRequest(Sender : TObject; ImageNumber : Integer;
var ImageName : string; var Abort : Boolean); override;
{ Properties }
property TarAutoHandle : Boolean
read FTarAutoHandle write SetTarAutoHandle;
property IsBzippedTar : Boolean
read FIsBzippedTar write FIsBzippedTar;
end;
function VerifyBzip2(Strm : TStream) : TAbArchiveType;
implementation
uses
{$IFDEF MSWINDOWS}
Windows, // Fix inline warnings
{$ENDIF}
StrUtils, SysUtils,
AbBzip2, AbExcept, AbVMStrm, AbBitBkt;
{ ****************** Helper functions Not from Classes Above ***************** }
function VerifyHeader(const Header : TAbBzip2Header) : Boolean;
begin
Result := (Header.FileHeader = AB_BZIP2_FILE_HEADER) and
(Header.BlockSize in AB_BZIP2_BLOCK_SIZE) and
(Header.BlockHeader = AB_BZIP2_BLOCK_HEADER);
end;
{ -------------------------------------------------------------------------- }
function VerifyBzip2(Strm : TStream) : TAbArchiveType;
var
Hdr : TAbBzip2Header;
CurPos : int64;
DecompStream, TarStream: TStream;
begin
Result := atUnknown;
CurPos := Strm.Position;
Strm.Seek(0, soBeginning);
try
if (Strm.Read(Hdr, SizeOf(Hdr)) = SizeOf(Hdr)) and VerifyHeader(Hdr) then begin
Result := atBzip2;
{ Check for embedded TAR }
Strm.Seek(0, soBeginning);
DecompStream := TBZDecompressionStream.Create(Strm);
try
TarStream := TMemoryStream.Create;
try
TarStream.CopyFrom(DecompStream, 512 * 2);
TarStream.Seek(0, soBeginning);
if VerifyTar(TarStream) = atTar then
Result := atBzippedTar;
finally
TarStream.Free;
end;
finally
DecompStream.Free;
end;
end;
except
on EReadError do
Result := atUnknown;
end;
Strm.Position := CurPos; { Return to original position. }
end;
{ ****************************** TAbBzip2Archive ***************************** }
constructor TAbBzip2Archive.CreateFromStream(aStream: TStream;
const aArchiveName: string);
begin
inherited CreateFromStream(aStream, aArchiveName);
FState := gsBzip2;
FBzip2Stream := FStream;
FBzip2Item := FItemList;
FTarStream := TAbVirtualMemoryStream.Create;
FTarList := TAbArchiveList.Create(True);
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.SwapToTar;
begin
FStream := FTarStream;
FItemList := FTarList;
FState := gsTar;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.SwapToBzip2;
begin
FStream := FBzip2Stream;
FItemList := FBzip2Item;
FState := gsBzip2;
end;
{ -------------------------------------------------------------------------- }
function TAbBzip2Archive.CreateItem(const FileSpec: string): TAbArchiveItem;
begin
if IsBzippedTar and TarAutoHandle then begin
SwapToTar;
Result := inherited CreateItem(FileSpec);
end
else begin
SwapToBzip2;
Result := TAbBzip2Item.Create;
try
Result.DiskFileName := ExpandFileName(FileSpec);
Result.FileName := FixName(FileSpec);
except
Result.Free;
raise;
end;
end;
end;
{ -------------------------------------------------------------------------- }
destructor TAbBzip2Archive.Destroy;
begin
SwapToBzip2;
FTarList.Free;
FTarStream.Free;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.ExtractItemAt(Index: Integer;
const NewName: string);
var
OutStream : TFileStream;
begin
if IsBzippedTar and TarAutoHandle then begin
SwapToTar;
inherited ExtractItemAt(Index, NewName);
end
else begin
SwapToBzip2;
OutStream := TFileStream.Create(NewName, fmCreate or fmShareDenyNone);
try
try
ExtractItemToStreamAt(Index, OutStream);
finally
OutStream.Free;
end;
{ Bz2 doesn't store the last modified time or attributes, so don't set them }
except
on E : EAbUserAbort do begin
FStatus := asInvalid;
if FileExists(NewName) then
DeleteFile(NewName);
raise;
end else begin
if FileExists(NewName) then
DeleteFile(NewName);
raise;
end;
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.ExtractItemToStreamAt(Index: Integer;
aStream: TStream);
begin
if IsBzippedTar and TarAutoHandle then begin
SwapToTar;
inherited ExtractItemToStreamAt(Index, aStream);
end
else begin
SwapToBzip2;
{ Index ignored as there's only one item in a Bz2 }
DecompressToStream(aStream);
end;
end;
{ -------------------------------------------------------------------------- }
function TAbBzip2Archive.GetSupportsEmptyFolders : Boolean;
begin
Result := IsBzippedTar and TarAutoHandle;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.LoadArchive;
var
Item: TAbBzip2Item;
Abort: Boolean;
ItemName: string;
begin
if FBzip2Stream.Size = 0 then
Exit;
if IsBzippedTar and TarAutoHandle then begin
{ Decompress and send to tar LoadArchive }
DecompressToStream(FTarStream);
SwapToTar;
inherited LoadArchive;
end
else begin
SwapToBzip2;
Item := TAbBzip2Item.Create;
Item.Action := aaNone;
{ Filename isn't stored, so constuct one based on the archive name }
ItemName := ExtractFileName(ArchiveName);
if ItemName = '' then
Item.FileName := 'unknown'
else if AnsiEndsText('.tbz', ItemName) or AnsiEndsText('.tbz2', ItemName) then
Item.FileName := ChangeFileExt(ItemName, '.tar')
else
Item.FileName := ChangeFileExt(ItemName, '');
Item.DiskFileName := Item.FileName;
FItemList.Add(Item);
end;
DoArchiveProgress(100, Abort);
FIsDirty := False;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.SaveArchive;
var
CompStream: TStream;
i: Integer;
CurItem: TAbBzip2Item;
InputFileStream: TStream;
begin
if IsBzippedTar and TarAutoHandle then
begin
SwapToTar;
inherited SaveArchive;
FTarStream.Position := 0;
FBzip2Stream.Size := 0;
CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);
try
CompStream.CopyFrom(FTarStream, 0);
finally
CompStream.Free;
end;
end
else begin
{ Things we know: There is only one file per archive.}
{ Actions we have to address in SaveArchive: }
{ aaNone & aaMove do nothing, as the file does not change, only the meta data }
{ aaDelete could make a zero size file unless there are two files in the list.}
{ aaAdd, aaStreamAdd, aaFreshen, & aaReplace will be the only ones to take action. }
SwapToBzip2;
for i := 0 to pred(Count) do begin
FCurrentItem := ItemList[i];
CurItem := TAbBzip2Item(ItemList[i]);
case CurItem.Action of
aaNone, aaMove: Break;{ Do nothing; bz2 doesn't store metadata }
aaDelete: ; {doing nothing omits file from new stream}
aaAdd, aaFreshen, aaReplace, aaStreamAdd: begin
FBzip2Stream.Size := 0;
CompStream := TBZCompressionStream.Create(bs9, FBzip2Stream);
try
if CurItem.Action = aaStreamAdd then
CompStream.CopyFrom(InStream, 0){ Copy/compress entire Instream to FBzip2Stream }
else begin
InputFileStream := TFileStream.Create(CurItem.DiskFileName, fmOpenRead or fmShareDenyWrite );
try
CompStream.CopyFrom(InputFileStream, 0);{ Copy/compress entire Instream to FBzip2Stream }
finally
InputFileStream.Free;
end;
end;
finally
CompStream.Free;
end;
Break;
end; { End aaAdd, aaFreshen, aaReplace, & aaStreamAdd }
end; { End of CurItem.Action Case }
end; { End Item for loop }
end; { End Tar Else }
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.SetTarAutoHandle(const Value: Boolean);
begin
if Value then
SwapToTar
else
SwapToBzip2;
FTarAutoHandle := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.DecompressToStream(aStream: TStream);
const
BufSize = $F000;
var
DecompStream: TBZDecompressionStream;
Buffer: PByte;
N: Integer;
begin
DecompStream := TBZDecompressionStream.Create(FBzip2Stream);
try
GetMem(Buffer, BufSize);
try
N := DecompStream.Read(Buffer^, BufSize);
while N > 0 do begin
aStream.WriteBuffer(Buffer^, N);
N := DecompStream.Read(Buffer^, BufSize);
end;
finally
FreeMem(Buffer, BufSize);
end;
finally
DecompStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.TestItemAt(Index: Integer);
var
Bzip2Type: TAbArchiveType;
BitBucket: TAbBitBucketStream;
begin
if IsBzippedTar and TarAutoHandle then begin
SwapToTar;
inherited TestItemAt(Index);
end
else begin
{ note Index ignored as there's only one item in a GZip }
Bzip2Type := VerifyBzip2(FBzip2Stream);
if not (Bzip2Type in [atBzip2, atBzippedTar]) then
raise EAbGzipInvalid.Create;// TODO: Add bzip2-specific exceptions }
BitBucket := TAbBitBucketStream.Create(1024);
try
DecompressToStream(BitBucket);
finally
BitBucket.Free;
end;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbBzip2Archive.DoSpanningMediaRequest(Sender: TObject;
ImageNumber: Integer; var ImageName: string; var Abort: Boolean);
begin
Abort := False;
end;
end.

View File

@@ -0,0 +1,238 @@
(* ***** 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: AbCBrows.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet file browser component *}
{*********************************************************}
unit AbCBrows;
{$I AbDefine.inc}
interface
uses
Classes,
AbBrowse,
AbCabTyp;
type
TAbCustomCabBrowser = class(TAbBaseBrowser)
protected {private}
FSetID : Word;
function GetCabArchive : TAbCabArchive;
function GetCabSize : Longint;
function GetCurrentCab : Word;
function GetFolderCount : Word;
function GetItem(Index : Integer) : TAbCabItem; virtual;
function GetHasNext : Boolean;
function GetHasPrev : Boolean;
function GetSetID : Word;
procedure InitArchive;
override;
procedure SetFileName(const aFileName : string); override;
procedure SetSetID(Value : Word);
protected {properties}
property CabSize : Longint
read GetCabSize;
property CurrentCab : Word
read GetCurrentCab;
property FolderCount : Word
read GetFolderCount;
property HasNext : Boolean
read GetHasNext;
property HasPrev : Boolean
read GetHasPrev;
property SetID : Word
read GetSetID
write SetSetID;
public {methods}
constructor Create(AOwner : TComponent);
override;
destructor Destroy;
override;
public {properties}
property CabArchive : TAbCabArchive
read GetCabArchive;
property Items[Index : Integer] : TAbCabItem
read GetItem; default;
end;
type
{$IFDEF HasPlatformsAttribute}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$ENDIF}
TAbCabBrowser = class(TAbCustomCabBrowser)
published
property ArchiveProgressMeter;
property BaseDirectory;
property CabSize;
property CurrentCab;
property FolderCount;
property HasNext;
property HasPrev;
property ItemProgressMeter;
property LogFile;
property Logging;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnLoad;
property SetID;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
{.Z+}
implementation
uses
SysUtils,
AbArcTyp,
AbUtils;
{ TAbCustomCabBrowser ====================================================== }
constructor TAbCustomCabBrowser.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
FArchiveType := atCab;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomCabBrowser.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetCabArchive : TAbCabArchive;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive)
else
Result := nil;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetCabSize : Longint;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).CabSize
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetCurrentCab : Word;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).CurrentCab
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetFolderCount : Word;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).FolderCount
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetHasNext : Boolean;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).HasNext
else
Result := False;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetHasPrev : Boolean;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).HasPrev
else
Result := False;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetItem(Index : Integer) : TAbCabItem;
{return cabinet item}
begin
if Assigned(CabArchive) then
Result := CabArchive.Items[Index]
else
Result := nil;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomCabBrowser.GetSetID : Word;
begin
if Assigned(Archive) then
Result := TAbCabArchive(Archive).SetID
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabBrowser.InitArchive;
begin
inherited InitArchive;
if Assigned(Archive) then
TAbCabArchive(Archive).SetID := FSetID;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabBrowser.SetFileName(const aFileName : string);
{open/create cabinet archive}
begin
FFileName := aFileName;
if (csDesigning in ComponentState) then
Exit;
if Assigned(FArchive) then begin
FArchive.Free;
FArchive := nil;
end;
if (aFileName <> '') and
FileExists(aFilename) and
(AbDetermineArcType(aFileName, atCab) = atCab) then
begin
FArchive := TAbCabArchive.Create(aFileName, fmOpenRead);
InitArchive;
FArchive.Load;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabBrowser.SetSetID(Value : Word);
begin
FSetID := Value;
if Assigned(Archive) then
TAbCabArchive(Archive).SetID := Value;
end;
{ -------------------------------------------------------------------------- }
end.

176
Abbrevia/source/AbCView.pas Normal file
View File

@@ -0,0 +1,176 @@
(* ***** 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: AbCView.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet archive viewer component *}
{* Use AbQCView.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
Unit AbCView;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
Windows, Classes,
{$IFDEF UsingClx}
AbQView,
{$ELSE}
AbView,
{$ENDIF}
AbCBrows,
AbCabTyp, AbArcTyp;
type
TAbCabView = class(TAbBaseViewer)
protected
FCabComponent : TAbCustomCabBrowser;
FEmptyItemList: TAbArchiveList;
function GetItem(RowNum : Longint) : TAbCabItem;
procedure SetCabComponent(Value : TAbCustomCabBrowser);
procedure Notification(AComponent : TComponent; Operation : TOperation);
override;
procedure DoChange(Sender : TObject);
override;
public
constructor Create(AOwner : TComponent);
override;
destructor Destroy;
override;
property Items[RowNum : Longint] : TAbCabItem
read GetItem;
published {properties}
property Align;
property Attributes;
property BorderStyle;
property Color;
property Colors;
{$IFNDEF UsingClx}
property Ctl3D;
{$ENDIF}
property Cursor;
property Headings;
property DefaultColWidth;
property DefaultRowHeight;
property DisplayOptions;
property HeaderRowHeight;
property SortAttributes;
{$IFNDEF UsingClx}
property DragCursor;
{$ENDIF}
property DragMode;
property Enabled;
property Font;
property ParentColor;
{$IFNDEF UsingClx}
property ParentCtl3D;
{$ENDIF}
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
property Version;
property CabComponent : TAbCustomCabBrowser
read FCabComponent write SetCabComponent;
published {Events}
property OnChange;
property OnClick;
property OnDblClick;
property OnEnter;
property OnExit;
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property OnSorted;
property OnDrawSortArrow;
end;
implementation
type
TAbCabBrowserFriend = class(TAbCustomCabBrowser);
{ ===== TAbCabView ========================================================= }
constructor TAbCabView.Create(AOwner : TComponent);
begin
inherited;
FEmptyItemList := FItemList;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCabView.Destroy;
begin
FItemList := FEmptyItemList;
inherited;
end;
{ -------------------------------------------------------------------------- }
function TAbCabView.GetItem(RowNum : Longint) : TAbCabItem;
begin
if Assigned(FItemList) then
Result := TAbCabItem(FItemList.Items[FRowMap[RowNum]])
else
Result := nil;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabView.Notification(AComponent : TComponent; Operation : TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
if Assigned(FCabComponent) and (AComponent = FCabComponent) then begin
FCabComponent := nil;
Refresh;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabView.SetCabComponent(Value : TAbCustomCabBrowser);
begin
FCabComponent := Value;
FCabComponent.OnChange := DoChange;
FCabComponent.OnLoad := DoLoad;
DoChange(Self);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabView.DoChange(Sender : TObject);
begin
if Assigned(FCabComponent) and Assigned(TAbCabBrowserFriend(FCabComponent).Archive) then
FItemList := TAbCabBrowserFriend(FCabComponent).Archive.ItemList
else if FEmptyItemList <> nil then
FItemList := FEmptyItemList;
inherited DoChange(Sender);
end;
end.

View File

@@ -0,0 +1,188 @@
(* ***** 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: AbCabExt.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet file extractor component *}
{*********************************************************}
unit AbCabExt;
{$I AbDefine.inc}
interface
uses
Classes,
AbCBrows,
AbArcTyp;
type
TAbCustomCabExtractor = class(TAbCustomCabBrowser)
protected {private}
FExtractOptions : TAbExtractOptions;
FOnConfirmOverwrite : TAbConfirmOverwriteEvent;
procedure DoConfirmOverwrite(var Name : string;
var Confirm : Boolean);
procedure InitArchive;
override;
procedure SetExtractOptions( Value : TAbExtractOptions );
protected {properties}
property ExtractOptions : TAbExtractOptions
read FExtractOptions
write SetExtractOptions
default AbDefExtractOptions;
property OnConfirmOverwrite : TAbConfirmOverwriteEvent
read FOnConfirmOverwrite
write FOnConfirmOverwrite;
public
constructor Create( AOwner : TComponent ); override;
destructor Destroy; override;
procedure ExtractAt(Index : Integer; const NewName : string);
procedure ExtractFiles(const FileMask : string);
procedure ExtractFilesEx(const FileMask, ExclusionMask : string);
procedure ExtractTaggedItems;
end;
{$IFDEF HasPlatformsAttribute}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$ENDIF}
TAbCabExtractor = class(TAbCustomCabExtractor)
published
property ArchiveProgressMeter;
property BaseDirectory;
property CabSize;
property CurrentCab;
property ExtractOptions;
property FolderCount;
property HasNext;
property HasPrev;
property ItemProgressMeter;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmOverwrite;
property OnConfirmProcessItem;
property OnLoad;
property OnProcessItemFailure;
property OnRequestImage;
property SetID;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
{.Z+}
implementation
uses
AbExcept;
{ TAbCustomCabExtractor ==================================================== }
constructor TAbCustomCabExtractor.Create(AOwner : TComponent);
begin
inherited Create( AOwner );
ExtractOptions := AbDefExtractOptions;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomCabExtractor.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.DoConfirmOverwrite
(var Name : string;
var Confirm : Boolean);
begin
if Assigned(FOnConfirmOverwrite) then
FOnConfirmOverwrite(Name, Confirm);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.ExtractAt(Index : Integer;
const NewName : string);
{extract a file from the archive that match the index}
begin
if Assigned( CabArchive ) then
CabArchive.ExtractAt( Index, NewName )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.ExtractFiles(const FileMask : string);
{Extract files from the cabinet matching the filemask}
begin
if Assigned( CabArchive ) then
CabArchive.ExtractFiles( FileMask )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.ExtractFilesEx(const FileMask, ExclusionMask : string);
{Extract files from the cabinet matching the FileMask, exluding those
matching ExclusionMask}
begin
if Assigned( CabArchive ) then
CabArchive.ExtractFilesEx( FileMask, ExclusionMask )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.ExtractTaggedItems;
{Extract items in the archive that have been tagged}
begin
if Assigned( CabArchive ) then
CabArchive.ExtractTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.InitArchive;
{Archive now points to the Cab file, update all Archive's properties...}
begin
inherited InitArchive;
if Assigned( CabArchive ) then begin
{poperties}
CabArchive.ExtractOptions := FExtractOptions;
{events}
CabArchive.OnConfirmOverwrite := DoConfirmOverwrite;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabExtractor.SetExtractOptions( Value : TAbExtractOptions );
begin
FExtractOptions := Value;
if Assigned( FArchive ) then
FArchive.ExtractOptions := Value;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,213 @@
(* ***** 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: AbCabKit.PAS *}
{*********************************************************}
{* ABBREVIA: Cabinet file builder/extractor component *}
{*********************************************************}
unit AbCabKit;
{$I AbDefine.inc}
interface
uses
Classes, AbArcTyp,
AbCabMak;
type
TAbCustomCabKit = class(TAbCustomMakeCab)
protected {private}
FExtractOptions : TAbExtractOptions;
FOnConfirmOverwrite : TAbConfirmOverwriteEvent;
procedure DoConfirmOverwrite(var Name : string;
var Confirm : Boolean);
procedure InitArchive; override;
procedure SetExtractOptions( Value : TAbExtractOptions );
procedure SetFileName(const aFileName : string); override;
protected {properties}
property ExtractOptions : TAbExtractOptions
read FExtractOptions
write SetExtractOptions
default AbDefExtractOptions;
protected {events}
property OnConfirmOverwrite : TAbConfirmOverwriteEvent
read FOnConfirmOverwrite
write FOnConfirmOverwrite;
public {methods}
constructor Create( AOwner : TComponent ); override;
destructor Destroy; override;
procedure ExtractAt(Index : Integer; const NewName : string);
procedure ExtractFiles(const FileMask : string);
procedure ExtractFilesEx(const FileMask, ExclusionMask : string);
procedure ExtractTaggedItems;
end;
{$IFDEF HasPlatformsAttribute}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$ENDIF}
TAbCabKit = class(TAbCustomCabKit)
published
property ArchiveProgressMeter;
property BaseDirectory;
property CabSize;
property CompressionType;
property CurrentCab;
property ExtractOptions;
property FolderCount;
property FolderThreshold;
property HasNext;
property HasPrev;
property ItemProgressMeter;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmOverwrite;
property OnConfirmProcessItem;
property OnLoad;
property OnProcessItemFailure;
property OnRequestImage;
property OnSave;
property SetID;
property SpanningThreshold;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
implementation
uses
SysUtils,
AbExcept,
AbCabTyp,
AbCBrows;
{ TAbCustomCabKit ==================================================== }
constructor TAbCustomCabKit.Create(AOwner : TComponent);
begin
inherited Create( AOwner );
ExtractOptions := AbDefExtractOptions;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomCabKit.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.DoConfirmOverwrite(var Name : string;
var Confirm : Boolean);
begin
if Assigned(FOnConfirmOverwrite) then
FOnConfirmOverwrite(Name, Confirm);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.ExtractAt(Index : Integer; const NewName : string);
{extract a file from the archive that match the index}
begin
if Assigned( CabArchive ) then
CabArchive.ExtractAt( Index, NewName )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.ExtractFiles(const FileMask : string);
{Extract files from the cabinet matching the filemask}
begin
if Assigned(CabArchive) then
CabArchive.ExtractFiles(FileMask)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.ExtractFilesEx(const FileMask, ExclusionMask : string);
{Extract files from the cabinet matching the FileMask, exluding those
matching ExclusionMask}
begin
if Assigned(CabArchive) then
CabArchive.ExtractFilesEx(FileMask, ExclusionMask)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.ExtractTaggedItems;
{Extract items in the archive that have been tagged}
begin
if Assigned(CabArchive) then
CabArchive.ExtractTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.InitArchive;
begin
inherited InitArchive;
if Assigned( CabArchive ) then begin
{poperties}
CabArchive.ExtractOptions := FExtractOptions;
{events}
CabArchive.OnConfirmOverwrite := DoConfirmOverwrite;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.SetExtractOptions( Value : TAbExtractOptions );
begin
FExtractOptions := Value;
if Assigned( FArchive ) then
FArchive.ExtractOptions := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomCabKit.SetFileName(const aFileName : string);
{Create or open the specified cabinet file}
begin
FFilename := aFileName;
if csDesigning in ComponentState then
Exit;
if Assigned(FArchive) then begin
FArchive.Free;
FArchive := nil;
end;
if (aFileName <> '') then begin
if (aFileName <> '') and FileExists(aFilename) then
FArchive := TAbCabArchive.Create(aFileName, fmOpenRead)
else
FArchive := TAbCabArchive.Create(aFileName, fmOpenWrite);
InitArchive;
FArchive.Load;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,237 @@
(* ***** 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: AbCabMak.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet builder component (VCL) *}
{* See AbQCabMk.pas for the CLX header *}
{*********************************************************}
unit AbCabMak;
{$I AbDefine.inc}
interface
uses
Classes,
AbCBrows,
AbArcTyp, AbCabTyp;
type
TAbCustomMakeCab = class(TAbCustomCabBrowser)
protected {private}
FFolderThreshold : Longint;
FCompressionType : TAbCabCompressionType;
FStoreOptions : TAbStoreOptions;
FOnSave : TAbArchiveEvent;
protected {methods}
procedure DoSave(Sender : TObject); virtual;
procedure InitArchive; override;
procedure SetFolderThreshold(Value : Longint);
procedure SetCompressionType(Value : TAbCabCompressionType);
procedure SetFileName(const aFileName : string); override;
procedure SetStoreOptions( Value : TAbStoreOptions );
protected {properties}
property CompressionType : TAbCabCompressionType
read FCompressionType
write SetCompressionType;
property FolderThreshold : Longint
read FFolderThreshold
write SetFolderThreshold;
property StoreOptions : TAbStoreOptions
read FStoreOptions
write SetStoreOptions
default AbDefStoreOptions;
protected {events}
property OnSave : TAbArchiveEvent
read FOnSave
write FOnSave;
public {methods}
constructor Create( AOwner : TComponent ); override;
procedure AddFiles(const FileMask : string; SearchAttr : Integer );
procedure AddFilesEx(const FileMask : string;
const ExclusionMask : string; SearchAttr : Integer );
procedure StartNewFolder;
procedure StartNewCabinet;
end;
type
{$IFDEF HasPlatformsAttribute}
[ComponentPlatformsAttribute(pidWin32 or pidWin64)]
{$ENDIF}
TAbMakeCab = class(TAbCustomMakeCab)
published
property ArchiveProgressMeter;
property BaseDirectory;
property CabSize;
property CompressionType;
property FolderThreshold;
property ItemProgressMeter;
property StoreOptions;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmProcessItem;
property OnLoad;
property OnProcessItemFailure;
property OnRequestImage;
property OnSave;
property SetID;
property SpanningThreshold;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
{.Z+}
implementation
uses
SysUtils,
AbExcept,
AbUtils;
{ TAbCustomMakeCab ========================================================= }
constructor TAbCustomMakeCab.Create( AOwner : TComponent );
begin
inherited Create( AOwner );
FCompressionType := AbDefCompressionType;
FSpanningThreshold := AbDefCabSpanningThreshold;
FFolderThreshold := AbDefFolderThreshold;
FSetID := 0;
FStoreOptions := AbDefStoreOptions;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.AddFiles(const FileMask : string; SearchAttr : Integer );
{Add files to the cabinet where the disk filespec matches}
begin
if Assigned(CabArchive) then
CabArchive.AddFiles(FileMask, SearchAttr)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.AddFilesEx(const FileMask : string;
const ExclusionMask : string;
SearchAttr : Integer);
{Add files that match Filemask except those matching ExclusionMask}
begin
if Assigned(CabArchive) then
CabArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.DoSave(Sender : TObject);
begin
if Assigned(FOnSave) then
FOnSave(Self);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.InitArchive;
begin
inherited InitArchive;
if Assigned(CabArchive) then begin
{properties}
CabArchive.FolderThreshold := FFolderThreshold;
CabArchive.CompressionType := FCompressionType;
CabArchive.SetID := FSetID;
CabArchive.StoreOptions := FStoreOptions;
{events}
CabArchive.OnSave := DoSave;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.SetCompressionType(Value : TAbCabCompressionType);
{Set the type of compression to use}
begin
FCompressionType := Value;
if Assigned(CabArchive) then
CabArchive.CompressionType := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.SetFileName(const aFileName : string);
{Create the specified cabinet file}
begin
FFilename := aFileName;
if csDesigning in ComponentState then
Exit;
if Assigned(FArchive) then begin
FArchive.Free;
FArchive := nil;
end;
if (aFileName <> '') then begin
FArchive := TAbCabArchive.Create(aFileName, fmOpenWrite);
InitArchive;
FArchive.Load;
FArchiveType := atCab;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.SetFolderThreshold(Value : Longint);
{Set folder compression boundary}
begin
FFolderThreshold := Value;
if Assigned(CabArchive) then
CabArchive.FolderThreshold := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.SetStoreOptions(Value : TAbStoreOptions);
begin
FStoreOptions := Value;
if Assigned(CabArchive) then
CabArchive.StoreOptions := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.StartNewCabinet;
{Flush current cabinet and start a new one}
begin
if Assigned(CabArchive) then
CabArchive.NewCabinet
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMakeCab.StartNewFolder;
{Flush current folder and start a new one}
begin
if Assigned(CabArchive) then
CabArchive.NewFolder
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,819 @@
(* ***** 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):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbCabTyp.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet Archive *}
{* Based on info from the FCI/FDI Library Description, *}
{* included in the Microsoft Cabinet SDK *}
{*********************************************************}
unit AbCabTyp;
{$I AbDefine.inc}
interface
uses
Windows, Classes, AbFciFdi, AbArcTyp, AbUtils;
type
TAbCabItem = class(TAbArchiveItem)
protected {private}
FPartialFile : Boolean;
FRawFileName : AnsiString;
public
property PartialFile : Boolean
read FPartialFile
write FPartialFile;
property RawFileName : AnsiString
read FRawFileName
write FRawFileName;
end;
type
TAbCabCompressionType = (ctNone, ctMSZIP, ctLZX);
TAbCabinetMode = (cmRead, cmWrite);
TAbCabStatus = (csFile, csFolder, csCabinet);
const
faExtractAndExecute = $040;
faUTF8Name = $080;
AbDefCabSpanningThreshold = 0;
AbDefFolderThreshold = 0;
AbDefCompressionType = ctMSZIP;
AbDefReserveHeaderSize = 0;
AbDefReserveFolderSize = 0;
AbDefReserveDataSize = 0;
AbDefLZXWindowSize = 18;
CompressionTypeMap : array[TAbCabCompressionType] of Word = (0, 1, 4611);
type
TAbCabArchive = class(TAbArchive)
protected {private}
{internal variables}
FCabName : AnsiString;
FCabPath : AnsiString;
FFCICabInfo : FCICabInfo;
FFCIContext : HFCI;
FFDIContext : HFDI;
FFDICabInfo : FDICabInfo;
FErrors : CabErrorRecord;
FItemInProgress : TAbCabItem;
FItemStream : TStream;
FIIPName : string;
FItemProgress : DWord;
FNextCabinet : string;
FNextDisk : string;
FTempFileID : Integer;
{property variables}
FCurrentCab : Word;
FCabSize : Longint;
FCompressionType : TAbCabCompressionType;
FFileCount : Word;
FFolderThreshold : LongWord;
FFolderCount : Word;
FHasPrev : Boolean;
FHasNext : Boolean;
FSetID : Word;
{internal methods}
procedure CloseCabFile;
procedure CreateCabFile;
function CreateItem( const FileSpec : string ): TAbArchiveItem;
override;
procedure DoCabItemProgress(BytesCompressed : DWord;
var Abort : Boolean);
procedure DoGetNextCabinet(CabIndex : Integer; var CabName : string;
var Abort : Boolean);
procedure ExtractItemAt(Index : Integer; const NewName : string);
override;
procedure ExtractItemToStreamAt(Index : Integer; OutStream : TStream);
override;
function GetItem(ItemIndex : Integer) : TAbCabItem;
procedure LoadArchive;
override;
procedure OpenCabFile;
procedure PutItem( Index : Integer; Value : TAbCabItem );
procedure SaveArchive;
override;
procedure SetFolderThreshold(Value : LongWord);
procedure SetSetID(Value : Word);
procedure SetSpanningThreshold(Value : Int64);
override;
procedure TestItemAt(Index : Integer);
override;
public {methods}
constructor Create(const FileName : string; Mode : Word);
override;
constructor CreateFromStream(aStream : TStream; const aArchiveName : string);
override;
destructor Destroy;
override;
procedure Add(aItem : TAbArchiveItem);
override;
procedure NewCabinet;
procedure NewFolder;
public {properties}
property CurrentCab : Word
read FCurrentCab;
property CabSize : Longint
read FCabSize;
property CompressionType : TAbCabCompressionType
read FCompressionType
write FCompressionType;
property FolderThreshold : LongWord
read FFolderThreshold
write SetFolderThreshold;
property FolderCount : Word
read FFolderCount;
property HasPrev : Boolean
read FHasPrev;
property HasNext : Boolean
read FHasNext;
property Items[Index : Integer] : TAbCabItem
read GetItem
write PutItem; default;
property ItemProgress : DWord
read FItemProgress
write FItemProgress;
property SetID : Word
read FSetID
write SetSetID;
end;
function VerifyCab(const Fn : string) : TAbArchiveType; overload;
function VerifyCab(Strm : TStream) : TAbArchiveType; overload;
implementation
uses
SysUtils,
{$IFDEF HasAnsiStrings}
System.AnsiStrings,
{$ENDIF}
AbCharset, AbConst, AbExcept;
{$WARN UNIT_PLATFORM OFF}
{$WARN SYMBOL_PLATFORM OFF}
type
PWord = ^Word;
PInteger = ^Integer;
{ == FDI/FCI Callback Functions - cdecl calling convention ================= }
function FXI_GetMem(uBytes : Integer) : Pointer;
cdecl;
{allocate memory}
begin
Result := nil;
if (uBytes > 0) then
GetMem(Result, uBytes);
end;
{ -------------------------------------------------------------------------- }
procedure FXI_FreeMem(lpBuffer : Pointer);
cdecl;
{free memory}
begin
FreeMem(lpBuffer);
end;
{ == FCI Callback Functions - cdecl calling convention ===================== }
function FCI_FileOpen(lpPathName: PAnsiChar; Flag, Mode: Integer;
PError: PInteger; Archive: TAbCabArchive) : PtrInt;
cdecl;
{open a file}
begin
Result := _lcreat(lpPathName, 0);
if (Result = -1) then
raise EAbFCIFileOpenError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileRead(hFile: PtrInt; lpBuffer: Pointer;
uBytes: UINT; PError: PInteger; Archive: TAbCabArchive) : UINT;
cdecl;
{read from a file}
begin
Result := _lread(hFile, lpBuffer, uBytes);
if (Result = UINT(-1)) then
raise EAbFCIFileReadError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileWrite(hFile: PtrInt; lpBuffer: Pointer;
uBytes: UINT; PError: PInteger; Archive: TAbCabArchive) : UINT;
cdecl;
{write to a file}
begin
Result := _lwrite(hFile, lpBuffer, uBytes);
if (Result = UINT(-1)) then
raise EAbFCIFileWriteError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileClose(hFile: PtrInt; PError: PInteger;
Archive: TAbCabArchive) : Integer;
cdecl;
{close a file}
begin
Result := _lclose(hFile);
if (Result = -1) then
raise EAbFCIFileCloseError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileSeek(hFile: PtrInt; Offset: Longint;
Origin: Integer; PError: PInteger; Archive: TAbCabArchive) : Longint;
cdecl;
{reposition file pointer}
begin
Result := _llseek(hFile, Offset, Origin);
if (Result = -1) then
raise EAbFCIFileSeekError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileDelete(lpFilename: PAnsiChar; PError: PInteger;
Archive: TAbCabArchive) : Boolean;
cdecl;
{delete a file}
begin
Result := SysUtils.DeleteFile(string(lpFilename));
if not Result then
raise EAbFCIFileDeleteError.Create;
end;
{ -------------------------------------------------------------------------- }
function FCI_GetNextCab(lpCCab: PFCICabInfo; PrevCab: Longint;
Archive: TAbCabArchive) : Boolean;
cdecl;
{get next cabinet filename}
var
CabName : string;
Abort : Boolean;
begin
Abort := False;
with lpCCab^ do begin
CabName := string(szCab);
{obtain next cabinet. Make index zero-based}
Archive.DoGetNextCabinet(Pred(iCab), CabName, Abort);
if not Abort then
AbStrPLCopy(szCab, AnsiString(CabName), Length(szCab));
end;
Result := not Abort;
end;
{ -------------------------------------------------------------------------- }
function FCI_FileDest(PCCab: PFCICabInfo; PFilename: PAnsiChar; cbFile: Longint;
Continuation: Boolean; Archive: TAbCabArchive) : Integer;
cdecl;
{currently not used}
begin
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function FCI_GetOpenInfo(lpPathname: Pointer; PDate, PTime, PAttribs : PWord;
PError: PInteger; Archive: TAbCabArchive) : PtrInt;
cdecl;
{open a file and return date/attributes}
var
AttrEx: TAbAttrExRec;
I, DT: Integer;
RawName: RawByteString;
begin
Result := FileOpen(string(lpPathname), fmOpenRead or fmShareDenyNone);
if (Result = -1) then
raise EAbFCIFileOpenError.Create;
if not AbFileGetAttrEx(string(lpPathname), AttrEx) then
raise EAbFileNotFound.Create;
PAttribs^ := AttrEx.Attr;
DT := DateTimeToFileDate(AttrEx.Time);
PDate^ := DT shr 16;
PTime^ := DT and $0FFFF;
Archive.ItemProgress := 0;
Archive.FItemInProgress.UncompressedSize := AttrEx.Size;
RawName := Archive.FItemInProgress.RawFileName;
for I := 1 to Length(RawName) do
if Ord(RawName[I]) > 127 then
PAttribs^ := PAttribs^ or faUTF8Name;
end;
{ -------------------------------------------------------------------------- }
function FCI_Status(Status: Word; cb1, cb2: DWord;
Archive: TAbCabArchive) : Longint; cdecl;
{keep archive informed}
var
Abort : Boolean;
begin
Result := 0;
if (Status = Word(csCabinet)) then begin
Archive.DoSave;
Archive.FCabSize := cb2;
Result := cb2;
end else if (Status = Word(csFolder)) then
Archive.FCabSize := Archive.FCabSize + Longint(cb2)
else if (Status = Word(csFile)) then begin
Archive.DoCabItemProgress(cb2, Abort);
Result := Longint(Abort);
end;
end;
{ -------------------------------------------------------------------------- }
function FCI_GetTempFile(lpTempName: PAnsiChar; TempNameSize: Integer;
Archive: TAbCabArchive) : PtrInt; cdecl;
{obtain temporary filename}
var
TempPath : array[0..255] of AnsiChar;
begin
Archive.FTempFileID := Archive.FTempFileID + 1;
if (Archive.TempDirectory <> '') then
AbStrPLCopy(TempPath, AnsiString(Archive.TempDirectory), Length(TempPath))
else
GetTempPathA(255, TempPath);
GetTempFileNameA(TempPath, 'VMS', Archive.FTempFileID, lpTempName);
Result := 1;
end;
{ == FDI Callback Functions - cdecl calling convention ===================== }
function FDI_FileOpen(lpPathName: PAnsiChar; Flag, Mode: Integer) : PtrInt;
cdecl;
{open a file}
begin
try
Result := PtrInt(TFileStream.Create(string(lpPathName), fmOpenRead or fmShareDenyWrite));
except on EFOpenError do
Result := -1;
end;
end;
{ -------------------------------------------------------------------------- }
function FDI_FileRead(hFile: PtrInt; lpBuffer: Pointer; uBytes: UINT) : UINT;
cdecl;
{read from a file}
begin
Result := TStream(hFile).Read(lpBuffer^, uBytes);
end;
{ -------------------------------------------------------------------------- }
function FDI_FileWrite(hFile: PtrInt; lpBuffer: Pointer; uBytes: UINT) : UINT;
cdecl;
{write to a file}
begin
Result := TStream(hFile).Write(lpBuffer^, uBytes);
end;
{ -------------------------------------------------------------------------- }
function FDI_FileClose(hFile : PtrInt) : Longint;
cdecl;
{close a file}
begin
try
TStream(hFile).Free;
Result := 0;
except
Result := -1;
end;
end;
{ -------------------------------------------------------------------------- }
function FDI_FileSeek(hFile : PtrInt; Offset : Longint; Origin : Integer) : Longint;
cdecl;
{reposition file pointer}
begin
Result := TStream(hFile).Seek(Offset, Origin);
end;
{ -------------------------------------------------------------------------- }
function FDI_EnumerateFiles(fdint : FDINOTIFICATIONTYPE;
pfdin : PFDINotification) : PtrInt;
cdecl;
{Enumerate the files and build the archive file list}
var
Item : TAbCabItem;
Archive : TAbCabArchive;
begin
Result := 0;
Archive := pfdin^.pv;
with Archive do case fdint of
FDINT_Cabinet_Info :
begin
FSetID := pfdin^.setID;
FCurrentCab := pfdin^.iCabinet;
FNextCabinet := string(pfdin^.psz1);
FNextDisk := string(pfdin^.psz2);
Result := 0;
end;
FDINT_Copy_File, FDINT_Partial_File :
begin
Item := TAbCabItem.Create;
with Item do begin
RawFileName := AnsiString(pfdin^.psz1);
if (pfdin^.attribs and faUTF8Name) = faUTF8Name then
Filename := UTF8ToString(RawFileName)
else
Filename := string(RawFileName);
UnCompressedSize := pfdin^.cb;
LastModFileDate := pfdin^.date;
LastModFileTime := pfdin^.time;
ExternalFileAttributes := pfdin^.attribs;
IsEncrypted := False; {encryption not implemented at this time}
PartialFile := (fdint = FDINT_Partial_File);
end;
FItemList.Add(Item);
Result := 0;
end;
end;
end;
{ -------------------------------------------------------------------------- }
function FDI_ExtractFiles(fdint : FDINOTIFICATIONTYPE;
pfdin : PFDINotification) : PtrInt;
cdecl;
{extract file from cabinet}
var
Archive : TAbCabArchive;
begin
Result := 0;
Archive := pfdin^.pv;
case fdint of
FDINT_Copy_File :
begin
if (AnsiString(pfdin^.psz1) = Archive.FItemInProgress.RawFileName) then
if Archive.FIIPName <> '' then
Result := Integer(TFileStream.Create(Archive.FIIPName, fmCreate))
else
Result := Integer(Archive.FItemStream)
else
Result := 0;
end;
FDINT_Next_Cabinet :
begin
if pfdin^.fdie = FDIError_None then
Result := 0
else
Result := -1;
end;
FDINT_Close_File_Info :
begin
if Archive.FIIPName <> '' then begin
FileSetDate(TFileStream(pfdin^.hf).Handle,
Longint(pfdin^.date) shl 16 + pfdin^.time);
TFileStream(pfdin^.hf).Free;
FileSetAttr(Archive.FIIPName, pfdin^.attribs);
end;
Result := 1;
end;
end;
end;
{ == TAbCabArchive ========================================================= }
function VerifyCab(const Fn : string) : TAbArchiveType;
var
Stream : TFileStream;
begin
Stream := TFileStream.Create(FN, fmOpenRead or fmShareDenyNone);
try
Result := VerifyCab(Stream);
finally
Stream.Free;
end;
end;
{ -------------------------------------------------------------------------- }
function VerifyCab(Strm : TStream) : TAbArchiveType; overload;
var
Context : HFDI;
Info : FDICabInfo;
Errors : CabErrorRecord;
StartPos : int64;
begin
Result := atUnknown;
Context := FDICreate(@FXI_GetMem, @FXI_FreeMem, @FDI_FileOpen,
@FDI_FileRead, @FDI_FileWrite, @FDI_FileClose, @FDI_FileSeek, cpuDefault,
@Errors);
if Context = nil then
Exit;
try
StartPos := Strm.Position;
if FDIIsCabinet(Context, Integer(Strm), @Info) then
Result := atCab;
Strm.Position := StartPos;
finally
FDIDestroy(Context);
end;
end;
{ == TAbCabArchive ========================================================= }
constructor TAbCabArchive.Create(const FileName : string; Mode : Word );
begin
{Mode is used to identify which interface to use: }
{ fmOpenWrite - FCI, fmOpenRead - FDI}
inherited CreateInit;
if (Mode and fmCreate) = fmCreate then FMode := fmOpenWrite
else FMode := Mode and fmOpenWrite;
FArchiveName := FileName;
FCabName := AnsiString(ExtractFileName(FileName));
FCabPath := AnsiString(ExtractFilePath(FileName));
SpanningThreshold := AbDefCabSpanningThreshold;
FFolderThreshold := AbDefFolderThreshold;
FItemInProgress := nil;
FItemProgress := 0;
end;
{ -------------------------------------------------------------------------- }
constructor TAbCabArchive.CreateFromStream(aStream : TStream;
const aArchiveName : string);
begin
raise EAbCabException.Create('TAbCabArchive does not support CreateFromStream');
end;
{ -------------------------------------------------------------------------- }
destructor TAbCabArchive.Destroy;
begin
CloseCabFile;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.Add(aItem : TAbArchiveItem);
{add a file to the cabinet}
var
Confirm, ItemAdded : Boolean;
Item : TAbCabItem;
begin
ItemAdded := False;
try
CheckValid;
if (FMode <> fmOpenWrite) then begin
DoProcessItemFailure(aItem, ptAdd, ecCabError, 0);
Exit;
end;
if FItemList.IsActiveDupe(aItem.FileName) then begin
DoProcessItemFailure(aItem, ptAdd, ecAbbrevia, AbDuplicateName);
Exit;
end;
DoConfirmProcessItem(aItem, ptAdd, Confirm);
if not Confirm then
Exit;
Item := TAbCabItem(aItem);
FItemInProgress := Item;
Item.Action := aaAdd;
Item.RawFileName := UTF8Encode(Item.FileName);
if not FCIAddFile(FFCIContext, Pointer(Item.DiskFileName),
PAnsiChar(Item.RawFileName), False, @FCI_GetNextCab, @FCI_Status,
@FCI_GetOpenInfo, CompressionTypeMap[FCompressionType]) then
raise EAbFCIAddFileError.Create;
FItemList.Add(Item);
ItemAdded := True;
FIsDirty := True;
finally
if not ItemAdded then
aItem.Free;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.CloseCabFile;
{Make sure the Cabinet DLL is shut down}
var
Abort : Boolean;
begin
if (FFDIContext <> nil) then begin
FDIDestroy(FFDIContext);
FFDIContext := nil;
end;
if (FFCIContext <> nil) then begin
FCIFlushCabinet(FFCIContext, False, @FCI_GetNextCab, @FCI_Status);
FCIDestroy(FFCIContext);
FFCIContext := nil;
end;
DoArchiveProgress(0, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.CreateCabFile;
{create a new cabinet}
begin
{set cabinet parameters}
with FFCICabInfo do begin
if (SpanningThreshold > 0) then
cb := SpanningThreshold
else
cb := AbDefCabSpanningThreshold;
if (FolderThreshold > 0) then
cbFolderThresh := FolderThreshold
else
cbFolderThresh := AbDefFolderThreshold;
cbReserveCFHeader := AbDefReserveHeaderSize;
cbReserveCFFolder := AbDefReserveFolderSize;
cbReserveCFData := AbDefReserveDataSize;
iCab := 1;
iDisk := 0;
fFailOnIncompressible := 0;
setID := SetID;
AbStrPCopy(szDisk, '');
AbStrPLCopy(szCab, FCabName, Length(szCab));
AbStrPLCopy(szCabPath, FCabPath, Length(szCabPath));
end;
{obtain an FCI context}
FFCIContext := FCICreate(@FErrors, @FCI_FileDest, @FXI_GetMem, @FXI_FreeMem,
@FCI_FileOpen, @FCI_FileRead, @FCI_FileWrite, @FCI_FileClose, @FCI_FileSeek,
@FCI_FileDelete, @FCI_GetTempFile, @FFCICabInfo, Self);
if (FFCIContext = nil) then
if FErrors.ErrorPresent then begin
CloseCabFile;
raise EAbFCICreateError.Create;
end;
end;
{ -------------------------------------------------------------------------- }
function TAbCabArchive.CreateItem( const FileSpec : string ): TAbArchiveItem;
{create a new item for the file list}
begin
Result := TAbCabItem.Create;
with TAbCabItem(Result) do begin
CompressedSize := 0;
DiskFileName := ExpandFileName(FileSpec);
FileName := FixName(FileSpec);
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.DoCabItemProgress(BytesCompressed : DWord;
var Abort : Boolean);
{fire OnCabItemProgress event}
var
Progress : Byte;
begin
Abort := False;
if Assigned(FOnArchiveItemProgress) then begin
Inc(FItemProgress, BytesCompressed);
Progress := AbPercentage(FItemProgress,
FItemInProgress.UnCompressedSize);
FOnArchiveItemProgress(Self, FItemInProgress, Progress, Abort);
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.DoGetNextCabinet(CabIndex : Integer;
var CabName : string; var Abort : Boolean);
{fire OnRequestImage event}
begin
Abort := False;
if Assigned(FOnRequestImage) then
FOnRequestImage(Self, CabIndex, CabName, Abort)
else
AbIncFilename(CabName, CabIndex);
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.ExtractItemAt(Index : Integer; const NewName : string);
{extract a file from the cabinet}
begin
FItemInProgress := GetItem(Index);
FIIPName := NewName;
try
if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,
@FDI_ExtractFiles, nil, Self) then
DoProcessItemFailure(FItemInProgress, ptExtract, ecCabError, FErrors.ErrorCode);
finally
FIIPName := '';
end;
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.ExtractItemToStreamAt(Index : Integer; OutStream : TStream);
begin
FItemInProgress := GetItem(Index);
FItemStream := OutStream;
try
if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,
@FDI_ExtractFiles, nil, Self) then
DoProcessItemFailure(FItemInProgress, ptExtract, ecCabError, FErrors.ErrorCode);
finally
FItemStream := nil;
end;
end;
{----------------------------------------------------------------------------}
function TAbCabArchive.GetItem(ItemIndex : Integer) : TAbCabItem;
{fetch an item from the file list}
begin
Result := TAbCabItem(FItemList.Items[ItemIndex]);
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.LoadArchive;
{Open existing cabinet or create a new one}
begin
if (FMode = fmOpenRead) then begin
FFDIContext := FDICreate(@FXI_GetMem, @FXI_FreeMem, @FDI_FileOpen,
@FDI_FileRead, @FDI_FileWrite, @FDI_FileClose, @FDI_FileSeek,
cpuDefault, @FErrors);
if (FFDIContext = nil) then
raise EAbFDICreateError.Create;
OpenCabFile;
end else
CreateCabFile;
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.NewCabinet;
{flush current cabinet and start a new one}
begin
if not FCIFlushCabinet(FFCIContext, True, @FCI_GetNextCab, @FCI_Status) then
raise EAbFCIFlushCabinetError.Create;
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.NewFolder;
{flush current folder and start a new one}
begin
if not FCIFlushFolder(FFCIContext, @FCI_GetNextCab, @FCI_Status) then
raise EAbFCIFlushFolderError.Create;
end;
{----------------------------------------------------------------------------}
procedure TAbCabArchive.OpenCabFile;
{Open an existing cabinet}
var
Abort : Boolean;
Stream : TFileStream;
begin
{verify that the archive can be opened and is a cabinet}
Stream := TFileStream.Create(FArchiveName, fmOpenRead or fmShareDenyNone);
try
if not FDIIsCabinet(FFDIContext, PtrInt(Stream), @FFDICabInfo) then begin
CloseCabFile;
raise EAbInvalidCabFile.Create;
end;
finally
Stream.Free;
end;
{store information about the cabinet}
FCabSize := FFDICabInfo.cbCabinet;
FFolderCount := FFDICabInfo.cFolders;
FFileCount := FFDICabInfo.cFiles;
FCurrentCab := FFDICabInfo.iCabinet;
FHasPrev := FFDICabInfo.hasPrev;
FHasNext := FFDICabInfo.hasNext;
{Enumerate the files and build the file list}
if not FDICopy(FFDIContext, PAnsiChar(FCabName), PAnsiChar(FCabPath), 0,
@FDI_EnumerateFiles, nil, Self) then begin
CloseCabFile;
raise EAbFDICopyError.Create;
end;
DoArchiveProgress(100, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.PutItem( Index : Integer; Value : TAbCabItem );
{replace an existing item in the file list}
begin
FItemList.Items[Index] := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.SaveArchive;
begin
{ No-op; file is flushed in destructor }
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.SetFolderThreshold(Value : LongWord);
{set maximum compression boundary}
begin
if (Value > 0) then
FFolderThreshold := Value
else
FFolderThreshold := AbDefFolderThreshold;
FFCICabInfo.cbFolderThresh := FFolderThreshold;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.SetSetID(Value : Word);
{set cabinet SetID}
begin
FSetID := Value;
FFCICabInfo.SetID := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.SetSpanningThreshold(Value : Int64);
{set maximum cabinet size}
begin
if (Value > 0) then
FSpanningThreshold := Value
else
FSpanningThreshold := AbDefCabSpanningThreshold;
FFCICabInfo.cb := FSpanningThreshold;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabArchive.TestItemAt(Index : Integer);
begin
{not implemented for cabinet archives}
end;
end.

View File

@@ -0,0 +1,343 @@
(* ***** 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
* Craig Peterson <capeterson@users.sourceforge.net>
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbCharset.pas *}
{*********************************************************}
{* ABBREVIA: Types and routines for working with various *}
{* character encodings. *}
{*********************************************************}
unit AbCharset;
{$I AbDefine.inc}
interface
{$IFDEF MSWINDOWS}
uses
Windows;
{$ENDIF}
{ Unicode backwards compatibility types }
{$IF NOT DECLARED(RawByteString)}
type
RawByteString = AnsiString;
{$IFEND}
{$IF NOT DECLARED(UnicodeString)}
type
UnicodeString = WideString;
{$IFEND}
type
TAbCharSet = (csASCII, csANSI, csUTF8);
function AbDetectCharSet(const aValue: RawByteString): TAbCharSet;
function AbIsOEM(const aValue: RawByteString): Boolean;
function AbRawBytesToString(const aValue: RawByteString): string;
function AbStringToUnixBytes(const aValue: string): RawByteString;
function AbSysCharSetIsUTF8: Boolean;
{$IFDEF MSWINDOWS}
function AbTryEncode(const aValue: UnicodeString; aCodePage: UINT;
aAllowBestFit: Boolean; out aResult: AnsiString): Boolean;
{$ENDIF}
{ Unicode backwards compatibility functions }
{$IFNDEF UNICODE}
function UTF8ToString(const S: RawByteString): string;
{$ENDIF}
implementation
uses
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
SysUtils;
function AbDetectCharSet(const aValue: RawByteString): TAbCharSet;
var
i, TrailCnt: Integer;
begin
Result := csASCII;
TrailCnt := 0;
for i := 1 to Length(aValue) do begin
if Byte(aValue[i]) >= $80 then
Result := csANSI;
if TrailCnt > 0 then
if Byte(aValue[i]) in [$80..$BF] then
Dec(TrailCnt)
else Exit
else if Byte(aValue[i]) in [$80..$BF] then
Exit
else
case Byte(aValue[i]) of
$C0..$C1, $F5..$FF: Exit;
$C2..$DF: TrailCnt := 1;
$E0..$EF: TrailCnt := 2;
$F0..$F4: TrailCnt := 3;
end;
end;
if (TrailCnt = 0) and (Result = csANSI) then
Result := csUTF8;
end;
{ -------------------------------------------------------------------------- }
function AbIsOEM(const aValue: RawByteString): Boolean;
// Detect whether a string of bytes is likely to be the system's ANSI or OEM codepage
{$IFDEF MSWINDOWS}
const
// Byte values of alpha-numeric characters in OEM and ANSI codepages.
// Excludes NBSP, ordinal indicators, exponents, the florin symbol, and, for
// ANSI codepages matched to certain OEM ones, the micro character.
//
// US (OEM 437, ANSI 1252)
Oem437AnsiChars =
[138, 140, 142, 154, 156, 158, 159, 181, 192..214, 216..246, 248..255];
Oem437OemChars =
[128..154, 160..165, 224..235, 237, 238];
// Arabic (OEM 720, ANSI 1256)
Oem720AnsiChars =
[129, 138, 140..144, 152, 154, 156, 159, 170, 181, 192..214, 216..239, 244,
249, 251, 252, 255];
Oem720OemChars =
[130, 131, 133, 135..140, 147, 149..155, 157..173, 224..239];
// Greek (OEM 737, ANSI 1253)
Oem737AnsiChars =
[162, 181, 184..186, 188, 190..209, 211..254];
Oem737OemChars =
[128..175, 224..240, 244, 245];
// Baltic Rim (OEM 775, ANSI 1257)
Oem775AnsiChars =
[168, 170, 175, 184, 186, 191..214, 216..246, 248..254];
Oem775OemChars =
[128..149, 151..155, 157, 160..165, 173, 181..184, 189, 190, 198, 199,
207..216, 224..238];
// Western European (OEM 850, ANSI 1252)
Oem850AnsiChars =
[138, 140, 142, 154, 156, 158, 159, 192..214, 216..246, 248..255];
Oem850OemChars =
[128..155, 157, 160..165, 181..183, 198, 199, 208..216, 222, 224..237];
// Central & Eastern European (OEM 852, ANSI 1250)
Oem852AnsiChars =
[138, 140..143, 154, 156..159, 163, 165, 170, 175, 179, 185, 186, 188,
190..214, 216..246, 248..254];
Oem852OemChars =
[128..157, 159..169, 171..173, 181..184, 189, 190, 198, 199, 208..216, 221,
222, 224..238, 251..253];
// Cyrillic (OEM 855, ANSI 1251)
Oem855AnsiChars =
[128, 129, 131, 138, 140..144, 154, 156..159, 161..163, 165, 168, 170, 175,
178..180, 184, 186, 188..255];
Oem855OemChars =
[128..173, 181..184, 189, 190, 198, 199, 208..216, 221, 222, 224..238,
241..252];
// Turkish (OEM 857, ANSI 1254)
Oem857AnsiChars =
[138, 140, 154, 156, 159, 192..214, 216..246, 248..255];
Oem857OemChars =
[128..155, 157..167, 181..183, 198, 199, 210..212, 214..216, 222, 224..230,
233..237];
// Hebrew (OEM 862, ANSI 1255)
Oem862AnsiChars =
[181, 212..214, 224..250];
Oem862OemChars =
[128..154, 160..165, 224..235, 237, 238];
// Cyrillic CIS (OEM 866, ANSI 1251)
Oem866AnsiChars =
[128, 129, 131, 138, 140..144, 154, 156..159, 161..163, 165, 168, 170, 175,
178..181, 184, 186, 188..255];
Oem866OemChars =
[128..175, 224..247];
var
AnsiChars, OemChars: set of Byte;
IsANSI: Boolean;
i: Integer;
begin
case GetOEMCP of
437:
begin
AnsiChars := Oem437AnsiChars;
OemChars := Oem437OemChars;
end;
720:
begin
AnsiChars := Oem720AnsiChars;
OemChars := Oem720OemChars;
end;
737:
begin
AnsiChars := Oem737AnsiChars;
OemChars := Oem737OemChars;
end;
775:
begin
AnsiChars := Oem775AnsiChars;
OemChars := Oem775OemChars;
end;
850:
begin
AnsiChars := Oem850AnsiChars;
OemChars := Oem850OemChars;
end;
852:
begin
AnsiChars := Oem852AnsiChars;
OemChars := Oem852OemChars;
end;
855:
begin
AnsiChars := Oem855AnsiChars;
OemChars := Oem855OemChars;
end;
857:
begin
AnsiChars := Oem857AnsiChars;
OemChars := Oem857OemChars;
end;
862:
begin
AnsiChars := Oem862AnsiChars;
OemChars := Oem862OemChars;
end;
866:
begin
AnsiChars := Oem866AnsiChars;
OemChars := Oem866OemChars;
end;
else
begin
Result := False;
Exit;
end;
end;
IsANSI := True;
Result := True;
for i := 0 to Length(aValue) do
if Ord(aValue[i]) >= $80 then
begin
if IsANSI then
IsANSI := Ord(aValue[i]) in AnsiChars;
if Result then
Result := Ord(aValue[i]) in OemChars;
if not IsANSI and not Result then
Break
end;
if IsANSI then
Result := False;
end;
{$ELSE !MSWINDOWS}
begin
Result := False;
end;
{$ENDIF !MSWINDOWS}
{ -------------------------------------------------------------------------- }
function AbSysCharSetIsUTF8: Boolean;
begin
{$IFDEF DARWIN}
Result := True;
{$ENDIF}
{$IFDEF MSWINDOWS}
Result := False;
{$ENDIF}
{$IFDEF LINUX}
Result := StrComp(nl_langinfo(_NL_CTYPE_CODESET_NAME), 'UTF-8') = 0;
{$ENDIF}
end;
{ -------------------------------------------------------------------------- }
function AbRawBytesToString(const aValue: RawByteString): string;
// Detect encoding of raw bytes and convert to a string
begin
case AbDetectCharSet(aValue) of
csASCII:
Result := string(aValue);
csANSI: begin
{$IFDEF MSWINDOWS}
if AbIsOEM(aValue) then begin
SetLength(Result, Length(aValue));
OemToCharBuff(PAnsiChar(aValue), PChar(Result), Length(Result));
end
else
{$ENDIF}
Result := string(aValue);
end;
csUTF8:
Result := UTF8ToString(aValue);
end;
end;
{ -------------------------------------------------------------------------- }
function AbStringToUnixBytes(const aValue: string): RawByteString;
// Convert from a string to an appropriate encoding for Unix archive types (tar/gz)
// Based on testing the system encoding should be used on Linux, and UTF-8
// everywhere else. Windows apps don't agree on whether to use ANSI, OEM, or UTF-8.
begin
// Delphi XE2+ Posix platforms only support the UTF-8 locale
{$IF DEFINED(LINUX) AND (DEFINED(FPC) OR DEFINED(KYLIX))}
Result := AnsiString(aValue);
{$ELSE}
Result := UTF8Encode(aValue);
{$IFEND}
end;
{ -------------------------------------------------------------------------- }
{$IFDEF MSWINDOWS}
function AbTryEncode(const aValue: UnicodeString; aCodePage: UINT;
aAllowBestFit: Boolean; out aResult: AnsiString): Boolean;
// Try to encode the given Unicode string as the requested codepage
const
WC_NO_BEST_FIT_CHARS = $00000400;
Flags: array[Boolean] of DWORD = (WC_NO_BEST_FIT_CHARS, 0);
var
UsedDefault: BOOL;
begin
if not aAllowBestFit and not CheckWin32Version(4, 1) then
Result := False
else begin
SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit],
PWideChar(aValue), Length(aValue), nil, 0, nil, @UsedDefault));
SetLength(aResult, WideCharToMultiByte(aCodePage, Flags[aAllowBestFit],
PWideChar(aValue), Length(aValue), PAnsiChar(aResult),
Length(aResult), nil, @UsedDefault));
Result := not UsedDefault;
end;
end;
{$ENDIF MSWINDOWS}
{ == Unicode backwards compatibility functions ============================= }
{$IFNDEF UNICODE}
function UTF8ToString(const S: RawByteString): string;
begin
Result := UTf8ToAnsi(S);
end;
{$ENDIF}
end.

File diff suppressed because it is too large Load Diff

2240
Abbrevia/source/AbCompnd.pas Normal file

File diff suppressed because it is too large Load Diff

220
Abbrevia/source/AbConst.pas Normal file
View File

@@ -0,0 +1,220 @@
(* ***** 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: AbConst.pas *}
{*********************************************************}
{* Abbrevia: Constants *}
{*********************************************************}
unit AbConst;
{$I AbDefine.inc}
interface
const
AbVersion = 5.0;
AbVersionS = '5.0';
Ab_MessageLen = 255;
Ab_CaptionLen = 80;
AB_ZIPPATHDELIM = '/';
const
AbZipVersionNeeded = 1;
AbUnknownCompressionMethod = 2;
AbNoExtractionMethod = 3;
AbInvalidPassword = 4;
AbNoInsertionMethod = 5;
AbInvalidFactor = 6;
AbDuplicateName = 7;
AbUnsupportedCompressionMethod = 8;
AbUserAbort = 9;
AbArchiveBusy = 10;
AbBadSpanStream = 11;
AbNoOverwriteSpanStream = 12;
AbNoSpannedSelfExtract = 13;
AbStreamFull = 14;
AbNoSuchDirectory = 15;
AbInflateBlockError = 16;
AbBadStreamType = 17;
AbTruncateError = 18;
AbZipBadCRC = 19;
AbZipBadStub = 20;
AbFileNotFound = 21;
AbInvalidLFH = 22;
AbNoArchive = 23;
AbErrZipInvalid = 24;
AbReadError = 25;
AbInvalidIndex = 26;
AbInvalidThreshold = 27;
AbUnhandledFileType = 28;
AbSpanningNotSupported = 29;
AbBBSReadTooManyBytes = 40;
AbBBSSeekOutsideBuffer = 41;
AbBBSInvalidOrigin = 42;
AbBBSWriteTooManyBytes = 43;
AbNoCabinetDllError = 50;
AbFCIFileOpenError = 51;
AbFCIFileReadError = 52;
AbFCIFileWriteError = 53;
AbFCIFileCloseError = 54;
AbFCIFileSeekError = 55;
AbFCIFileDeleteError = 56;
AbFCIAddFileError = 57;
AbFCICreateError = 58;
AbFCIFlushCabinetError = 59;
AbFCIFlushFolderError = 60;
AbFDICopyError = 61;
AbFDICreateError = 62;
AbInvalidCabTemplate = 63;
AbInvalidCabFile = 64;
AbSWSNotEndofStream = 80;
AbSWSSeekFailed = 81;
AbSWSWriteFailed = 82;
AbSWSInvalidOrigin = 83;
AbSWSInvalidNewOrigin = 84;
AbVMSReadTooManyBytes = 100;
AbVMSInvalidOrigin = 101;
AbVMSErrorOpenSwap = 102;
AbVMSSeekFail = 103;
AbVMSReadFail = 104;
AbVMSWriteFail = 105;
AbVMSWriteTooManyBytes = 106;
AbGZipInvalid = 200;
AbGzipBadCRC = 201;
AbGzipBadFileSize = 202;
AbTarInvalid = 220;
AbTarBadFileName = 221;
AbTarBadLinkName = 222;
AbTarBadOp = 223;
function AbStrRes(Index : Integer) : string;
implementation
uses
AbResString;
type
AbStrRec = record
ID: Integer;
Str: string;
end;
const
AbStrArray : array [0..66] of AbStrRec = (
(ID: AbZipVersionNeeded; Str: AbZipVersionNeededS),
(ID: AbUnknownCompressionMethod; Str: AbUnknownCompressionMethodS),
(ID: AbNoExtractionMethod; Str: AbNoExtractionMethodS),
(ID: AbInvalidPassword; Str: AbInvalidPasswordS),
(ID: AbNoInsertionMethod; Str: AbNoInsertionMethodS),
(ID: AbInvalidFactor; Str: AbInvalidFactorS),
(ID: AbDuplicateName; Str: AbDuplicateNameS),
(ID: AbUnsupportedCompressionMethod; Str: AbUnsupportedCompressionMethodS),
(ID: AbUserAbort; Str: AbUserAbortS),
(ID: AbArchiveBusy; Str: AbArchiveBusyS),
(ID: AbBadSpanStream; Str: AbBadSpanStreamS),
(ID: AbNoOverwriteSpanStream; Str: AbNoOverwriteSpanStreamS),
(ID: AbNoSpannedSelfExtract; Str: AbNoSpannedSelfExtractS),
(ID: AbStreamFull; Str: AbStreamFullS),
(ID: AbNoSuchDirectory; Str: AbNoSuchDirectoryS),
(ID: AbInflateBlockError; Str: AbInflateBlockErrorS),
(ID: AbBadStreamType; Str: AbBadStreamTypeS),
(ID: AbTruncateError; Str: AbTruncateErrorS),
(ID: AbZipBadCRC; Str: AbZipBadCRCS),
(ID: AbZipBadStub; Str: AbZipBadStubS),
(ID: AbFileNotFound; Str: AbFileNotFoundS),
(ID: AbInvalidLFH; Str: AbInvalidLFHS),
(ID: AbNoArchive; Str: AbNoArchiveS),
(ID: AbErrZipInvalid; Str: AbErrZipInvalidS),
(ID: AbReadError; Str: AbReadErrorS),
(ID: AbInvalidIndex; Str: AbInvalidIndexS),
(ID: AbInvalidThreshold; Str: AbInvalidThresholdS),
(ID: AbUnhandledFileType; Str: AbUnhandledFileTypeS),
(ID: AbSpanningNotSupported; Str: AbSpanningNotSupportedS),
(ID: AbBBSReadTooManyBytes; Str: AbBBSReadTooManyBytesS),
(ID: AbBBSSeekOutsideBuffer; Str: AbBBSSeekOutsideBufferS),
(ID: AbBBSInvalidOrigin; Str: AbBBSInvalidOriginS),
(ID: AbBBSWriteTooManyBytes; Str: AbBBSWriteTooManyBytesS),
(ID: AbNoCabinetDllError; Str: AbNoCabinetDllErrorS),
(ID: AbFCIFileOpenError; Str: AbFCIFileOpenErrorS),
(ID: AbFCIFileReadError; Str: AbFCIFileReadErrorS),
(ID: AbFCIFileWriteError; Str: AbFCIFileWriteErrorS),
(ID: AbFCIFileCloseError; Str: AbFCIFileCloseErrorS),
(ID: AbFCIFileSeekError; Str: AbFCIFileSeekErrorS),
(ID: AbFCIFileDeleteError; Str: AbFCIFileDeleteErrorS),
(ID: AbFCIAddFileError; Str: AbFCIAddFileErrorS),
(ID: AbFCICreateError; Str: AbFCICreateErrorS),
(ID: AbFCIFlushCabinetError; Str: AbFCIFlushCabinetErrorS),
(ID: AbFCIFlushFolderError; Str: AbFCIFlushFolderErrorS),
(ID: AbFDICopyError; Str: AbFDICopyErrorS),
(ID: AbFDICreateError; Str: AbFDICreateErrorS),
(ID: AbInvalidCabTemplate; Str: AbInvalidCabTemplateS),
(ID: AbInvalidCabFile; Str: AbInvalidCabFileS),
(ID: AbSWSNotEndofStream; Str: AbSWSNotEndofStreamS),
(ID: AbSWSSeekFailed; Str: AbSWSSeekFailedS),
(ID: AbSWSWriteFailed; Str: AbSWSWriteFailedS),
(ID: AbSWSInvalidOrigin; Str: AbSWSInvalidOriginS),
(ID: AbSWSInvalidNewOrigin; Str: AbSWSInvalidNewOriginS),
(ID: AbVMSReadTooManyBytes; Str: AbVMSReadTooManyBytesS),
(ID: AbVMSInvalidOrigin; Str: AbVMSInvalidOriginS),
(ID: AbVMSErrorOpenSwap; Str: AbVMSErrorOpenSwapS),
(ID: AbVMSSeekFail; Str: AbVMSSeekFailS),
(ID: AbVMSReadFail; Str: AbVMSReadFailS),
(ID: AbVMSWriteFail; Str: AbVMSWriteFailS),
(ID: AbVMSWriteTooManyBytes; Str: AbVMSWriteTooManyBytesS),
(ID: AbGzipInvalid; Str: AbGzipInvalidS),
(ID: AbGzipBadCRC; Str: AbGzipBadCRCS),
(ID: AbGzipBadFileSize; Str: AbGzipBadFileSizeS),
(ID: AbTarInvalid; Str: AbTarInvalidS),
(ID: AbTarBadFileName; Str: AbTarBadFileNameS),
(ID: AbTarBadLinkName; Str: AbTarBadLinkNameS),
(ID: AbTarBadOp; Str: AbTarBadOpS)
);
function AbStrRes(Index : Integer) : string;
var
i : Integer;
begin
for i := Low(AbStrArray) to High(AbStrArray) do
if AbStrArray[i].ID = Index then
Result := AbStrArray[i].Str;
end;
end.

184
Abbrevia/source/AbCrtl.pas Normal file
View File

@@ -0,0 +1,184 @@
(* ***** 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):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbCrtl.pas *}
{*********************************************************}
{* ABBREVIA: C++Builder C runtime functions *}
{*********************************************************}
unit AbCrtl;
{$I AbDefine.inc}
interface
uses
Windows;
type
UInt32 = LongWord;
size_t = {$IF defined(CPUX64)}Int64{$ELSE}Integer{$IFEND}; // NativeInt is 8 bytes in Delphi 2007
const
__turboFloat: LongInt = 0;
_fltused: LongInt = 0;
procedure abs; cdecl;
external 'msvcrt.dll';
procedure _llshl; cdecl;
external 'msvcrt.dll';
procedure _llushr; cdecl;
external 'msvcrt.dll';
procedure _ftol; cdecl;
external 'msvcrt.dll' {$IFDEF BCB}name '__ftol'{$ENDIF};
{ ctype.h declarations ===================================================== }
function isdigit(ch: Integer): Integer; cdecl;
{ string.h declarations ==================================================== }
function memcpy(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;
function memmove(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;
function memset(Dest: Pointer; Value: Byte; Count: size_t): Pointer; cdecl;
function strlen(P: PAnsiChar): Integer; cdecl;
function strcpy(Des, Src: PAnsiChar): PAnsiChar; cdecl;
function strncpy(Des, Src: PAnsiChar; MaxLen: Integer): PAnsiChar; cdecl;
function memcmp(s1,s2: Pointer; numBytes: LongWord): integer; cdecl;
external 'msvcrt.dll';
function wcscpy(strDestination, strSource: PWideChar): PWideChar; cdecl;
external 'msvcrt.dll';
{ stdlib.h declarations ==================================================== }
function malloc(Size: Integer): Pointer; cdecl;
procedure free(Ptr: Pointer); cdecl;
function realloc(Ptr: Pointer; Size: Integer): Pointer; cdecl;
{ intrin.h declarations ==================================================== }
procedure ___cpuid(CPUInfo: PInteger; InfoType: Integer); cdecl;
external 'msvcrt.dll';
{ stdio.h declarations ===================================================== }
function sprintf(S: PChar; const Format: PChar): Integer;
cdecl; varargs; external 'msvcrt.dll' {$IFDEF BCB}name '_sprintf'{$ENDIF};
{ process.h declarations =================================================== }
function _beginthreadex(security: Pointer; stack_size: Cardinal;
start_address: Pointer; arglist: Pointer; initflag: Cardinal;
var thrdaddr: Cardinal): THandle; cdecl;
{ MSVC/Win64 declarations ================================================== }
procedure __C_specific_handler; cdecl; external 'msvcrt.dll';
implementation
{ ctype.h declarations ===================================================== }
function isdigit(ch: Integer): Integer; cdecl;
begin
if AnsiChar(ch) in ['0'..'9'] then
Result := 1
else
Result := 0;
end;
{ string.h declarations ==================================================== }
function memcpy(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;
begin
System.Move(Src^, Dest^, Count);
Result := Dest;
end;
{ -------------------------------------------------------------------------- }
function memmove(Dest, Src: Pointer; Count: size_t): Pointer; cdecl;
begin
System.Move(Src^, Dest^, Count);
Result := Dest;
end;
{ -------------------------------------------------------------------------- }
function memset(Dest: Pointer; Value: Byte; Count: size_t): Pointer; cdecl;
begin
FillChar(Dest^, Count, Value);
Result := Dest;
end;
{ -------------------------------------------------------------------------- }
function strlen(P: PAnsiChar): Integer; cdecl;
{$IF RTLVersion >= 20}
asm
jmp System.@PCharLen
end;
{$ELSE}
begin
Result := 0;
while P^ <> #0 do
Inc(P);
end;
{$IFEND}
{ -------------------------------------------------------------------------- }
function strcpy(Des, Src: PAnsiChar): PAnsiChar; cdecl;
begin
Result := Des;
Move(Src^, Des^, strlen(Src) + 1);
end;
{ -------------------------------------------------------------------------- }
function strncpy(Des, Src: PAnsiChar; MaxLen: Integer): PAnsiChar; cdecl;
var
Len: Integer;
begin
Len := strlen(Src);
if Len > MaxLen then
Len := MaxLen;
Move(Src^, Des^, Len);
if Len < MaxLen then
FillChar(Des[Len], MaxLen - Len, 0);
Result := Des;
end;
{ stdlib.h declarations ==================================================== }
function malloc(Size: Integer): Pointer; cdecl;
begin
GetMem(Result, Size);
end;
{ -------------------------------------------------------------------------- }
procedure free(Ptr: Pointer); cdecl;
begin
FreeMem(Ptr)
end;
{ -------------------------------------------------------------------------- }
function realloc(Ptr: Pointer; Size: Integer): Pointer; cdecl;
begin
Result := ReallocMemory(Ptr, Size);
end;
{ process.h declarations =================================================== }
function _beginthreadex(security: Pointer; stack_size: Cardinal;
start_address: Pointer; arglist: Pointer; initflag: Cardinal;
var thrdaddr: Cardinal): THandle; cdecl;
begin
Result := CreateThread(security, stack_size, start_address, arglist,
initflag, thrdaddr);
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,293 @@
(* ***** 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: AbDefine.inc *}
{*********************************************************}
{* ABBREVIA: Compiler options/directives include file *}
{*********************************************************}
{NOTE: ABDEFINE.INC is included in all ABBREVIA units; hence you can
specify global compiler options here. ABDEFINE.INC is included
*before* each unit's own required compiler options, so options
specified here could be overridden by hardcoded options in the
unit source file.}
{====Compiler options that can be changed====}
{$A+ Force alignment on word/dword boundaries}
{$S- No stack checking}
{---Global compiler defines for 32-bit OS's---}
{====Global fixed compiler options (do NOT change)====}
{$B- Incomplete boolean evaluation}
{$H+ Long string support}
{$P- No open string parameters}
{$Q- Arithmetic overflow checking} {!! - Needs to be turned on!}
{$R- Range checking} {!! - Needs to be turned on!}
{$T+ No type-checked pointers}
{$V- No var string checking}
{$X+ Extended syntax}
{$Z1 Enumerations are byte sized}
{====Platform defines================================================}
{ map Delphi platform defines to FreePascal's (MSWINDOWS/UNIX/LINUX/DARWIN) }
{$IFNDEF FPC}
{$IF DEFINED(LINUX) AND (CompilerVersion < 15)}
{$DEFINE KYLIX}
{$DEFINE UNIX}
{$IFEND}
{$IFDEF MACOS}
{$DEFINE DARWIN}
{$ENDIF}
{$IFDEF POSIX}
{$DEFINE UNIX}
{$ENDIF}
{$ENDIF}
{ Unix API (Kylix/Delphi/FreePascal) }
{$IFDEF UNIX}
{$IF DEFINED(FPC)}
{$DEFINE FPCUnixAPI}
{$ELSEIF DEFINED(KYLIX)}
{$DEFINE LibcAPI}
{$ELSE}
{$DEFINE PosixAPI}
{$IFEND}
{$ENDIF}
{$IFDEF FPC}
{$MODE DELPHI}
{$PACKRECORDS C}
{$ENDIF}
{Activate this define to show CLX/LCL dialogs for spanning media requests. The
default behavior will abort the operation instead. This define is only safe
when using Abbrevia from the foreground thread. If using it from a background
thread override OnRequestLastDisk, OnRequestNthDisk, and OnRequestBlankDisk and
synchronize to the foreground yourself. The Windows version always MessageBox
so it's thread-safe.}
{.$DEFINE UnixDialogs}
{====RTL defines=====================================================}
{$IFNDEF FPC}
{$IF RTLVersion >= 18} // Delphi 2006
{$DEFINE HasAdvancedRecords}
{$IFEND}
{$IF RTLVersion >= 20} // Delphi 2009
{$DEFINE HasThreadFinished}
{$DEFINE HasInline}
{$IFEND}
{$IF RTLVersion >= 21} // Delphi 2010
{$DEFINE HasThreadStart}
{$IFEND}
{$IF RTLVersion >= 23} // Delphi XE2
{$DEFINE HasPlatformsAttribute}
{$IFEND}
{$ENDIF}
{====Widgetset defines===============================================}
{ VCL version specific defines }
{$IFNDEF FPC}
{$IF RTLVersion >= 17} // Delphi 2005
{$DEFINE HasOnMouseActivate}
{$IFEND}
{$IF RTLVersion >= 18} // Delphi 2006
{$DEFINE HasOnMouseEnter}
{$IFEND}
{$IF RTLVersion >= 20} // Delphi 2009
{$DEFINE HasListViewGroups}
{$DEFINE HasListViewOnItemChecked}
{$DEFINE HasParentDoubleBuffered}
{$DEFINE HasTreeViewExpandedImageIndex}
{$IFEND}
{$IF RTLVersion >= 21} // Delphi 2010
{$DEFINE HasGridDrawingStyle}
{$DEFINE HasTouch}
{$IFEND}
{$IF RTLVersion >= 24} // Delphi XE3
{$DEFINE HasUITypes}
{$IFEND}
{$IF RTLVersion >= 25} // Delphi XE4
{$DEFINE HasAnsiStrings}
{$IFEND}
{$ENDIF}
{====General defines=================================================}
{Activate the following define to include extra code to get rid of all
hints and warnings. Parts of ABBREVIA are written in such a way
that the hint/warning algorithms of the Delphi compilers are
fooled and report things like variables being used before
initialisation and so on when in reality the problem does not exist.}
{$DEFINE DefeatWarnings}
{ Disable warnings for explicit string casts }
{$IFDEF UNICODE}
{$WARN EXPLICIT_STRING_CAST OFF}
{$WARN EXPLICIT_STRING_CAST_LOSS OFF}
{$ENDIF}
{ Disable hints on Delphi XE2/Mac to prevent unexpanded inline messages }
{$IFDEF POSIX}
{$HINTS OFF}
{$ENDIF}
{====Bzip2 defines===================================================}
{Activate this define to statically link bzip2 .obj files into the application.
Curerntly only supported by Delphi/Win32.}
{.$DEFINE Bzip2Static}
{Activate this define to dynamically link to a libbz2.dll/libbbz2.so.1}
{.$DEFINE Bzip2Dynamic}
{Activate this define to load libbz2.dll/libbz2.so.1 at runtime using LoadLibrary}
{.$DEFINE Bzip2Runtime}
{Pick an appropriate linking method if none of the above are activate}
{$IF NOT DEFINED(Bzip2Static) AND NOT DEFINED(Bzip2Dynamic) AND NOT DEFINED(Bzip2Runtime)}
{$IFDEF FPC}
{$DEFINE Bzip2Runtime}
{$ELSE}
{$IFDEF MSWINDOWS}
{$DEFINE Bzip2Static}
{$ELSE}
{$DEFINE Bzip2Dynamic}
{$ENDIF}
{$ENDIF}
{$IFEND}
{====Zip defines=====================================================}
{Activate the following define when you don't want Visual parts of
the VCL library included for a program using a TAbArchive or
TAbZipArchive}
{.$DEFINE BuildingStub}
{Activate the following define to include support for extracting files
using PKzip compatible unShrink.}
{.$DEFINE UnzipShrinkSupport}
{Activate the following define to include support for extracting files
using PKZip compatible unReduce.}
{.$DEFINE UnzipReduceSupport}
{Activate the following define to include support for extracting files
using PKZip compatible unImplode.}
{.$DEFINE UnzipImplodeSupport}
{Activate the following to include support for extracting files using
all older PKZip compatible methods (Shrink, Reduce, Implode}
{$DEFINE UnzipBackwardSupport}
{Activate the following to include support for extracting files using
BZIP2 compression. Added in AppNote.txt v4.6. }
{.$DEFINE UnzipBzip2Support}
{Activate the following to include support for extracting files using
7-zip compatible Lzma compression. Added in AppNote.txt v6.3.}
{.$DEFINE UnzipLzmaSupport}
{Activate the following to include support for extracting files using
zipx PPMd I compression. Added in AppNote.txt v6.3.}
{.$DEFINE UnzipPPMdSupport}
{Activate the following to include support for extracting .wav files
using zipx WavPack compression. Requires copyright notice in your
documentation. Check "WavPack License.txt" for details.
Added in AppNote.txt v6.3. }
{.$DEFINE UnzipWavPackSupport}
{Activate the following to include support for extracting files using
all newer (zipx) compatible methods (Bzip2, Lzma, PPMd, WavPack)}
{$DEFINE UnzipZipxSupport}
{Activate the following to include logging support in the deflate/
inflate code. Since this logging support is a by-product of assertion
checking, you should only activate it if that is also on: $C+}
{$IFOPT C+} //if Assertions are on
{.$DEFINE UseLogging}
{$ENDIF}
{
According to
http://www.gzip.org/zlib/rfc1952.txt
A compliant gzip compressor should calculate and set the CRC32 and ISIZE.
However, a compliant decompressor should not check these values.
If you want to check the the values of the CRC32 and ISIZE in a GZIP file
when decompressing enable the STRICTGZIP define below. }
{.$DEFINE STRICTGZIP}
{ The following define is ONLY used for Abbrevia Unit Tests.
It has no effect on the Abbrevia Library.
If defined it uses Winzip to create and test archives for compatability.
The winzip tests require Systools stSpawn.pas
It can be downloaded at http://sf.net/projects/tpsystools }
{$IFDEF MSWINDOWS}
{.$DEFINE WINZIPTESTS}
{$ENDIF}
{-------- !! DO NOT CHANGE DEFINES BELOW THIS LINE !! --------}
{$IFDEF UnzipBackwardSupport}
{$DEFINE UnzipShrinkSupport}
{$DEFINE UnzipReduceSupport}
{$DEFINE UnzipImplodeSupport}
{$ENDIF}
{$IFDEF UnzipZipxSupport}
{$DEFINE UnzipBzip2Support}
{$DEFINE UnzipLzmaSupport}
{$DEFINE UnzipPPMdSupport}
{$DEFINE UnzipWavPackSupport}
{$ENDIF}
{ Linking .obj files isn't currently supported in Kylix or FPC }
{$IF DEFINED(FPC) OR NOT DEFINED(MSWINDOWS)}
{$UNDEF UnzipLzmaSupport}
{$UNDEF UnzipPPMdSupport}
{$UNDEF UnzipWavPackSupport}
{$IFEND}

View File

@@ -0,0 +1,819 @@
(* ***** 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: AbDfBase.pas *}
{*********************************************************}
{* Deflate base unit *}
{*********************************************************}
unit AbDfBase;
{$I AbDefine.inc}
interface
uses
SysUtils,
Classes;
type
PAbDfLongintList = ^TAbDfLongintList;
TAbDfLongintList =
array [0..pred(MaxInt div sizeof(longint))] of longint;
const
dfc_CodeLenCodeLength = 7;
dfc_LitDistCodeLength = 15;
dfc_MaxCodeLength = 15;
const
dfc_MaxMatchLen = 258; {lengths are 3..258 for deflate}
dfc_MaxMatchLen64 = 64 * 1024; {lengths are 3..65536 for deflate64}
const
dfc_LitExtraOffset = 257;
dfc_LitExtraBits : array [0..30] of byte =
(0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
4, 4, 4, 4, 5, 5, 5, 5, 16, 99, 99);
{ note: the last two are required to avoid going beyond the end}
{ of the array when generating static trees}
dfc_DistExtraOffset = 0;
dfc_DistExtraBits : array [0..31] of byte =
(0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
10, 10, 11, 11, 12, 12, 13, 13, 14, 14);
{ note: the last two are only use for deflate64}
dfc_LengthBase : array [0..28] of word =
(3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43,
51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 3);
{ note: the final 3 is correct for deflate64; for symbol 285,}
{ lengths are stored as (length - 3)}
{ for deflate it's very wrong, but there's special code in}
{ the (de)compression code to cater for this}
dfc_DistanceBase : array [0..31] of word =
(1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257,
385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289,
16385, 24577, 32769, 49153);
dfc_CodeLengthIndex : array [0..18] of byte =
(16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15);
const
dfc_CanUseStored = $01;
dfc_CanUseStatic = $02;
dfc_CanUseDynamic = $04;
dfc_UseLazyMatch = $08;
dfc_UseDeflate64 = $10;
dfc_UseAdler32 = $20;
dfc_CanUseHuffman = dfc_CanUseStatic or dfc_CanUseDynamic;
dfc_TestOnly = $40000000;
type
TAbProgressStep = procedure (aPercentDone : integer) of object;
{-progress metering of deflate/inflate; abort with AbortProgress}
TAbDeflateHelper = class
private
FAmpleLength : longint;
FChainLength : longint;
FLogFile : string;
FMaxLazy : longint;
FOnProgressStep : TAbProgressStep;
FOptions : longint;
FPartSize : Int64;
FSizeCompressed : Int64;
FSizeNormal : Int64;
FStreamSize : Int64;
FWindowSize : longint;
FZipOption : AnsiChar;
protected
procedure dhSetAmpleLength(aValue : longint);
procedure dhSetChainLength(aValue : longint);
procedure dhSetLogFile(const aValue : string);
procedure dhSetMaxLazy(aValue : longint);
procedure dhSetOnProgressStep(aValue : TAbProgressStep);
procedure dhSetOptions(aValue : longint);
procedure dhSetWindowSize(aValue : longint);
procedure dhSetZipOption(aValue : AnsiChar);
public
constructor Create;
procedure Assign(aHelper : TAbDeflateHelper);
property AmpleLength : longint
read FAmpleLength write dhSetAmpleLength;
property ChainLength : longint
read FChainLength write dhSetChainLength;
property LogFile : string
read FLogFile write dhSetLogFile;
property MaxLazyLength : longint
read FMaxLazy write dhSetMaxLazy;
property Options : longint
read FOptions write dhSetOptions;
property PartialSize : Int64
read FPartSize write FPartSize;
property PKZipOption : AnsiChar
read FZipOption write dhSetZipOption;
property StreamSize : Int64
read FStreamSize write FStreamSize;
property WindowSize : longint
read FWindowSize write dhSetWindowSize;
property CompressedSize : Int64
read FSizeCompressed write FSizeCompressed;
property NormalSize : Int64
read FSizeNormal write FSizeNormal;
property OnProgressStep : TAbProgressStep
read FOnProgressStep write dhSetOnProgressStep;
end;
type
TAbLineDelimiter = (ldCRLF, ldLF);
TAbLogger = class(TStream)
private
FBuffer : PAnsiChar;
FCurPos : PAnsiChar;
FLineDelim : TAbLineDelimiter;
FStream : TFileStream;
protected
function logWriteBuffer : boolean;
public
constructor Create(const aLogName : string);
destructor Destroy; override;
function Read(var Buffer; Count : longint) : longint; override;
function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;
function Write(const Buffer; Count : longint) : longint; override;
procedure WriteLine(const S : string);
procedure WriteStr(const S : string);
property LineDelimiter : TAbLineDelimiter
read FLineDelim write FLineDelim;
end;
type
TAbNodeManager = class
private
FFreeList : pointer;
FNodeSize : cardinal;
FNodesPerPage : cardinal;
FPageHead : pointer;
FPageSize : cardinal;
protected
function nmAllocNewPage : pointer;
public
constructor Create(aNodeSize : cardinal);
destructor Destroy; override;
function AllocNode : pointer;
function AllocNodeClear : pointer;
procedure FreeNode(aNode : pointer);
end;
{---exception classes---}
type
EAbAbortProgress = class(Exception);
EAbPartSizedInflate = class(Exception);
EAbInflatePasswordError = class(Exception);
EAbInternalInflateError = class(Exception);
EAbInflateError = class(Exception)
public
constructor Create(const aMsg : string);
constructor CreateUnknown(const aMsg : string;
const aErrorMsg : string);
end;
EAbInternalDeflateError = class(Exception);
EAbDeflateError = class(Exception)
public
constructor Create(const aMsg : string);
constructor CreateUnknown(const aMsg : string;
const aErrorMsg : string);
end;
{---aborting a process---}
procedure AbortProgress;
{---calculation of checksums---}
procedure AbUpdateAdlerBuffer(var aAdler : longint;
var aBuffer; aCount : integer);
procedure AbUpdateCRCBuffer(var aCRC : longint;
var aBuffer; aCount : integer);
implementation
uses
AbUtils;
{===TAbDeflateHelper=================================================}
constructor TAbDeflateHelper.Create;
begin
inherited Create;
FAmpleLength := 8;
FChainLength := 32;
{FLogFile := '';}
FMaxLazy := 16;
{FOnProgressStep := nil;}
FOptions := $F;
{FStreamSize := 0;}
FWindowSize := 32 * 1024;
FZipOption := 'n';
end;
{--------}
procedure TAbDeflateHelper.Assign(aHelper : TAbDeflateHelper);
begin
FAmpleLength := aHelper.FAmpleLength;
FChainLength := aHelper.FChainLength;
FLogFile := aHelper.FLogFile;
FMaxLazy := aHelper.FMaxLazy;
FOnProgressStep := aHelper.FOnProgressStep;
FOptions := aHelper.FOptions;
FPartSize := aHelper.FPartSize;
FStreamSize := aHelper.FStreamSize;
FWindowSize := aHelper.FWindowSize;
FZipOption := aHelper.FZipOption;
end;
{--------}
procedure TAbDeflateHelper.dhSetAmpleLength(aValue : longint);
begin
if (aValue <> AmpleLength) then begin
if (aValue <> -1) and (aValue < 4) then
aValue := 4;
FAmpleLength := aValue;
FZipOption := '?';
end;
end;
{--------}
procedure TAbDeflateHelper.dhSetChainLength(aValue : longint);
begin
if (aValue <> ChainLength) then begin
if (aValue <> -1) and (aValue < 4) then
aValue := 4;
FChainLength := aValue;
FZipOption := '?';
end;
end;
{--------}
procedure TAbDeflateHelper.dhSetLogFile(const aValue : string);
begin
FLogFile := aValue;
end;
{--------}
procedure TAbDeflateHelper.dhSetMaxLazy(aValue : longint);
begin
if (aValue <> MaxLazyLength) then begin
if (aValue <> -1) and (aValue < 4) then
aValue := 4;
FMaxLazy := aValue;
FZipOption := '?';
end;
end;
{--------}
procedure TAbDeflateHelper.dhSetOnProgressStep(aValue : TAbProgressStep);
begin
FOnProgressStep := aValue;
end;
{--------}
procedure TAbDeflateHelper.dhSetOptions(aValue : longint);
begin
if (aValue <> Options) then begin
FOptions := aValue;
FZipOption := '?';
end;
end;
{--------}
procedure TAbDeflateHelper.dhSetWindowSize(aValue : longint);
var
NewValue : longint;
begin
if (aValue <> WindowSize) then begin
{calculate the window size rounded to nearest 1024 bytes}
NewValue := ((aValue + 1023) div 1024) * 1024;
{if the new window size is greater than 32KB...}
if (NewValue > 32 * 1024) then
{if the Deflate64 option is set, force to 64KB}
if ((Options and dfc_UseDeflate64) <> 0) then
NewValue := 64 * 1024
{otherwise, force to 32KB}
else
NewValue := 32 * 1024;
{set the new window size}
FWindowSize := NewValue;
end;
end;
{--------}
procedure TAbDeflateHelper.dhSetZipOption(aValue : AnsiChar);
begin
{notes:
The original Abbrevia code used the following table for
setting the equivalent values:
Good Lazy Chain UseLazy Option
4 4 4 N s ^
4 5 8 N |
4 6 32 N f faster
4 4 16 Y slower
8 16 32 Y n |
8 16 128 Y |
8 32 256 Y |
32 128 1024 Y |
32 258 4096 Y x V
The new Abbrevia 3 code follows these values to a certain extent.
}
{force to lower case}
if ('A' <= aValue) and (aValue <= 'Z') then
aValue := AnsiChar(ord(aValue) + ord('a') - ord('A'));
{if the value has changed...}
if (aValue <> PKZipOption) then begin
{switch on the new value...}
case aValue of
'0' : {no compression}
begin
FZipOption := aValue;
FOptions := (FOptions and (not $0F)) or dfc_CanUseStored;
FAmpleLength := 8; { not actually needed}
FChainLength := 32; { not actually needed}
FMaxLazy := 16; { not actually needed}
end;
'2' : {hidden option: Abbrevia 2 compatibility}
begin
FZipOption := aValue;
FOptions := FOptions or $0F;
FAmpleLength := 8;
FChainLength := 32;
FMaxLazy := 16;
end;
'f' : {fast compression}
begin
FZipOption := aValue;
FOptions := FOptions or $07; { no lazy matching}
FAmpleLength := 4;
FChainLength := 32;
FMaxLazy := 6;
end;
'n' : {normal compression}
begin
FZipOption := aValue;
FOptions := FOptions or $0F;
FAmpleLength := 16;
FChainLength := 32;
FMaxLazy := 24;
end;
's' : {super fast compression}
begin
FZipOption := aValue;
FOptions := FOptions or $07; { no lazy matching}
FAmpleLength := 4;
FChainLength := 4;
FMaxLazy := 4;
end;
'x' : {maximum compression}
begin
FZipOption := aValue;
FOptions := FOptions or $0F;
FAmpleLength := 64;{32;}
FChainLength := 4096;
FMaxLazy := 258;
end;
end;
end;
end;
{====================================================================}
{===TAbLogger========================================================}
const
LogBufferSize = 4096;
{--------}
constructor TAbLogger.Create(const aLogName : string);
begin
Assert(aLogName <> '',
'TAbLogger.Create: a filename must be provided for the logger');
{create the ancestor}
inherited Create;
{set the default line terminator}
{$IFDEF MSWINDOWS}
FLineDelim := ldCRLF;
{$ENDIF}
{$IFDEF UNIX}
FLineDelim := ldLF;
{$ENDIF}
{create and initialize the buffer}
GetMem(FBuffer, LogBufferSize);
FCurPos := FBuffer;
{create the log file}
FStream := TFileStream.Create(aLogName, fmCreate);
end;
{--------}
destructor TAbLogger.Destroy;
begin
{if there is a buffer ensure that it is flushed before freeing it}
if (FBuffer <> nil) then begin
if (FCurPos <> FBuffer) then
logWriteBuffer;
FreeMem(FBuffer, LogBufferSize);
end;
{free the stream}
FStream.Free;
{destroy the ancestor}
inherited Destroy;
end;
{--------}
function TAbLogger.logWriteBuffer : boolean;
var
BytesToWrite : longint;
BytesWritten : longint;
begin
BytesToWrite := FCurPos - FBuffer;
BytesWritten := FStream.Write(FBuffer^, BytesToWrite);
if (BytesWritten = BytesToWrite) then begin
Result := true;
FCurPos := FBuffer;
end
else begin
Result := false;
if (BytesWritten <> 0) then begin
Move(FBuffer[BytesWritten], FBuffer^, BytesToWrite - BytesWritten);
FCurPos := FBuffer + (BytesToWrite - BytesWritten);
end;
end;
end;
{--------}
function TAbLogger.Read(var Buffer; Count : longint) : longint;
begin
Assert(false, 'TAbLogger.Read: loggers are write-only, no reading allowed');
Result := 0;
end;
{--------}
function TAbLogger.Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64;
begin
case Origin of
soBeginning :
begin
end;
soCurrent :
if (Offset = 0) then begin
Result := FStream.Position + (FCurPos - FBuffer);
Exit;
end;
soEnd :
if (Offset = 0) then begin
Result := FStream.Position + (FCurPos - FBuffer);
Exit;
end;
end;
Assert(false, 'TAbLogger.Seek: loggers are write-only, no seeking allowed');
Result := 0;
end;
{--------}
function TAbLogger.Write(const Buffer; Count : longint) : longint;
var
UserBuf : PAnsiChar;
BytesToGo : longint;
BytesToWrite : longint;
begin
{reference the user's buffer as a PChar}
UserBuf := @Buffer;
{start the counter for the number of bytes written}
Result := 0;
{if needed, empty the internal buffer into the underlying stream}
if (LogBufferSize = FCurPos - FBuffer) then
if not logWriteBuffer then
Exit;
{calculate the number of bytes to copy this time from the user's
buffer to the internal buffer}
BytesToGo := Count;
BytesToWrite := LogBufferSize - (FCurPos - FBuffer);
if (BytesToWrite > BytesToGo) then
BytesToWrite := BytesToGo;
{copy the bytes}
Move(UserBuf^, FCurPos^, BytesToWrite);
{adjust the counters}
inc(FCurPos, BytesToWrite);
dec(BytesToGo, BytesToWrite);
inc(Result, BytesToWrite);
{while there are still more bytes to copy, do so}
while (BytesToGo <> 0) do begin
{advance the user's buffer}
inc(UserBuf, BytesToWrite);
{empty the internal buffer into the underlying stream}
if not logWriteBuffer then
Exit;
{calculate the number of bytes to copy this time from the user's
buffer to the internal buffer}
BytesToWrite := LogBufferSize;
if (BytesToWrite > BytesToGo) then
BytesToWrite := BytesToGo;
{copy the bytes}
Move(UserBuf^, FCurPos^, BytesToWrite);
{adjust the counters}
inc(FCurPos, BytesToWrite);
dec(BytesToGo, BytesToWrite);
inc(Result, BytesToWrite);
end;
end;
{--------}
procedure TAbLogger.WriteLine(const S : string);
const
cLF : AnsiChar = ^J;
cCRLF : array [0..1] of AnsiChar = ^M^J;
begin
if (length(S) > 0) then
Write(S[1], length(S));
case FLineDelim of
ldLF : Write(cLF, sizeof(cLF));
ldCRLF : Write(cCRLF, sizeof(cCRLF));
end;
end;
{--------}
procedure TAbLogger.WriteStr(const S : string);
begin
if (length(S) > 0) then
Write(S[1], length(S));
end;
{====================================================================}
{===Calculate checksums==============================================}
procedure AbUpdateAdlerBuffer(var aAdler : longint;
var aBuffer; aCount : integer);
var
S1 : LongWord;
S2 : LongWord;
i : integer;
Buffer : PAnsiChar;
BytesToUse : integer;
begin
{Note: this algorithm will *only* work if the buffer is 4KB or less,
which is why we go to such lengths to chop up the user buffer
into usable chunks of 4KB.
However, for Delphi 3 there is no proper 32-bit longword.
Although the additions pose no problems in this situation,
the mod operations below (especially for S2) will be signed
integer divisions, producing an (invalid) signed result. In
this case, the buffer is chopped up into 2KB chunks to avoid
any signed problems.}
{split the current Adler checksum into its halves}
S1 := LongWord(aAdler) and $FFFF;
S2 := LongWord(aAdler) shr 16;
{reference the user buffer as a PChar: it makes it easier}
Buffer := @aBuffer;
{while there's still data to checksum...}
while (aCount <> 0) do begin
{calculate the number of bytes to checksum this time}
{$IFDEF HasLongWord}
BytesToUse := 4096;
{$ELSE}
BytesToUse := 2048;
{$ENDIF}
if (BytesToUse > aCount) then
BytesToUse := aCount;
{checksum the bytes}
for i := 0 to pred(BytesToUse) do begin
inc(S1, ord(Buffer^));
inc(S2, S1);
inc(Buffer);
end;
{recalibrate the Adler checksum halves}
S1 := S1 mod 65521;
S2 := S2 mod 65521;
{calculate the number of bytes still to go}
dec(aCount, BytesToUse);
end;
{join the halves to produce the complete Adler checksum}
aAdler := longint((S2 shl 16) or S1);
end;
{--------}
procedure AbUpdateCRCBuffer(var aCRC : longint;
var aBuffer; aCount : integer);
var
i : integer;
CRC : LongWord;
Buffer : PAnsiChar;
begin
{$R-}{$Q-}
{reference the user buffer as a PChar: it makes it easier}
Buffer := @aBuffer;
{get the current CRC as a local variable, it's faster}
CRC := aCRC;
{checksum the bytes in the buffer}
for i := 0 to pred(aCount) do begin
CRC := AbCrc32Table[byte(CRC) xor byte(Buffer^)] xor (CRC shr 8);
inc(Buffer);
end;
{return the new CRC}
aCRC := CRC;
{$R+}{$Q+}
end;
{====================================================================}
{===EAbInflateError==================================================}
constructor EAbInflateError.Create(const aMsg : string);
begin
inherited Create(
'Abbrevia inflate error, possibly a corrupted compressed stream. ' +
'(Internal cause: ' + aMsg + ')');
end;
{--------}
constructor EAbInflateError.CreateUnknown(const aMsg : string;
const aErrorMsg : string);
begin
inherited Create(aMsg + ': ' + aErrorMsg);
end;
{====================================================================}
{===EAbDeflateError==================================================}
constructor EAbDeflateError.Create(const aMsg : string);
begin
inherited Create(
'Abbrevia deflate error. ' +
'(Internal cause: ' + aMsg + ')');
end;
{--------}
constructor EAbDeflateError.CreateUnknown(const aMsg : string;
const aErrorMsg : string);
begin
inherited Create(aMsg + ': ' + aErrorMsg);
end;
{====================================================================}
{===Node manager=====================================================}
const
PageSize = 8 * 1024;
type
PGenericNode = ^TGenericNode;
TGenericNode = packed record
gnNext : PGenericNode;
gnData : record end;
end;
{--------}
constructor TAbNodeManager.Create(aNodeSize : cardinal);
const
Gran = sizeof(pointer);
Mask = not (Gran - 1);
begin
{create the ancestor}
inherited Create;
{save the node size rounded to nearest 4 bytes}
if (aNodeSize <= sizeof(pointer)) then
aNodeSize := sizeof(pointer)
else
aNodeSize := (aNodeSize + Gran - 1) and Mask;
FNodeSize := aNodeSize;
{calculate the page size (default 1024 bytes) and the number of
nodes per page; if the default page size is not large enough for
two or more nodes, force a single node per page}
FNodesPerPage := (PageSize - sizeof(pointer)) div aNodeSize;
if (FNodesPerPage > 1) then
FPageSize := PageSize
else begin
FNodesPerPage := 1;
FPagesize := aNodeSize + sizeof(pointer);
end;
end;
{--------}
destructor TAbNodeManager.Destroy;
var
Temp : pointer;
begin
{dispose of all the pages, if there are any}
while (FPageHead <> nil) do begin
Temp := PGenericNode(FPageHead)^.gnNext;
FreeMem(FPageHead, FPageSize);
FPageHead := Temp;
end;
{destroy the ancestor}
inherited Destroy;
end;
{--------}
function TAbNodeManager.AllocNode : pointer;
begin
Result := FFreeList;
if (Result = nil) then
Result := nmAllocNewPage
else
FFreeList := PGenericNode(Result)^.gnNext;
end;
{--------}
function TAbNodeManager.AllocNodeClear : pointer;
begin
Result := FFreeList;
if (Result = nil) then
Result := nmAllocNewPage
else
FFreeList := PGenericNode(Result)^.gnNext;
FillChar(Result^, FNodeSize, 0);
end;
{--------}
procedure TAbNodeManager.FreeNode(aNode : pointer);
begin
{add the node (if non-nil) to the top of the free list}
if (aNode <> nil) then begin
PGenericNode(aNode)^.gnNext := FFreeList;
FFreeList := aNode;
end;
end;
{--------}
function TAbNodeManager.nmAllocNewPage : pointer;
var
NewPage : PAnsiChar;
i : integer;
FreeList : pointer;
NodeSize : integer;
begin
{allocate a new page and add it to the front of the page list}
GetMem(NewPage, FPageSize);
PGenericNode(NewPage)^.gnNext := FPageHead;
FPageHead := NewPage;
{now split up the new page into nodes and push them all onto the
free list; note that the first 4 bytes of the page is a pointer to
the next page, so remember to skip over it}
inc(NewPage, sizeof(pointer));
FreeList := FFreeList;
NodeSize := FNodeSize;
for i := 0 to pred(FNodesPerPage) do begin
PGenericNode(NewPage)^.gnNext := FreeList;
FreeList := NewPage;
inc(NewPage, NodeSize);
end;
{return the top of the list}
Result := FreeList;
FFreeList := PGenericNode(Result)^.gnNext;
end;
{====================================================================}
{====================================================================}
procedure AbortProgress;
begin
raise EAbAbortProgress.Create('Abort');
end;
{====================================================================}
end.

View File

@@ -0,0 +1,634 @@
(* ***** 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: AbDfCryS.pas *}
{*********************************************************}
{* Deflate encryption streams *}
{*********************************************************}
unit AbDfCryS;
{$I AbDefine.inc}
interface
uses
Classes;
type
TAbZipEncryptHeader = array [0..11] of byte;
TAbZipDecryptEngine = class
private
FReady : boolean;
FState : array [0..2] of longint;
protected
procedure zdeInitState(const aPassphrase : AnsiString);
public
constructor Create;
function Decode(aCh : byte) : byte;
{-decodes a byte}
procedure DecodeBuffer(var aBuffer; aCount : integer);
{-decodes a buffer}
function VerifyHeader(const aHeader : TAbZipEncryptHeader;
const aPassphrase : AnsiString;
aCheckValue : longint) : boolean;
{-validate an encryption header}
end;
TAbDfDecryptStream = class(TStream)
private
FCheckValue : longint;
FEngine : TAbZipDecryptEngine;
FOwnsStream : Boolean;
FPassphrase : AnsiString;
FReady : boolean;
FStream : TStream;
protected
public
constructor Create(aStream : TStream;
aCheckValue : longint;
const aPassphrase : AnsiString);
destructor Destroy; override;
function IsValid : boolean;
function Read(var aBuffer; aCount : longint) : longint; override;
function Seek(aOffset : longint; aOrigin : word) : longint; override;
function Write(const aBuffer; aCount : longint) : longint; override;
property OwnsStream : Boolean
read FOwnsStream
write FOwnsStream;
end;
TAbZipEncryptEngine = class
private
FReady : boolean;
FState : array [0..2] of longint;
protected
procedure zeeInitState(const aPassphrase : AnsiString);
public
constructor Create;
function Encode(aCh : byte) : byte;
{-encodes a byte}
procedure EncodeBuffer(var aBuffer; aCount : integer);
{-encodes a buffer}
procedure CreateHeader(var aHeader : TAbZipEncryptHeader;
const aPassphrase : AnsiString;
aCheckValue : longint);
{-generate an encryption header}
end;
TAbDfEncryptStream = class(TStream)
private
FBuffer : PAnsiChar;
FBufSize : integer;
FEngine : TAbZipEncryptEngine;
FStream : TStream;
protected
public
constructor Create(aStream : TStream;
aCheckValue : longint;
const aPassphrase : AnsiString);
destructor Destroy; override;
function Read(var aBuffer; aCount : longint) : longint; override;
function Seek(aOffset : longint; aOrigin : word) : longint; override;
function Write(const aBuffer; aCount : longint) : longint; override;
end;
implementation
{Notes: the ZIP spec defines a couple of primitive routines for
performing encryption. For speed Abbrevia inlines them into
the respective methods of the encryption/decryption engines
char crc32(long,char)
return updated CRC from current CRC and next char
update_keys(char):
Key(0) <- crc32(key(0),char)
Key(1) <- Key(1) + (Key(0) & 000000ffH)
Key(1) <- Key(1) * 134775813 + 1
Key(2) <- crc32(key(2),key(1) >> 24)
end update_keys
char decrypt_byte()
local unsigned short temp
temp <- Key(2) | 2
decrypt_byte <- (temp * (temp ^ 1)) >> 8
end decrypt_byte
}
uses
AbUtils;
{---magic numbers from ZIP spec---}
const
StateInit1 = 305419896;
StateInit2 = 591751049;
StateInit3 = 878082192;
MagicNumber = 134775813;
{===internal encryption class========================================}
constructor TAbZipDecryptEngine.Create;
begin
{create the ancestor}
inherited Create;
{we're not ready for decryption yet since a header hasn't been
properly verified with VerifyHeader}
FReady := false;
end;
{--------}
function TAbZipDecryptEngine.Decode(aCh : byte) : byte;
var
Temp : longint;
begin
{check for programming error}
Assert(FReady,
'TAbZipDecryptEngine.Decode: must successfully call VerifyHeader first');
{calculate the decoded byte (uses inlined decrypt_byte)}
Temp := (FState[2] and $FFFF) or 2;
Result := aCh xor ((Temp * (Temp xor 1)) shr 8);
{mix the decoded byte into the state (uses inlined update_keys)}
FState[0] := AbUpdateCrc32(Result, FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
end;
{--------}
procedure TAbZipDecryptEngine.DecodeBuffer(var aBuffer; aCount : integer);
var
i : integer;
Temp : longint;
Buffer : PAnsiChar;
WorkState : array [0..2] of longint;
begin
{check for programming error}
Assert(FReady,
'TAbZipDecryptEngine.Decode: must successfully call VerifyHeader first');
{move the state to a local variable--for better speed}
WorkState[0] := FState[0];
WorkState[1] := FState[1];
WorkState[2] := FState[2];
{reference the buffer as a PChar--easier arithmetic}
Buffer := @aBuffer;
{for each byte in the buffer...}
for i := 0 to pred(aCount) do begin
{calculate the next decoded byte (uses inlined decrypt_byte)}
Temp := (WorkState[2] and $FFFF) or 2;
Buffer^ := AnsiChar(
byte(Buffer^) xor ((Temp * (Temp xor 1)) shr 8));
{mix the decoded byte into the state (uses inlined update_keys)}
WorkState[0] := AbUpdateCrc32(byte(Buffer^), WorkState[0]);
WorkState[1] := WorkState[1] + (WorkState[0] and $FF);
WorkState[1] := (WorkState[1] * MagicNumber) + 1;
WorkState[2] := AbUpdateCrc32(WorkState[1] shr 24, WorkState[2]);
{move onto the next byte}
inc(Buffer);
end;
{save the state}
FState[0] := WorkState[0];
FState[1] := WorkState[1];
FState[2] := WorkState[2];
end;
{--------}
function TAbZipDecryptEngine.VerifyHeader(const aHeader : TAbZipEncryptHeader;
const aPassphrase : AnsiString;
aCheckValue : longint) : boolean;
type
TLongAsBytes = packed record
L1, L2, L3, L4 : byte
end;
var
i : integer;
Temp : longint;
WorkHeader : TAbZipEncryptHeader;
begin
{check for programming errors}
Assert(aPassphrase <> '',
'TAbZipDecryptEngine.VerifyHeader: need a passphrase');
{initialize the decryption state}
zdeInitState(aPassphrase);
{decrypt the bytes in the header}
for i := 0 to 11 do begin
{calculate the next decoded byte (uses inlined decrypt_byte)}
Temp := (FState[2] and $FFFF) or 2;
WorkHeader[i] := aHeader[i] xor ((Temp * (Temp xor 1)) shr 8);
{mix the decoded byte into the state (uses inlined update_keys)}
FState[0] := AbUpdateCrc32(WorkHeader[i], FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
end;
{the header is valid if the twelfth byte of the decrypted header
equals the fourth byte of the check value}
Result := WorkHeader[11] = TLongAsBytes(aCheckValue).L4;
{note: zips created with PKZIP prior to version 2.0 also checked
that the tenth byte of the decrypted header equals the third
byte of the check value}
FReady := Result;
end;
{--------}
procedure TAbZipDecryptEngine.zdeInitState(const aPassphrase : AnsiString);
var
i : integer;
begin
{initialize the decryption state}
FState[0] := StateInit1;
FState[1] := StateInit2;
FState[2] := StateInit3;
{mix in the passphrase to the state (uses inlined update_keys)}
for i := 1 to length(aPassphrase) do begin
FState[0] := AbUpdateCrc32(byte(aPassphrase[i]), FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
end;
end;
{====================================================================}
{====================================================================}
constructor TAbDfDecryptStream.Create(aStream : TStream;
aCheckValue : longint;
const aPassphrase : AnsiString);
begin
{create the ancestor}
inherited Create;
{save the parameters}
FStream := aStream;
FCheckValue := aCheckValue;
FPassphrase := aPassphrase;
{create the decryption engine}
FEngine := TAbZipDecryptEngine.Create;
end;
{--------}
destructor TAbDfDecryptStream.Destroy; {new !!.02}
begin
FEngine.Free;
if FOwnsStream then
FStream.Free;
inherited Destroy;
end;
{--------}
function TAbDfDecryptStream.IsValid : boolean;
var
Header : TAbZipEncryptHeader;
begin
{read the header from the stream}
FStream.ReadBuffer(Header, sizeof(Header));
{check to see if the decryption engine agrees it's valid}
Result := FEngine.VerifyHeader(Header, FPassphrase, FCheckValue);
{if it isn't valid, reposition the stream, ready for the next try}
if not Result then begin
FStream.Seek(-sizeof(Header), soCurrent);
FReady := false;
end
{otherwise, the stream is ready for decrypting data}
else
FReady := true;
end;
{--------}
function TAbDfDecryptStream.Read(var aBuffer; aCount : longint) : longint;
begin
{check for programming error}
Assert(FReady,
'TAbDfDecryptStream.Read: the stream header has not been verified');
{read the data from the underlying stream}
Result := FStream.Read(aBuffer, aCount);
{decrypt the data}
FEngine.DecodeBuffer(aBuffer, Result);
end;
{--------}
function TAbDfDecryptStream.Seek(aOffset : longint; aOrigin : word) : longint;
begin
Result := FStream.Seek(aOffset, aOrigin);
end;
{--------}
function TAbDfDecryptStream.Write(const aBuffer; aCount : longint) : longint;
begin
{check for programming error}
Assert(false,
'TAbDfDecryptStream.Write: the stream is read-only');
Result := 0;
end;
{====================================================================}
{===TAbZipEncryptEngine==============================================}
constructor TAbZipEncryptEngine.Create;
begin
{create the ancestor}
inherited Create;
{we're not ready for encryption yet since a header hasn't been
properly generated with CreateHeader}
FReady := false;
end;
{--------}
procedure TAbZipEncryptEngine.CreateHeader(
var aHeader : TAbZipEncryptHeader;
const aPassphrase : AnsiString;
aCheckValue : longint);
type
TLongAsBytes = packed record
L1, L2, L3, L4 : byte
end;
var
Ch : byte;
i : integer;
Temp : longint;
WorkHeader : TAbZipEncryptHeader;
begin
{check for programming errors}
Assert(aPassphrase <> '',
'TAbZipEncryptEngine.CreateHeader: need a passphrase');
{set the first ten bytes of the header with random values (in fact,
we use a random value for each byte and mix it in with the state)}
{initialize the decryption state}
zeeInitState(aPassphrase);
{for the first ten bytes...}
for i := 0 to 9 do begin
{get a random value}
Ch := Random( 256 );
{calculate the XOR encoding byte (uses inlined decrypt_byte)}
Temp := (FState[2] and $FFFF) or 2;
Temp := (Temp * (Temp xor 1)) shr 8;
{mix the unencoded byte into the state (uses inlined update_keys)}
FState[0] := AbUpdateCrc32(Ch, FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
{set the current byte of the header}
WorkHeader[i] := Ch xor Temp;
end;
{now encrypt the first ten bytes of the header (this merely sets up
the state so that we can encrypt the last two bytes)}
{reinitialize the decryption state}
zeeInitState(aPassphrase);
{for the first ten bytes...}
for i := 0 to 9 do begin
{calculate the XOR encoding byte (uses inlined decrypt_byte)}
Temp := (FState[2] and $FFFF) or 2;
Temp := (Temp * (Temp xor 1)) shr 8;
{mix the unencoded byte into the state (uses inlined update_keys)}
FState[0] := AbUpdateCrc32(WorkHeader[i], FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
{set the current byte of the header}
WorkHeader[i] := WorkHeader[i] xor Temp;
end;
{now initialize byte 10 of the header, and encrypt it}
Ch := TLongAsBytes(aCheckValue).L3;
Temp := (FState[2] and $FFFF) or 2;
Temp := (Temp * (Temp xor 1)) shr 8;
FState[0] := AbUpdateCrc32(Ch, FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
WorkHeader[10] := Ch xor Temp;
{now initialize byte 11 of the header, and encrypt it}
Ch := TLongAsBytes(aCheckValue).L4;
Temp := (FState[2] and $FFFF) or 2;
Temp := (Temp * (Temp xor 1)) shr 8;
FState[0] := AbUpdateCrc32(Ch, FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
WorkHeader[11] := Ch xor Temp;
{we're now ready to encrypt}
FReady := true;
{return the header}
aHeader := WorkHeader;
end;
{--------}
function TAbZipEncryptEngine.Encode(aCh : byte) : byte;
var
Temp : longint;
begin
{check for programming error}
Assert(FReady,
'TAbZipEncryptEngine.Encode: must call CreateHeader first');
{calculate the encoded byte (uses inlined decrypt_byte)}
Temp := (FState[2] and $FFFF) or 2;
Result := aCh xor (Temp * (Temp xor 1)) shr 8;
{mix the unencoded byte into the state (uses inlined update_keys)}
FState[0] := AbUpdateCrc32(aCh, FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
end;
{--------}
procedure TAbZipEncryptEngine.EncodeBuffer(var aBuffer; aCount : integer);
var
Ch : byte;
i : integer;
Temp : longint;
Buffer : PAnsiChar;
WorkState : array [0..2] of longint;
begin
{check for programming error}
Assert(FReady,
'TAbZipEncryptEngine.EncodeBuffer: must call CreateHeader first');
{move the state to a local variable--for better speed}
WorkState[0] := FState[0];
WorkState[1] := FState[1];
WorkState[2] := FState[2];
{reference the buffer as a PChar--easier arithmetic}
Buffer := @aBuffer;
{for each byte in the buffer...}
for i := 0 to pred(aCount) do begin
{calculate the next encoded byte (uses inlined decrypt_byte)}
Temp := (WorkState[2] and $FFFF) or 2;
Ch := byte(Buffer^);
Buffer^ := AnsiChar(Ch xor ((Temp * (Temp xor 1)) shr 8));
{mix the decoded byte into the state (uses inlined update_keys)}
WorkState[0] := AbUpdateCrc32(Ch, WorkState[0]);
WorkState[1] := WorkState[1] + (WorkState[0] and $FF);
WorkState[1] := (WorkState[1] * MagicNumber) + 1;
WorkState[2] := AbUpdateCrc32(WorkState[1] shr 24, WorkState[2]);
{move onto the next byte}
inc(Buffer);
end;
{save the state}
FState[0] := WorkState[0];
FState[1] := WorkState[1];
FState[2] := WorkState[2];
end;
{--------}
procedure TAbZipEncryptEngine.zeeInitState(const aPassphrase : AnsiString);
var
i : integer;
begin
{initialize the decryption state}
FState[0] := StateInit1;
FState[1] := StateInit2;
FState[2] := StateInit3;
{mix in the passphrase to the state (uses inlined update_keys)}
for i := 1 to length(aPassphrase) do begin
FState[0] := AbUpdateCrc32(byte(aPassphrase[i]), FState[0]);
FState[1] := FState[1] + (FState[0] and $FF);
FState[1] := (FState[1] * MagicNumber) + 1;
FState[2] := AbUpdateCrc32(FState[1] shr 24, FState[2]);
end;
end;
{====================================================================}
{===TAbDfEncryptStream===============================================}
constructor TAbDfEncryptStream.Create(aStream : TStream;
aCheckValue : longint;
const aPassphrase : AnsiString);
var
Header : TAbZipEncryptHeader;
begin
{create the ancestor}
inherited Create;
{save the stream parameter}
FStream := aStream;
{create the encryption engine}
FEngine := TAbZipEncryptEngine.Create;
{generate the encryption header, write it to the stream}
FEngine.CreateHeader(Header, aPassphrase, aCheckValue);
aStream.WriteBuffer(Header, sizeof(Header));
end;
{--------}
destructor TAbDfEncryptStream.Destroy;
begin
{free the internal buffer if used}
if (FBuffer <> nil) then
FreeMem(FBuffer);
{free the engine}
FEngine.Free;
{destroy the ancestor}
inherited Destroy;
end;
{--------}
function TAbDfEncryptStream.Read(var aBuffer; aCount : longint) : longint;
begin
{check for programming error}
Assert(false,
'TAbDfEncryptStream.Read: the stream is write-only');
Result := 0;
end;
{--------}
function TAbDfEncryptStream.Seek(aOffset : longint; aOrigin : word) : longint;
begin
Result := FStream.Seek(aOffset, aOrigin);
end;
{--------}
function TAbDfEncryptStream.Write(const aBuffer; aCount : longint) : longint;
begin
{note: since we cannot alter a const parameter, we should copy the
data to our own buffer, encrypt it and then write it}
{check that our buffer is large enough}
if (FBufSize < aCount) then begin
if (FBuffer <> nil) then
FreeMem(FBuffer);
GetMem(FBuffer, aCount);
FBufSize := aCount;
end;
{copy the data to our buffer}
Move(aBuffer, FBuffer^, aCount);
{encrypt the data in our buffer}
FEngine.EncodeBuffer(FBuffer^, aCount);
{write the data in our buffer to the underlying stream}
Result := FStream.Write(FBuffer^, aCount);
end;
{====================================================================}
end.

822
Abbrevia/source/AbDfDec.pas Normal file
View File

@@ -0,0 +1,822 @@
(* ***** 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: AbDfDec.pas *}
{*********************************************************}
{* Deflate decoding unit *}
{*********************************************************}
unit AbDfDec;
{$I AbDefine.inc}
interface
uses
Classes,
AbDfBase;
function Inflate(aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper) : longint;
implementation
uses
SysUtils,
AbDfStrm,
AbDfHufD,
AbDfOutW,
AbDfCryS;
{===Helper routines==================================================}
procedure ReadLitDistCodeLengths(aInStrm : TAbDfInBitStream;
aCodeLenTree : TAbDfDecodeHuffmanTree;
var aCodeLens : array of integer;
aCount : integer;
var aTotalBits : integer);
var
i : integer;
SymbolCount : integer;
LookupValue : integer;
EncodedSymbol : longint;
Symbol : integer;
SymbolCodeLen : integer;
RepeatCount : integer;
BitBuffer : TAb32bit;
BitCount : integer;
begin
{$IFDEF UseLogging}
{we need to calculate the total number of bits in the code lengths
for reporting purposes, so zero the count}
aTotalBits := 0;
{$ENDIF}
{clear the code lengths array}
FillChar(aCodeLens, sizeof(aCodeLens), 0);
{read all the Symbols required in the bit stream}
SymbolCount := 0;
while (SymbolCount < aCount) do begin
{grab the lookup set of bits}
BitCount := aCodeLenTree.LookupBitLength + 7;
{$IFOPT C+}
BitBuffer := aInStrm.PeekBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
BitBuffer := aInStrm.PeekMoreBits(BitCount)
else
BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];
{$ENDIF}
LookupValue :=
BitBuffer and AbExtractMask[aCodeLenTree.LookupBitLength];
{get the encoded Symbol}
{$IFOPT C+} {if Assertions are on}
EncodedSymbol := aCodeLenTree.Decode(LookupValue);
{$ELSE}
EncodedSymbol := aCodeLenTree.Decodes^[LookupValue];
{$ENDIF}
{extract the data}
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
{$IFDEF UseLogging}
{keep count of the total number of bits read}
inc(aTotalBits, SymbolCodeLen);
{$ENDIF}
{check that the symbol is between 0 and 18}
if not ((0 <= Symbol) and (Symbol <= 18)) then
raise EAbInternalInflateError.Create(
'decoded a symbol not between 0 and 18 {ReadLitDistCodeLengths}');
{check that the codelength is in range}
if not ((0 < SymbolCodeLen) and
(SymbolCodeLen <= aCodeLenTree.LookupBitLength)) then
raise EAbInternalInflateError.Create(
'decoded a code length out of range {ReadLitDistCodeLengths}');
{for a Symbol of 0..15, just save the value}
if (Symbol <= 15) then begin
aCodeLens[SymbolCount] := Symbol;
inc(SymbolCount);
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end
{for a Symbol of 16, get two more bits and copy the previous
code length that many times + 3}
else if (Symbol = 16) then begin
RepeatCount := 3 + ((BitBuffer shr SymbolCodeLen) and $3);
Symbol := aCodeLens[SymbolCount-1];
for i := 0 to pred(RepeatCount) do
aCodeLens[SymbolCount+i] := Symbol;
inc(SymbolCount, RepeatCount);
BitCount := SymbolCodeLen + 2;
{$IFOPT C+}
aInStrm.DiscardBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
aInStrm.DiscardMoreBits(BitCount)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;
aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;
end;
{$ENDIF}
{$IFDEF UseLogging}
inc(aTotalBits, 2);
{$ENDIF}
end
{for a Symbol of 17, get three more bits and copy a zero code
length that many times + 3}
else if (Symbol = 17) then begin
RepeatCount := 3 + ((BitBuffer shr SymbolCodeLen) and $7);
{note: the codelengths array was aet to zeros at the start so
the following two lines are not needed
for i := 0 to pred(RepeatCount) do
aCodeLens[SymbolCount+i] := 0;}
inc(SymbolCount, RepeatCount);
BitCount := SymbolCodeLen + 3;
{$IFOPT C+}
aInStrm.DiscardBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
aInStrm.DiscardMoreBits(BitCount)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;
aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;
end;
{$ENDIF}
{$IFDEF UseLogging}
inc(aTotalBits, 3);
{$ENDIF}
end
{for a Symbol of 18, get seven more bits and copy a zero code
length that many times + 11}
else if (Symbol = 18) then begin
RepeatCount := 11 + ((BitBuffer shr SymbolCodeLen) and $7F);
{note: the codelengths array was aet to zeros at the start so
the following two lines are not needed
for i := 0 to pred(RepeatCount) do
aCodeLens[SymbolCount+i] := 0;}
inc(SymbolCount, RepeatCount);
BitCount := SymbolCodeLen + 7;
{$IFOPT C+}
aInStrm.DiscardBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
aInStrm.DiscardMoreBits(BitCount)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;
aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;
end;
{$ENDIF}
{$IFDEF UseLogging}
inc(aTotalBits, 7);
{$ENDIF}
end;
end;
end;
{--------}
procedure DecodeData(aInStrm : TAbDfInBitStream;
aOutWindow : TAbDfOutputWindow;
aLiteralTree : TAbDfDecodeHuffmanTree;
aDistanceTree : TAbDfDecodeHuffmanTree;
aDeflate64 : boolean);
var
LookupValue : integer;
EncodedSymbol : longint;
Symbol : integer;
SymbolCodeLen : integer;
ExtraBitCount : integer;
Length : integer;
Distance : integer;
BitBuffer : TAb32bit;
BitCount : integer;
begin
{extract the first symbol (it's got to be a literal/length symbol)}
{..grab the lookup set of bits}
if aDeflate64 then
BitCount := aLiteralTree.LookupBitLength + 16
else
BitCount := aLiteralTree.LookupBitLength + 5;
{$IFOPT C+}
BitBuffer := aInStrm.PeekBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
BitBuffer := aInStrm.PeekMoreBits(BitCount)
else
BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];
{$ENDIF}
LookupValue :=
BitBuffer and AbExtractMask[aLiteralTree.LookupBitLength];
{..get the encoded symbol}
{$IFOPT C+} {if Assertions are on}
EncodedSymbol := aLiteralTree.Decode(LookupValue);
{$ELSE}
EncodedSymbol := aLiteralTree.Decodes^[LookupValue];
{$ENDIF}
{..extract the data}
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
// ExtraBitCount := EncodedSymbol shr 24;
{repeat until we get the end-of-block symbol}
while ((Symbol <> 256) {and (ExtraBitCount <> 15)}) do begin
{for a literal, just output it to the sliding window}
if (Symbol < 256) then begin
aOutWindow.AddLiteral(AnsiChar(Symbol));
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end
{for a length value, we need to get any extra bits, and then the
distance (plus any extra bits for that), and then add the
duplicated characters to the sliding window}
else begin
{check that the length symbol is less than or equal to 285}
if (Symbol > 285) then
raise EAbInternalInflateError.Create(
'decoded an invalid length symbol: greater than 285 [DecodeData]');
{calculate the length (if need be, by calculating the number of
extra bits that encode the length)}
if (not aDeflate64) and (Symbol = 285) then begin
Length := 258;
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end
else begin
ExtraBitCount := EncodedSymbol shr 24;
if (ExtraBitCount = 0) then begin
Length := dfc_LengthBase[Symbol - 257];
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end
else begin
Length := dfc_LengthBase[Symbol - 257] +
((BitBuffer shr SymbolCodeLen) and
AbExtractMask[ExtraBitCount]);
BitCount := SymbolCodeLen + ExtraBitCount;
{$IFOPT C+}
aInStrm.DiscardBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
aInStrm.DiscardMoreBits(BitCount)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;
aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;
end;
{$ENDIF}
end;
end;
{extract the distance}
{..grab the lookup set of bits}
BitCount := aDistanceTree.LookupBitLength + 14;
{$IFOPT C+}
BitBuffer := aInStrm.PeekBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
BitBuffer := aInStrm.PeekMoreBits(BitCount)
else
BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];
{$ENDIF}
LookupValue :=
BitBuffer and AbExtractMask[aDistanceTree.LookupBitLength];
{..get the encoded symbol}
{$IFOPT C+} {if Assertions are on}
EncodedSymbol := aDistanceTree.Decode(LookupValue);
{$ELSE}
EncodedSymbol := aDistanceTree.Decodes^[LookupValue];
{$ENDIF}
{..extract the data}
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
{check that the distance symbol is less than or equal to 29}
if (not aDeflate64) and (Symbol > 29) then
raise EAbInternalInflateError.Create(
'decoded an invalid distance symbol: greater than 29 [DecodeData]');
{..calculate the extra bits for the distance}
ExtraBitCount := EncodedSymbol shr 24;
{..calculate the distance}
if (ExtraBitCount = 0) then begin
Distance := dfc_DistanceBase[Symbol];
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end
else begin
Distance := dfc_DistanceBase[Symbol] +
((BitBuffer shr SymbolCodeLen) and
AbExtractMask[ExtraBitCount]);
BitCount := SymbolCodeLen + ExtraBitCount;
{$IFOPT C+}
aInStrm.DiscardBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
aInStrm.DiscardMoreBits(BitCount)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr BitCount;
aInStrm.BitsLeft := aInStrm.BitsLeft - BitCount;
end;
{$ENDIF}
end;
{duplicate the characters in the sliding window}
aOutWindow.AddLenDist(Length, Distance);
end;
{extract the next symbol}
{..grab the lookup set of bits}
if aDeflate64 then
BitCount := aLiteralTree.LookupBitLength + 16
else
BitCount := aLiteralTree.LookupBitLength + 5;
{$IFOPT C+}
BitBuffer := aInStrm.PeekBits(BitCount);
{$ELSE}
if (aInStrm.BitsLeft < BitCount) then
BitBuffer := aInStrm.PeekMoreBits(BitCount)
else
BitBuffer := aInStrm.BitBuffer and AbExtractMask[BitCount];
{$ENDIF}
LookupValue :=
BitBuffer and AbExtractMask[aLiteralTree.LookupBitLength];
{..get the encoded symbol}
{$IFOPT C+} {if Assertions are on}
EncodedSymbol := aLiteralTree.Decode(LookupValue);
{$ELSE}
EncodedSymbol := aLiteralTree.Decodes^[LookupValue];
{$ENDIF}
{..extract the data}
Symbol := EncodedSymbol and $FFFF;
SymbolCodeLen := (EncodedSymbol shr 16) and $FF;
end;
{discard the bits for the end-of-block marker}
{$IFOPT C+}
aInStrm.DiscardBits(SymbolCodeLen);
{$ELSE}
if (aInStrm.BitsLeft < SymbolCodeLen) then
aInStrm.DiscardMoreBits(SymbolCodeLen)
else begin
aInStrm.BitBuffer := aInStrm.BitBuffer shr SymbolCodeLen;
aInStrm.BitsLeft := aInStrm.BitsLeft - SymbolCodeLen;
end;
{$ENDIF}
end;
{--------}
procedure InflateStoredBlock(aInStrm : TAbDfInBitStream;
aOutWindow : TAbDfOutputWindow;
aLog : TAbLogger);
const
BufferSize = 16 * 1024;
var
LenNotLen : packed record
Len : word;
NotLen : word;
end;
BytesToGo : integer;
BytesToWrite : integer;
Buffer : pointer;
begin
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine('....a stored block');
{$ENDIF}
{align the input bit stream to the nearest byte boundary}
aInStrm.AlignToByte;
{read the length of the stored data and the notted length}
aInStrm.ReadBuffer(LenNotLen, sizeof(LenNotLen));
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine(Format('..block length: %d (%-4x, NOT %-4x)',
[LenNotLen.Len, LenNotLen.Len, LenNotLen.NotLen]));
{$ENDIF}
{check that NOT of the length equals the notted length}
if ((not LenNotLen.Len) <> LenNotLen.NotLen) then
raise EAbInternalInflateError.Create(
'invalid stored block (length and NOT length do not match) [InflateStoredBlock]');
{calculate the number of bytes to copy from the stored block}
BytesToGo := LenNotLen.Len;
{allocate a large buffer}
GetMem(Buffer, BufferSize);
{copy all the data in the stored block to the output window}
try
{while there are still some bytes to copy...}
while (BytesToGo <> 0) do begin
{calculate the number of bytes this time}
if (BytesToGo > BufferSize) then
BytesToWrite := BufferSize
else
BytesToWrite := BytesToGo;
{read that many bytes and write them to the output window}
aInStrm.ReadBuffer(Buffer^, BytesToWrite);
aOutWindow.AddBuffer(Buffer^, BytesToWrite);
{calculate the number of bytes still to copy}
dec(BytesToGo, BytesToWrite);
end;
finally
FreeMem(Buffer);
end;
end;
{--------}
procedure InflateStaticBlock(aInStrm : TAbDfInBitStream;
aOutWindow : TAbDfOutputWindow;
aLog : TAbLogger;
aDeflate64 : boolean);
begin
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine('....a static huffman tree block');
{$ENDIF}
{decode the data with the static trees}
DecodeData(aInStrm, aOutWindow,
AbStaticLiteralTree, AbStaticDistanceTree, aDeflate64);
end;
{--------}
procedure InflateDynamicBlock(aInStrm : TAbDfInBitStream;
aOutWindow : TAbDfOutputWindow;
aLog : TAbLogger;
aDeflate64 : boolean);
var
i : integer;
LitCount : integer;
DistCount : integer;
CodeLenCount : integer;
CodeLens : array [0..285+32] of integer;
CodeLenTree : TAbDfDecodeHuffmanTree;
LiteralTree : TAbDfDecodeHuffmanTree;
DistanceTree : TAbDfDecodeHuffmanTree;
TotalBits : integer;
begin
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine('....a dynamic huffman tree block');
{$ENDIF}
{prepare for the try..finally}
CodeLenTree := nil;
LiteralTree := nil;
DistanceTree := nil;
try
{decode the number of literal, distance and codelength codes}
LitCount := aInStrm.ReadBits(5) + 257;
DistCount := aInStrm.ReadBits(5) + 1;
CodeLenCount := aInStrm.ReadBits(4) + 4;
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then begin
aLog.WriteLine(Format('Count of literals: %d', [LitCount]));
aLog.WriteLine(Format('Count of distances: %d', [DistCount]));
aLog.WriteLine(Format('Count of code lengths: %d', [CodeLenCount]));
end;
{$ENDIF}
{verify that the counts are valid}
if (LitCount > 286) then
raise EAbInternalInflateError.Create(
'count of literal codes in dynamic block is greater than 286 [InflateDynamicBlock]');
if (not aDeflate64) and (DistCount > 30) then
raise EAbInternalInflateError.Create(
'count of distance codes in dynamic block is greater than 30 [InflateDynamicBlock]');
{read the codelengths}
FillChar(CodeLens, 19 * sizeof(integer), 0);
for i := 0 to pred(CodeLenCount) do
CodeLens[dfc_CodeLengthIndex[i]] := aInStrm.ReadBits(3);
{$IFDEF UseLogging}
{log them}
if (aLog <> nil) then begin
aLog.WriteLine('CodeLength Huffman tree: code lengths');
for i := 0 to 18 do
aLog.WriteStr(Format('%-3d', [CodeLens[i]]));
aLog.WriteLine('');
aLog.WriteLine(Format('..total bits: %d', [CodeLenCount * 3]));
end;
{$ENDIF}
{create the codelength huffman tree}
CodeLenTree := TAbDfDecodeHuffmanTree.Create(19, 7, huDecoding);
CodeLenTree.Build(CodeLens, 0, 19, [0], $FFFF);
{$IFDEF UseLogging}
{log the tree}
if (aLog <> nil) then begin
aLog.WriteLine('Code lengths tree');
CodeLenTree.DebugPrint(aLog);
end;
{$ENDIF}
{read the codelengths for both the literal/length and distance
huffman trees}
ReadLitDistCodeLengths(aInStrm, CodeLenTree, CodeLens,
LitCount + DistCount, TotalBits);
{$IFDEF UseLoggingx}
{log them}
if (aLog <> nil) then begin
aLog.WriteLine('Literal/length & Dist Huffman trees: code lengths');
for i := 0 to pred(LitCount + DistCount) do
aLog.WriteLine(Format('%3d: %3d', [i, CodeLens[i]]));
aLog.WriteLine('');
aLog.WriteLine(Format('..total bits: %d', [TotalBits]));
end;
{$ENDIF}
{create the literal huffman tree}
LiteralTree := TAbDfDecodeHuffmanTree.Create(286, 15, huDecoding);
LiteralTree.Build(CodeLens, 0, LitCount,
dfc_LitExtraBits, dfc_LitExtraOffset);
{$IFDEF UseLogging}
{log the tree}
if (aLog <> nil) then begin
aLog.WriteLine('Literal/length tree');
LiteralTree.DebugPrint(aLog);
end;
{$ENDIF}
{create the distance huffman tree}
if aDeflate64 then
DistanceTree := TAbDfDecodeHuffmanTree.Create(32, 15, huDecoding)
else
DistanceTree := TAbDfDecodeHuffmanTree.Create(30, 15, huDecoding);
DistanceTree.Build(CodeLens, LitCount, DistCount,
dfc_DistExtraBits, dfc_DistExtraOffset);
{$IFDEF UseLogging}
{log the tree}
if (aLog <> nil) then begin
aLog.WriteLine('Distance tree');
DistanceTree.DebugPrint(aLog);
end;
{$ENDIF}
{using the literal and distance trees, decode the bit stream}
DecodeData(aInStrm, aOutWindow,
LiteralTree, DistanceTree, aDeflate64);
finally
CodeLenTree.Free;
LiteralTree.Free;
DistanceTree.Free;
end;
end;
{====================================================================}
{===Interfaced routine===============================================}
function Inflate(aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper) : longint;
var
Helper : TAbDeflateHelper;
InBitStrm : TAbDfInBitStream;
OutWindow : TAbDfOutputWindow;
Log : TAbLogger;
UseDeflate64 : boolean;
UseCRC32 : boolean;
IsFinalBlock : boolean;
BlockType : integer;
TestOnly : boolean;
SourceStartPos : longint;
DestStartPos : longint;
{$IFDEF UseLogging}
StartPosn : longint;
{$ENDIF}
begin
{$IFDEF DefeatWarnings}
Result := 0;
SourceStartPos := 0;
DestStartPos := 0;
TestOnly := False;
{$ENDIF}
{$IFDEF UseLogging}
StartPosn := 0;
{$ENDIF}
{pre-conditions: streams must be allocated of course}
Assert(aSource <> nil, 'Deflate: aSource stream cannot be nil');
Assert(aDest <> nil, 'Deflate: aDest stream cannot be nil');
{prepare for the try..finally}
Helper := nil;
InBitStrm := nil;
OutWindow := nil;
Log := nil;
try {finally}
try {except}
{create our helper; assign the passed one to it}
Helper := TAbDeflateHelper.Create;
if (aHelper <> nil) then
Helper.Assign(aHelper);
{get the initial start positions of both streams}
SourceStartPos := aSource.Position;
DestStartPos := aDest.Position;
{if the helper's stream size is -1, and it has a progress event
handler, calculate the stream size from the stream itself}
if Assigned(Helper.OnProgressStep) then begin
if (Helper.StreamSize = -1) then
Helper.StreamSize := aSource.Size;
end
{otherwise we certainly can't do any progress reporting}
else begin
Helper.OnProgressStep := nil;
Helper.StreamSize := 0;
end;
{create the logger, if requested}
if (Helper.LogFile <> '') then begin
Log := TAbLogger.Create(Helper.LogFile);
Log.WriteLine('INFLATING STREAM...');
{$IFNDEF UseLogging}
Log.WriteLine('Need to recompile the app with UseLogging turned on');
{$ENDIF}
end;
InBitStrm := TAbDfInBitStream.Create(aSource,
Helper.OnProgressStep,
Helper.StreamSize);
{create the output sliding window}
UseDeflate64 := (Helper.Options and dfc_UseDeflate64) <> 0;
UseCRC32 := (Helper.Options and dfc_UseAdler32) = 0;
TestOnly := (Helper.Options and dfc_TestOnly) <> 0;
OutWindow := TAbDfOutputWindow.Create(
aDest, UseDeflate64, UseCRC32, Helper.PartialSize,
TestOnly, Log);
{start decoding the deflated stream}
repeat
{read the final block flag and the block type}
IsFinalBlock := InBitStrm.ReadBit;
BlockType := InBitStrm.ReadBits(2);
{$IFDEF UseLogging}
{log it}
if (Log <> nil) then begin
Log.WriteLine('');
Log.WriteLine('Starting new block');
Log.WriteLine(Format('..final block? %d', [ord(IsFinalBlock)]));
Log.WriteLine(Format('..block type? %d', [BlockType]));
StartPosn := OutWindow.Position;
end;
{$ENDIF}
case BlockType of
0 : InflateStoredBlock(InBitStrm, OutWindow, Log);
1 : InflateStaticBlock(InBitStrm, OutWindow, Log, UseDeflate64);
2 : InflateDynamicBlock(InBitStrm, OutWindow, Log, UseDeflate64);
else
raise EAbInternalInflateError.Create(
'starting new block, but invalid block type [Inflate]');
end;
{$IFDEF UseLogging}
{log it}
if (Log <> nil) then
Log.WriteLine(Format('---block end--- (decoded size %d bytes)',
[OutWindow.Position - StartPosn]));
{$ENDIF}
until IsFinalBlock;
{get the uncompressed stream's checksum}
Result := OutWindow.Checksum;
if TestOnly and (aHelper <> nil) then
aHelper.NormalSize := OutWindow.Position;
{$IFDEF UseLogging}
{log it}
if (Log <> nil) then
Log.WriteLine(Format('End of compressed stream, checksum %-8x',
[Result]));
{$ENDIF}
except
on E : EAbPartSizedInflate do begin
{nothing, just swallow the exception}
Result := 0;
end;
on E : EAbAbortProgress do begin
{nothing, just swallow the exception}
Result := 0;
end;
on E : EAbInternalInflateError do begin
if (Log <> nil) then
Log.WriteLine(Format('Internal exception raised: %s',
[E.Message]));
raise EAbInflateError.Create(E.Message);
end;
end;
finally
Helper.Free;
OutWindow.Free;
InBitStrm.Free;
Log.Free;
end;
{if there's a helper return the compressed and uncompressed sizes}
if (aHelper <> nil) then begin
if not TestOnly then
aHelper.NormalSize := aDest.Position - DestStartPos;
aHelper.CompressedSize := aSource.Position - SourceStartPos;
end;
{WARNING NOTE: the compiler will warn that the return value of this
function might be undefined. However, it is wrong: it
has been fooled by the code. If you don't want to see
this warning again, enable the DefeatWarnings
compiler define in AbDefine.inc.}
end;
{====================================================================}
end.

906
Abbrevia/source/AbDfEnc.pas Normal file
View File

@@ -0,0 +1,906 @@
(* ***** 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: AbDfEnc.pas *}
{*********************************************************}
{* Deflate encoding unit *}
{*********************************************************}
unit AbDfEnc;
{$I AbDefine.inc}
interface
uses
Classes,
AbDfBase;
function Deflate(aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper) : longint;
implementation
uses
AbDfInW,
AbDfHufD,
AbDfStrm,
AbDfCryS,
AbDfPkMg;
{====================================================================}
function CalcDynamicBitCount(aUseDeflate64: boolean;
aLitBuckets : PAbDfLitBuckets;
aDistBuckets : PAbDfDistBuckets;
aCodeBuckets : PAbDfCodeLenBuckets;
const aCodeLens : array of integer;
const aCLCodeLens : array of integer;
aLitCount : integer;
aDistCount : integer;
aCodeCount : integer) : longint;
var
Symbol : integer;
LastSymbol : integer;
Inx : integer;
begin
{note: this routine calculates the number of bits required to
compress a given block}
{a dynamic block starts off with 5 bits of literal symbol count, 5
bits of distance symbol count, 4 bits of codelength symbol count,
and then 3 bits for every codelength symbol used}
Result := 5 + 5 + 4 +
(aCodeCount * 3);
{add in the bits needed to compress the literal and distance trees}
inc(Result, aCodeBuckets^[16] * (aCLCodeLens[16] + 2));
inc(Result, aCodeBuckets^[17] * (aCLCodeLens[16] + 3));
inc(Result, aCodeBuckets^[18] * (aCLCodeLens[16] + 7));
for Symbol := 3 to pred(aCodeCount) do begin
Inx := dfc_CodeLengthIndex[Symbol];
Assert(Inx <=15,
'CalcDynamicBitCount: the index array of codelengths is corrupted');
inc(Result, aCodeBuckets^[Inx] * aCLCodeLens[Inx])
end;
{make the literal symbol 285 a special case}
LastSymbol := pred(aLitCount);
if (LastSymbol = 285) then
LastSymbol := 284;
{add in all the bits needed to compress the literals (except 285)}
for Symbol := 0 to LastSymbol do
if (Symbol < dfc_LitExtraOffset) then
inc(Result, aLitBuckets^[Symbol] * aCodeLens[Symbol])
else
inc(Result, aLitBuckets^[Symbol] *
(aCodeLens[Symbol] +
dfc_LitExtraBits[Symbol - dfc_LitExtraOffset]));
{add in all the bits needed to compress the literal symbol 285}
if (pred(aLitCount) = 285) then
if (not aUseDeflate64) then
inc(Result, aLitBuckets^[285] * aCodeLens[285])
else
inc(Result, aLitBuckets^[285] * (aCodeLens[285] + 16));
{add in all the bits needed to compress the distances}
for Symbol := 0 to pred(aDistCount) do
inc(Result, aDistBuckets^[Symbol] *
(aCodeLens[aLitCount + Symbol] +
dfc_DistExtraBits[Symbol]));
end;
{====================================================================}
{====================================================================}
procedure OutputEndOfBlock(aBitStrm : TAbDfOutBitStream;
aLitTree : TAbDfDecodeHuffmanTree);
var
Code : longint;
begin
{note: this routine encodes the end-of-block character (symbol 256)
and then writes out the code to the bit stream}
{encode the end-of-block character as a symbol}
{$IFOPT C+} {if Assertions are on }
Code := aLitTree.Encode(256);
{$ELSE}
Code := aLitTree.Encodes^[256];
{$ENDIF}
{write the code out to the bit stream}
aBitStrm.WriteBits(Code and $FFFF, (Code shr 16) and $FF);
end;
{--------}
procedure EncodeLZStreamStored(aFinalBlock : boolean;
aStream : TAbDfLZStream;
aBitStrm : TAbDfOutBitStream;
aDataSize : integer;
aLog : TAbLogger);
var
BlockHeader : packed record
bhSize : word;
bhNotSize : word;
end;
Buffer : pointer;
Code : integer;
BlockSize : integer;
begin
{note: this routine writes out an incompressible block to the bit
stream (the store algorithm)}
{allocate the maximum buffer we can write at once}
GetMem(Buffer, 64 * 1024);
try
{while there's more incompressible data to store...}
while (aDataSize <> 0) do begin
{calculate the block size to write this time}
if (aDataSize > $FFFF) then begin
BlockSize := $FFFF;
dec(aDataSize, $FFFF);
end
else begin
BlockSize := aDataSize;
aDataSize := 0;
end;
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then begin
aLog.WriteLine('..Writing new block...');
aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));
aLog.WriteLine('..block type? 0');
aLog.WriteLine(Format('..block size: %d', [BlockSize]));
end;
{$ENDIF}
{output the block information to the bit stream}
if aFinalBlock then
Code := 1 + (0 shl 1)
else
Code := 0 + (0 shl 1);
aBitStrm.WriteBits(Code, 3);
{align the bit stream to the nearest byte}
aBitStrm.AlignToByte;
{write the stored block header}
BlockHeader.bhSize := BlockSize;
BlockHeader.bhNotSize := not BlockHeader.bhSize;
aBitStrm.WriteBuffer(BlockHeader, sizeof(BlockHeader));
{get and write this block}
aStream.ReadStoredBuffer(Buffer^, BlockSize);
aBitStrm.WriteBuffer(Buffer^, BlockSize);
end;
finally
FreeMem(Buffer);
end;
{clear the stream, ready for the next block}
aStream.Clear;
end;
{--------}
procedure EncodeLZStreamStatic(aFinalBlock : boolean;
aUseDeflate64 : boolean;
aStream : TAbDfLZStream;
aBitStrm : TAbDfOutBitStream;
aLog : TAbLogger);
var
Code : integer;
begin
{note: this routine writes out the stream of LZ77 tokens for the
current block to the bit stream, using the static huffman
trees to encode the token symbols}
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then begin
aLog.WriteLine('..Writing new block...');
aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));
aLog.WriteLine('..block type? 1');
end;
{$ENDIF}
{output the block information to the bit stream}
if aFinalBlock then
Code := 1 + (1 shl 1)
else
Code := 0 + (1 shl 1);
aBitStrm.WriteBits(Code, 3);
{encode the LZ77 stream}
aStream.Encode(aBitStrm,
AbStaticLiteralTree, AbStaticDistanceTree,
aUseDeflate64);
{output the end-of-block marker to the bit stream}
OutputEndOfBlock(aBitStrm, AbStaticLiteralTree);
{$IFDEF UseLogging}
if (aLog <> nil) then
aLog.WriteLine('Char: end-of-block marker (#256)');
{$ENDIF}
end;
{--------}
procedure EncodeLZStreamDynamic(aFinalBlock : boolean;
aUseDeflate64 : boolean;
aUseBest : boolean;
aStream : TAbDfLZStream;
aBitStrm : TAbDfOutBitStream;
aLog : TAbLogger);
var
i : integer;
LitTree : TAbDfDecodeHuffmanTree;
DistTree : TAbDfDecodeHuffmanTree;
CodeLenTree : TAbDfDecodeHuffmanTree;
CodeLenStream : TAbDfCodeLenStream;
CodeLens : array [0..285+32] of integer;
CLCodeLens : array [0..18] of integer;
LitCodeCount : integer;
DistCodeCount : integer;
LenCodeCount : integer;
BitCount : integer;
Code : integer;
StaticSize : integer;
StoredSize : integer;
begin
{note: this routine writes out the stream of LZ77 tokens for the
current block to the bit stream, using the dynamic huffman
trees to encode the token symbols; if the routine determines
that the data can better be compressed using the static
huffman trees or should be stored as is, it'll switch
algorithms}
{prepare for the try..finally}
LitTree := nil;
DistTree := nil;
CodeLenTree := nil;
CodeLenStream := nil;
try
{calculate the code lengths for the literal symbols}
GenerateCodeLengths(15, aStream.LitBuckets^, CodeLens, 0, aLog);
{calculate the number of the used codelengths for the literals}
LitCodeCount := 286;
repeat
dec(LitCodeCount);
until (CodeLens[LitCodeCount] <> 0);
inc(LitCodeCount);
{calculate the code lengths for the distance symbols}
GenerateCodeLengths(15, aStream.DistBuckets^, CodeLens,
LitCodeCount, aLog);
{calculate the number of the used codelengths for the distances}
DistCodeCount := 32;
repeat
dec(DistCodeCount);
until (CodeLens[DistCodeCount + LitCodeCount] <> 0);
inc(DistCodeCount);
{calculate the code lengths array as a stream of items}
CodeLenStream := TAbDfCodeLenStream.Create(aLog);
CodeLenStream.Build(CodeLens, LitCodeCount + DistCodeCount);
{calculate the codelengths for the code lengths}
GenerateCodeLengths(7, CodeLenStream.Buckets^, CLCodeLens, 0, nil);
{calculate the number of the used codelengths for the code lengths}
LenCodeCount := 19;
repeat
dec(LenCodeCount);
until (CLCodeLens[dfc_CodeLengthIndex[LenCodeCount]] <> 0);
inc(LenCodeCount);
{..there's a minimum of four, though}
if (LenCodeCount < 4) then
LenCodeCount := 4;
{if we have to work out and use the best method...}
if aUseBest then begin
{calculate the number of bits required for the compressed data
using dynamic huffman trees}
BitCount := CalcDynamicBitCount(aUseDeflate64,
aStream.LitBuckets,
aStream.DistBuckets,
CodeLenStream.Buckets,
CodeLens,
CLCodeLens,
LitCodeCount,
DistCodeCount,
LenCodeCount);
{choose the algorithm with the smallest size}
StaticSize := aStream.StaticSize;
StoredSize := (aStream.StoredSize + 4) * 8;
if (StaticSize < BitCount) then begin
if (StoredSize < StaticSize) then
EncodeLZStreamStored(aFinalBlock, aStream, aBitStrm,
(StoredSize div 8) - 4, aLog)
else
EncodeLZStreamStatic(aFinalBlock, aUseDeflate64,
aStream, aBitStrm, aLog);
Exit;
end
else if (StoredSize < BitCount) then begin
EncodeLZStreamStored(aFinalBlock, aStream, aBitStrm,
(StoredSize div 8) - 4, aLog);
Exit;
end;
end;
{create the code lengths tree}
CodeLenTree := TAbDfDecodeHuffmanTree.Create(19, 7, huEncoding);
CodeLenTree.Build(CLCodeLens, 0, 19, [0], $FFFF);
{$IFDEF UseLogging}
{log the tree}
if (aLog <> nil) then begin
aLog.WriteLine('Code lengths tree');
CodeLenTree.DebugPrint(aLog);
end;
{$ENDIF}
{calculate the literal encoding tree}
LitTree := TAbDfDecodeHuffmanTree.Create(286, 15, huEncoding);
LitTree.Build(CodeLens, 0, LitCodeCount,
dfc_LitExtraBits, dfc_LitExtraOffset);
{$IFDEF UseLogging}
{log the tree}
if (aLog <> nil) then begin
aLog.WriteLine('Literal/length tree');
LitTree.DebugPrint(aLog);
end;
{$ENDIF}
{calculate the distance tree}
if aUseDeflate64 then
DistTree := TAbDfDecodeHuffmanTree.Create(32, 15, huEncoding)
else
DistTree := TAbDfDecodeHuffmanTree.Create(30, 15, huEncoding);
DistTree.Build(CodeLens, LitCodeCount, DistCodeCount,
dfc_DistExtraBits, dfc_DistExtraOffset);
{$IFDEF UseLogging}
if (aLog <> nil) then begin
{log the tree}
aLog.WriteLine('Distance tree');
DistTree.DebugPrint(aLog);
{log the new block}
aLog.WriteLine('..Writing new block...');
aLog.WriteLine(Format('..final block? %d', [ord(aFinalBlock)]));
aLog.WriteLine('..block type? 2');
aLog.WriteLine(Format('Count of literals: %d', [LitCodeCount]));
aLog.WriteLine(Format('Count of distances: %d', [DistCodeCount]));
aLog.WriteLine(Format('Count of code lengths: %d', [LenCodeCount]));
end;
{$ENDIF}
{output the block information to the bit stream}
if aFinalBlock then
Code := 1 + (2 shl 1)
else
Code := 0 + (2 shl 1);
aBitStrm.WriteBits(Code, 3);
{output the various counts to the bit stream}
Code := (LitCodeCount - 257) +
((DistCodeCount - 1) shl 5) +
((LenCodeCount - 4) shl 10);
aBitStrm.WriteBits(Code, 14);
{output the code length codelengths to the bit stream}
for i := 0 to pred(LenCodeCount) do
aBitStrm.WriteBits(CLCodeLens[dfc_CodeLengthIndex[i]], 3);
{encode and write the codelength stream to the bit stream}
CodeLenStream.Encode(aBitStrm, CodeLenTree);
{encode and write the LZ77 stream to the bit stream}
aStream.Encode(aBitStrm, LitTree, DistTree, aUseDeflate64);
{output the end-of-block marker to the bit stream}
OutputEndOfBlock(aBitStrm, LitTree);
{$IFDEF UseLogging}
if (aLog <> nil) then
aLog.WriteLine('Char: end-of-block marker (#256)');
{$ENDIF}
finally
LitTree.Free;
DistTree.Free;
CodeLenTree.Free;
CodeLenStream.Free;
end;
end;
{====================================================================}
{===Single algorithm Static/Dynamic Huffman tree deflate=============}
function DeflateStaticDynamic(aStatic : boolean;
aUseBest: boolean;
aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper;
aLog : TAbLogger) : longint;
var
i : integer;
SlideWin : TAbDfInputWindow;
BitStrm : TAbDfOutBitStream;
LZ77Stream : TAbDfLZStream;
KeyLen : integer;
Match : TAbDfMatch;
PrevMatch : TAbDfMatch;
UseDeflate64 : boolean;
UseCRC32 : boolean;
GotMatch : boolean;
LZStrmIsFull : boolean;
TestForBinary: boolean;
begin
{note: turn on the following define to see when and how the lazy
matching algorithm works}
{$IFDEF UseLogging}
{$DEFINE UseLazyMatchLogging}
{$ENDIF}
{$IFDEF UseLogging}
if (aLog <> nil) then
if aStatic then
aLog.WriteLine('..compressing source data with static huffman trees')
else
aLog.WriteLine('..compressing source data with dynamic huffman trees');
{$ENDIF}
{prepare for the try..finally}
SlideWin := nil;
BitStrm := nil;
LZ77Stream := nil;
try
{create the sliding window}
UseDeflate64 := (aHelper.Options and dfc_UseDeflate64) <> 0;
UseCRC32 := (aHelper.Options and dfc_UseAdler32) = 0;
SlideWin := TAbDfInputWindow.Create(aSource,
aHelper.StreamSize,
aHelper.WindowSize,
aHelper.ChainLength,
UseDeflate64, UseCRC32);
SlideWin.OnProgress := aHelper.OnProgressStep;
{create the bit stream}
BitStrm := TAbDfOutBitStream.Create(aDest);
{create the LZ77 stream}
LZ77Stream := TAbDfLZStream.Create(SlideWin, UseDeflate64, aLog);
LZStrmIsFull := false;
TestForBinary := true;
{set the previous match to be a literal character: this will
ensure that no lazy matching goes on with the first key read}
PrevMatch.maLen := 0;
{get the first key length}
KeyLen := SlideWin.GetNextKeyLength;
{while the current key is three characters long...}
while (KeyLen = 3) do begin
{tweak for binary/text}
{note: the test for whether a stream is binary or not is to
check whether there are any #0 characters in the first
1024 bytes: if there are the stream is binary.
this test and tweaking is based on experimentation
compression ratios for binary and text files based on the
PKZIP 'n' option.}
if TestForBinary and (LZ77Stream.StoredSize = 1024) then begin
if (aHelper.PKZipOption = 'n') then
if (LZ77Stream.LitBuckets^[0] = 0) then begin
aHelper.AmpleLength := aHelper.AmpleLength * 2;
aHelper.MaxLazyLength := aHelper.MaxLazyLength * 2;
aHelper.ChainLength := aHelper.ChainLength * 2;
SlideWin.ChainLen := aHelper.ChainLength;
end;
TestForBinary := false;
end;
{if the LZ77 stream is full, empty it}
if LZStrmIsFull then begin
if aStatic then
EncodeLZStreamStatic(false, UseDeflate64,
LZ77Stream, BitStrm, aLog)
else
EncodeLZStreamDynamic(false, UseDeflate64, aUseBest,
LZ77Stream, BitStrm, aLog);
LZ77Stream.Clear;
LZStrmIsFull := false;
end;
{try and find a match of three or more characters (note: this
has the side effect of adding the current key to the internal
hash table); this routine will only return true if it finds a
match greater than the previous match}
GotMatch := SlideWin.FindLongestMatch(aHelper.AmpleLength,
Match, PrevMatch);
{if the maximum match length were three and the distance exceeds
4096 bytes, it's most likely that we'll get better compression
by outputting the three literal bytes rather than by outputting
a length symbol, a distance symbol, and at least ten extra
bits for the extra distance value}
if (Match.maLen = 3) and (Match.maDist > 4096) then
GotMatch := false;
{if we found a match...}
if GotMatch then begin
{if there were no previous match, we can't do any lazy match
processing now, so save the current match details ready for
lazy matching the next time through, and advance the sliding
window}
if (PrevMatch.maLen = 0) then begin
PrevMatch.maLen := Match.maLen;
PrevMatch.maDist := Match.maDist;
PrevMatch.maLit := Match.maLit;
SlideWin.AdvanceByOne;
end
{otherwise the previous match is smaller than this one, so
we're going to accept this match in preference; throw away
the previous match, output the previous literal character
instead and save these match details}
else begin
{$IFDEF UseLazyMatchLogging}
if (aLog <> nil) then
aLog.WriteLine(
Format(
'..this match longer, rejecting previous one (%d,%d)',
[PrevMatch.maLen, PrevMatch.maDist]));
{$ENDIF}
LZStrmIsFull := LZ77Stream.AddLiteral(PrevMatch.maLit);
PrevMatch.maLen := Match.maLen;
PrevMatch.maDist := Match.maDist;
PrevMatch.maLit := Match.maLit;
SlideWin.AdvanceByOne;
end;
{if, by this point, we're storing up a match, check to see
if it equals or exceeds the maximum lazy match length; if
it does then output the match right now and avoid checking
for a lazy match}
if (PrevMatch.maLen >= aHelper.MaxLazyLength) then begin
{$IFDEF UseLazyMatchLogging}
if (aLog <> nil) then
if ((aHelper.Options and dfc_UseLazyMatch) <> 0) then
aLog.WriteLine('..match longer than max lazy match, using it');
{$ENDIF}
LZStrmIsFull :=
LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);
SlideWin.Advance(PrevMatch.maLen - 1, PrevMatch.maLen - 1);
PrevMatch.maLen := 0;
end;
end
{otherwise, we don't have a match at all: so we possibly just
need to output a literal character}
else begin
{if there was a previous match, output it and discard the
results of this match}
if (PrevMatch.maLen <> 0) then begin
LZStrmIsFull :=
LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);
SlideWin.Advance(PrevMatch.maLen - 1, PrevMatch.maLen - 2);
PrevMatch.maLen := 0;
end
{otherwise there was no previous match or it's already been
output, so output this literal}
else begin
LZStrmIsFull := LZ77Stream.AddLiteral(Match.maLit);
SlideWin.AdvanceByOne;
PrevMatch.maLen := 0;
end;
end;
{get the next key}
KeyLen := SlideWin.GetNextKeyLength;
end;
{if the last key read were one or two characters in length, save
them as literal character encodings}
if (KeyLen > 0) then begin
{if there's a match pending, it'll be of length 3: output it}
if (PrevMatch.maLen <> 0) then begin
Assert(PrevMatch.maLen = 3,
'DeflateStaticDynamic: previous match should be length 3');
LZ77Stream.AddLenDist(PrevMatch.maLen, PrevMatch.maDist);
end
{otherwise, output the one or two final literals}
else
for i := 1 to KeyLen do
LZ77Stream.AddLiteral(SlideWin.GetNextChar);
end;
{empty the LZ77 stream}
if aStatic then
EncodeLZStreamStatic(true, UseDeflate64,
LZ77Stream, BitStrm, aLog)
else
EncodeLZStreamDynamic(true, UseDeflate64, aUseBest,
LZ77Stream, BitStrm, aLog);
{calculate the checksum of the input stream}
Result := SlideWin.Checksum;
finally
{free the objects}
SlideWin.Free;
BitStrm.Free;
LZ77Stream.Free;
end;{try..finally}
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine(Format('..checksum: %8x', [Result]))
{$ENDIF}
end;
{====================================================================}
{===Simple storing===================================================}
function DeflateStored(aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper;
aLog : TAbLogger) : longint;
const
StoredBlockSize = $FFFF;
var
Buffer : PAnsiChar;
BytesRead : LongWord;
ByteCount : Int64;
BytesToGo : Int64;
CurPos : Int64;
Size : Int64;
Percent : longint;
CheckSum : longint;
UseCRC32 : boolean;
BlockHeader : packed record
bhInfo : byte;
bhSize : word;
bhNotSize : word;
end;
begin
{note: this routine merely stores the aSource stream data, no
compression is attempted or done}
{$IFDEF UseLogging}
if (aLog <> nil) then
aLog.WriteLine('..storing source data to destination, no compression');
{$ENDIF}
{initialize}
ByteCount := 0;
UseCRC32 := (aHelper.Options and dfc_UseAdler32) = 0;
if UseCRC32 then
Checksum := -1 { CRC32 starts off with all bits set}
else
CheckSum := 1; { Adler32 starts off with a value of 1}
if (aHelper.StreamSize > 0) then
BytesToGo := aHelper.StreamSize
else begin
CurPos := aSource.Seek(0, soCurrent);
Size := aSource.Seek(0, soEnd);
aSource.Seek(CurPos, soBeginning);
BytesToGo := Size - CurPos;
end;
{get a buffer}
GetMem(Buffer, StoredBlockSize);
try
{while there is still data to be stored...}
while (BytesToGo <> 0) do begin
{read the next block}
BytesRead := aSource.Read(Buffer^, StoredBlockSize);
{fire the progress event}
if Assigned(aHelper.OnProgressStep) then begin
inc(ByteCount, BytesRead);
Percent := Round((100.0 * ByteCount) / aHelper.StreamSize);
aHelper.OnProgressStep(Percent);
end;
{update the checksum}
if UseCRC32 then
AbUpdateCRCBuffer(Checksum, Buffer^, BytesRead)
else
AbUpdateAdlerBuffer(Checksum, Buffer^, BytesRead);
{write the block header}
if (BytesRead = BytesToGo) then
BlockHeader.bhInfo := 1 {ie, final block, stored}
else
BlockHeader.bhInfo := 0; {ie, not final block, stored}
BlockHeader.bhSize := BytesRead;
BlockHeader.bhNotSize := not BlockHeader.bhSize;
aDest.WriteBuffer(BlockHeader, sizeof(BlockHeader));
{write the block of data}
aDest.WriteBuffer(Buffer^, BytesRead);
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then begin
if (BlockHeader.bhInfo = 0) then
aLog.WriteLine(Format('..block size: %d', [BytesRead]))
else
aLog.WriteLine(Format('..block size: %d (final block)',
[BytesRead]));
end;
{$ENDIF}
{decrement the number of bytes to go}
dec(BytesToGo, BytesRead);
end;
finally
FreeMem(Buffer);
end;
{return the checksum}
{note: the CRC32 checksum algorithm requires a post-conditioning
step after being calculated (the result is NOTted), whereas
Adler32 does not}
if UseCRC32 then
Result := not Checksum
else
Result := Checksum;
{$IFDEF UseLogging}
{log it}
if (aLog <> nil) then
aLog.WriteLine(Format('..checksum: %8x', [Result]))
{$ENDIF}
end;
{====================================================================}
{===Interfaced routine===============================================}
function Deflate(aSource : TStream; aDest : TStream;
aHelper : TAbDeflateHelper) : longint;
var
Helper : TAbDeflateHelper;
Log : TAbLogger;
SourceStartPos : longint;
DestStartPos : longint;
begin
{pre-conditions: streams are allocated,
options enable some kind of archiving}
Assert(aSource <> nil, 'Deflate: aSource stream cannot be nil');
Assert(aDest <> nil, 'Deflate: aDest stream cannot be nil');
Assert((aHelper = nil) or ((aHelper.Options and $07) <> 0),
'Deflate: aHelper.Options must enable some kind of archiving');
{$IFDEF DefeatWarnings}
Result := 0;
{$ENDIF}
{prepare for the try..finally}
Helper := nil;
Log := nil;
try {finally}
try {except}
{create our helper; assign the passed one to it}
Helper := TAbDeflateHelper.Create;
if (aHelper <> nil) then
Helper.Assign(aHelper);
{save the current positions of both streams}
SourceStartPos := aSource.Position;
DestStartPos := aDest.Position;
{if the helper's stream size is -1, and it has a progress event
handler, calculate the stream size from the stream itself}
if Assigned(Helper.OnProgressStep) then begin
if (Helper.StreamSize = -1) then
Helper.StreamSize := aSource.Size;
end
{otherwise we certainly can't do any progress reporting}
else begin
Helper.OnProgressStep := nil;
Helper.StreamSize := 0;
end;
{if lazy matching is not requested, ensure the maximum lazy
match length is zero: this make the LZ77 code a little easier
to understand}
if ((Helper.Options and dfc_UseLazyMatch) = 0) then
Helper.MaxLazyLength := 0;
{patch up the various lengths in the helper if they specify the
maximum (that is, are equal to -1)}
if (Helper.AmpleLength = -1) then
Helper.AmpleLength := MaxLongInt;
if (Helper.MaxLazyLength = -1) then
Helper.MaxLazyLength := MaxLongInt;
if (Helper.ChainLength = -1) then
Helper.ChainLength := MaxLongInt;
{create the logger, if requested}
if (Helper.LogFile <> '') then begin
Log := TAbLogger.Create(Helper.LogFile);
Log.WriteLine('DEFLATING STREAM...');
{$IFNDEF UseLogging}
Log.WriteLine('Need to recompile the app with UseLogging turned on');
{$ENDIF}
end;
{use the helper's options property to decide what to do}
case (Helper.Options and $07) of
dfc_CanUseStored :
Result := DeflateStored(aSource, aDest, Helper, Log);
dfc_CanUseStatic :
Result := DeflateStaticDynamic(true, false, aSource, aDest, Helper, Log);
dfc_CanUseDynamic :
Result := DeflateStaticDynamic(false, false, aSource, aDest, Helper, Log);
else
Result := DeflateStaticDynamic(false, true, aSource, aDest, Helper, Log);
end;
{save the uncompressed and compressed sizes}
if (aHelper <> nil) then begin
aHelper.NormalSize := aSource.Position - SourceStartPos;
aHelper.CompressedSize := aDest.Position - DestStartPos;
end;
except
on E : EAbInternalDeflateError do begin
{$IFDEF UseLogging}
if (Log <> nil) then
Log.WriteLine(Format('Internal exception raised: %s',
[E.Message]));
{$ENDIF}
raise EAbDeflateError.Create(E.Message);
end;
end;
finally
Helper.Free;
Log.Free;
end;
{WARNING NOTE: the compiler will warn that the return value of this
function might be undefined. However, it is wrong: it
has been fooled by the code. If you don't want to see
this warning again, enable the DefeatWarnings
compiler define in AbDefine.inc.}
end;
{====================================================================}
end.

View File

@@ -0,0 +1,530 @@
(* ***** 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: AbDfHufD.pas *}
{*********************************************************}
{* Deflate Huffman tree for decoder *}
{*********************************************************}
unit AbDfHufD;
{$I AbDefine.inc}
{Activate this compiler define and rebuild if you want the complete
huffman tree output to print to the current log. The output is
voluminous to say the least...}
{$IFDEF UseLogging}
{.$DEFINE EnableMegaLog}
{$ENDIF}
{Notes:
The object of this class is to build a decoder array, not to build a
Huffman tree particularly. We don't want to decode huffman strings bit
by bit. moving down the Huffman tree sometimes left, sometimes right.
Instead we want to grab a set of bits and look them up in an array.
Sometimes we'll grab too many bits, sure, but we can deal with that
later. So, the object of the exercise is to calculate the code for a
symbol, reverse it ('cos that's how the input bit stream will present
it to us) and set that element of the array to the decoded symbol
value (plus some extra information: bit lengths).
If the alphabet size were 19 (the codelengths huffman tree) and the
maximum code length 5, for example, the decoder array would be 2^5
elements long, much larger than the alphabet size. The user of this
class will be presenting sets of 5 bits for us to decode. We would
like to look up these 5 bits in the array (as an index) and have the
symbol returned. Now, since the alphabet size is much less than the
number of elements in the decoder array, we must set the other
elements in the array as well. Consider a symbol that has a code of
110 in this scenario. The reversed code is 011, or 3, so we'd be
setting element 3. However we should also be setting elements 01011,
10011, and 11011 to this symbol information as well, since the lookup
will be 5 bits long.
Because the code is a huffman code from a prefix tree, we won't get
any index clashes between actual codes by this "filling in" process.
For the codelength Huffman tree, the maximum code length is at most 7.
This equates to a 128 element array. For the literal and distance
trees, the max code length is at most 15. This equates to a 32768
element array.
For a given lookup value the decoder will return a 32-bit value. The
lower 16 bits is the decoded symbol, the next 8 bits is the code
length for that symbol, the last 8 bits (the most significant) are the
number of extra bits that must be extracted from the input bit stream.
}
interface
uses
AbDfBase;
type
TAbDfHuffmanUsage = ( {usage of a huffman decoder..}
huEncoding, {..encoding}
huDecoding, {..decoding}
huBoth); {..both (used for static trees)}
TAbDfDecodeHuffmanTree = class
private
FAlphaSize : integer;
FDecodes : PAbDfLongintList;
FDefMaxCodeLen : integer;
FEncodes : PAbDfLongintList;
{$IFOPT C+}
FMask : integer;
{$ENDIF}
FMaxCodeLen : integer;
FUsage : TAbDfHuffmanUsage;
protected
public
constructor Create(aAlphabetSize : integer;
aDefMaxCodeLen: integer;
aUsage : TAbDfHuffmanUsage);
destructor Destroy; override;
procedure Build(const aCodeLengths : array of integer;
aStartInx : integer;
aCount : integer;
const aExtraBits : array of byte;
aExtraOffset : integer);
function Decode(aLookupBits : integer) : longint;
function Encode(aSymbol : integer) : longint;
{$IFDEF UseLogging}
procedure DebugPrint(aLog : TAbLogger);
{$ENDIF}
property LookupBitLength : integer read FMaxCodeLen;
property Decodes : PAbDfLongintList read FDecodes;
property Encodes : PAbDfLongintList read FEncodes;
end;
var
AbStaticLiteralTree : TAbDfDecodeHuffmanTree;
AbStaticDistanceTree : TAbDfDecodeHuffmanTree;
implementation
uses
SysUtils;
const
PowerOfTwo : array [0..dfc_MaxCodeLength] of integer =
(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
4096, 8192, 16384, 32768);
{===Debug helper routine=============================================}
{$IFDEF EnableMegaLog}
function CodeToStr(aCode : longint; aLen : integer) : string;
var
i : integer;
begin
if (aLen = 0) then
Result := 'no code'
else begin
SetLength(Result, 32);
FillChar(Result[1], 32, ' ');
for i := 32 downto (33-aLen) do begin
if Odd(aCode) then
Result[i] := '1'
else
Result[i] := '0';
aCode := aCode shr 1;
end;
end;
end;
{$ENDIF}
{====================================================================}
{===TAbDfDecodeHuffmanTree===========================================}
constructor TAbDfDecodeHuffmanTree.Create(
aAlphabetSize : integer;
aDefMaxCodeLen: integer;
aUsage : TAbDfHuffmanUsage);
begin
{protect against dumb programming mistakes}
Assert(aAlphabetSize >= 2,
'TAbDfDecodeHuffmanTree.Create: a huffman tree must be for at least two symbols');
{let the ancestor initialize}
inherited Create;
{save the alphabet size, etc}
FAlphaSize := aAlphabetSize;
FDefMaxCodeLen := aDefMaxCodeLen;
FUsage := aUsage;
{allocate the encoder array (needs to be initialized to zeros)}
if (aUsage <> huDecoding) then
FEncodes := AllocMem(FAlphaSize * sizeof(longint));
end;
{--------}
destructor TAbDfDecodeHuffmanTree.Destroy;
begin
{destroy the codes arrays}
if (FDecodes <> nil) then
FreeMem(FDecodes);
if (FEncodes <> nil) then
FreeMem(FEncodes);
{let the ancestor die}
inherited Destroy;
end;
{--------}
procedure TAbDfDecodeHuffmanTree.Build(
const aCodeLengths : array of integer;
aStartInx : integer;
aCount : integer;
const aExtraBits : array of byte;
aExtraOffset : integer);
const
ByteRevTable : array [0..255] of byte = (
$00, $80, $40, $C0, $20, $A0, $60, $E0, $10, $90, $50, $D0,
$30, $B0, $70, $F0, $08, $88, $48, $C8, $28, $A8, $68, $E8,
$18, $98, $58, $D8, $38, $B8, $78, $F8, $04, $84, $44, $C4,
$24, $A4, $64, $E4, $14, $94, $54, $D4, $34, $B4, $74, $F4,
$0C, $8C, $4C, $CC, $2C, $AC, $6C, $EC, $1C, $9C, $5C, $DC,
$3C, $BC, $7C, $FC, $02, $82, $42, $C2, $22, $A2, $62, $E2,
$12, $92, $52, $D2, $32, $B2, $72, $F2, $0A, $8A, $4A, $CA,
$2A, $AA, $6A, $EA, $1A, $9A, $5A, $DA, $3A, $BA, $7A, $FA,
$06, $86, $46, $C6, $26, $A6, $66, $E6, $16, $96, $56, $D6,
$36, $B6, $76, $F6, $0E, $8E, $4E, $CE, $2E, $AE, $6E, $EE,
$1E, $9E, $5E, $DE, $3E, $BE, $7E, $FE, $01, $81, $41, $C1,
$21, $A1, $61, $E1, $11, $91, $51, $D1, $31, $B1, $71, $F1,
$09, $89, $49, $C9, $29, $A9, $69, $E9, $19, $99, $59, $D9,
$39, $B9, $79, $F9, $05, $85, $45, $C5, $25, $A5, $65, $E5,
$15, $95, $55, $D5, $35, $B5, $75, $F5, $0D, $8D, $4D, $CD,
$2D, $AD, $6D, $ED, $1D, $9D, $5D, $DD, $3D, $BD, $7D, $FD,
$03, $83, $43, $C3, $23, $A3, $63, $E3, $13, $93, $53, $D3,
$33, $B3, $73, $F3, $0B, $8B, $4B, $CB, $2B, $AB, $6B, $EB,
$1B, $9B, $5B, $DB, $3B, $BB, $7B, $FB, $07, $87, $47, $C7,
$27, $A7, $67, $E7, $17, $97, $57, $D7, $37, $B7, $77, $F7,
$0F, $8F, $4F, $CF, $2F, $AF, $6F, $EF, $1F, $9F, $5F, $DF,
$3F, $BF, $7F, $FF);
var
i : integer;
Symbol : integer;
LengthCount : array [0..dfc_MaxCodeLength] of integer;
NextCode : array [0..dfc_MaxCodeLength] of integer;
Code : longint;
CodeLen : integer;
CodeData : longint;
DecoderLen : integer;
CodeIncr : integer;
Decodes : PAbDfLongintList;
Encodes : PAbDfLongintList;
{$IFDEF CPU386}
DecodesEnd : pointer;
{$ENDIF}
TablePtr : pointer;
begin
{count the number of instances of each code length and calculate the
maximum code length at the same time}
FillChar(LengthCount, sizeof(LengthCount), 0);
FMaxCodeLen := 0;
for i := 0 to pred(aCount) do begin
CodeLen := aCodeLengths[i + aStartInx];
Assert((CodeLen <= FDefMaxCodeLen),
Format('TAbDfDecodeHuffmanTree.Build: a code length is greater than %d',
[FDefMaxCodeLen]));
if (CodeLen > FMaxCodeLen) then
FMaxCodeLen := CodeLen;
inc(LengthCount[CodeLen]);
end;
{now we know the maximum code length we can allocate our decoder
array}
{$IFNDEF CPU386}
DecoderLen := 0;
{$ENDIF}
if (FUsage <> huEncoding) then begin
DecoderLen := PowerOfTwo[FMaxCodeLen];
GetMem(FDecodes, DecoderLen * sizeof(longint));
{$IFDEF CPU386}
DecodesEnd := PAnsiChar(FDecodes) + (DecoderLen * sizeof(longint));
{$ENDIF}
{$IFOPT C+}
FillChar(FDecodes^, DecoderLen * sizeof(longint), $FF);
FMask := not (DecoderLen - 1);
{$ENDIF}
end;
{calculate the start codes for each code length}
Code := 0;
LengthCount[0] := 0;
for i := 1 to FDefMaxCodeLen do begin
Code := (Code + LengthCount[i-1]) shl 1;
NextCode[i] := Code;
end;
{for speed and convenience}
Decodes := FDecodes;
Encodes := FEncodes;
TablePtr := @ByteRevTable;
{for each symbol...}
for Symbol := 0 to pred(aCount) do begin
{calculate the code length}
CodeLen := aCodeLengths[Symbol + aStartInx];
{if the code length were zero, just set the relevant entry in the
encoder array; the decoder array doesn't need anything}
if (CodeLen = 0) then begin
if (FUsage <> huDecoding) then
Encodes^[Symbol] := -1
end
{otherwise we need to fill elements in both the encoder and
decoder arrays}
else begin
{calculate *reversed* code}
Code := NextCode[CodeLen];
{$IFDEF CPU386}
asm
push esi
mov eax, Code
mov esi, TablePtr
xor ecx, ecx
xor edx, edx
mov cl, ah
mov dl, al
mov al, [esi+ecx]
mov ah, [esi+edx]
mov ecx, 16
pop esi
sub ecx, CodeLen
shr eax, cl
mov Code, eax
end;
{$ELSE}
CodeData:= Code;
LongRec(Code).Bytes[1]:= ByteRevTable[LongRec(CodeData).Bytes[0]];
LongRec(Code).Bytes[0]:= ByteRevTable[LongRec(CodeData).Bytes[1]];
Code:= Code shr (16-CodeLen);
{$ENDIF}
{set the code data (bit count, extra bits required, symbol),
everywhere the reversed code would appear in the decoder array;
set the code data in the encoder array as well}
if (Symbol >= aExtraOffset) then begin
if (FUsage <> huEncoding) then
CodeData := Symbol + { symbol}
(CodeLen shl 16) + { code length}
(aExtraBits[Symbol-aExtraOffset] shl 24);
{ extra bits required}
if (FUsage <> huDecoding) then
Encodes^[Symbol] := Code + { code}
(CodeLen shl 16) + { code length}
(aExtraBits[Symbol-aExtraOffset] shl 24)
{ extra bits required}
end
else begin
if (FUsage <> huEncoding) then
CodeData := Symbol + { symbol}
(CodeLen shl 16); { code length}
if (FUsage <> huDecoding) then
Encodes^[Symbol] := Code + { code}
(CodeLen shl 16); { code length}
end;
{OPTIMIZATION NOTE: the following code
CodeIncr := PowerOfTwo[CodeLen];
while Code < DecoderLen do begin
Decodes^[Code] := CodeData;
inc(Code, CodeIncr);
end;
was replaced by the asm code below to improve the speed. The
code in the loop is the big time sink in this routine so it was
best to replace it.}
if (FUsage <> huEncoding) then begin
{$IFDEF CPU386}
CodeIncr := PowerOfTwo[CodeLen] * sizeof(longint);
asm
push edi { save edi}
mov eax, Decodes { get the Decodes array}
mov edi, DecodesEnd { get the end of the Decodes array}
mov edx, Code { get Code and..}
shl edx, 1 { ..multiply by 4}
shl edx, 1
add eax, edx { eax => first element to be set}
mov edx, CodeData { get the CodeData}
mov ecx, CodeIncr { get the increment per loop}
@@1:
mov [eax], edx { set the element}
add eax, ecx { move to the next element}
cmp eax, edi { if we haven't gone past the end..}
jl @@1 { ..go back for the next one}
pop edi { retrieve edi}
end;
{$ELSE}
CodeIncr := PowerOfTwo[CodeLen];
while Code < DecoderLen do begin
Decodes^[Code] := CodeData;
inc(Code, CodeIncr);
end;
{$ENDIF}
end;
{we've used this code up for this symbol, so increment for the
next symbol at this code length}
inc(NextCode[CodeLen]);
end;
end;
end;
{--------}
{$IFDEF UseLogging}
procedure TAbDfDecodeHuffmanTree.DebugPrint(aLog : TAbLogger);
{$IFDEF EnableMegaLog}
var
i : integer;
Code : longint;
{$ENDIF}
begin
{to print the huffman tree, we must have a logger...}
Assert(aLog <> nil,
'TAbDfDecodeHuffmanTree.DebugPrint needs a logger object to which to print');
if (FUsage <> huEncoding) then begin
aLog.WriteLine('Huffman decoder array');
aLog.WriteLine(Format('Alphabet size: %d', [FAlphaSize]));
aLog.WriteLine(Format('Max codelength: %d', [FMaxCodeLen]));
{$IFDEF EnableMegaLog}
aLog.WriteLine('Index Len Xtra Symbol Reversed Code');
for i := 0 to pred(PowerOfTwo[FMaxCodeLen]) do begin
Code := FDecodes^[i];
if (Code = -1) then
aLog.WriteLine(Format('%5d%49s', [i, 'no code']))
else
aLog.WriteLine(Format('%5d%4d%5d%7d%33s',
[i,
((Code shr 16) and $FF),
((Code shr 24) and $FF),
(Code and $FFFF),
CodeToStr(i, ((Code shr 16) and $FF))]));
end;
aLog.WriteLine('---end decoder array---');
{$ENDIF}
end;
if (FUsage <> huDecoding) then begin
aLog.WriteLine('Huffman encoder array');
aLog.WriteLine(Format('Alphabet size: %d', [FAlphaSize]));
{$IFDEF EnableMegaLog}
aLog.WriteLine('Symbol Len Xtra Reversed Code');
for i := 0 to pred(FAlphaSize) do begin
Code := FEncodes^[i];
if (Code = -1) then
aLog.WriteLine(Format('%6d%42s', [i, 'no code']))
else
aLog.WriteLine(Format('%6d%4d%5d%33s',
[i,
((Code shr 16) and $FF),
((Code shr 24) and $FF),
CodeToStr((Code and $FFFF), ((Code shr 16) and $FF))]));
end;
aLog.WriteLine('---end encoder array---');
{$ENDIF}
end;
end;
{$ENDIF}
{--------}
function TAbDfDecodeHuffmanTree.Decode(aLookupBits : integer) : longint;
begin
{protect against dumb programming mistakes (note: FMask only exists
if assertions are on)}
{$IFOPT C+}
Assert((aLookupBits and FMask) = 0,
'TAbDfDecodeHuffmanTree.Decode: trying to decode too many bits, use LookupBitLength property');
{$ENDIF}
{return the code data}
Result := FDecodes^[aLookupBits];
end;
{--------}
function TAbDfDecodeHuffmanTree.Encode(aSymbol : integer) : longint;
begin
{protect against dumb programming mistakes}
Assert((0 <= aSymbol) and (aSymbol < FAlphaSize),
'TAbDfDecodeHuffmanTree.Encode: trying to encode a symbol that is not in the alphabet');
{return the code data}
Result := FEncodes^[aSymbol];
{if the result is -1, it's another programming mistake: the user is
attempting to get a code for a symbol that wasn't being used}
Assert(Result <> -1,
'TAbDfDecodeHuffmanTree.Encode: trying to encode a symbol that was not used');
end;
{====================================================================}
{===BuildStaticTrees=================================================}
procedure BuildStaticTrees;
var
i : integer;
CodeLens : array [0..287] of integer;
begin
{this routine builds the static huffman trees, those whose code
lengths are determined by the deflate spec}
{the static literal tree first}
for i := 0 to 143 do
CodeLens[i] := 8;
for i := 144 to 255 do
CodeLens[i] := 9;
for i := 256 to 279 do
CodeLens[i] := 7;
for i := 280 to 287 do
CodeLens[i] := 8;
AbStaticLiteralTree := TAbDfDecodeHuffmanTree.Create(288, 15, huBoth);
AbStaticLiteralTree.Build(CodeLens, 0, 288,
dfc_LitExtraBits, dfc_LitExtraOffset);
{the static distance tree afterwards}
for i := 0 to 31 do
CodeLens[i] := 5;
AbStaticDistanceTree := TAbDfDecodeHuffmanTree.Create(32, 15, huBoth);
AbStaticDistanceTree.Build(CodeLens, 0, 32,
dfc_DistExtraBits, dfc_DistExtraOffset);
end;
{====================================================================}
initialization
BuildStaticTrees;
finalization
AbStaticLiteralTree.Free;
AbStaticDistanceTree.Free;
end.

764
Abbrevia/source/AbDfInW.pas Normal file
View File

@@ -0,0 +1,764 @@
(* ***** 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: AbDfInW.pas *}
{*********************************************************}
{* Deflate input sliding window unit *}
{*********************************************************}
unit AbDfInW;
{$I AbDefine.inc}
interface
uses
Classes,
AbDfBase;
{Notes: TdfInputWindow implements a sliding window on data for the
LZ77 dictionary encoding.
The stream passed to the class is automatically read when
required to keep the internal buffer fully loaded.
}
type
TAbDfMatch = record
maLen : integer;
maDist : integer;
maLit : AnsiChar;
end;
type
PAbPointerList = ^TAbPointerList;
TAbPointerList = array[0..MaxInt div SizeOf(Pointer) - 1] of Pointer;
TAbDfInputWindow = class
private
FAdvanceStart : boolean;
FBuffer : PAnsiChar;
FBufferEnd : PAnsiChar;
FBytesUsed : longint;
FChainLen : integer;
FHashChains : PAbPointerList;
FHashHeads : PAbPointerList;
FHashIndex : integer;
FChecksum : longint;
FCurrent : PAnsiChar;
FLookAheadEnd : PAnsiChar;
FMaxMatchLen : integer;
FMustSlide : boolean;
FOnProgress : TAbProgressStep;
FSlidePoint : PAnsiChar;
FStart : PAnsiChar;
FStartOffset : longint;
FStream : TStream;
FStreamSize : Int64;
FUseCRC32 : boolean;
FUseDeflate64 : boolean;
FWinMask : integer;
FWinSize : integer;
protected
function iwGetChecksum : longint;
procedure iwReadFromStream;
procedure iwSetCapacity(aValue : longint);
procedure iwSlide;
public
constructor Create(aStream : TStream;
aStreamSize : Int64;
aWinSize : integer;
aChainLength : integer;
aUseDeflate64 : boolean;
aUseCRC32 : boolean);
destructor Destroy; override;
procedure Advance(aCount : integer;
aHashCount : integer);
procedure AdvanceByOne;
function FindLongestMatch(aAmpleLength : integer;
var aMatch : TAbDfMatch;
const aPrevMatch : TAbDfMatch) : boolean;
function GetNextChar : AnsiChar;
function GetNextKeyLength : integer;
function Position : longint;
procedure ReadBuffer(var aBuffer; aCount : longint;
aOffset : Int64);
property ChainLen : integer read FChainLen write FChainLen;
property Checksum : longint read iwGetChecksum;
property OnProgress : TAbProgressStep
read FOnProgress write FOnProgress;
end;
implementation
uses
SysUtils;
{Notes:
Meaning of the internal pointers:
|----------+===================+==+--------------------------|
| | | | |
FBuffer FStart FCurrent FLookAheadEnd FBufferEnd
FCurrent is the current match position. The valid data that
can be matched is between FStart and FLookAheadEnd, The data
between FStart and FCurrent has already been seen; the data
between FCurrent and FLookAheadEnd can be used for matching.
The buffer size depends on the requested window size (a
multiple of 1KB, up to 32KB for deflate, up to 64KB for
deflate64) and the lookahead size (up to 258 bytes for deflate
and 64KB for deflate64.)
The window of data continuously slides to the right, and is
slid back to FBuffer whenever FStart reaches a point 16KB
away, this point being given by FSlidePoint.
The hash table:
This is a chained hash table with some peculiarities. First
the table itself, FHashHeads. It contains pointers to strings
in the window buffer, not to chains. The chains are held is a
separate structure, FHashChains. The hash function on the
three-character keys is a Rabin-Karp function:
((((Ch1 shl 5) xor Ch2) shl 5) xor Ch3) and $3FFF
designed so that a running hash value can be kept and
calculated per character. The hash table is $4000 elements
long (obviously, given the hash function).
On insertion, the previous pointer in the hash table at the
calculated index is saved and replaced by the new pointer. The
old pointer is saved in the chains array. This has the same
number of elements as the sliding window has characters. The
pointer is placed at (Ptr and (WindowsSize-1)) overwriting the
value that's already there. In this fashion the individual
chains in the standard hash table are interwoven with each
other in this hash table, like a skein of threads.
}
const
c_HashCount = $4000; {the number of hash entries}
c_HashMask = c_HashCount - 1; {a mask for the hash function}
c_HashShift = 5; {shift value for the hash function}
{===TAbDfInputWindow=================================================}
constructor TAbDfInputWindow.Create(aStream : TStream;
aStreamSize : Int64;
aWinSize : integer;
aChainLength : integer;
aUseDeflate64 : boolean;
aUseCRC32 : boolean);
begin
{create the ancestor}
inherited Create;
{save parameters}
FStreamSize := aStreamSize;
FWinSize := aWinSize;
FWinMask := aWinSize - 1;
FStream := aStream;
FChainLen := aChainLength;
FUseDeflate64 := aUseDeflate64;
FUseCRC32 := aUseCRC32;
if aUseCRC32 then
FChecksum := -1 { CRC32 starts off with all bits set }
else
FCheckSum := 1; { Adler32 starts off with a value of 1 }
{set capacity of sliding window}
iwSetCapacity(aWinSize);
{create the hash table, first the hash table itself (and set all
entries to nil)}
FHashHeads := AllocMem(c_HashCount * sizeof(pointer));
{..now the chains (there's no need to set the entries to nil, since
the chain entries get fed from the head entries before searching)}
GetMem(FHashChains, aWinSize * sizeof(pointer));
{read the first chunk of data from the stream}
FMustSlide := true;
iwReadFromStream;
{if there are at least two bytes, prime the hash index}
if ((FLookAheadEnd - FBuffer) >= 2) then
FHashIndex := ((longint(FBuffer[0]) shl c_HashShift) xor
longint(FBuffer[1])) and
c_HashMask;
end;
{--------}
destructor TAbDfInputWindow.Destroy;
begin
{free the hash table}
FreeMem(FHashHeads);
FreeMem(FHashChains);
{free the buffer}
FreeMem(FBuffer);
{destroy the ancestor}
inherited Destroy;
end;
{--------}
procedure TAbDfInputWindow.Advance(aCount : integer;
aHashCount : integer);
var
i : integer;
ByteCount : integer;
Percent : integer;
HashChains: PAbPointerList;
HashHeads : PAbPointerList;
HashInx : integer;
CurPos : PAnsiChar;
begin
Assert((FLookAheadEnd - FCurrent) >= aCount,
'TAbDfInputWindow.Advance: seem to be advancing into the unknown');
Assert((aHashCount = aCount) or (aHashCount = pred(aCount)),
'TAbDfInputWindow.Advance: the parameters are plain wrong');
{use local var for speed}
CurPos := FCurrent;
{advance the current pointer if needed}
if (aCount > aHashCount) then
inc(CurPos);
{make sure we update the hash table; remember that the string[3] at
the current position has already been added to the hash table (for
notes on updating the hash table, see FindLongestMatch}
{use local vars for speed}
HashChains := FHashChains;
HashHeads := FHashHeads;
HashInx := FHashIndex;
{update the hash table}
for i := 0 to pred(aHashCount) do begin
HashInx :=
((HashInx shl c_HashShift) xor longint(CurPos[2])) and
c_HashMask;
HashChains^[longint(CurPos) and FWinMask] :=
HashHeads^[HashInx];
HashHeads^[HashInx] := CurPos;
inc(CurPos);
end;
{replace old values}
FHashChains := HashChains;
FHashHeads := HashHeads;
FHashIndex := HashInx;
FCurrent := CurPos;
{if we've seen at least FWinSize bytes...}
if FAdvanceStart then begin
{advance the start of the sliding window}
inc(FStart, aCount);
inc(FStartOffset, aCount);
{check to see if we have advanced into the slide zone}
if FMustSlide and (FStart >= FSlidePoint) then
iwSlide;
end
{otherwise check to see if we've seen at least FWinSize bytes}
else if ((CurPos - FStart) >= FWinSize) then begin
FAdvanceStart := true;
{note: we can't advance automatically aCount bytes here, we need
to calculate the actual count}
ByteCount := (CurPos - FWinSize) - FStart;
inc(FStart, ByteCount);
inc(FStartOffset, ByteCount);
end;
{show progress}
if Assigned(FOnProgress) then begin
inc(FBytesUsed, aCount);
if ((FBytesUsed and $FFF) = 0) then begin
Percent := Round((100.0 * FBytesUsed) / FStreamSize);
FOnProgress(Percent);
end;
end;
{check to see if we have advanced into the slide zone}
if (FStart >= FSlidePoint) then
iwSlide;
end;
{--------}
procedure TAbDfInputWindow.AdvanceByOne;
var
Percent : integer;
begin
{advance the current pointer}
inc(FCurrent);
{if we've seen at least FWinSize bytes...}
if FAdvanceStart then begin
{advance the start of the sliding window}
inc(FStart, 1);
inc(FStartOffset, 1);
{check to see if we have advanced into the slide zone}
if FMustSlide and (FStart >= FSlidePoint) then
iwSlide;
end
{otherwise check to see if we've seen FWinSize bytes}
else if ((FCurrent - FStart) = FWinSize) then
FAdvanceStart := true;
{show progress}
if Assigned(FOnProgress) then begin
inc(FBytesUsed, 1);
if ((FBytesUsed and $FFF) = 0) then begin
Percent := Round((100.0 * FBytesUsed) / FStreamSize);
FOnProgress(Percent);
end;
end;
end;
{--------}
function TAbDfInputWindow.FindLongestMatch(aAmpleLength : integer;
var aMatch : TAbDfMatch;
const aPrevMatch : TAbDfMatch)
: boolean;
{Note: this routine implements a greedy algorithm and is by far the
time sink for compression. There are two versions, one written
in Pascal for understanding, one in assembler for speed.
Activate one and only one of the following compiler defines.}
{$IFDEF CPU386}
{$DEFINE UseGreedyAsm}
{$ELSE}
{$DEFINE UseGreedyPascal}
{$ENDIF}
{Check to see that all is correct}
{$IFDEF UseGreedyAsm}
{$IFDEF UseGreedyPascal}
!! Compile Error: only one of the greedy compiler defines can be used
{$ENDIF}
{$ELSE}
{$IFNDEF UseGreedyPascal}
!! Compile Error: one of the greedy compiler defines must be used
{$ENDIF}
{$ENDIF}
type
PLongint = ^longint;
PWord = ^word;
var
MaxLen : longint;
MaxDist : longint;
MaxMatch : integer;
ChainLen : integer;
PrevStrPos : PAnsiChar;
CurPos : PAnsiChar;
{$IFDEF UseGreedyAsm}
CurWord : word;
MaxWord : word;
{$ENDIF}
{$IFDEF UseGreedyPascal}
Len : longint;
MatchStr : PAnsiChar;
CurrentCh : PAnsiChar;
CurCh : AnsiChar;
MaxCh : AnsiChar;
{$ENDIF}
begin
{calculate the hash index for the current position; using the
Rabin-Karp algorithm this is equal to the previous index less the
effect of the character just lost plus the effect of the character
just gained}
CurPos := FCurrent;
FHashIndex :=
((FHashIndex shl c_HashShift) xor longint(CurPos[2])) and
c_HashMask;
{get the head of the hash chain: this is the position in the sliding
window of the previous 3-character string with this hash value}
PrevStrPos := FHashHeads^[FHashIndex];
{set the head of the hash chain equal to our current position}
FHashHeads^[FHashIndex] := CurPos;
{update the chain itself: set the entry for this position equal to
the previous string position}
FHashChains^[longint(CurPos) and FWinMask] := PrevStrPos;
{calculate the maximum match we could do at this position}
MaxMatch := (FLookAheadEnd - CurPos);
if (MaxMatch > FMaxMatchLen) then
MaxMatch := FMaxMatchLen;
if (aAmpleLength > MaxMatch) then
aAmpleLength := MaxMatch;
{calculate the current match length}
if (aPrevMatch.maLen = 0) then
MaxLen := 2
else begin
if (MaxMatch < aPrevMatch.maLen) then begin
Result := false;
aMatch.maLen := 0;
aMatch.maLit := CurPos^;
Exit;
end;
MaxLen := aPrevMatch.maLen;
end;
{get the bytes at the current position and at the end of the maximum
match we have to better}
{$IFDEF UseGreedyAsm}
CurWord := PWord(CurPos)^;
MaxWord := PWord(CurPos + pred(MaxLen))^;
{$ENDIF}
{$IFDEF UseGreedyPascal}
CurCh := CurPos^;
MaxCh := (CurPos + pred(MaxLen))^;
{$ENDIF}
{set the chain length to search based on the current maximum match
(basically: if we've already satisfied the ample length
requirement, don't search as far)}
if (MaxLen >= aAmpleLength) then
ChainLen := FChainLen div 4
else
ChainLen := FChainLen;
{get ready for the loop}
{$IFDEF DefeatWarnings}
MaxDist := 0;
{$ENDIF}
{$IFDEF UseGreedyAsm} { slip into assembler for speed...}
asm
push ebx { save those registers we should}
push esi
push edi
mov ebx, Self { ebx will store the Self pointer}
mov edi, PrevStrPos { edi => previous string}
mov esi, CurPos { esi => current string}
@@TestThisPosition:
{ check previous string is in range}
or edi, edi
je @@Exit
cmp edi, [ebx].TAbDfInputWindow.FStart
jb @@Exit
cmp edi, CurPos
jae @@Exit
mov ax, [edi] { check previous string starts with same}
cmp CurWord, ax { two bytes as current}
jne @@GetNextPosition { ..nope, they don't match}
mov edx, edi { check previous string ends with same}
add edi, MaxLen { two bytes as current (by "ends" we}
dec edi { mean the last two bytes at the}
mov ax, [edi] { current match length)}
cmp MaxWord, ax
mov edi, edx
jne @@GetNextPosition { ..nope, they don't match}
push edi { compare the previous string with the}
push esi { current string}
mov eax, MaxMatch
add edi, 2 { (we've already checked that the first}
sub eax, 2 { two characters are the same)}
add esi, 2
mov ecx, eax
@@CmpQuads:
cmp ecx, 4
jb @@CmpSingles
mov edx, [esi]
cmp edx, [edi]
jne @@CmpSingles
add esi, 4
add edi, 4
sub ecx, 4
jnz @@CmpQuads
jmp @@MatchCheck
@@CmpSingles:
or ecx, ecx
jb @@MatchCheck
mov dl, [esi]
cmp dl, [edi]
jne @@MatchCheck
inc esi
inc edi
dec ecx
jnz @@CmpSingles
@@MatchCheck:
sub eax, ecx
add eax, 2
pop esi
pop edi
cmp eax, MaxLen { have we found a longer match?}
jbe @@GetNextPosition { ..no}
mov MaxLen, eax { ..yes, so save it}
mov eax, esi { calculate the dist for this new match}
sub eax, edi
mov MaxDist, eax
cmp eax, aAmpleLength { if this match is ample enough, exit}
jae @@Exit
mov eax, esi { calculate the two bytes at the end of}
add eax, MaxLen { this new match}
dec eax
mov ax, [eax]
mov MaxWord, ax
@@GetNextPosition:
mov eax, ChainLen { we've visited one more link on the}
dec eax { chain, if that's the last one we}
je @@Exit { should visit, exit}
mov ChainLen, eax
{ advance along the chain}
mov edx, [ebx].TAbDfInputWindow.FHashChains
mov eax, [ebx].TAbDfInputWindow.FWinMask
and edi, eax
shl edi, 2
mov edi, [edx+edi]
jmp @@TestThisPosition
@@Exit:
pop edi
pop esi
pop ebx
end;
{$ENDIF}
{$IFDEF UseGreedyPascal}
{for all possible hash nodes in the chain...}
while (FStart <= PrevStrPos) and (PrevStrPos < CurPos) do begin
{if the initial and maximal characters match...}
if (PrevStrPos[0] = CurCh) and
(PrevStrPos[pred(MaxLen)] = MaxCh) then begin
{compare more characters}
Len := 1;
CurrentCh := CurPos + 1;
MatchStr := PrevStrPos + 1;
{compare away, but don't go above the maximum length}
while (Len < MaxMatch) and (MatchStr^ = CurrentCh^) do begin
inc(CurrentCh);
inc(MatchStr);
inc(Len);
end;
{have we reached another maximum for the length?}
if (Len > MaxLen) then begin
MaxLen := Len;
{calculate the distance}
MaxDist := CurPos - PrevStrPos;
MaxCh := CurPos[pred(MaxLen)];
{is the new best length ample enough?}
if MaxLen >= aAmpleLength then
Break;
end;
end;
{have we reached the end of this chain?}
dec(ChainLen);
if (ChainLen = 0) then
Break;
{otherwise move onto the next position}
PrevStrPos := FHashChains^[longint(PrevStrPos) and FWinMask];
end;
{$ENDIF}
{based on the results of our investigation, return the match values}
if (MaxLen < 3) or (MaxLen <= aPrevMatch.maLen) then begin
Result := false;
aMatch.maLen := 0;
aMatch.maLit := CurPos^;
end
else begin
Result := true;
aMatch.maLen := MaxLen;
aMatch.maDist := MaxDist;
aMatch.maLit := CurPos^; { just in case...}
end;
end;
{--------}
function TAbDfInputWindow.GetNextChar : AnsiChar;
begin
Result := FCurrent^;
inc(FCurrent);
end;
{--------}
function TAbDfInputWindow.GetNextKeyLength : integer;
begin
Result := FLookAheadEnd - FCurrent;
if (Result > 3) then
Result := 3;
end;
{--------}
function TAbDfInputWindow.iwGetChecksum : longint;
begin
{the CRC32 checksum algorithm requires a post-conditioning step
after being calculated (the result is NOTted), whereas Adler32 does
not}
if FUseCRC32 then
Result := not FChecksum
else
Result := FChecksum;
end;
{--------}
procedure TAbDfInputWindow.iwReadFromStream;
var
BytesRead : longint;
BytesToRead : longint;
begin
{read some more data into the look ahead zone}
BytesToRead := FBufferEnd - FLookAheadEnd;
BytesRead := FStream.Read(FLookAheadEnd^, BytesToRead);
{if nothing was read, we reached the end of the stream; hence
there's no more need to slide the window since we have all the
data}
if (BytesRead = 0) then
FMustSlide := false
{otherwise something was actually read...}
else begin
{update the checksum}
if FUseCRC32 then
AbUpdateCRCBuffer(FChecksum, FLookAheadEnd^, BytesRead)
else
AbUpdateAdlerBuffer(FChecksum, FLookAheadEnd^, BytesRead);
{reposition the pointer for the end of the lookahead area}
inc(FLookAheadEnd, BytesRead);
end;
end;
{--------}
procedure TAbDfInputWindow.iwSetCapacity(aValue : longint);
var
ActualSize : integer;
begin
{calculate the actual size; this will be the value passed in, plus
the correct look ahead size, plus 16KB}
ActualSize := aValue + (16 * 1024);
if FUseDeflate64 then begin
inc(ActualSize, dfc_MaxMatchLen64);
FMaxMatchLen := dfc_MaxMatchLen64;
end
else begin
inc(ActualSize, dfc_MaxMatchLen);
FMaxMatchLen := dfc_MaxMatchLen;
end;
{get the new buffer}
GetMem(FBuffer, ActualSize);
{set the other buffer pointers}
FStart := FBuffer;
FCurrent := FBuffer;
FLookAheadEnd := FBuffer;
FBufferEnd := FBuffer + ActualSize;
FSlidePoint := FBuffer + (16 * 1024);
end;
{--------}
procedure TAbDfInputWindow.iwSlide;
type
PLongint = ^longint;
var
i : integer;
ByteCount : integer;
Buffer : longint;
ListItem : PLongint;
begin
{move current valid data back to the start of the buffer}
ByteCount := FLookAheadEnd - FStart;
Move(FStart^, FBuffer^, ByteCount);
{reset the various pointers}
ByteCount := FStart - FBuffer;
FStart := FBuffer;
dec(FCurrent, ByteCount);
dec(FLookAheadEnd, ByteCount);
{patch up the hash table: the head pointers}
Buffer := longint(FBuffer);
ListItem := PLongint(@FHashHeads^[0]);
for i := 0 to pred(c_HashCount) do begin
dec(ListItem^, ByteCount);
if (ListItem^ < Buffer) then
ListItem^ := 0;
inc(PAnsiChar(ListItem), sizeof(pointer));
end;
{..the chain pointers}
ListItem := PLongint(@FHashChains^[0]);
for i := 0 to pred(FWinSize) do begin
dec(ListItem^, ByteCount);
if (ListItem^ < Buffer) then
ListItem^ := 0;
inc(PAnsiChar(ListItem), sizeof(pointer));
end;
{now read some more data from the stream}
iwReadFromStream;
end;
{--------}
function TAbDfInputWindow.Position : longint;
begin
Result := (FCurrent - FStart) + FStartOffset;
end;
{--------}
procedure TAbDfInputWindow.ReadBuffer(var aBuffer; aCount : longint;
aOffset : Int64);
var
CurPos : Int64;
begin
CurPos := FStream.Seek(0, soCurrent);
FStream.Seek(aOffSet, soBeginning);
FStream.ReadBuffer(aBuffer, aCount);
FStream.Seek(CurPos, soBeginning);
end;
{====================================================================}
end.

View File

@@ -0,0 +1,377 @@
(* ***** 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: AbDfOutW.pas *}
{*********************************************************}
{* Deflate output sliding window *}
{*********************************************************}
unit AbDfOutW;
{$I AbDefine.inc}
interface
uses
Classes,
AbDfBase;
{Notes: TAbDfOutputWindow implements a sliding window on previously
written data for the LZ77 dictionary decoding.
AddLiteral will add a literal character at the current
position and advance by one. AddLenDist will copy the required
number of characters from the given position to the current
position, and advance the stream on by the length. The class
will periodically update the stream from the internal buffer.
For normal Deflate, the internal buffer is 48K + 512 bytes in
size. Once there is 48Kb worth of data, 16KB is written to
file, and the buffer is shifted left by 16KB. We need to keep
the last decoded 32KB in memory at all times.
For Deflate64, the internal buffer is 96K + 512 bytes in
size. Once there is 96Kb worth of data, 32KB is written to
file, and the buffer is shifted left by 32KB. We need to keep
the last decoded 64KB in memory at all times.
}
type
TAbDfOutputWindow = class
private
FBuffer : PAnsiChar;
FChecksum : longint;
FCurrent : PAnsiChar;
FLog : TAbLogger;
FPartSize : longint;
FSlideCount : integer;
FStream : TStream;
FStreamPos : longint;
FTestOnly : boolean;
FUseCRC32 : boolean;
FWritePoint : PAnsiChar;
protected
function swGetChecksum : longint;
procedure swWriteToStream(aFlush : boolean);
public
constructor Create(aStream : TStream;
aUseDeflate64 : boolean;
aUseCRC32 : boolean;
aPartSize : longint;
aTestOnly : boolean;
aLog : TAbLogger);
destructor Destroy; override;
procedure AddBuffer(var aBuffer; aCount : integer);
procedure AddLiteral(aCh : AnsiChar);
procedure AddLenDist(aLen : integer; aDist : integer);
function Position : longint;
property Checksum : longint read swGetChecksum;
property Log : TAbLogger read FLog;
end;
implementation
uses
SysUtils;
{Notes:
Meaning of the internal pointers:
|==============================+------------------------+----|
| | |
FBuffer FCurrent FWritePoint
Once FCurrent reaches or exceeds FWritePoint, FSlideCount
bytes of data from FBuffer are written to the stream and the
remaining data is moved back FSlideCount bytes, moving
FCurrent along with it as well.
}
{===TAbDfOutputWindow==================================================}
constructor TAbDfOutputWindow.Create(aStream : TStream;
aUseDeflate64 : boolean;
aUseCRC32 : boolean;
aPartSize : longint;
aTestOnly : boolean;
aLog : TAbLogger);
var
Size : integer;
LookAheadSize : integer;
begin
{allow the ancestor to initialize}
inherited Create;
{save parameters}
FLog := aLog;
FStream := aStream;
FTestOnly := aTestOnly;
if (aPartSize <= 0) then
FPartSize := 0
else
FPartSize := aPartSize;
FUseCRC32 := aUseCRC32;
if aUseCRC32 then
FChecksum := -1 { CRC32 starts off with all bits set}
else
FCheckSum := 1; { Adler32 starts off with a value of 1}
{set capacity of sliding window}
if aUseDeflate64 then begin
Size := 96 * 1024;
FSlideCount := 32 * 1024;
LookAheadSize := 64 * 1024;
end
else begin
Size := 64 * 1024;
FSlideCount := 32 * 1024;
LookAheadSize := 258;
end;
GetMem(FBuffer, Size + LookAheadSize);
{set the other internal pointers}
FCurrent := FBuffer;
FWritePoint := FBuffer + Size;
if (FPartSize > Size) then
FPartSize := Size;
end;
{--------}
destructor TAbDfOutputWindow.Destroy;
begin
{write remaining data and free the buffer}
if (FBuffer <> nil) then begin
if (FCurrent <> FBuffer) then
swWriteToStream(true);
FreeMem(FBuffer);
end;
{destroy the ancestor}
inherited Destroy;
end;
{--------}
procedure TAbDfOutputWindow.AddBuffer(var aBuffer; aCount : integer);
var
Buffer : PAnsiChar;
BytesToWrite : integer;
begin
{if we've advanced to the point when we need to write, do so}
if (FCurrent >= FWritePoint) then
swWriteToStream(false);
{cast the user buffer to a PChar, it's easier to use}
Buffer := @aBuffer;
{calculate the number of bytes to copy}
BytesToWrite := FWritePoint - FCurrent;
if (BytesToWrite > aCount) then
BytesToWrite := aCount;
{move this block of bytes}
Move(Buffer^, FCurrent^, BytesToWrite);
{advance pointers and counters}
inc(FCurrent, BytesToWrite);
dec(aCount, BytesToWrite);
{while there is still data to copy...}
while (aCount > 0) do begin
{advance the user buffer pointer}
inc(Buffer, BytesToWrite);
{write the sliding window chunk to the stream}
swWriteToStream(false);
{calculate the number of bytes to copy}
BytesToWrite := FWritePoint - FCurrent;
if (BytesToWrite > aCount) then
BytesToWrite := aCount;
{move this block of bytes}
Move(Buffer^, FCurrent^, BytesToWrite);
{advance pointers and counters}
inc(FCurrent, BytesToWrite);
dec(aCount, BytesToWrite);
end;
end;
{--------}
procedure AddLenDistToLog(aLog : TAbLogger;
aPosn : longint;
aLen : integer;
aDist : integer;
aOverLap : boolean);
begin
{NOTE the reason for this separate routine is to avoid string
allocations and try..finally blocks in the main method: an
optimization issue}
if aOverLap then
aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d **overlap**',
[aPosn, aLen, aDist]))
else
aLog.WriteLine(Format('%8x Len: %-3d, Dist: %-5d',
[aPosn, aLen, aDist]));
end;
{--------}
procedure TAbDfOutputWindow.AddLenDist(aLen : integer; aDist : integer);
var
i : integer;
ToChar : PAnsiChar;
FromChar : PAnsiChar;
begin
{log it}
{$IFDEF UseLogging}
if (FLog <> nil) then
AddLenDistToLog(FLog, Position, aLen, aDist, (aLen > aDist));
{$ENDIF}
{if the length to copy is less than the distance, just do a move}
if (aLen <= aDist) then begin
Move((FCurrent - aDist)^ , FCurrent^, aLen);
end
{otherwise we have to use a byte-by-byte copy}
else begin
FromChar := FCurrent - aDist;
ToChar := FCurrent;
for i := 1 to aLen do begin
ToChar^ := FromChar^;
inc(FromChar);
inc(ToChar);
end;
end;
{increment the current pointer}
inc(FCurrent, aLen);
{if we've reached the point requested, abort}
if (FPartSize > 0) and ((FCurrent - FBuffer) >= FPartSize) then
raise EAbPartSizedInflate.Create(''); {NOTE: This exception is expected during detection of .GZ and .TGZ files. (VerifyGZip)}
{if we've advanced to the point when we need to write, do so}
if (FCurrent >= FWritePoint) then
swWriteToStream(false);
end;
{--------}
procedure AddLiteralToLog(aLog : TAbLogger;
aPosn : longint;
aCh : AnsiChar);
begin
{NOTE the reason for this separate routine is to avoid string
allocations and try..finally blocks in the main method: an
optimization issue}
if (' ' < aCh) and (aCh <= '~') then
aLog.WriteLine(Format('%8x Char: %3d $%2x [%s]', [aPosn, ord(aCh), ord(aCh), aCh]))
else
aLog.WriteLine(Format('%8x Char: %3d $%2x', [aPosn, ord(aCh), ord(aCh)]));
end;
{--------}
procedure TAbDfOutputWindow.AddLiteral(aCh : AnsiChar);
begin
{log it}
{$IFDEF UseLogging}
if (FLog <> nil) then
AddLiteralToLog(FLog, Position, aCh);
{$ENDIF}
{add the literal to the buffer}
FCurrent^ := aCh;
{increment the current pointer}
inc(FCurrent);
{if we've reached the point requested, abort}
if (FPartSize > 0) and ((FCurrent - FBuffer) >= FPartSize) then
raise EAbPartSizedInflate.Create('');
{if we've advanced to the point when we need to write, do so}
if (FCurrent >= FWritePoint) then
swWriteToStream(false);
end;
{--------}
function TAbDfOutputWindow.Position : longint;
begin
if FTestOnly then
Result := FStreamPos + (FCurrent - FBuffer)
else
Result := FStream.Position + (FCurrent - FBuffer);
end;
{--------}
function TAbDfOutputWindow.swGetChecksum : longint;
begin
{since the checksum is calculated by the method that flushes to the
stream, make sure any buffered data is written out first}
if (FCurrent <> FBuffer) then
swWriteToStream(true);
{the CRC32 checksum algorithm requires a post-conditioning step
after being calculated (the result is NOTted), whereas Adler32 does
not}
if FUseCRC32 then
Result := not FChecksum
else
Result := FChecksum;
end;
{--------}
procedure TAbDfOutputWindow.swWriteToStream(aFlush : boolean);
var
FromPtr : PAnsiChar;
begin
{if the request was to flush, write all remaining data after
updating the checksum}
if aFlush then begin
if FUseCRC32 then
AbUpdateCRCBuffer(FChecksum, FBuffer^, FCurrent - FBuffer)
else
AbUpdateAdlerBuffer(FChecksum, FBuffer^, FCurrent - FBuffer);
if FTestOnly then
inc(FStreamPos, FCurrent - FBuffer)
else
FStream.WriteBuffer(FBuffer^, FCurrent - FBuffer);
FCurrent := FBuffer;
end
{otherwise, update the checksum with the data in the sliding window
chunk, write it out to the stream, and move the rest of the buffer
back}
else begin
if FUseCRC32 then
AbUpdateCRCBuffer(FChecksum, FBuffer^, FSlideCount)
else
AbUpdateAdlerBuffer(FChecksum, FBuffer^, FSlideCount);
if FTestOnly then
inc(FStreamPos, FSlideCount)
else
FStream.WriteBuffer(FBuffer^, FSlideCount);
FromPtr := FBuffer + FSlideCount;
Move(FromPtr^, FBuffer^, FCurrent - FromPtr);
FCurrent := FCurrent - FSlideCount;
end;
end;
{====================================================================}
end.

View File

@@ -0,0 +1,282 @@
(* ***** 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: AbDfPkMg.pas *}
{*********************************************************}
{* Deflate package-merge algorithm *}
{*********************************************************}
unit AbDfPkMg;
{$I AbDefine.inc}
interface
uses
AbDfBase;
procedure GenerateCodeLengths(aMaxCodeLen : integer;
const aWeights : array of integer;
var aCodeLengths : array of integer;
aStartInx : integer;
aLog : TAbLogger);
implementation
type
PPkgNode = ^TPkgNode;
TPkgNode = packed record
pnWeight : integer;
pnCount : integer;
pnLeft : PPkgNode;
pnRight : PPkgNode;
end;
PPkgNodeList = ^TPkgNodeList;
TPkgNodeList = array [0..pred(286 * 2)] of PPkgNode;
{Note: the "286" is the number of literal/length symbols, the
maximum number of weights we'll be calculating the optimal
code lengths for}
{===helper routines==================================================}
function IsCalcFeasible(aCount : integer;
aMaxCodeLen : integer) : boolean;
begin
{works out if length-limited codes can be calculated for a given
number of symbols and the maximum code length}
{return whether 2^aMaxCodeLen > aCount}
Result := (1 shl aMaxCodeLen) > aCount;
end;
{--------}
procedure QSS(aList : PPkgNodeList;
aFirst : integer;
aLast : integer);
var
L, R : integer;
Pivot : integer;
Temp : pointer;
begin
{while there are at least two items to sort}
while (aFirst < aLast) do begin
{the pivot is the middle item}
Pivot := aList^[(aFirst+aLast) div 2]^.pnWeight;
{set indexes and partition}
L := pred(aFirst);
R := succ(aLast);
while true do begin
repeat dec(R); until (aList^[R]^.pnWeight <= Pivot);
repeat inc(L); until (aList^[L]^.pnWeight >= Pivot);
if (L >= R) then Break;
Temp := aList^[L];
aList^[L] := aList^[R];
aList^[R] := Temp;
end;
{quicksort the first subfile}
if (aFirst < R) then
QSS(aList, aFirst, R);
{quicksort the second subfile - recursion removal}
aFirst := succ(R);
end;
end;
{--------}
procedure SortList(aList : PPkgNodeList; aCount : integer);
begin
QSS(aList, 0, pred(aCount));
end;
{--------}
procedure Accumulate(aNode : PPkgNode);
begin
while (aNode^.pnLeft <> nil) do begin
Accumulate(aNode^.pnLeft);
aNode := aNode^.pnRight;
end;
inc(aNode^.pnCount);
end;
{====================================================================}
{===Interfaced routine===============================================}
procedure GenerateCodeLengths(aMaxCodeLen : integer;
const aWeights : array of integer;
var aCodeLengths : array of integer;
aStartInx : integer;
aLog : TAbLogger);
var
i : integer;
Bit : integer;
WeightCount : integer;
OrigList : PPkgNodeList;
OrigListCount : integer;
MergeList : PPkgNodeList;
MergeListCount : integer;
PkgList : PPkgNodeList;
PkgListCount : integer;
OrigInx : integer;
PkgInx : integer;
Node : PPkgNode;
NodeMgr : TAbNodeManager;
begin
{calculate the number of weights}
WeightCount := succ(high(aWeights));
{check for dumb programming errors}
Assert((0 < aMaxCodeLen) and (aMaxCodeLen <= 15),
'GenerateCodeLengths: the maximum code length should be in the range 1..15');
Assert((1 <= WeightCount) and (WeightCount <= 286),
'GenerateCodeLengths: the weight array must have 1..286 elements');
Assert(IsCalcFeasible(WeightCount, aMaxCodeLen),
'GenerateCodeLengths: the package-merge algorithm should always be feasible');
{clear the code lengths array}
FillChar(aCodeLengths[aStartInx], WeightCount * sizeof(integer), 0);
{prepare for the try..finally}
OrigList := nil;
MergeList := nil;
PkgList := nil;
NodeMgr := nil;
try
{create the node manager}
NodeMgr := TAbNodeManager.Create(sizeof(TPkgNode));
{create the original list of nodes}
GetMem(OrigList, WeightCount * sizeof(PPkgNode));
OrigListCount := 0;
for i := 0 to pred(WeightCount) do
if (aWeights[i] <> 0) then begin
Node := NodeMgr.AllocNode;
Node^.pnLeft := nil; { this will indicate a leaf}
Node^.pnRight := pointer(i); { the index of the weight}
Node^.pnWeight := aWeights[i]; { the weight itself}
Node^.pnCount := 1; { how many times used}
OrigList^[OrigListCount] := Node;
inc(OrigListCount);
end;
{we need at least 2 items, so make anything less a special case}
if (OrigListCount <= 1) then begin
{if there are no items at all in the original list, we need to
pretend that there is one, since we shall eventually need to
calculate a Count-1 value that cannot be negative}
if (OrigListCount = 0) then begin
aCodeLengths[aStartInx] := 1;
Exit;
end;
{otherwise there is only one item: set its code length directly}
for i := 0 to pred(WeightCount) do
if (aWeights[i] <> 0) then begin
aCodeLengths[aStartInx + i] := 1;
Exit;
end;
end;
{there are at least 2 items in the list; so sort the list}
SortList(OrigList, OrigListCount);
{create the merge and package lists}
GetMem(MergeList, OrigListCount * 2 * sizeof(PPkgNode));
GetMem(PkgList, OrigListCount * 2 * sizeof(PPkgNode));
{initialize the merge list to have the same items as the
original list}
Move(OrigList^, MergeList^, OrigListCount * sizeof(PPkgNode));
MergeListCount := OrigListCount;
{do aMaxCodeLen - 2 times...}
for Bit := 1 to pred(aMaxCodeLen) do begin
{generate the package list from the merge list by grouping pairs
from the merge list and adding them to the package list}
PkgListCount := 0;
for i := 0 to pred(MergeListCount div 2) do begin
Node := NodeMgr.AllocNode;
Node^.pnLeft := MergeList^[i * 2];
Node^.pnRight := MergeList^[i * 2 + 1];
Node^.pnWeight := Node^.pnLeft^.pnWeight +
Node^.pnRight^.pnWeight;
{$IFOPT C+}
Node^.pnCount := 0;
{$ENDIF}
PkgList^[PkgListCount] := Node;
inc(PkgListCount);
end;
{merge the original list and the package list}
MergeListCount := 0;
OrigInx := 0;
PkgInx := 0;
{note the optimization here: the package list will *always* be
last to empty in the merge process since it will have at least
one item whose accumulated weight is greater than all of the
items in the original list}
while (OrigInx < OrigListCount) and (PkgInx < PkgListCount) do begin
if (OrigList^[OrigInx]^.pnWeight <= PkgList^[PkgInx]^.pnWeight) then begin
MergeList^[MergeListCount] := OrigList^[OrigInx];
inc(OrigInx);
end
else begin
MergeList^[MergeListCount] := PkgList^[PkgInx];
inc(PkgInx);
end;
inc(MergeListCount);
end;
if (OrigInx < OrigListCount) then begin
Move(OrigList^[OrigInx], MergeList^[MergeListCount],
(OrigListCount - OrigInx) * sizeof(PPkgNode));
inc(MergeListCount, (OrigListCount - OrigInx));
end
else begin
Move(PkgList^[PkgInx], MergeList^[MergeListCount],
(PkgListCount - PkgInx) * sizeof(PPkgNode));
inc(MergeListCount, (PkgListCount - PkgInx));
end;
end;
{calculate the code lengths}
for i := 0 to (OrigListCount * 2) - 3 do begin
Node := MergeList^[i];
if (Node^.pnLeft <> nil) then
Accumulate(Node);
end;
for i := 0 to pred(OrigListCount) do
aCodeLengths[aStartInx + integer(OrigList^[i].pnRight)] :=
OrigList^[i].pnCount;
finally
FreeMem(OrigList);
FreeMem(MergeList);
FreeMem(PkgList);
NodeMgr.Free;
end;
end;
{====================================================================}
end.

1519
Abbrevia/source/AbDfStrm.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,194 @@
(* ***** 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: AbDfXlat.pas *}
{*********************************************************}
{* Deflate length/dist to symbol translator *}
{*********************************************************}
unit AbDfXlat;
{$I AbDefine.inc}
interface
uses
SysUtils;
type
TAbDfTranslator = class
private
FBuffer : PAnsiChar;
FLenSymbols : PByteArray;
{for lengths 3..258}
FLongDistSymbols : PByteArray;
{for distances 32769..65536 (deflate64)}
FMediumDistSymbols : PByteArray;
{for distances 257..32768}
FShortDistSymbols : PByteArray;
{for distances 1..256}
protected
procedure trBuild;
public
constructor Create;
destructor Destroy; override;
function TranslateLength(aLen : integer): integer;
function TranslateDistance(aDist : integer) : integer;
property LenSymbols : PByteArray read FLenSymbols;
property LongDistSymbols : PByteArray read FLongDistSymbols;
property MediumDistSymbols : PByteArray read FMediumDistSymbols;
property ShortDistSymbols : PByteArray read FShortDistSymbols;
end;
var
AbSymbolTranslator : TAbDfTranslator;
implementation
uses
AbDfBase;
{====================================================================}
constructor TAbDfTranslator.Create;
begin
{create the ancestor}
inherited Create;
{allocate the translation arrays (the buffer *must* be zeroed)}
FBuffer := AllocMem(256 + 2 + 256 + 256);
FLenSymbols := PByteArray(FBuffer);
FLongDistSymbols := PByteArray(FBuffer + 256);
FMediumDistSymbols := PByteArray(FBuffer + 256 + 2);
FShortDistSymbols := PByteArray(FBuffer + 256 + 2 + 256);
{build the translation arrays}
trBuild;
end;
{--------}
destructor TAbDfTranslator.Destroy;
begin
if (FBuffer <> nil) then
FreeMem(FBuffer);
inherited Destroy;
end;
{--------}
function TAbDfTranslator.TranslateDistance(aDist : integer) : integer;
begin
{save against dumb programming mistakes}
Assert((1 <= aDist) and (aDist <= 65536),
'TAbDfTranslator.Translate: distance should be 1..65536');
{translate the distance}
if (aDist <= 256) then
Result := FShortDistSymbols[aDist - 1]
else if (aDist <= 32768) then
Result := FMediumDistSymbols[((aDist - 1) div 128) - 2]
else
Result := FLongDistSymbols[((aDist - 1) div 16384) - 2];
end;
{--------}
function TAbDfTranslator.TranslateLength(aLen : integer): integer;
begin
{save against dumb programming mistakes}
Assert((3 <= aLen) and (aLen <= 65536),
'TAbDfTranslator.Translate: length should be 3..65536');
{translate the length}
dec(aLen, 3);
if (0 <= aLen) and (aLen <= 255) then
Result := FLenSymbols[aLen] + 257
else
Result := 285;
end;
{--------}
procedure TAbDfTranslator.trBuild;
var
i : integer;
Len : integer;
Dist : integer;
Value : integer;
begin
{initialize the length translation array; elements will contain
(Symbol - 257) for a given (length - 3)}
for i := low(dfc_LengthBase) to pred(high(dfc_LengthBase)) do begin
Len := dfc_LengthBase[i] - 3;
FLenSymbols[Len] := i;
end;
FLenSymbols[255] := 285 - 257;
Value := -1;
for i := 0 to 255 do begin
if (Value < FLenSymbols[i]) then
Value := FLenSymbols[i]
else
FLenSymbols[i] := Value;
end;
{initialize the short distance translation array: it will contain
the Symbol for a given (distance - 1) where distance <= 256}
for i := 0 to 15 do begin
Dist := dfc_DistanceBase[i] - 1;
FShortDistSymbols[Dist] := i;
end;
Value := -1;
for i := 0 to 255 do begin
if (Value < FShortDistSymbols[i]) then
Value := FShortDistSymbols[i]
else
FShortDistSymbols[i] := Value;
end;
{initialize the medium distance translation array: it will contain
the Symbol for a given (((distance - 1) div 128) - 2) where
distance is in the range 256..32768}
for i := 16 to 29 do begin
Dist := ((dfc_DistanceBase[i] - 1) div 128) - 2;
FMediumDistSymbols[Dist] := i;
end;
Value := -1;
for i := 0 to 255 do begin
if (Value < FMediumDistSymbols[i]) then
Value := FMediumDistSymbols[i]
else
FMediumDistSymbols[i] := Value;
end;
{initialize the long distance translation array: it will contain the
Symbol for a given ((distance - 1) div 16384) - 2) for distances
over 32768 in deflate64}
FLongDistSymbols[0] := 30;
FLongDistSymbols[1] := 31;
end;
{====================================================================}
initialization
AbSymbolTranslator := TAbDfTranslator.Create;
finalization
AbSymbolTranslator.Free;
end.

Binary file not shown.

View File

@@ -0,0 +1,243 @@
(* ***** 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: AbDlgDir.pas *}
{*********************************************************}
{* ABBREVIA: Dialog - Directory *}
{* Use AbQDgDir.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbDlgDir;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows, Messages, ShlObj, ActiveX,
{$ENDIF}
SysUtils, Classes,
{$IFDEF UsingClx}
QButtons, QExtCtrls, QGraphics, QForms, QControls, QStdCtrls,
{$ELSE}
Buttons, ExtCtrls, Graphics, Forms, Controls, StdCtrls,
{$WARN UNIT_PLATFORM OFF}
FileCtrl,
{$WARN UNIT_PLATFORM ON}
{$ENDIF}
AbResString;
type
{$IFNDEF UsingClx}
TDirDlg = class(TForm)
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
DriveComboBox1: TDriveComboBox;
DirectoryListBox1: TDirectoryListBox;
Panel1: TPanel;
procedure DirectoryListBox1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
public
SelectedFolder: string;
end;
{$ELSE}
TDirDlg = class(TForm)
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
Panel1: TPanel;
procedure DirectoryListBox1Change(Sender: TObject);
procedure FormCreate(Sender: TObject);
public
SelectedFolder: string;
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
type
TAbDirDlg = class(TComponent)
protected {private}
FAdditionalText : string;
FCaption : string;
FHandle : Integer;
FIDList : PItemIDList;
FSelectedFolder : string;
procedure SetSelectedFolder(const Value : string);
procedure FreeIDList;
public {properties}
property AdditionalText : string
read FAdditionalText
write FAdditionalText;
property Caption : string
read FCaption
write FCaption;
property Handle : Integer
read FHandle;
property IDList : PItemIDList
read FIDList;
property SelectedFolder : string
read FSelectedFolder
write SetSelectedFolder;
public {methods}
constructor Create(AOwner : TComponent);
override;
destructor Destroy;
override;
function Execute : Boolean;
end;
{$ENDIF}
var
DirDlg: TDirDlg;
implementation
{$IFNDEF UsingCLX}
{$R *.dfm}
{$ENDIF}
{== TAbDirDlg ========================================================}
{$IFDEF MSWINDOWS}
function AbDirDlgCallbackProc(hWnd : HWND; Msg : UINT; lParam : LPARAM;
Data : LPARAM): Integer; stdcall;
var
X, Y : Integer;
R : TRect;
Buf : array[0..MAX_PATH-1] of Char;
begin
Result := 0;
with TAbDirDlg(Data) do begin
case Msg of
BFFM_INITIALIZED :
begin
FHandle := hWnd;
if (FCaption <> '') then
SendMessage(hWnd, WM_SETTEXT, 0, Integer(PChar(FCaption)));
SendMessage(hWnd, BFFM_SETSELECTION, 1, Integer(PChar(SelectedFolder)));
GetWindowRect(hWnd, R);
X := (Screen.Width div 2) - ((R.Right - R.Left) div 2);
Y := (Screen.Height div 2) - ((R.Bottom - R.Top) div 2);
SetWindowPos(hWnd, 0, X, Y, 0, 0, SWP_NOSIZE or SWP_NOZORDER);
end;
BFFM_SELCHANGED :
if (FHandle <> 0) then begin
FIDList := PItemIDList(lParam);
SHGetPathFromIDList(IDList, Buf);
SelectedFolder := Buf;
end;
end;
end;
end;
{ -------------------------------------------------------------------------- }
constructor TAbDirDlg.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
end;
{ -------------------------------------------------------------------------- }
destructor TAbDirDlg.Destroy;
begin
if FIDList <> nil then
FreeIDList;
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
function TAbDirDlg.Execute : Boolean;
var
Info : TBrowseInfo;
Buf : array[0..MAX_PATH-1] of Char;
begin
if (FIDList <> nil) then
FreeIDList;
{$IFNDEF UsingClx}
if (Owner is TWinControl) then
Info.hwndOwner := (Owner as TWinControl).Handle
else if Owner is TApplication then
Info.hwndOwner := (Owner as TApplication).Handle
else
{$ENDIF}
Info.hwndOwner := 0;
Info.pidlRoot := nil;
Info.pszDisplayName := Buf;
Info.lpszTitle := PChar(FAdditionalText);
Info.ulFlags := BIF_RETURNONLYFSDIRS;
Info.lpfn := AbDirDlgCallbackProc;
Info.lParam := Integer(Self);
Info.iImage := 0;
FIDList := SHBrowseForFolder(Info);
FHandle := 0;
Result := (FIDList <> nil);
end;
{ -------------------------------------------------------------------------- }
procedure TAbDirDlg.FreeIDList;
var
Malloc : IMalloc;
begin
if coGetMalloc(MEMCTX_TASK, Malloc) = NOERROR then begin
Malloc.Free(FIDList);
FIDList := nil;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbDirDlg.SetSelectedFolder(const Value : string);
begin
FSelectedFolder := Value;
if FSelectedFolder <> '' then
if FSelectedFolder[Length(FSelectedFolder)] = '\' then
Delete(FSelectedFolder, Length(FSelectedFolder), 1);
if (Length(FSelectedFolder) = 2) then
FSelectedFolder := FSelectedFolder + '\';
end;
{$ENDIF}
{== TDirDlg ========================================================}
{ TDirDlg }
procedure TDirDlg.FormCreate(Sender: TObject);
begin
DirectoryListBox1Change(nil);
OKBtn.Caption := AbOKS;
CancelBtn.Caption := AbCancelS;
Caption := AbSelectDirectoryS;
end;
{ -------------------------------------------------------------------------- }
procedure TDirDlg.DirectoryListBox1Change(Sender: TObject);
begin
{$IFNDEF UsingClx}
SelectedFolder := DirectoryListBox1.Directory;
{$ENDIF}
Panel1.Caption := SelectedFolder;
end;
end.

Binary file not shown.

View File

@@ -0,0 +1,130 @@
(* ***** 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: AbDlgPwd.pas *}
{*********************************************************}
{* ABBREVIA: Dialog - Password *}
{* Use AbQDgPwd.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbDlgPwd;
{$R *.dfm}
{$ENDIF}
{$I AbDefine.inc}
interface
uses
SysUtils,
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
{$IFDEF UsingClx}
QGraphics, QForms, QControls, QStdCtrls,
QButtons, QExtCtrls,
{$ELSE}
Graphics, Forms, Controls, StdCtrls,
Buttons, ExtCtrls,
{$ENDIF}
Classes;
type
TPassWordDlg = class(TForm)
OKBtn: TButton;
CancelBtn: TButton;
Bevel1: TBevel;
Edit1: TEdit;
{$IFDEF MSWINDOWS}
Edit2: TEdit;
{$ENDIF}
Label1: TLabel;
{$IFDEF MSWINDOWS}
Label2: TLabel;
{$ENDIF}
procedure Edit1Change(Sender: TObject);
procedure Edit2Change(Sender: TObject);
procedure FormActivate(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
PassWordDlg: TPassWordDlg;
implementation
uses
AbResString;
procedure TPassWordDlg.Edit1Change(Sender: TObject);
begin
{$IFDEF MSWINDOWS}
Edit2.Text := '';
OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);
{$ELSE}
OKBtn.Enabled := true;
{$ENDIF}
end;
procedure TPassWordDlg.Edit2Change(Sender: TObject);
begin
{$IFDEF MSWINDOWS}
OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);
{$ELSE}
OKBtn.Enabled := true;
{$ENDIF}
end;
procedure TPassWordDlg.FormActivate(Sender: TObject);
begin
{$IFDEF MSWINDOWS}
OKBtn.Enabled := ( CompareStr( Edit1.Text, Edit2.Text ) = 0);
{$ELSE}
OKBtn.Enabled := true;
{$ENDIF}
end;
procedure TPassWordDlg.FormCreate(Sender: TObject);
begin
Caption := AbEnterPasswordS;
OKBtn.Caption := AbOKS;
CancelBtn.Caption := AbCancelS;
Label1.Caption := AbPasswordS;
{$IFDEF MSWINDOWS}
Label2.Caption := AbVerifyS;
{$ENDIF}
end;
end.

View File

@@ -0,0 +1,847 @@
(* ***** 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: AbExcept.pas *}
{*********************************************************}
{* ABBREVIA: Exception classes *}
{*********************************************************}
unit AbExcept;
{$I AbDefine.inc}
interface
uses
SysUtils,
AbUtils;
type
EAbException = class( Exception )
public
ErrorCode : Integer;
end;
EAbArchiveBusy = class( EAbException )
public
constructor Create;
end;
EAbBadStream = class( EAbException )
protected
FInnerException : Exception;
public
constructor Create;
constructor CreateInner(aInnerException : Exception);
property InnerException : Exception read FInnerException;
end;
EAbDuplicateName = class( EAbException )
public
constructor Create;
end;
EAbFileNotFound = class( EAbException )
public
constructor Create;
end;
EAbNoArchive = class( EAbException )
public
constructor Create;
end;
EAbUserAbort = class( EAbException )
public
constructor Create;
end;
EAbNoSuchDirectory = class( EAbException )
public
constructor Create;
end;
EAbUnhandledType = class( EAbException )
public
constructor Create;
end;
EAbSpanningNotSupported = class (EAbException)
public
constructor Create;
end;
EAbInvalidSpanningThreshold = class ( EAbException )
public
constructor Create;
end;
EAbZipException = class( EAbException ); {Zip exception}
EAbCabException = class( EAbException ); {Cab exception}
EAbTarException = class( EAbException ); {Tar Exception}
EAbGzipException = class( EAbException); {GZip exception}
EAbZipBadSpanStream = class( EAbZipException )
public
constructor Create;
end;
EAbZipBadCRC = class( EAbZipException )
public
constructor Create;
end;
EAbZipInflateBlock = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalid = class( EAbZipException )
public
constructor Create;
end;
EAbInvalidIndex = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalidFactor = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalidLFH = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalidMethod = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalidPassword = class( EAbZipException )
public
constructor Create;
end;
EAbZipInvalidStub= class( EAbZipException )
public
constructor Create;
end;
EAbZipNoExtraction = class( EAbZipException )
public
constructor Create;
end;
EAbZipNoInsertion = class( EAbZipException )
public
constructor Create;
end;
EAbZipSpanOverwrite= class( EAbZipException )
public
constructor Create;
end;
EAbZipStreamFull = class( EAbZipException )
public
constructor Create;
end;
EAbZipTruncate = class( EAbZipException )
public
constructor Create;
end;
EAbZipUnsupported = class( EAbZipException )
public
constructor Create;
end;
EAbZipVersion = class( EAbZipException )
public
constructor Create;
end;
EAbReadError = class( EAbZipException )
public
constructor Create;
end;
EAbGzipBadCRC = class( EAbGZipException )
public
constructor Create;
end;
EAbGzipBadFileSize = class( EAbGZipException )
public
constructor Create;
end;
EAbGzipInvalid = class( EAbGZipException )
public
constructor Create;
end;
EAbTarInvalid = class( EAbTarException)
public
constructor Create;
end;
EAbTarBadFileName = class( EAbTarException)
public
constructor Create;
end;
EAbTarBadLinkName = class( EAbTarException)
public
constructor Create;
end;
EAbTarBadOp = class( EAbTarException)
public
constructor Create;
end;
EAbVMSInvalidOrigin = class( EAbZipException )
public
constructor Create( Value : Integer );
end;
EAbVMSErrorOpenSwap = class( EAbZipException )
public
constructor Create( const Value : string );
end;
EAbVMSSeekFail = class( EAbZipException )
public
constructor Create( const Value : string );
end;
EAbVMSReadFail = class( EAbZipException )
public
constructor Create( Count : Integer; const Value : string );
end;
EAbVMSWriteFail = class( EAbZipException )
public
constructor Create( Count : Integer; const Value : string );
end;
EAbVMSWriteTooManyBytes = class( EAbZipException )
public
constructor Create( Count : Integer );
end;
EAbBBSReadTooManyBytes = class( EAbZipException )
public
constructor Create(Count : Integer );
end;
EAbBBSSeekOutsideBuffer = class( EAbZipException )
public
constructor Create;
end;
EAbBBSInvalidOrigin = class( EAbZipException )
public
constructor Create;
end;
EAbBBSWriteTooManyBytes = class( EAbZipException )
public
constructor Create(Count : Integer );
end;
EAbSWSNotEndofStream = class( EAbZipException )
public
constructor Create;
end;
EAbSWSSeekFailed = class( EAbZipException )
public
constructor Create;
end;
EAbSWSWriteFailed = class( EAbZipException )
public
constructor Create;
end;
EAbSWSInvalidOrigin = class( EAbZipException )
public
constructor Create;
end;
EAbSWSInvalidNewOrigin = class( EAbZipException )
public
constructor Create;
end;
EAbNoCabinetDll = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileOpenError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileReadError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileWriteError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileCloseError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileSeekError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFileDeleteError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIAddFileError = class( EAbCabException )
public
constructor Create;
end;
EAbFCICreateError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFlushCabinetError = class( EAbCabException )
public
constructor Create;
end;
EAbFCIFlushFolderError = class( EAbCabException )
public
constructor Create;
end;
EAbFDICopyError = class( EAbCabException )
public
constructor Create;
end;
EAbFDICreateError = class( EAbCabException )
public
constructor Create;
end;
EAbInvalidCabTemplate = class( EAbCabException )
public
constructor Create;
end;
EAbInvalidCabFile = class( EAbCabException )
public
constructor Create;
end;
EAbFileTooLarge = class(EAbException)
public
constructor Create;
end;
procedure AbConvertException( const E : Exception;
var eClass : TAbErrorClass;
var eErrorCode : Integer );
implementation
uses
Classes,
AbConst,
AbResString;
constructor EAbArchiveBusy.Create;
begin
inherited Create(AbArchiveBusyS);
ErrorCode := AbArchiveBusy;
end;
constructor EAbBadStream.Create;
begin
inherited Create(AbBadStreamTypeS);
FInnerException := nil;
ErrorCode := AbBadStreamType;
end;
constructor EAbBadStream.CreateInner(aInnerException: Exception);
begin
inherited Create(AbBadStreamTypeS + #13#10 + aInnerException.Message);
FInnerException := aInnerException;
ErrorCode := AbBadStreamType;
end;
constructor EAbDuplicateName.Create;
begin
inherited Create(AbDuplicateNameS);
ErrorCode := AbDuplicateName;
end;
constructor EAbNoSuchDirectory.Create;
begin
inherited Create(AbNoSuchDirectoryS);
ErrorCode := AbNoSuchDirectory;
end;
constructor EAbInvalidSpanningThreshold.Create;
begin
inherited Create(AbInvalidThresholdS);
ErrorCode := AbInvalidThreshold;
end;
constructor EAbFileNotFound.Create;
begin
inherited Create(AbFileNotFoundS);
ErrorCode := AbFileNotFound;
end;
constructor EAbNoArchive.Create;
begin
inherited Create(AbNoArchiveS);
ErrorCode := AbNoArchive;
end;
constructor EAbUserAbort.Create;
begin
inherited Create(AbUserAbortS);
ErrorCode := AbUserAbort;
end;
constructor EAbZipBadSpanStream.Create;
begin
inherited Create(AbBadSpanStreamS);
ErrorCode := AbBadSpanStream;
end;
constructor EAbZipBadCRC.Create;
begin
inherited Create(AbZipBadCRCS);
ErrorCode := AbZipBadCRC;
end;
constructor EAbZipInflateBlock.Create;
begin
inherited Create(AbInflateBlockErrorS);
ErrorCode := AbInflateBlockError;
end;
constructor EAbZipInvalid.Create;
begin
inherited Create(AbErrZipInvalidS);
ErrorCode := AbErrZipInvalid;
end;
constructor EAbInvalidIndex.Create;
begin
inherited Create(AbInvalidIndexS);
ErrorCode := AbInvalidIndex;
end;
constructor EAbZipInvalidFactor.Create;
begin
inherited Create(AbInvalidFactorS);
ErrorCode := AbInvalidFactor;
end;
constructor EAbZipInvalidLFH.Create;
begin
inherited Create(AbInvalidLFHS);
ErrorCode := AbInvalidLFH;
end;
constructor EAbZipInvalidMethod.Create;
begin
inherited Create(AbUnknownCompressionMethodS);
ErrorCode := AbUnknownCompressionMethod;
end;
constructor EAbZipInvalidPassword.Create;
begin
inherited Create(AbInvalidPasswordS);
ErrorCode := AbInvalidPassword;
end;
constructor EAbZipInvalidStub.Create;
begin
inherited Create(AbZipBadStubS);
ErrorCode := AbZipBadStub;
end;
constructor EAbZipNoExtraction.Create;
begin
inherited Create(AbNoExtractionMethodS);
ErrorCode := AbNoExtractionMethod;
end;
constructor EAbZipNoInsertion.Create;
begin
inherited Create(AbNoInsertionMethodS);
ErrorCode := AbNoInsertionMethod;
end;
constructor EAbZipSpanOverwrite.Create;
begin
inherited Create(AbNoOverwriteSpanStreamS);
ErrorCode := AbNoOverwriteSpanStream;
end;
constructor EAbZipStreamFull.Create;
begin
inherited Create(AbStreamFullS);
ErrorCode := AbStreamFull;
end;
constructor EAbZipTruncate.Create;
begin
inherited Create(AbTruncateErrorS);
ErrorCode := AbTruncateError;
end;
constructor EAbZipUnsupported.Create;
begin
inherited Create(AbUnsupportedCompressionMethodS);
ErrorCode := AbUnsupportedCompressionMethod;
end;
constructor EAbZipVersion.Create;
begin
inherited Create(AbZipVersionNeededS);
ErrorCode := AbZipVersionNeeded;
end;
constructor EAbReadError.Create;
begin
inherited Create(AbReadErrorS);
ErrorCode := AbReadError;
end;
constructor EAbVMSInvalidOrigin.Create( Value : Integer );
begin
inherited Create(Format(AbVMSInvalidOriginS, [Value]));
ErrorCode := AbVMSInvalidOrigin;
end;
constructor EAbBBSReadTooManyBytes.Create(Count : Integer );
begin
inherited Create(Format(AbBBSReadTooManyBytesS, [Count]));
ErrorCode := AbBBSReadTooManyBytes;
end;
constructor EAbBBSSeekOutsideBuffer.Create;
begin
inherited Create(AbBBSSeekOutsideBufferS);
ErrorCode := AbBBSSeekOutsideBuffer;
end;
constructor EAbBBSInvalidOrigin.Create;
begin
inherited Create(AbBBSInvalidOriginS);
ErrorCode := AbBBSInvalidOrigin;
end;
constructor EAbBBSWriteTooManyBytes.Create(Count : Integer);
begin
inherited Create(Format(AbBBSWriteTooManyBytesS, [Count]));
ErrorCode := AbBBSWriteTooManyBytes;
end;
constructor EAbVMSErrorOpenSwap.Create( const Value : string );
begin
inherited Create(Format(AbVMSErrorOpenSwapS, [Value]));
ErrorCode := AbVMSErrorOpenSwap;
end;
constructor EAbVMSSeekFail.Create( const Value : string );
begin
inherited Create(Format(AbVMSSeekFailS, [Value]));
ErrorCode := AbVMSSeekFail;
end;
constructor EAbVMSReadFail.Create( Count : Integer; const Value : string );
begin
inherited Create(Format(AbVMSReadFailS, [Count, Value]));
ErrorCode := AbVMSReadFail;
end;
constructor EAbVMSWriteFail.Create( Count : Integer; const Value : string );
begin
inherited Create(Format(AbVMSWriteFailS, [Count, Value]));
ErrorCode := AbVMSWriteFail;
end;
constructor EAbVMSWriteTooManyBytes.Create( Count : Integer );
begin
inherited Create(Format(AbVMSWriteTooManyBytesS, [Count]));
ErrorCode := AbVMSWriteTooManyBytes;
end;
constructor EAbSWSNotEndofStream.Create;
begin
inherited Create(AbSWSNotEndofStreamS);
ErrorCode := AbSWSNotEndofStream;
end;
constructor EAbSWSSeekFailed.Create;
begin
inherited Create(AbSWSSeekFailedS);
ErrorCode := AbSWSSeekFailed;
end;
constructor EAbSWSWriteFailed.Create;
begin
inherited Create(AbSWSWriteFailedS);
ErrorCode := AbSWSWriteFailed;
end;
constructor EAbSWSInvalidOrigin.Create;
begin
inherited Create(AbSWSInvalidOriginS);
ErrorCode := AbSWSInvalidOrigin;
end;
constructor EAbSWSInvalidNewOrigin.Create;
begin
inherited Create(AbSWSInvalidNewOriginS);
ErrorCode := AbSWSInvalidNewOrigin;
end;
constructor EAbFCIFileOpenError.Create;
begin
inherited Create(AbFCIFileOpenErrorS);
ErrorCode := AbFCIFileOpenError;
end;
constructor EAbNoCabinetDll.Create;
begin
inherited Create(AbNoCabinetDllErrorS);
ErrorCode := AbNoCabinetDllError;
end;
constructor EAbFCIFileReadError.Create;
begin
inherited Create(AbFCIFileReadErrorS);
ErrorCode := AbFCIFileReadError;
end;
constructor EAbFCIFileWriteError.Create;
begin
inherited Create(AbFCIFileWriteErrorS);
ErrorCode := AbFCIFileWriteError;
end;
constructor EAbFCIFileCloseError.Create;
begin
inherited Create(AbFCIFileCloseErrorS);
ErrorCode := AbFCIFileCloseError;
end;
constructor EAbFCIFileSeekError.Create;
begin
inherited Create(AbFCIFileSeekErrorS);
ErrorCode := AbFCIFileSeekError;
end;
constructor EAbFCIFileDeleteError.Create;
begin
inherited Create(AbFCIFileDeleteErrorS);
ErrorCode := AbFCIFileDeleteError;
end;
constructor EAbFCIAddFileError.Create;
begin
inherited Create(AbFCIAddFileErrorS);
ErrorCode := AbFCIAddFileError;
end;
constructor EAbFCICreateError.Create;
begin
inherited Create(AbFCICreateErrorS);
ErrorCode := AbFCICreateError;
end;
constructor EAbFCIFlushCabinetError.Create;
begin
inherited Create(AbFCIFlushCabinetErrorS);
ErrorCode := AbFCIFlushCabinetError;
end;
constructor EAbFCIFlushFolderError.Create;
begin
inherited Create(AbFCIFlushFolderErrorS);
ErrorCode := AbFCIFlushFolderError;
end;
constructor EAbFDICopyError.Create;
begin
inherited Create(AbFDICopyErrorS);
ErrorCode := AbFDICopyError;
end;
constructor EAbFDICreateError.Create;
begin
inherited Create(AbFDICreateErrorS);
ErrorCode := AbFDICreateError;
end;
constructor EAbInvalidCabTemplate.Create;
begin
inherited Create(AbInvalidCabTemplateS);
ErrorCode := AbInvalidCabTemplate;
end;
constructor EAbInvalidCabFile.Create;
begin
inherited Create(AbInvalidCabFileS);
ErrorCode := AbInvalidCabFile;
end;
procedure AbConvertException( const E : Exception;
var eClass : TAbErrorClass;
var eErrorCode : Integer );
begin
eClass := ecOther;
eErrorCode := 0;
if E is EAbException then begin
eClass := ecAbbrevia;
eErrorCode := (E as EAbException).ErrorCode;
end
else if E is EInOutError then begin
eClass := ecInOutError;
eErrorCode := (E as EInOutError).ErrorCode;
end
else if E is EFilerError then
eClass := ecFilerError
else if E is EFOpenError then
eClass := ecFileOpenError
else if E is EFCreateError then
eClass := ecFileCreateError;
end;
{ EAbUnhandledType }
constructor EAbUnhandledType.Create;
begin
inherited Create(AbUnhandledFileTypeS);
ErrorCode := AbUnhandledFileType;
end;
{ EAbGzipBadCRC }
constructor EAbGzipBadCRC.Create;
begin
inherited Create(AbGzipBadCRCS);
ErrorCode := AbGzipBadCRC;
end;
{ EAbGzipBadFileSize }
constructor EAbGzipBadFileSize.Create;
begin
inherited Create(AbGzipBadFileSizeS);
ErrorCode := AbGzipBadFileSize;
end;
{ EAbGzipInvalid }
constructor EAbGzipInvalid.Create;
begin
inherited Create(AbSpanningNotSupportedS);
ErrorCode := AbSpanningNotSupported;
end;
{ EAbTarInvalid }
constructor EAbTarInvalid.Create;
begin
inherited Create(AbTarInvalidS);
ErrorCode := AbTarInvalid;
end;
{ EAbTarBadFileName }
constructor EAbTarBadFileName.Create;
begin
inherited Create(AbTarBadFileNameS);
ErrorCode := AbTarBadFileName;
end;
{ EAbTarBadLinkName }
constructor EAbTarBadLinkName.Create;
begin
inherited Create(AbTarBadLinkNameS);
ErrorCode := AbTarBadLinkName;
end;
{ EAbTarBadOp }
constructor EAbTarBadOp.Create;
begin
inherited Create(AbTarBadOpS);
ErrorCode := AbTarBadOp;
end;
{ EAbSpanningNotSupported }
constructor EAbSpanningNotSupported.Create;
begin
inherited Create(AbSpanningNotSupportedS);
ErrorCode := AbSpanningNotSupported;
end;
{ EAbFileTooLarge }
constructor EAbFileTooLarge.Create;
begin
{TODO Create const and fix wording}
inherited Create(AbFileSizeTooBigS);
end;
end.

View File

@@ -0,0 +1,414 @@
(* ***** 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: AbFciFdi.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet DLL wrapper *}
{* Based on info from the FCI/FDI Library Description, *}
{* included in the Microsoft Cabinet SDK *}
{*********************************************************}
unit AbFciFdi;
{$I AbDefine.inc}
interface
uses
Windows, AbUtils;
const
CabinetDLL = 'cabinet.dll';
cpuUnknown = -1;
cpu80286 = 0;
cpu80386 = 1;
cpuDefault = cpuUnknown;
type
{FDI errors}
FDIError =
(FDIError_None, FDIError_Cabinet_Not_Found,
FDIError_Not_A_Cabinet, FDIError_Unknown_Cabinet_Version,
FDIError_Corrupt_Cabinet, FDIError_Alloc_Fail,
FDIError_Bad_Compr_Type, FDIError_MDI_Fail,
FDIError_Target_File, FDIError_Reserve_Mismatch,
FDIError_Wrong_Cabinet, FDIError_User_Abort);
{FCI errors}
FCIError =
(FCIError_NONE, FCIError_Open_SRC,
FCIError_Read_SRC, FCIError_Alloc_Fail,
FCIError_Temp_File, FCIError_Bad_Compr_Type,
FCIError_Cab_File, FCIError_User_Abort,
FCIERRor_MCI_Fail);
{FDI notifications}
FDINotificationType =
(FDINT_Cabinet_Info, FDINT_Partial_File,
FDINT_Copy_File, FDINT_Close_File_Info,
FDINT_Next_Cabinet, FDINT_Enumerate);
{FDI/FCI error structure}
PCabErrorRecord = ^CabErrorRecord;
CabErrorRecord = record
ErrorCode : Integer;
ErrorType : Integer;
ErrorPresent : BOOL;
end;
{FDI cabinet information structure}
PFDICabInfo = ^FDICabInfo;
FDICabInfo = record
cbCabinet : Longint;
cFolders : Word;
cFiles : Word;
setID : Word;
iCabinet : Word;
fReserve : BOOL;
hasprev : BOOL;
hasnext : BOOL;
end;
{FCI cabinet information structure}
PFCICabInfo = ^FCICabInfo;
FCICabInfo = record
cb : Longint;
cbFolderThresh : Longint;
cbReserveCFHeader : Integer;
cbReserveCFFolder : Integer;
cbReserveCFData : Integer;
iCab : Integer;
iDisk : Integer;
fFailOnIncompressible : Integer;
setID : Word;
szDisk : array[0..255] of AnsiChar;
szCab : array[0..255] of AnsiChar;
szCabPath : array[0..255] of AnsiChar;
end;
{FDI notification structure}
PFDINotification = ^FDINotification;
FDINotification = record
cb : Longint;
psz1 : PAnsiChar;
psz2 : PAnsiChar;
psz3 : PAnsiChar;
pv : Pointer;
hf : PtrInt;
date : Word;
time : Word;
attribs : Word;
setID : Word;
iCabinet : Word;
iFolder : Word;
fdie : FDIERROR;
end;
{misc defines}
HFDI = Pointer;
HFCI = Pointer;
FARPROC = Pointer;
{== Cabinet DLL routine prototypes ==========================================}
type
TFDICreate =
function (pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
pfnseek : FARPROC; cpuType : Integer; pError : PCabErrorRecord) : HFDI;
cdecl;
{----------------------------------------------------------------------------}
TFDIIsCabinet =
function(hfdi : HFDI; hf : PtrInt; pfdici : PFDICabInfo) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFDICopy =
function(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;
flags : Integer; pfnfdin, pfnfdid : FARPROC; Archive : Pointer) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFDIDestroy =
function(hfdi : HFDI) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFCICreate =
function(pError : PCabErrorRecord; pfnfcifp, pfnalloc, pfnfree,
pfnopen, pfnread, pfnwrite, pfnclose, pfnseek, pfndelete,
pfnfcigtf : FARPROC; pccab : PFCICabInfo; Archive : Pointer) : HFCI;
cdecl;
{----------------------------------------------------------------------------}
TFCIAddFile =
function(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;
fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
typeCompress : Word) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFCIFlushCabinet =
function(hfci : HFCI; fGetNextCab : BOOL;
pfnfcignc, pfnfcis : FARPROC) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFCIFlushFolder =
function(hfci : HFCI; pfnfcignc, pfnfcis : FARPROC) : BOOL;
cdecl;
{----------------------------------------------------------------------------}
TFCIDestroy =
function(hfci : HFCI) : BOOL;
cdecl;
{== DLL routine wrappers ====================================================}
function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,
pfnwrite, pfnclose, pfnseek : FARPROC;
cpuType : Integer; pError : PCabErrorRecord) : HFDI;
{returns an FDI context for opening an existing cabinet}
{ pfnalloc - heap allocation callback function }
{ pfnfree - heap deallocation callback function }
{ pfnopen - open file callback function }
{ pfnwrite - write file callback function }
{ pfnclose - close file callback function }
{ pfnseek - reposition file pointer callback function }
{ cpuType - -1: unknown, 0: 80286, 1: 80386 }
{ pError - pointer to error record }
{----------------------------------------------------------------------------}
function FDIIsCabinet(hfdi : HFDI; hf : PtrInt;
pfdici : PFDICabInfo) : BOOL;
{checks cabinet file for validity}
{ hfdi - FDI context }
{ hf - cabinet file handle }
{ pfdici - pointer to FDI cabinet info structure }
{----------------------------------------------------------------------------}
function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;
flags : Integer; pfnfdin, pfnfdid : FARPROC;
Archive : Pointer) : BOOL;
{enumerates every file in the cabinet. The callback function }
{should indicate whether or not to extract a given file}
{ hfdi - FDI context }
{ pszCabinet - cabinet file name }
{ pszCabPath - cabinet file path }
{ flags - currently not used }
{ pfnfdin - FDI notifaction callback function }
{ pfnfdid - decryption callback (currently not used)}
{ Archive - the calling TAbCabArchive instance }
{----------------------------------------------------------------------------}
function FDIDestroy(hfdi : HFDI) : BOOL;
{releases FDI context and frees resources}
{ hfdi - FDI context }
{----------------------------------------------------------------------------}
function FCICreate(pError : PCabErrorRecord;
pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
pfnseek, pfndelete, pfnfcigtf : FARPROC;
pccab : PFCICabInfo; Archive : Pointer) : HFCI;
{creates a new cabinet file and returns the FCI context}
{ pError - pointer to error record }
{ pfnfcifp - callback notification when file has been placed in cabinet }
{ pfnalloc - callback function to allocate memory }
{ pfnfree - callback function to free memory }
{ pfnopen - callback function to open a file }
{ pfnwrite - callback function to write to a file }
{ pfnclose - callback function to close a file }
{ pfnseek - callback function to reposition file pointer }
{ pfndelete - callback function to delete a file }
{ pfnfcigtf - callback function to obtain temp filename }
{ pccab - pointer to FCI cabinet infor structure }
{ Archive - the calling TAbCabArchive instance }
{----------------------------------------------------------------------------}
function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;
fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
typeCompress : Word) : BOOL;
{adds a file to the cabinet}
{ hfci - FCI context }
{ pszFilePath - full pathname of file being added }
{ pszFileName - just the file name }
{ fExecute - flag to indicate if file is executable }
{ pfnfcignc - callback function to obtain next cabinet info }
{ pfnfcis - callback function to relay progress }
{ pfnfcigoi - callback function to open file and get attributes }
{ typeCompress - compression type to use }
{----------------------------------------------------------------------------}
function FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL;
pfnfcignc, pfnfcis : FARPROC) : BOOL;
{writes current cabinet file out to disk and optionally starts a new one}
{ hfci - FCI context }
{ fGetNextCab - flag indicating whether to start a new cabinet }
{ pfnfcignc - callback function to obtain next cabinet info }
{ pfnfcis - callback function to relay progress }
{----------------------------------------------------------------------------}
function FCIFlushFolder(hfci : HFCI;
pfnfcignc, pfnfcis : FARPROC) : BOOL;
{close current compression block and start a new one}
{ hfci - FCI context }
{ pfnfcignc - callback function to obtain next cabinet info }
{ pfnfcis - callback function to relay progress }
{----------------------------------------------------------------------------}
function FCIDestroy(hfci : HFCI) : BOOL;
{releases FCI context and frees resources}
{ hfdi - FDI context }
{----------------------------------------------------------------------------}
implementation
uses
AbExcept;
var
CabDLLLoaded : Boolean;
CabDLLHandle : THandle;
FDICreateProc : TFDICreate;
FDIIsCabinetProc : TFDIIsCabinet;
FDICopyProc : TFDICopy;
FDIDestroyProc : TFDIDestroy;
FCICreateProc : TFCICreate;
FCIAddFileProc : TFCIAddFile;
FCIFlushCabinetProc : TFCIFlushCabinet;
FCIFlushFolderProc : TFCIFlushFolder;
FCIDestroyProc : TFCIDestroy;
{============================================================================}
procedure LoadCabinetDLL;
begin
if CabDllLoaded then
Exit;
CabDllHandle := LoadLibrary(CabinetDLL);
if (CabDllHandle = 0) then
raise EAbNoCabinetDLL.Create;
@FDICreateProc := GetProcAddress(CabDllHandle, 'FDICreate');
@FDIIsCabinetProc := GetProcAddress(CabDllHandle, 'FDIIsCabinet');
@FDICopyProc := GetProcAddress(CabDllHandle, 'FDICopy');
@FDIDestroyProc := GetProcAddress(CabDllHandle, 'FDIDestroy');
@FCICreateProc := GetProcAddress(CabDllHandle, 'FCICreate');
@FCIAddFileProc := GetProcAddress(CabDllHandle, 'FCIAddFile');
@FCIFlushCabinetProc := GetProcAddress(CabDllHandle, 'FCIFlushCabinet');
@FCIFlushFolderProc := GetProcAddress(CabDllHandle, 'FCIFlushFolder');
@FCIDestroyProc := GetProcAddress(CabDllHandle, 'FCIDestroy');
CabDllLoaded := True;
end;
{----------------------------------------------------------------------------}
function FDICreate(pfnalloc, pfnfree, pfnopen, pfnread,
pfnwrite, pfnclose, pfnseek : FARPROC;
cpuType : Integer; pError : PCabErrorRecord) : HFDI;
begin
LoadCabinetDLL;
if Assigned(FDICreateProc) then
Result := FDICreateProc(pfnalloc, pfnfree, pfnopen, pfnread,
pfnwrite, pfnclose, pfnseek, cpuType, pError)
else
Result := nil;
end;
{----------------------------------------------------------------------------}
function FDIIsCabinet(hfdi : HFDI; hf : PtrInt;
pfdici : PFDICabInfo) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FDIIsCabinetProc) then
Result := FDIIsCabinetProc(hfdi, hf, pfdici)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FDICopy(hfdi : HFDI; pszCabinet, pszCabPath : PAnsiChar;
flags : Integer; pfnfdin, pfnfdid : FARPROC;
Archive : Pointer) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FDICopyProc) then
Result := FDICopyProc(hfdi, pszCabinet, pszCabPath, flags,
pfnfdin, pfnfdid, Archive)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FDIDestroy(hfdi : HFDI) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FDIDestroyProc) then
Result := FDIDestroyProc(hfdi)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FCICreate(pError : PCabErrorRecord;
pfnfcifp, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,
pfnseek, pfndelete, pfnfcigtf : FARPROC;
pccab : PFCICabInfo; Archive : Pointer) : HFCI;
begin
LoadCabinetDLL;
if Assigned(FCICreateProc) then
Result := FCICreateProc(pError, pfnfcifp, pfnalloc, pfnfree, pfnopen,
pfnread, pfnwrite, pfnclose, pfnseek, pfndelete, pfnfcigtf,
pccab, Archive)
else
Result := nil;
end;
{----------------------------------------------------------------------------}
function FCIAddFile(hfci : HFCI; pszFilePath, pszFileName : PAnsiChar;
fExecute : BOOL; pfnfcignc, pfnfcis, pfnfcigoi : FARPROC;
typeCompress : Word) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FCIAddFileProc) then
Result := FCIAddFileProc(hfci, pszFilePath, pszFileName,
fExecute, pfnfcignc, pfnfcis, pfnfcigoi, typeCompress)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FCIFlushCabinet(hfci : HFCI; fGetNextCab : BOOL;
pfnfcignc, pfnfcis : FARPROC) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FCIFlushCabinetProc) then
Result := FCIFlushCabinetProc(hfci, fGetNextCab, pfnfcignc, pfnfcis)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FCIFlushFolder(hfci : HFCI;
pfnfcignc, pfnfcis : FARPROC) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FCIFlushFolderProc) then
Result := FCIFlushFolderProc(hfci, pfnfcignc, pfnfcis)
else
Result := False;
end;
{----------------------------------------------------------------------------}
function FCIDestroy(hfci : HFCI) : BOOL;
begin
LoadCabinetDLL;
if Assigned(FCIDestroyProc) then
Result := FCIDestroyProc(hfci)
else
Result := False;
end;
{----------------------------------------------------------------------------}
initialization
CabDllLoaded := False;
end.

1290
Abbrevia/source/AbGzTyp.pas Normal file

File diff suppressed because it is too large Load Diff

119
Abbrevia/source/AbHexVw.pas Normal file
View File

@@ -0,0 +1,119 @@
(* ***** 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: AbHexVw.pas *}
{*********************************************************}
{* Abbrevia: Hex View utility *}
{*********************************************************}
{$I AbDefine.inc}
{$IFNDEF UsingCLX}
unit AbHexVw;
{$ENDIF}
interface
uses
Classes,
{$IFDEF UsingCLX}
QStdCtrls, QGraphics,
{$ELSE}
StdCtrls, Graphics,
{$ENDIF}
SysUtils;
type
THexView = class(TMemo)
protected
FBlockSize : Integer;
public
procedure SetStream(Strm : TStream);
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
property Stream : TStream write SetStream;
property BlockSize : Integer read FBlockSize write FBlockSize;
end;
implementation
{$IFDEF HasUITypes}
uses
System.UITypes;
{$ENDIF}
constructor THexView.Create(AOwner : TComponent);
begin
Inherited Create(AOwner);
Font.Style := Font.Style + [fsBold];
ReadOnly := True;
ScrollBars := ssVertical;
WordWrap := False;
WantTabs := True;
FBlockSize := 512;
end;
destructor THexView.Destroy;
begin
inherited Destroy;
end;
procedure THexView.SetStream(Strm : TStream);
var
Buff : Array[0..15] of Byte;
i, j : Integer;
Str : String;
StrList : TStringList;
begin
Strm.Seek(0, soBeginning);
StrList := TStringList.Create;
Clear;
while Strm.Position < Strm.Size do begin
if ((Strm.Position mod FBlockSize) = 0) then
StrList.Add('===========================================================');
Str := '';
for j := 0 to 15 do
Buff[j] := Byte(chr(0));
Strm.Read(Buff, 16);
Str := Str + Format('%4.4X', [strm.Position - $10]) + ':' + #9;
for i := 0 to 15 do begin
Str := Str + Format('%2.2X', [Buff[i]]) + ' ';
if i = 7 then Str := Str + #9;
end;
Str := Str + #9;
for i := 0 to 15 do begin
if (Buff[i] < $30) then
Buff[i] := byte('.');
Str := Str + Char(Buff[i]);
end;
StrList.Add(Str);
end;
SetLines(StrList);
StrList.Free;
end;
end.

630
Abbrevia/source/AbLZMA.pas Normal file
View File

@@ -0,0 +1,630 @@
(* ***** 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 Craig Peterson
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Craig Peterson <capeterson@users.sourceforge.net>
* Pierre le Riche <pierre_le_riche@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbLZMA.pas *}
{*********************************************************}
{* ABBREVIA: Lzma compression/decompression procedures. *}
{*********************************************************}
unit AbLZMA;
{$I AbDefine.inc}
interface
uses
Classes, Windows, SysUtils, AbCrtl, AbUtils;
{ Raw LZMA decompression =================================================== }
{ Decompresses the LZMA compressed data in ASrc to ADes. ASrc should not have
the header used by the other compression/decompression routines, and
AProperties should contain any necessary data. }
procedure LzmaDecodeStream(AProperties: PByte; APropSize: Integer; ASrc, ADes: TStream;
AUncompressedSize: Int64 = -1); overload;
{ Stream compression and decompression (taken from LzmaUtil.c) ============= }
procedure LzmaDecodeStream(ASourceStream, ATargetStream: TStream); overload;
procedure LzmaEncodeStream(ASourceStream, ATargetStream: TStream; ASourceSize: Int64);
{ In-memory compression and decompression ================================== }
{ Given a pointer to the compressed data, this will return the size of the
decompressed data. }
function LzmaGetUncompressedSize(APCompressedData: Pointer; ACompressedSize: Integer): Integer;
{ Decompresses the LZMA compressed data at APCompressedData to the buffer
pointed to by APUncompressedData. The buffer at APUncompressedData should be
large enough to hold the number of bytes as returned by LzmaGetDecompressedSize. }
procedure LzmaDecodeBuffer(APCompressedData: Pointer; ACompressedSize: Integer;
APUncompressedData: Pointer);
{ Compresses the data at APUncompressedData to the buffer at APCompressedData,
and returns the number of bytes written. If ACompressedDataBufferCapacity is
less than the number of bytes required to store the entire compressed stream,
or any other error occurs, then an exception is raised. (A safe number for
ACompressedDataBufferCapacity is slightly more than AUncompressedDataBufferSize.)
Leave ACompressionLevel and ADictionarySize at -1 in order to use the default
values (5 and 16MB respectively). }
function LzmaEncodeBuffer(APUncompressedData: Pointer; AUncompressedSize: Integer;
APCompressedData: Pointer; ACompressedDataBufferCapacity: Integer;
ACompressionLevel: Integer = -1; ADictionarySize: Integer = -1): Integer;
{ Types.h declarations ===================================================== }
const
SZ_OK = 0;
SZ_ERROR_DATA = 1;
SZ_ERROR_MEM = 2;
SZ_ERROR_CRC = 3;
SZ_ERROR_UNSUPPORTED = 4;
SZ_ERROR_PARAM = 5;
SZ_ERROR_INPUT_EOF = 6;
SZ_ERROR_OUTPUT_EOF = 7;
SZ_ERROR_READ = 8;
SZ_ERROR_WRITE = 9;
SZ_ERROR_PROGRESS = 10;
SZ_ERROR_FAIL = 11;
SZ_ERROR_THREAD = 12;
SZ_ERROR_ARCHIVE = 16;
SZ_ERROR_NO_ARCHIVE = 17;
type
SRes = Integer;
ISeqInStream = packed record
Read: function(p: Pointer; var buf; var size: size_t): SRes; cdecl;
end;
PISeqInStream = ^ISeqInStream;
ISeqOutStream = packed record
Write: function(p: Pointer; const buf; size: size_t): size_t; cdecl;
end;
PISeqOutStream = ^ISeqOutStream;
ICompressProgress = packed record
Progress: function(p: Pointer; inSize, outSize: Int64): SRes; cdecl;
end;
PICompressProgress = ^ICompressProgress;
ISzAlloc = packed record
Alloc: function(p: Pointer; size: size_t): Pointer; cdecl;
Free: procedure(p: Pointer; address: Pointer); cdecl;
end;
PISzAlloc = ^ISzAlloc;
{ LzmaDec.h declarations =================================================== }
type
CLzmaProb = Word;
// LZMA Properties
const
LZMA_PROPS_SIZE = 5;
type
CLzmaProps = packed record
lc, lp, pb: Cardinal;
dicSize: UInt32;
end;
// LZMA Decoder state
const
LZMA_REQUIRED_INPUT_MAX = 20;
type
CLzmaDec = packed record
prop: CLzmaProps;
probs: ^CLzmaProb;
dic: PByte;
buf: PByte;
range, code: UInt32;
dicPos: size_t;
dicBufSize: size_t;
processedPos: UInt32;
checkDicSize: UInt32;
state: Cardinal;
reps: array[0..3] of UInt32;
remainLen: Cardinal;
needFlush: Integer;
needInitState: Integer;
numProbs: UInt32;
tempBufSize: Cardinal;
tempBuf: array[0..LZMA_REQUIRED_INPUT_MAX - 1] of Byte;
end;
type
ELzmaFinishMode = LongInt;
const
LZMA_FINISH_ANY = 0; // finish at any point
LZMA_FINISH_END = 1; // block must be finished at the end
type
ELzmaStatus = LongInt;
const
LZMA_STATUS_NOT_SPECIFIED = 0; // use main error code instead
LZMA_STATUS_FINISHED_WITH_MARK = 1; // stream was finished with end mark.
LZMA_STATUS_NOT_FINISHED = 3; // stream was not finished
LZMA_STATUS_NEEDS_MORE_INPUT = 4; // you must provide more input bytes
LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK = 5; // there is probability that stream was finished without end mark
procedure LzmaDec_Construct(var p: CLzmaDec); cdecl;
procedure LzmaDec_Init(var p: CLzmaDec); cdecl; external;
function LzmaDec_DecodeToBuf(var p: CLzmaDec; dest: PByte; var destLen: size_t;
src: PByte; var srcLen: size_t; finishMode: ELzmaFinishMode;
var status: ELzmaStatus): SRes; cdecl; external;
function LzmaDec_Allocate(var state: CLzmaDec; prop: PByte; propsSize: Integer;
alloc: PISzAlloc): SRes; cdecl; external;
procedure LzmaDec_Free(var state: CLzmaDec; alloc: PISzAlloc); cdecl; external;
// One call decoding interface
function LzmaDecode(dest: PByte; var destLen: size_t; src: PByte;
var srcLen: size_t; propData: PByte; propSize: Integer;
finishMode: ELzmaFinishMode; var status: ELzmaStatus;
alloc: PISzAlloc): SRes; cdecl; external;
{ LzmaEnc.h declarations =================================================== }
type
CLzmaEncHandle = Pointer;
CLzmaEncProps = packed record
level: Integer; // 0 <= level <= 9
dictSize: UInt32; // (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
// (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
// default = (1 << 24)
lc: Integer; // 0 <= lc <= 8, default = 3
lp: Integer; // 0 <= lp <= 4, default = 0
pb: Integer; // 0 <= pb <= 4, default = 2
algo: Integer; // 0 - fast, 1 - normal, default = 1
fb: Integer; // 5 <= fb <= 273, default = 32
btMode: Integer; // 0 - hashChain Mode, 1 - binTree mode - normal, default = 1
numHashBytes: Integer; // 2, 3 or 4, default = 4
mc: UInt32; // 1 <= mc <= (1 << 30), default = 32
writeEndMark: Cardinal; // 0 - do not write EOPM, 1 - write EOPM, default = 0
numThreads: Integer; // 1 or 2, default = 2
end;
procedure LzmaEncProps_Init(var p: CLzmaEncProps); cdecl; external;
function LzmaEnc_Create(Alloc: PISzAlloc): CLzmaEncHandle; cdecl; external;
procedure LzmaEnc_Destroy(p: CLzmaEncHandle; Alloc, allocBig: PISzAlloc); cdecl; external;
function LzmaEnc_SetProps(p: CLzmaEncHandle; var props: CLzmaEncProps): SRes; cdecl; external;
function LzmaEnc_WriteProperties(p: CLzmaEncHandle; properties: PByte;
var size: size_t): SRes; cdecl; external;
function LzmaEnc_Encode(p: CLzmaEncHandle; outStream: PISeqOutStream;
inStream: PISeqInStream; Progress: PICompressProgress;
Alloc, allocBig: PISzAlloc): SRes; cdecl; external;
function LzmaEnc_MemEncode(p: CLzmaEncHandle; dest: PByte; var destLen: size_t;
src: PByte; srcLen: size_t; writeEndMark: Integer; Progress: PICompressProgress;
Alloc, allocBig: PISzAlloc): SRes; cdecl; external;
// One call encoding interface
function LzmaEncode(dest: PByte; var destLen: size_t; src: PByte;
srcLen: size_t; var props: CLzmaEncProps; propsEncoded: PByte;
var propsSize: size_t; writeEndMark: Integer; progress: PICompressProgress;
alloc: pISzAlloc; allocBig: PISzAlloc): SRes; cdecl; external;
{ LzFind.h declarations ==================================================== }
procedure MatchFinder_NeedMove; external;
procedure MatchFinder_GetPointerToCurrentPos; external;
procedure MatchFinder_MoveBlock; external;
procedure MatchFinder_ReadIfRequired; external;
procedure MatchFinder_Construct; external;
procedure MatchFinder_Create; external;
procedure MatchFinder_Free; external;
procedure MatchFinder_Normalize3; external;
procedure MatchFinder_ReduceOffsets; external;
procedure GetMatchesSpec1; external;
procedure MatchFinder_Init; external;
procedure MatchFinder_CreateVTable; external;
{ LzFindMt.h declarations ================================================== }
procedure MatchFinderMt_Construct; external;
procedure MatchFinderMt_Destruct; external;
procedure MatchFinderMt_Create; external;
procedure MatchFinderMt_CreateVTable; external;
procedure MatchFinderMt_ReleaseStream; external;
{ Lzma header fields ======================================================= }
type
// The condensed compression properties
TLZMAPropertyData = array[0..LZMA_PROPS_SIZE - 1] of Byte;
// The header usually stored in front of LZMA compressed data
TLZMAHeader = packed record
PropertyData: TLZMAPropertyData;
UncompressedSize: Int64;
end;
PLZMAHeader = ^TLZMAHeader;
{ Error handling =========================================================== }
type
EAbLZMAException = class(Exception);
procedure LzmaCheck(AResultCode: SRes);
procedure RaiseLzmaException(AResultCode: SRes);
{ Linker directives ======================================================== }
{$WARN BAD_GLOBAL_SYMBOL OFF}
{$IF DEFINED(WIN32)}
{$L Win32\LzFind.obj}
{$L Win32\LzFindMt.obj}
{$L Win32\LzmaDec.obj}
{$L Win32\LzmaEnc.obj}
{$L Win32\Threads.obj}
{$ELSEIF DEFINED(WIN64)}
{$L Win64\LzFind.obj}
{$L Win64\LzFindMt.obj}
{$L Win64\LzmaDec.obj}
{$L Win64\LzmaEnc.obj}
{$L Win64\Threads.obj}
{$IFEND}
implementation
{ Error handling =========================================================== }
procedure LzmaCheck(AResultCode: SRes);
begin
if AResultCode <> SZ_OK then
RaiseLzmaException(AResultCode);
end;
{ -------------------------------------------------------------------------- }
procedure RaiseLzmaException(AResultCode: SRes);
begin
case AResultCode of
SZ_ERROR_DATA: raise EAbLZMAException.Create('LZMA Data Error.');
SZ_ERROR_MEM: raise EAbLZMAException.Create('LZMA Memory Error.');
SZ_ERROR_CRC: raise EAbLZMAException.Create('LZMA CRC Error.');
SZ_ERROR_UNSUPPORTED: raise EAbLZMAException.Create('LZMA "Unsupported" Error.');
SZ_ERROR_PARAM: raise EAbLZMAException.Create('LZMA Parameter Error.');
SZ_ERROR_INPUT_EOF: raise EAbLZMAException.Create('LZMA Input EOF Error.');
SZ_ERROR_OUTPUT_EOF: raise EAbLZMAException.Create('LZMA Output EOF Error.');
SZ_ERROR_READ: raise EAbLZMAException.Create('LZMA Read Error.');
SZ_ERROR_WRITE: raise EAbLZMAException.Create('LZMA Write Error.');
SZ_ERROR_PROGRESS: raise EAbLZMAException.Create('LZMA Progress Error.');
SZ_ERROR_FAIL: raise EAbLZMAException.Create('LZMA "Fail" Error.');
SZ_ERROR_THREAD: raise EAbLZMAException.Create('LZMA Thread Error.');
SZ_ERROR_ARCHIVE: raise EAbLZMAException.Create('LZMA Archive Error.');
SZ_ERROR_NO_ARCHIVE: raise EAbLZMAException.Create('LZMA "No Archive" Error.');
else
raise EAbLZMAException.CreateFmt('Unknown LZMA error (%d)', [AResultCode]);
end;
end;
{ Helper Routines ========================================================== }
procedure LzmaDec_Construct(var p: CLzmaDec); cdecl;
begin
p.dic := nil;
p.probs := nil;
end;
{ -------------------------------------------------------------------------- }
function SzAlloc(p: Pointer; size: size_t): Pointer; cdecl;
begin
Result := GetMemory(size);
end;
{ -------------------------------------------------------------------------- }
procedure SzFree(p, address: Pointer); cdecl;
begin
FreeMemory(address);
end;
var
DelphiMMInterface: ISzAlloc = (Alloc: SzAlloc; Free: SzFree);
{ CSeq*Stream implementation =============================================== }
type
CSeqInStream = packed record
Intf: ISeqInStream;
Stream: TStream;
end;
CSeqOutStream = packed record
Intf: ISeqOutStream;
Stream: TStream;
end;
{ -------------------------------------------------------------------------- }
function ISeqInStream_Read(p: Pointer; var buf; var size: size_t): SRes; cdecl;
begin
try
size := CSeqInStream(p^).Stream.Read(buf, size);
Result := SZ_OK;
except
Result := SZ_ERROR_DATA;
end;
end;
{ -------------------------------------------------------------------------- }
function ISeqOutStream_Write(p: Pointer; const buf; size: size_t): size_t; cdecl;
begin
try
Result := CSeqOutStream(p^).Stream.Write(buf, size);
except
Result := 0;
end;
end;
{ Raw LZMA decompression =================================================== }
{ Decompress an Lzma compressed stream. Based on LzmaUtil.c::Decode2 }
function LzmaDecode2(var aState: CLzmaDec; aOutStream, aInStream: TStream;
aUncompressedSize: Int64 = -1): SRes;
const
IN_BUF_SIZE = 1 shl 16;
OUT_BUF_SIZE = 1 shl 16;
var
LHasSize: Boolean;
LInBuf: array [0..IN_BUF_SIZE - 1] of Byte;
LOutBuf: array [0..OUT_BUF_SIZE - 1] of Byte;
LInPos, LInSize, LOutPos: size_t;
LInProcessed, LOutProcessed: size_t;
LFinishMode: ELzmaFinishMode;
LStatus: ELzmaStatus;
begin
Result := 0;
LHasSize := aUncompressedSize <> -1;
LInPos := 0;
LInSize := 0;
LOutPos := 0;
LzmaDec_Init(aState);
while True do
begin
if LInPos = LInSize then
begin
LInSize := aInStream.Read(LInBuf, IN_BUF_SIZE);
LInPos := 0;
if LInSize = 0 then
Break;
end
else
begin
LInProcessed := LInSize - LInPos;
LOutProcessed := OUT_BUF_SIZE - LOutPos;
LFinishMode := LZMA_FINISH_ANY;
if LHasSize and (LOutProcessed > aUncompressedSize) then
begin
LOutProcessed := size_t(aUncompressedSize);
LFinishMode := LZMA_FINISH_END;
end;
Result := LzmaDec_DecodeToBuf(aState, @LOutBuf[LOutPos], LOutProcessed,
@LInBuf[LInPos], LInProcessed, LFinishMode, LStatus);
Inc(LInPos, LInProcessed);
Inc(LOutPos, LOutProcessed);
Dec(aUncompressedSize, LOutProcessed);
if (aOutStream <> nil) and (aOutStream.Write(LOutBuf, LOutPos) <> LOutPos) then
begin
Result := SZ_ERROR_WRITE;
Exit;
end;
LOutPos := 0;
if (Result <> SZ_OK) or (LHasSize and (aUncompressedSize = 0)) then
Exit;
if (LInProcessed = 0) and (LOutProcessed = 0) then
begin
if LHasSize or (LStatus <> LZMA_STATUS_FINISHED_WITH_MARK) then
Result := SZ_ERROR_DATA;
Exit;
end;
end;
end;
end;
{ -------------------------------------------------------------------------- }
{ Decompress an LZMA compressed stream. Pass AUncompressedSize = -1 if the
uncompressed size is not known. }
procedure LzmaDecodeStream(AProperties: PByte; APropSize: Integer;
ASrc, ADes: TStream; AUncompressedSize: Int64);
var
LLZMADecState: CLzmaDec;
begin
LzmaDec_Construct(LLZMADecState);
try
LzmaCheck(LzmaDec_Allocate(LLZMADecState, AProperties, APropSize, @DelphiMMInterface));
LzmaCheck(LzmaDecode2(LLZMADecState, ADes, ASrc, AUncompressedSize));
finally
LzmaDec_Free(LLZMADecState, @DelphiMMInterface);
end;
end;
{ Stream to stream compression and decompression =========================== }
{ Decompresses streams compressed with the LZMA SDK's LzmaUtil.exe.
Based on LzmaUtil.c::Decode }
procedure LzmaDecodeStream(ASourceStream, ATargetStream: TStream);
var
LUncompressedSize: Int64;
// Header: 5 bytes of LZMA properties and 8 bytes of uncompressed size
LHeader: TLZMAHeader;
begin
// Read and parse header
ASourceStream.ReadBuffer(LHeader, SizeOf(LHeader));
LUncompressedSize := LHeader.UncompressedSize;
LzmaDecodeStream(PByte(@LHeader.PropertyData), LZMA_PROPS_SIZE, ASourceStream,
ATargetStream, LUncompressedSize);
end;
{ -------------------------------------------------------------------------- }
{ Compresses a stream so it's compatible with the LZMA SDK's LzmaUtil.exe.
Based on LzmaUtil.c::Encode }
procedure LzmaEncodeStream(ASourceStream, ATargetStream: TStream; ASourceSize: Int64);
var
LEncHandle: CLzmaEncHandle;
LEncProps: CLzmaEncProps;
LHeader: TLZMAHeader;
LPropDataSize: size_t;
LInStreamRec: CSeqInStream;
LOutStreamRec: CSeqOutStream;
begin
LInStreamRec.Intf.Read := ISeqInStream_Read;
LInStreamRec.Stream := ASourceStream;
LOutStreamRec.Intf.Write := ISeqOutStream_Write;
LOutStreamRec.Stream := ATargetStream;
LEncHandle := LzmaEnc_Create(@DelphiMMInterface);
if LEncHandle = nil then
LzmaCheck(SZ_ERROR_MEM);
try
LzmaEncProps_Init(LEncProps);
LzmaCheck(LzmaEnc_SetProps(LEncHandle, LEncProps));
LPropDataSize := LZMA_PROPS_SIZE;
LzmaCheck(LzmaEnc_WriteProperties(LEncHandle, PByte(@LHeader.PropertyData),
LPropDataSize));
LHeader.UncompressedSize := ASourceSize;
ATargetStream.WriteBuffer(LHeader, SizeOf(LHeader));
LzmaCheck(LzmaEnc_Encode(LEncHandle, @LOutStreamRec.Intf,
@LInStreamRec.Intf, nil, @DelphiMMInterface, @DelphiMMInterface));
finally
LzmaEnc_Destroy(LEncHandle, @DelphiMMInterface, @DelphiMMInterface);
end;
end;
{ In-memory compression and decompression ================================== }
{ Given a pointer to the compressed data, this will return the size of the
decompressed data. }
function LzmaGetUncompressedSize(APCompressedData: Pointer; ACompressedSize: Integer): Integer;
begin
if ACompressedSize <= SizeOf(TLZMAHeader) then
raise EAbLZMAException.Create('The LZMA compressed data is invalid (not enough bytes)');
Result := PLZMAHeader(APCompressedData).UncompressedSize;
end;
{ -------------------------------------------------------------------------- }
{ Decompresses the LZMA compressed data at APCompressedData to the buffer
pointed to by APUncompressedData. The buffer at APUncompressedData should be
large enough to hold the number of bytes as returned by LzGetDecompressedSize. }
procedure LzmaDecodeBuffer(APCompressedData: Pointer; ACompressedSize: Integer;
APUncompressedData: Pointer);
var
LPropertyData: TLZMAPropertyData;
LUncompressedSize: Int64;
LInputByteCount, LOutputByteCount: size_t;
LStatus: ELzmaStatus;
begin
if ACompressedSize <= SizeOf(TLZMAHeader) then
raise EAbLZMAException.Create('The LZMA compressed data is invalid (not enough bytes)');
// Read the header from the compressed data.
LPropertyData := PLZMAHeader(APCompressedData).PropertyData;
LUncompressedSize := PLZMAHeader(APCompressedData).UncompressedSize;
Inc(PAnsiChar(APCompressedData), SizeOf(TLZMAHeader));
Dec(ACompressedSize, SizeOf(TLZMAHeader));
// Decompress from the input to the output buffer. This will change the byte
// count variables to the actual number of bytes consumed/written.
LInputByteCount := ACompressedSize;
LOutputByteCount := LUncompressedSize;
LzmaCheck(LzmaDecode(APUncompressedData, LOutputByteCount,
APCompressedData, LInputByteCount, PByte(@LPropertyData), LZMA_PROPS_SIZE,
LZMA_FINISH_END, LStatus, @DelphiMMInterface));
// Check that the input buffer was fully consumed and the output buffer was filled up.
if (LOutputByteCount <> LUncompressedSize) or (LInputByteCount <> ACompressedSize) then
raise EAbLZMAException.Create('LZMA decompression data error');
end;
{ -------------------------------------------------------------------------- }
{ Compresses the data at APUncompressedData to the buffer at APCompressedData,
and returns the number of bytes written. If ACompressedDataBufferCapacity is
less than the number of bytes required to store the entire compressed stream,
or any other error occurs, then an exception is raised. (A safe number for
ACompressedDataBufferCapacity is slightly more than AUncompressedDataBufferSize.)
Leave ACompressionLevel and ADictionarySize at -1 in order to use the default
values (5 and 16MB respectively). }
function LzmaEncodeBuffer(APUncompressedData: Pointer; AUncompressedSize: Integer;
APCompressedData: Pointer;
ACompressedDataBufferCapacity, ACompressionLevel, ADictionarySize: Integer): Integer;
var
LEncProps: CLzmaEncProps;
LPropsSize: size_t;
LPOutBuf: PByte;
LOutputBytes: size_t;
begin
if ACompressedDataBufferCapacity <= SizeOf(TLZMAHeader) then
raise EAbLZMAException.Create('LZMA output buffer too small');
// Set the uncompressed size in the header
PLZMAHeader(APCompressedData).UncompressedSize := AUncompressedSize;
// Set the properties
LzmaEncProps_Init(LEncProps);
if ACompressionLevel >= 0 then
LEncProps.level := ACompressionLevel;
if ADictionarySize >= 0 then
LEncProps.dictSize := ADictionarySize;
LPOutBuf := PByte(PtrUInt(APCompressedData) + SizeOf(TLZMAHeader));
LOutputBytes := ACompressedDataBufferCapacity - SizeOf(TLZMAHeader);
LPropsSize := LZMA_PROPS_SIZE;
LzmaCheck(LzmaEncode(LPOutBuf, LOutputBytes, APUncompressedData,
AUncompressedSize, LEncProps, APCompressedData, LPropsSize, 0, nil,
@DelphiMMInterface, @DelphiMMInterface));
Result := LOutputBytes + SizeOf(TLZMAHeader);
end;
initialization
// The LZMA routines are multithreaded and use the Delphi memory manager.
IsMultiThread := True;
end.

View File

@@ -0,0 +1,836 @@
(* ***** 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 Pierre le Riche
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Pierre le Riche <pierre_le_riche@users.sourceforge.net>
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK *****
Usage:
LZMA Compression:
1) Create a TAbLZMACompressionStream, passing as parameter to the constructor
the output stream where you want the compressed data stored.
2) Write the data that you want to compress to the TAbLZMACompressionStream.
Compression occurs in a background thread.
3) (Optional) Notify the background compression thread that no more data will
be written by calling NoMoreDataToCompress. Poll the IsBusy method to
determine whether the background thread is still busy.
4) Free the TAbLZMACompressionStream to finish up and release resources. The
compressed data will now be available in the output stream.
LZMA Decompression:
1) Create a TAbLZMADecompressionStream, passing as parameter to the constructor
the stream that contains the compressed data.
2) Read the decompressed data from TAbLZMADecompressionStream.
3) Free the TAbLZMADecompressionStream to finish up and release resources.
*)
unit AbLZMAStream;
{$I AbDefine.inc}
interface
uses
Windows, Classes, SysUtils, AbLZMA, AbUtils;
const
{The size of the intermediate buffers for compressed and decompressed data.}
CompressedDataBufferSize = 16 * 1024;
UncompressedDataBufferSize = 32 * 1024;
{When reading/writing very small blocks from/to a (de)compression stream an
intermediate buffer is used to buffer the small IO operations in order to
improve performance. Reads and writes larger than this size are unbuffered
and handled by the (de)compression algorithm directly. This value must be
smaller than the compressed and uncompressed data buffers.}
MaximumBlockSizeForBufferedIO = 1024;
type
{------------LZMA compression stream------------}
TAbLZMACompressionStream = class;
{The background compression thread.}
TAbLZMACompressionThread = class(TThread)
protected
FCompressionStream: TAbLZMACompressionStream;
{$IFNDEF HasThreadFinished}
FFinished: Boolean;
procedure DoTerminate; override;
property Finished: Boolean read FFinished;
{$ENDIF}
public
procedure Execute; override;
end;
{Buffers queued for compression by the background compression thread.}
PAbQueuedBuffer = ^TAbQueuedBuffer;
TAbQueuedBuffer = packed record
PreviousBuffer, NextBuffer: PAbQueuedBuffer;
DataSize: Integer;
{Adds this buffer to the compression queue for the given compression stream.
It is assumed that the compression stream has acquired the buffer critical
section.}
procedure QueueBuffer(ACompressionStream: TAbLZMACompressionStream);
{Removes this buffer from the compression queue}
procedure UnQueueBuffer;
{Returns a pointer to the data the given offset into the buffer}
function GetDataPointer(AOffset: Integer): Pointer;
end;
TAbLZMACompressionStream = class(TStream)
protected
FOutputStream: TStream;
{The critical section used to control access to the buffers that are queued
for compression. The main thread and the compression thread may not access
the buffer queue at the same time.}
FBufferCriticalSection: TRTLCriticalSection;
{This semaphore is signalled by the main thread when it added a workload
for the compression thread (usually when a buffer has been added to
compress).}
FPendingWorkSemaphore: THandle;
{The LZMA compression handle}
FLZMAEncHandle: CLzmaEncHandle;
{The background thread used to perform the compression}
FCompressionThread: TAbLZMACompressionThread;
{The error code returned by the compression method. 0 = Success.}
FCompressionErrorCode: Integer;
{The intermediate compression buffer used to aggregate small writes. When
NoMoreDataToCompress is called this buffer is freed, so no more data may
be written.}
FPIntermediateCompressionBuffer: PAbQueuedBuffer;
FIntermediateCompressionBufferAvailableBytes: Integer;
{The circular linked list of buffers that are queued for compression.}
FQueuedData: TAbQueuedBuffer;
{The number of bytes of buffer FQueuedData.NextBuffer that has already been
submitted to the compressor.}
FCurrentBufferBytesSubmitted: Integer;
{The position in the output stream where the uncompressed size must be
stored.}
FOutputStreamHeaderSizeFieldPosition: Int64;
{The total number of bytes written to the compression stream}
FTotalBytesWritten: Int64;
{Wakes up the compression thread by signalling the "pending work semaphore"}
procedure WakeCompressionThread; inline;
public
constructor Create(AOutputStream: TStream; ACompressionLevel: Integer = 5;
ADictionarySize: Integer = 65536);
destructor Destroy; override;
{Reading is not supported and will raise an exception.}
function Read(var ABuffer; ACount: Longint): Longint; override;
{Submits data to the compression queue.}
function Write(const ABuffer; ACount: Longint): Longint; override;
{Will raise an exception if an attempt is made to seek off the current
position.}
function Seek(AOffset: Integer; AOrigin: Word): Integer; override;
function Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override;
{Signals the compression thread that no more data will be submitted.
Calling write after NoMoreDataToCompress has been called will raise an
exception.}
procedure NoMoreDataToCompress;
{Calls NoMoreDataToCompress and then waits for the background compression
process to complete, returning the value of ErrorCode (0 = success).}
function WaitForCompressionToFinish: Integer;
{Returns True if the background thread is still busy compressing data. Will
always return True until NoMoreDataToCompress is called.}
function IsBusy: Boolean;
{-------------Public properties---------------}
{The error code returned by the compression method. 0 = Success.}
property ErrorCode: Integer read FCompressionErrorCode;
end;
{------------LZMA decompression stream------------}
TAbLZMADecompressionStream = class(TStream)
protected
FSourceStream: TStream;
{The intermediate buffers for compressed and uncompressed data
respectively.}
FCompressedDataBuffer: array[0..CompressedDataBufferSize - 1] of Byte;
FUncompressedDataBuffer: array[0..UncompressedDataBufferSize - 1] of Byte;
{Read buffer control: Used to speed up frequent small reads via
FUncompressedDataBuffer.}
FReadBufferSize: Integer;
FReadBufferAvailableBytes: Integer;
{The current size and position into FCompressedDataBuffer}
FCompressedDataBufferSize: Integer;
FCompressedDataBufferPosition: Integer;
{The uncompressed size according to the header.}
FUncompressedSize: Int64;
{The total number of bytes that have been decompressed.}
FBytesDecompressed: Int64;
{The LZMA decompression state}
FLzmaState: CLzmaDec;
{Decompresses data from the compressed source to the buffer pointed to by
APBuffer. Returns the number of actual bytes stored (which may be less
than the requested size if the end of the compressed stream was reached).}
function InternalDecompressToBuffer(APBuffer: Pointer; ABufferSize: Integer): Integer;
{---Property getters/setters---}
function GetBytesRead: Int64;
function GetSize: Int64; override;
public
constructor Create(ASourceStream: TStream);
destructor Destroy; override;
function Read(var ABuffer; ACount: Integer): Integer; override;
{Writing to a decompression stream is not allowed}
function Write(const ABuffer; ACount: Integer): Integer; override;
{Will raise an exception if an attempt is made to seek off the current
position.}
function Seek(AOffset: Integer; AOrigin: Word): Integer; override;
function Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64; override;
{---Public properties---}
{The number of decompressed bytes read from the decompression stream.}
property BytesRead: Int64 read GetBytesRead;
end;
implementation
uses
AbCrtl;
{------------Memory management-------------}
function SzAlloc(p: Pointer; size: size_t): Pointer; cdecl;
begin
Result := GetMemory(size);
end;
procedure SzFree(p, address: Pointer); cdecl;
begin
FreeMemory(address);
end;
var
DelphiMMInterface: ISzAlloc = (Alloc: SzAlloc; Free: SzFree);
{------------Compression "interface"-------------}
type
{The "interfaces" for the input and output streams}
CSeqInStream_Compress = packed record
Intf: ISeqInStream;
CompressionStream: TAbLZMACompressionStream;
end;
CSeqOutStream_Compress = packed record
Intf: ISeqOutStream;
OutputStream: TStream;
end;
function ISeqInStream_Compress_Read(p: Pointer; var buf; var size: size_t): SRes; cdecl;
var
LDoNotWaitForMoreData: Boolean;
LStream: TAbLZMACompressionStream;
LPSourceBuf, LPTargetBuf: PAnsiChar;
LTargetSpace, LSourceBytesAvail: Integer;
LPCurBuf: PAbQueuedBuffer;
begin
try
LTargetSpace := size;
LPTargetBuf := @buf;
LStream := CSeqInStream_Compress(p^).CompressionStream;
while True do
begin
{Copy any buffered data to the LZMA buffer, returning the number of bytes
written}
EnterCriticalSection(LStream.FBufferCriticalSection);
try
{If the write buffer has been freed that the main thread will not add
any more buffers for compression.}
LDoNotWaitForMoreData := LStream.FPIntermediateCompressionBuffer = nil;
{Copy as much queued data to the LZMA compression buffer as we have (or
will fit).}
while True do
begin
LPCurBuf := LStream.FQueuedData.NextBuffer;
{No buffers left? -> Break the loop}
if LPCurBuf = @LStream.FQueuedData then
Break;
{Can this buffer be submitted in its entirety, or only a part?}
LPSourceBuf := LPCurBuf.GetDataPointer(LStream.FCurrentBufferBytesSubmitted);
LSourceBytesAvail := LPCurBuf.DataSize - LStream.FCurrentBufferBytesSubmitted;
if LSourceBytesAvail > LTargetSpace then
begin
{Submit only part of the buffer}
System.Move(LPSourceBuf^, LPTargetBuf^, LTargetSpace);
Inc(LStream.FCurrentBufferBytesSubmitted, LTargetSpace);
LTargetSpace := 0;
Break;
end
else
begin
{Submit all the remaining bytes in the buffer and free it.}
System.Move(LPSourceBuf^, LPTargetBuf^, LSourceBytesAvail);
Inc(LPTargetBuf, LSourceBytesAvail);
Dec(LTargetSpace, LSourceBytesAvail);
LStream.FCurrentBufferBytesSubmitted := 0;
LPCurBuf.UnQueueBuffer;
FreeMem(LPCurBuf);
end;
end;
finally
LeaveCriticalSection(LStream.FBufferCriticalSection);
end;
{If data was submitted to the compressor, or the main thread indicated
that compression is complete then the loop is broken.}
if (LTargetSpace <> size) or LDoNotWaitForMoreData then
Break;
{No data currently queued, but there may still be more coming: Wait for
the main thread to notify this thread that more work is pending.}
WaitForSingleObject(LStream.FPendingWorkSemaphore, INFINITE);
end;
{Update the number of bytes written}
Dec(size, LTargetSpace);
Result := SZ_OK;
except
Result := SZ_ERROR_DATA;
end;
end;
function ISeqOutStream_Compress_Write(p: Pointer; const buf; size: size_t): size_t; cdecl;
begin
try
Result := CSeqOutStream_Compress(p^).OutputStream.Write(buf, size);
except
Result := 0;
end;
end;
{ TAbQueuedBuffer }
function TAbQueuedBuffer.GetDataPointer(AOffset: Integer): Pointer;
begin
Result := Pointer(PtrUInt(@Self) + SizeOf(TAbQueuedBuffer) + PtrUInt(AOffset));
end;
procedure TAbQueuedBuffer.QueueBuffer(ACompressionStream: TAbLZMACompressionStream);
begin
PreviousBuffer:= ACompressionStream.FQueuedData.PreviousBuffer;
NextBuffer:= @ACompressionStream.FQueuedData;
ACompressionStream.FQueuedData.PreviousBuffer.NextBuffer := @Self;
ACompressionStream.FQueuedData.PreviousBuffer := @Self;
end;
procedure TAbQueuedBuffer.UnQueueBuffer;
begin
PreviousBuffer.NextBuffer := NextBuffer;
NextBuffer.PreviousBuffer := PreviousBuffer;
PreviousBuffer := nil;
NextBuffer := nil;
end;
{ TAbLZMACompressionStream }
constructor TAbLZMACompressionStream.Create(AOutputStream: TStream; ACompressionLevel,
ADictionarySize: Integer);
var
LLZMAProps: CLzmaEncProps;
LLZMAPropData: TLZMAPropertyData;
LHeaderSize: size_t;
begin
inherited Create;
FOutputStream := AOutputStream;
{Initialize the linked list of buffers.}
FQueuedData.PreviousBuffer := @FQueuedData;
FQueuedData.NextBuffer := @FQueuedData;
{Allocate the intermediate compression buffer}
GetMem(FPIntermediateCompressionBuffer, UncompressedDataBufferSize + SizeOf(TAbQueuedBuffer));
FIntermediateCompressionBufferAvailableBytes := UncompressedDataBufferSize;
{Initialize the critical section used to control access to the queued data
buffer.}
InitializeCriticalSection(FBufferCriticalSection);
{Create the semaphore used to put the worker thread to sleep when the input
buffer is empty.}
FPendingWorkSemaphore := CreateSemaphore(nil, 0, 1, nil);
{Create the LZMA encoder}
FLZMAEncHandle := LzmaEnc_Create(@DelphiMMInterface);
if FLZMAEncHandle = nil then
raise Exception.Create('Unable to allocate memory for the LZMA compressor.');
{Set the compression properties}
LzmaEncProps_Init(LLZMAProps);
LLZMAProps.level := ACompressionLevel;
LLZMAProps.dictSize := ADictionarySize;
LzmaCheck(LzmaEnc_SetProps(FLZMAEncHandle, LLZMAProps));
{Store the header in the output stream, making note of the position in the
stream where the uncompressed size will be stored when compression is
completed.}
LHeaderSize := LZMA_PROPS_SIZE;
LzmaCheck(LzmaEnc_WriteProperties(FLZMAEncHandle, PByte(@LLZMAPropData), LHeaderSize));
FOutputStream.WriteBuffer(LLZMAPropData, LHeaderSize);
FOutputStreamHeaderSizeFieldPosition := FOutputStream.Position;
FOutputStream.WriteBuffer(FTotalBytesWritten, SizeOf(FTotalBytesWritten));
{Create and start the compression thread.}
FCompressionThread := TAbLZMACompressionThread.Create(True);
FCompressionThread.FCompressionStream := Self;
{$IFDEF HasThreadStart}
FCompressionThread.Start;
{$ELSE}
FCompressionThread.Resume;
{$ENDIF}
end;
destructor TAbLZMACompressionStream.Destroy;
var
LPBuf: PAbQueuedBuffer;
LOldPos: Int64;
begin
WaitForCompressionToFinish;
{If something went wrong during creation of this object before the thread was
created, then the encoder handle may be non-nil.}
if FLZMAEncHandle <> nil then
begin
LzmaEnc_Destroy(FLZMAEncHandle, @DelphiMMInterface, @DelphiMMInterface);
FLZMAEncHandle := nil;
end;
{Free the critical section and semaphore}
DeleteCriticalSection(FBufferCriticalSection);
CloseHandle(FPendingWorkSemaphore);
{Free the intermediate compression buffer if something went wrong before the
thread could be created.}
FreeMem(FPIntermediateCompressionBuffer);
{If compression failed there may be uncompressed data in the queue: free
those buffers.}
while True do
begin
LPBuf := FQueuedData.NextBuffer;
if LPBuf = @FQueuedData then
Break;
LPBuf.UnQueueBuffer;
FreeMem(LPBuf);
end;
{Unpdate the uncompressed size in the header}
if FTotalBytesWritten > 0 then
begin
LOldPos := FOutputStream.Position;
FOutputStream.Position := FOutputStreamHeaderSizeFieldPosition;
FOutputStream.WriteBuffer(FTotalBytesWritten, SizeOf(FTotalBytesWritten));
FOutputStream.Position := LOldPos;
end;
inherited Destroy;
end;
function TAbLZMACompressionStream.IsBusy: Boolean;
begin
Result := (FCompressionThread <> nil) and (not FCompressionThread.Finished);
end;
procedure TAbLZMACompressionStream.NoMoreDataToCompress;
var
LUnqueuedBytes: Integer;
begin
if FPIntermediateCompressionBuffer <> nil then
begin
EnterCriticalSection(FBufferCriticalSection);
try
{No more data may be submitted at this point. Set the flag to indicate
this, and wake the compression thread so that it can finish up.}
LUnqueuedBytes := UncompressedDataBufferSize - FIntermediateCompressionBufferAvailableBytes;
if LUnqueuedBytes > 0 then
begin
FPIntermediateCompressionBuffer.DataSize := LUnqueuedBytes;
FPIntermediateCompressionBuffer.QueueBuffer(Self);
end
else
FreeMem(FPIntermediateCompressionBuffer);
{The temporary buffer is always released, so no further writes may be
performed.}
FPIntermediateCompressionBuffer := nil;
finally
LeaveCriticalSection(FBufferCriticalSection);
end;
{Wake up the compression thread so it can finish the compression process.}
WakeCompressionThread;
end;
end;
function TAbLZMACompressionStream.Read(var ABuffer; ACount: Integer): Longint;
begin
raise Exception.Create('The compression stream does not support reading.');
end;
function TAbLZMACompressionStream.Seek(const AOffset: Int64;
AOrigin: TSeekOrigin): Int64;
begin
Result := FTotalBytesWritten;
if ((AOrigin <> soBeginning) or (AOffset <> Result))
and ((AOrigin = soBeginning) or (AOffset <> 0)) then
begin
raise Exception.Create('The compression stream does not support seeking away from the current position.');
end;
end;
function TAbLZMACompressionStream.Seek(AOffset: Integer; AOrigin: Word): Integer;
begin
Result := Seek(Int64(AOffset), TSeekOrigin(AOrigin));
end;
function TAbLZMACompressionStream.WaitForCompressionToFinish: Integer;
begin
if FCompressionThread <> nil then
begin
{Notify the thread that no further data will be submitted.}
NoMoreDataToCompress;
{Wait for the compression thread to complete normally and then free it.}
FCompressionThread.WaitFor;
FreeAndNil(FCompressionThread);
end;
Result := FCompressionErrorCode;
end;
procedure TAbLZMACompressionStream.WakeCompressionThread;
begin
ReleaseSemaphore(FPendingWorkSemaphore, 1, nil);
end;
function TAbLZMACompressionStream.Write(const ABuffer; ACount: Integer): Longint;
var
LPSource: PAnsiChar;
LPBufData: Pointer;
LPLargeBuf: PAbQueuedBuffer;
begin
if FPIntermediateCompressionBuffer = nil then
raise Exception.Create('Write may not be called after NoMoreDataToCompress.');
if ACount <= 0 then
begin
Result := 0;
Exit;
end;
LPSource := @ABuffer;
{Get a pointer to the position in the intermediate buffer to be written.}
LPBufData := FPIntermediateCompressionBuffer.GetDataPointer(
UncompressedDataBufferSize - FIntermediateCompressionBufferAvailableBytes);
if FIntermediateCompressionBufferAvailableBytes > ACount then
begin
{Copy the data into the intermediate buffer and exit.}
System.Move(LPSource^, LPBufData^, ACount);
Dec(FIntermediateCompressionBufferAvailableBytes, ACount);
Result := ACount;
end
else
begin
{Fill up the intermediate buffer}
System.Move(LPSource^, LPBufData^, FIntermediateCompressionBufferAvailableBytes);
Dec(ACount, FIntermediateCompressionBufferAvailableBytes);
Inc(LPSource, FIntermediateCompressionBufferAvailableBytes);
Result := FIntermediateCompressionBufferAvailableBytes;
{If we get here the current intermediate buffer is now full, and must be
queued.}
EnterCriticalSection(FBufferCriticalSection);
try
{Insert this buffer into the compression queue.}
FPIntermediateCompressionBuffer.DataSize := UncompressedDataBufferSize;
FPIntermediateCompressionBuffer.QueueBuffer(Self);
{Allocate a new intermediate compression buffer}
GetMem(FPIntermediateCompressionBuffer, UncompressedDataBufferSize + SizeOf(TAbQueuedBuffer));
FIntermediateCompressionBufferAvailableBytes := UncompressedDataBufferSize;
{Should the remaining data be copied into the intermediate compression
buffer, or is it too large and must it be queued separately?}
if ACount < UncompressedDataBufferSize then
begin
LPBufData := FPIntermediateCompressionBuffer.GetDataPointer(0);
System.Move(LPSource^, LPBufData^, ACount);
Dec(FIntermediateCompressionBufferAvailableBytes, ACount);
end
else
begin
{The remaining data is larger than the intermediate buffer: queue it
separately}
GetMem(LPLargeBuf, ACount + SizeOf(TAbQueuedBuffer));
LPLargeBuf.DataSize := ACount;
LPLargeBuf.QueueBuffer(Self);
{Copy the data across}
LPBufData := LPLargeBuf.GetDataPointer(0);
System.Move(LPSource^, LPBufData^, ACount);
end;
{Update the number of bytes written}
Inc(Result, ACount);
finally
LeaveCriticalSection(FBufferCriticalSection);
end;
{Wake up the compression thread to compress the newly queued data}
WakeCompressionThread;
end;
Inc(FTotalBytesWritten, Result);
end;
{ TAbLZMACompressionThread }
{$IFNDEF HasThreadFinished}
procedure TAbLZMACompressionThread.DoTerminate;
begin
inherited DoTerminate;
FFinished := True;
end;
{$ENDIF}
procedure TAbLZMACompressionThread.Execute;
var
LInStreamRec: CSeqInStream_Compress;
LOutStreamRec: CSeqOutStream_Compress;
begin
{Call the compression function and save the error code}
LInStreamRec.Intf.Read := ISeqInStream_Compress_Read;
LInStreamRec.CompressionStream := FCompressionStream;
LOutStreamRec.Intf.Write := ISeqOutStream_Compress_Write;
LOutStreamRec.OutputStream := FCompressionStream.FOutputStream;
FCompressionStream.FCompressionErrorCode := LzmaEnc_Encode(FCompressionStream.FLZMAEncHandle,
@LOutStreamRec.Intf, @LInStreamRec.Intf, nil, @DelphiMMInterface, @DelphiMMInterface);
{Free the compression handle}
LzmaEnc_Destroy(FCompressionStream.FLZMAEncHandle, @DelphiMMInterface, @DelphiMMInterface);
FCompressionStream.FLZMAEncHandle := nil;
end;
{ TAbLZMADecompressionStream }
constructor TAbLZMADecompressionStream.Create(ASourceStream: TStream);
var
LLZMAPropData: TLZMAPropertyData;
begin
inherited Create;
FSourceStream := ASourceStream;
{Read the header and uncompressed size from the compressed data stream.}
FSourceStream.ReadBuffer(LLZMAPropData, LZMA_PROPS_SIZE);
FSourceStream.ReadBuffer(FUncompressedSize, SizeOf(FUncompressedSize));
{Initialize the decompressor using the information from the header}
LzmaDec_Construct(FLzmaState);
LzmaCheck(LzmaDec_Allocate(FLzmaState, PByte(@LLZMAPropData), LZMA_PROPS_SIZE,
@DelphiMMInterface));
LzmaDec_Init(FLzmaState);
end;
destructor TAbLZMADecompressionStream.Destroy;
var
LUnusedBytes: Integer;
begin
{Release all decompression resources.}
LzmaDec_Free(FLzmaState, @DelphiMMInterface);
{Any unconsumed bytes in the compressed input buffer should be returned to
the source stream.}
LUnusedBytes := FCompressedDataBufferSize - FCompressedDataBufferPosition;
if LUnusedBytes > 0 then
FSourceStream.Position := FSourceStream.Position - LUnusedBytes;
inherited Destroy;
end;
function TAbLZMADecompressionStream.GetBytesRead: Int64;
begin
Result := FBytesDecompressed - FReadBufferAvailableBytes;
end;
function TAbLZMADecompressionStream.GetSize: Int64;
begin
Result := FUncompressedSize;
end;
function TAbLZMADecompressionStream.InternalDecompressToBuffer(APBuffer: Pointer;
ABufferSize: Integer): Integer;
var
LInputBytesProcessed, LOutputBytesProcessed: size_t;
LFinishMode: Integer;
LStatus: ELzmaStatus;
begin
Result := 0;
{Any more data to decompress to the output buffer?}
while ABufferSize > 0 do
begin
{Read more compressed data into the compressed data buffer, if required.}
if FCompressedDataBufferPosition >= FCompressedDataBufferSize then
begin
FCompressedDataBufferSize := FSourceStream.Read(FCompressedDataBuffer,
CompressedDataBufferSize);
FCompressedDataBufferPosition := 0;
end;
{Initialize the "processed byte count" variables to the sizes of the input
and output buffers.}
LInputBytesProcessed := FCompressedDataBufferSize - FCompressedDataBufferPosition;
LOutputBytesProcessed := ABufferSize;
{We may not read more bytes than the number of uncompressed bytes according
to the header.}
if (FUncompressedSize - FBytesDecompressed) <= LOutputBytesProcessed then
begin
LOutputBytesProcessed := FUncompressedSize - FBytesDecompressed;
LFinishMode := LZMA_FINISH_END;
end
else
LFinishMode := LZMA_FINISH_ANY;
{Decompress from the input to the output buffer}
LzmaCheck(LzmaDec_DecodeToBuf(FLzmaState, APBuffer,
LOutputBytesProcessed, @FCompressedDataBuffer[FCompressedDataBufferPosition],
LInputBytesProcessed, LFinishMode, LStatus));
{Update the input and output buffer stats}
Inc(FCompressedDataBufferPosition, LInputBytesProcessed);
Inc(PAnsiChar(APBuffer), LOutputBytesProcessed);
Dec(ABufferSize, LOutputBytesProcessed);
{Update the number of bytes decompressed}
Inc(Result, LOutputBytesProcessed);
Inc(FBytesDecompressed, LOutputBytesProcessed);
{Was all the data decompressed? If so, break the loop.}
if FUncompressedSize = FBytesDecompressed then
Break;
{Was nothing from the input or output streams processed? If so, then
something has gone wrong.}
if (LInputBytesProcessed = 0) and (LOutputBytesProcessed = 0) then
raise Exception.Create('LZMA decompression data error');
end;
end;
function TAbLZMADecompressionStream.Read(var ABuffer; ACount: Integer): Integer;
var
LBytesAlreadyRead: Integer;
begin
{Anything to read?}
if ACount > 0 then
begin
{Do we have enough data in the read buffer to satisfy the request?}
if FReadBufferAvailableBytes >= ACount then
begin
{Enough data in the buffer: Fill the output buffer.}
System.Move(PAnsiChar(@FUncompressedDataBuffer)[FReadBufferSize - FReadBufferAvailableBytes],
ABuffer, ACount);
{Subtract from the available bytes in the read buffer.}
Dec(FReadBufferAvailableBytes, ACount);
{Successfully read the number of bytes requested}
Result := ACount;
end
else
begin
{Not enough bytes available in the read buffer: Is there anything
available in the uncompressed data buffer? If so, then transfer what we
have.}
if FReadBufferAvailableBytes > 0 then
begin
{There is some data in the buffer: Read everything}
System.Move(PAnsiChar(@FUncompressedDataBuffer)[FReadBufferSize - FReadBufferAvailableBytes],
ABuffer, FReadBufferAvailableBytes);
LBytesAlreadyRead := FReadBufferAvailableBytes;
FReadBufferAvailableBytes := 0;
end
else
LBytesAlreadyRead := 0;
{If we get here it means the read buffer has been emptied and some data
still has to be read: Do we need to fill up the read buffer again, or do
we read directly into the target buffer? Large reads bypass the read
buffering mechanism.}
if ACount <= MaximumBlockSizeForBufferedIO then
begin
{Try to fill the read buffer again}
FReadBufferSize := InternalDecompressToBuffer(@FUncompressedDataBuffer, UncompressedDataBufferSize);
FReadBufferAvailableBytes := FReadBufferSize;
{No more data available? If so we're done.}
if FReadBufferAvailableBytes = 0 then begin
Result := LBytesAlreadyRead;
Exit;
end;
{Is enough data now available?}
if FReadBufferAvailableBytes >= (ACount - LBytesAlreadyRead) then
begin
{Enough data in the buffer: Fill the output buffer.}
System.Move(FUncompressedDataBuffer,
PAnsiChar(@ABuffer)[LBytesAlreadyRead],
ACount - LBytesAlreadyRead);
{Subtract from the available bytes in the read buffer and return the
number of bytes read.}
Dec(FReadBufferAvailableBytes, ACount - LBytesAlreadyRead);
{Successfully read the number of bytes requested}
Result := ACount;
end
else
begin
{Enough data is still not available (the end of the compressed stream
has been reached): Read what we can.}
System.Move(FUncompressedDataBuffer,
PAnsiChar(@ABuffer)[LBytesAlreadyRead],
FReadBufferAvailableBytes);
Inc(LBytesAlreadyRead, FReadBufferAvailableBytes);
FReadBufferAvailableBytes := 0;
Result := LBytesAlreadyRead;
end;
end
else
begin
{Decompress directly into the output buffer.}
Result := InternalDecompressToBuffer(
@PAnsiChar(@ABuffer)[LBytesAlreadyRead],
ACount - LBytesAlreadyRead) + LBytesAlreadyRead;
end;
end;
end
else
Result := 0;
end;
function TAbLZMADecompressionStream.Seek(const AOffset: Int64; AOrigin: TSeekOrigin): Int64;
begin
Result := GetBytesRead;
if ((AOrigin <> soBeginning) or (AOffset <> Result))
and ((AOrigin <> soCurrent) or (AOffset <> 0)) then
begin
raise Exception.Create('Decompression streams do not support seeking away '
+ 'from the current position.');
end;
end;
function TAbLZMADecompressionStream.Seek(AOffset: Integer; AOrigin: Word): Integer;
begin
Result := Seek(Int64(AOffset), TSeekOrigin(AOrigin));
end;
function TAbLZMADecompressionStream.Write(const ABuffer; ACount: Integer): Integer;
begin
raise Exception.Create('Writing to a LZMA decompression stream is not supported.');
end;
end.

307
Abbrevia/source/AbMeter.pas Normal file
View File

@@ -0,0 +1,307 @@
(* ***** 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: AbMeter.pas *}
{*********************************************************}
{* ABBREVIA: Progress meter *}
{* Use AbQMeter.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbMeter;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
Classes,
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
{$IFDEF UsingCLX }
QControls, QGraphics, QForms, QExtCtrls,
{$ELSE}
Controls, Graphics, Forms, ExtCtrls,
{$ENDIF}
AbBrowse;
type
TAbMeterOrientation = (moHorizontal, moVertical);
TAbCustomMeter = class(TGraphicControl, IAbProgressMeter)
{.Z+}
protected {private}
{property variables}
FBorderStyle : TBorderStyle;
FCtl3D : Boolean;
FOrientation : TAbMeterOrientation;
FPercent : Integer;
FTickMarks : Byte;
FUsedColor : TColor;
FUnusedColor : TColor;
{internal methods}
function GetVersion : string;
procedure Paint;
override;
procedure SetBorderStyle(const Value : TBorderStyle);
procedure SetCtl3D(const Value : Boolean);
procedure SetOrientation(const O : TAbMeterOrientation);
procedure SetTickMarks(const Value: Byte);
procedure SetUnusedColor(const C : TColor);
procedure SetUsedColor(const C : TColor);
procedure SetVersion(Value : string);
property Version : string
read GetVersion write SetVersion stored False;
{.Z-}
public {methods}
constructor Create(AOwner : TComponent);
override;
procedure DoProgress(Progress : Byte);
procedure Reset;
public {properties}
property BorderStyle : TBorderStyle
read FBorderStyle write SetBorderStyle default bsSingle;
property Ctl3D : Boolean
read FCtl3D write SetCtl3D default True;
property Orientation : TAbMeterOrientation
read FOrientation write SetOrientation;
property TickMarks: Byte
read FTickMarks write SetTickMarks default 10;
property UnusedColor : TColor
read FUnusedColor write SetUnusedColor;
property UsedColor : TColor
read FUsedColor write SetUsedColor;
end;
TAbMeter = class(TAbCustomMeter)
published
property Anchors;
property Constraints;
property Align;
property BorderStyle;
property Ctl3D;
property Font;
property OnClick;
property OnDblClick;
property OnMouseDown;
property OnMouseMove;
property OnMouseUp;
property Orientation;
property ParentFont;
property ParentShowHint;
property ShowHint;
property TickMarks;
property UnusedColor;
property UsedColor;
property Version;
property Visible;
end;
{.Z+}
implementation
uses
Types, AbConst;
{ == TAbCustomMeter ======================================================== }
constructor TAbCustomMeter.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
{$IFNDEF UsingCLX}
if NewStyleControls then
ControlStyle := ControlStyle + [csOpaque]
else
ControlStyle := ControlStyle + [csOpaque, csFramed];
{$ELSE}
ControlStyle := ControlStyle + [csOpaque, csFramed];
{$ENDIF}
FBorderStyle := bsSingle;
FCtl3D := True;
FOrientation := moHorizontal;
FTickMarks := 10;
FUnusedColor := clBtnFace;
FUsedColor := clNavy;
Width := 150;
Height := 16;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomMeter.GetVersion : string;
begin
Result := AbVersionS;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.DoProgress(Progress : Byte);
begin
if (Progress <> FPercent) then begin
FPercent := Progress;
if (FPercent >= 100) then
FPercent := 0;
Refresh;
Application.ProcessMessages;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.Paint;
const
VSpace = 2;
HSpace = 1;
LSpace = 1;
RSpace = 1;
var
ClRect, R : TRect;
ClWidth : Integer;
ClHeight : Integer;
BlockWidth : Integer;
BlockCount : Integer;
i : Integer;
begin
ClRect := ClientRect;
ClWidth := ClRect.Right - CLRect.Left + 1;
ClHeight := ClRect.Bottom - ClRect.Top + 1;
if (Orientation = moHorizontal) then
BlockWidth := ((ClWidth - LSpace - RSpace - (9 * VSpace)) div FTickMarks) + 1
else
BlockWidth := ((ClHeight - LSpace - RSpace - (9 * HSpace)) div FTickMarks) + 1;
BlockCount := FPercent div FTickMarks;
if not Assigned((Canvas as TControlCanvas).Control) then begin
TControlCanvas(Canvas).Control := self;
end;
with Canvas do begin
Brush.Color := FUnusedColor;
FillRect(Rect(ClRect.Left, ClRect.Top, ClRect.Left + ClWidth - 1,
ClRect.Top + ClHeight - 1));
Brush.Color := FUsedColor;
if (BlockCount > 0) then begin
if (Orientation = moHorizontal) then begin
R.Top := ClRect.Top + HSpace;
R.Bottom := ClRect.Bottom - HSpace;
for i := 0 to Pred(BlockCount) do begin
R.Left := ClRect.Left + LSpace + (i * VSpace) +
(i * BlockWidth);
R.Right := R.Left + BlockWidth;
FillRect(R);
end;
end else begin {moVertical}
R.Left := ClRect.Left + VSpace;
R.Right := ClRect.Right - VSpace;
for i := 0 to Pred(BlockCount) do begin
R.Bottom := ClRect.Bottom - LSpace - (i * HSpace) -
(i * BlockWidth);
R.Top := R.Bottom - BlockWidth;
FillRect(R);
end;
end;
end;
end;
{$IFNDEF LCL}
if (BorderStyle <> bsNone) then begin
if Ctl3D then
Frame3D(Canvas, ClRect, clBtnShadow, clBtnHighlight, 1)
else
Frame3D(Canvas, ClRect, clBlack, clBlack, 1);
end;
{$ENDIF}
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.Reset;
begin
DoProgress(0);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetBorderStyle(const Value : TBorderStyle);
begin
if (Value <> FBorderStyle) then begin
FBorderStyle := Value;
Invalidate;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetCtl3D(const Value : Boolean);
begin
if (Value <> FCtl3D) then begin
FCtl3D := Value;
Invalidate;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetOrientation(const O : TAbMeterOrientation);
var
Temp : Integer;
begin
if (O <> FOrientation) then begin
FOrientation := O;
if not (csLoading in ComponentState) then begin
Temp := Width;
Width := Height;
Height := Temp;
end;
Invalidate;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetTickMarks(const Value: Byte);
begin
if Value <= 0 then
FTickMarks := 10
else
FTickMarks := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetUnusedColor(const C : TColor);
begin
if (C <> FUnusedColor) then begin
FUnusedColor := C;
Invalidate;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetUsedColor(const C : TColor);
begin
if (C <> FUsedColor) then begin
FUsedColor := C;
Invalidate;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomMeter.SetVersion(Value : string);
begin
{NOP}
end;
end.

167
Abbrevia/source/AbPPMd.pas Normal file
View File

@@ -0,0 +1,167 @@
(* ***** 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 Craig Peterson
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbPPMd.pas *}
{*********************************************************}
{* ABBREVIA: PPMd decompression *}
{*********************************************************}
unit AbPPMd;
{$I AbDefine.inc}
interface
uses
Classes;
procedure DecompressPPMd(aSrc, aDes: TStream);
implementation
uses
AbCrtl,
SysUtils,
AbExcept;
// Compiled with:
// Release: bcc32 -q -c *.c
// Debug: bcc32 -q -c -v -y *.c
{ Linker derectives ======================================================== }
// Don't re-order these; it will cause linker errors
{$IF DEFINED(WIN32)}
{$L Win32\PPMdVariantI.obj}
{$L Win32\PPMdContext.obj}
{$L Win32\PPMdSubAllocatorVariantI.obj}
{$L Win32\CarrylessRangeCoder.obj}
{$ELSEIF DEFINED(WIN64)}
{$L Win64\PPMdVariantI.obj}
{$L Win64\PPMdContext.obj}
{$L Win64\PPMdSubAllocatorVariantI.obj}
{$L Win64\CarrylessRangeCoder.obj}
{$IFEND}
{ CarrylessRangeCoder.h ==================================================== }
type
PInStream = ^TInStream;
TInStream = record
nextByte: function(Self: PInStream): Byte; cdecl;
// Private data
stream: TStream;
InPos: Integer;
InCount: Integer;
InBuf: array[0..4097] of Byte;
end;
{ -------------------------------------------------------------------------- }
function TInStream_NextByte(Self: PInStream): Byte; cdecl;
begin
if Self.InPos = Self.InCount then begin
Self.InCount := Self.stream.Read(Self.InBuf, SizeOf(Self.InBuf));
if Self.InCount = 0 then
raise EAbReadError.Create;
Self.InPos := 0;
end;
Result := Self.InBuf[Self.InPos];
Inc(Self.InPos);
end;
{ -------------------------------------------------------------------------- }
function TInStream_Create(aStream: TStream): PInStream;
begin
GetMem(Result, SizeOf(TInStream));
Result.nextByte := TInStream_NextByte;
Result.stream := aStream;
Result.InPos := 0;
Result.InCount := 0;
end;
{ PPMdVariantI.h =========================================================== }
type
PPMdModelVariantI = Pointer;
function CreatePPMdModelVariantI(const input: TInStream;
suballocsize, maxorder, restoration: Integer): PPMdModelVariantI; cdecl; external;
procedure FreePPMdModelVariantI(Self: PPMdModelVariantI); cdecl; external;
function NextPPMdVariantIByte(Self: PPMdModelVariantI): Integer; cdecl; external;
{ Decompression routines =================================================== }
procedure DecompressPPMd(aSrc, aDes: TStream);
const
OutBufSize = 4096;
var
nextByte: Integer;
params: word;
ppmd: PPMdModelVariantI;
Src: PInStream;
OutBuf: PByteArray;
OutPos: Integer;
begin
Src := TInStream_Create(aSrc);
try
GetMem(OutBuf, OutBufSize);
try
OutPos := 0;
ASrc.ReadBuffer(Params, SizeOf(Params));// Pkzip stream header
ppmd := CreatePPMdModelVariantI(Src^,
(((Params shr 4) and $FF) + 1) shl 20,// sub-allocator size
(Params and $0F) + 1, // model order
Params shr 12); // model restoration method
try
while True do begin
nextByte := NextPPMdVariantIByte(ppmd);
if nextByte < 0 then Break;
OutBuf[OutPos] := Byte(nextByte);
Inc(OutPos);
if OutPos = OutBufSize then begin
aDes.WriteBuffer(OutBuf^, OutBufSize);
OutPos := 0;
end;
end;
if OutPos > 0 then
aDes.WriteBuffer(OutBuf^, OutPos);
finally
FreePPMdModelVariantI(ppmd);
end;
finally
FreeMem(OutBuf);
end;
finally
FreeMem(Src);
end;
end;
end.

BIN
Abbrevia/source/AbPeCol.dfm Normal file

Binary file not shown.

177
Abbrevia/source/AbPeCol.pas Normal file
View File

@@ -0,0 +1,177 @@
(* ***** 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: AbPeCol.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - ZipView column headings *}
{* Use AbQPeCol.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbPeCol;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF UsingClx}
QGraphics,
QForms,
QControls,
QStdCtrls,
QButtons,
QExtCtrls,
AbQView,
AbBseCLX,
{$ELSE}
Graphics,
Forms,
Controls,
StdCtrls,
Buttons,
ExtCtrls,
AbView,
AbBseVcl,
{$ENDIF}
DesignIntf,
DesignEditors,
AbConst,
SysUtils,
Classes;
type
TAbColHeadingsEditor = class(TForm)
Panel1: TPanel;
Label1: TLabel;
Attribute1: TComboBox;
Done1: TBitBtn;
Apply1: TBitBtn;
Label2: TLabel;
Heading1: TEdit;
Button1: TButton;
procedure FormShow(Sender: TObject);
procedure Attribute1Click(Sender: TObject);
procedure Apply1Click(Sender: TObject);
procedure Heading1Exit(Sender: TObject);
private
{ Private declarations }
public
Viewer : TAbBaseViewer;
end;
TAbColHeadingsProperty = class(TClassProperty)
public
procedure Edit; override;
function GetAttributes: TPropertyAttributes; override;
end;
var
AbColHeadingsEditor: TAbColHeadingsEditor;
implementation
uses
AbResString;
{$IFNDEF UsingCLX}
{$R *.dfm}
{$ENDIF}
type
TAbViewerFriend = class(TAbBaseViewer);
{===TAbColHeadingsProperty==========================================}
procedure TAbColHeadingsProperty.Edit;
var
hEditor : TAbColHeadingsEditor;
begin
hEditor := TAbColHeadingsEditor.Create(Application);
try
hEditor.Viewer := TAbViewerFriend(GetComponent(0));
hEditor.ShowModal;
Designer.Modified;
finally
hEditor.Free;
end;
end;
{ -------------------------------------------------------------------------- }
function TAbColHeadingsProperty.GetAttributes: TPropertyAttributes;
begin
Result := inherited GetAttributes + [paDialog, paAutoUpdate];
end;
{===TAbColHeadingsEditor============================================}
procedure TAbColHeadingsEditor.FormShow(Sender: TObject);
const
cResString: array[TAbViewAttribute] of string = (AbItemNameHeadingS,
AbPackedHeadingS, AbMethodHeadingS, AbRatioHeadingS, AbCRCHeadingS,
AbFileAttrHeadingS, AbFileFormatHeadingS, AbEncryptionHeadingS,
AbTimeStampHeadingS, AbFileSizeHeadingS, AbVersionMadeHeadingS,
AbVersionNeededHeadingS, AbPathHeadingS);
var
i : TAbViewAttribute;
begin
with Attribute1 do begin
Clear;
for i := Low(TAbViewAttribute) to High(TAbViewAttribute) do
Items.Add(cResString[i]);
ItemIndex := 0;
end;
Attribute1Click(nil);
end;
procedure TAbColHeadingsEditor.Attribute1Click(Sender: TObject);
begin
if (Attribute1.ItemIndex > -1) then
Heading1.Text := TAbViewerFriend(Viewer).Headings[Attribute1.ItemIndex];
end;
procedure TAbColHeadingsEditor.Apply1Click(Sender: TObject);
begin
if (Attribute1.ItemIndex > -1) then begin
TAbViewerFriend(Viewer).Headings[Attribute1.ItemIndex] := Heading1.Text;
TAbViewerFriend(Viewer).InvalidateRow(0);
end;
end;
procedure TAbColHeadingsEditor.Heading1Exit(Sender: TObject);
begin
Apply1Click(nil);
end;
end.

123
Abbrevia/source/AbPeDir.pas Normal file
View File

@@ -0,0 +1,123 @@
(* ***** 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: AbPeDir.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - Directory *}
{* Use AbQPeDir.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbPeDir;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF UsingClx}
QGraphics,
QForms,
QControls,
QStdCtrls,
QButtons,
QExtCtrls,
{$ELSE}
Graphics,
Forms,
Controls,
StdCtrls,
Buttons,
ExtCtrls,
{$ENDIF}
DesignIntf,
DesignEditors,
SysUtils,
Classes;
type
TAbDirectoryProperty = class( TStringProperty )
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
implementation
uses
{$IFDEF UsingClx}
AbQDgDir;
{$ELSE}
AbDlgDir;
{$ENDIF}
function TAbDirectoryProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
{$IFDEF MSWINDOWS}
procedure TAbDirectoryProperty.Edit;
var
D : TAbDirDlg;
begin
D := TAbDirDlg.Create(Application);
try
D.Caption := 'Directory';
D.AdditionalText := 'Select Directory';
if D.Execute then
Value := D.SelectedFolder;
finally
D.Free;
end;
end;
{$ELSE}
procedure TAbDirectoryProperty.Edit;
var
D : TDirDlg;
begin
D := TDirDlg.Create(Application);
try
{$IFDEF MSWINDOWS}
D.DirectoryListBox1.Directory := Value;
{$ENDIF}
D.ShowModal;
if D.ModalResult = mrOK then
Value := D.SelectedFolder;
finally
D.Free;
end;
end;
{$ENDIF}
end.

176
Abbrevia/source/AbPeFn.pas Normal file
View File

@@ -0,0 +1,176 @@
(* ***** 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: AbPeFn.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - FileName *}
{* Use AbQPeFn.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbPeFn;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF UsingClx }
QDialogs, QForms,
{$ELSE}
Dialogs, Forms,
{$ENDIF}
DesignIntf,
DesignEditors,
SysUtils;
type
TAbFileNameProperty = class(TStringProperty)
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
TAbExeNameProperty = class(TStringProperty)
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
TAbCabNameProperty = class( TStringProperty )
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
TAbLogNameProperty = class( TStringProperty )
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
implementation
uses
AbResString,
AbArcTyp;
{ -------------------------------------------------------------------------- }
procedure AbGetFilename(const Ext : string;
const Filter : string;
const Title : string;
var aFilename : string);
var
D : TOpenDialog;
begin
D := TOpenDialog.Create( Application );
try
D.DefaultExt := Ext;
D.Filter := Filter;
D.FilterIndex := 0;
D.Options := [];
D.Title := Title;
D.FileName := aFilename;
if D.Execute then
aFilename := D.FileName;
finally
D.Free;
end;
end;
{ == for zip files ========================================================= }
function TAbFileNameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
{ -------------------------------------------------------------------------- }
procedure TAbFileNameProperty.Edit;
var
FN : string;
begin
FN := Value;
AbGetFilename(AbDefaultExtS, AbFilterS, AbFileNameTitleS, FN);
Value := FN;
end;
{ == for exe files ========================================================= }
function TAbExeNameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
{ -------------------------------------------------------------------------- }
procedure TAbExeNameProperty.Edit;
var
FN : string;
begin
FN := Value;
AbGetFilename(AbExeExtS, AbExeFilterS, AbFileNameTitleS, FN);
Value := FN;
end;
{ == for cab files ========================================================= }
function TAbCabNameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
{ -------------------------------------------------------------------------- }
procedure TAbCabNameProperty.Edit;
var
FN : string;
begin
FN := Value;
AbGetFilename(AbCabExtS, AbCabFilterS, AbFileNameTitleS, FN);
Value := FN;
end;
{ == for log files ========================================================= }
function TAbLogNameProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
{ -------------------------------------------------------------------------- }
procedure TAbLogNameProperty.Edit;
var
FN : string;
begin
FN := Value;
AbGetFilename(AbLogExtS, AbLogFilterS, AbFileNameTitleS, FN);
Value := FN;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,103 @@
(* ***** 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: AbPePass.pas *}
{*********************************************************}
{* ABBREVIA: Password property editor *}
{* Use AbQPePas.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbPePass;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF UsingClx}
QGraphics,
QForms,
QControls,
QStdCtrls,
QButtons,
QExtCtrls,
{$ELSE}
Graphics,
Forms,
Controls,
StdCtrls,
Buttons,
ExtCtrls,
{$ENDIF}
DesignIntf,
DesignEditors,
SysUtils,
Classes;
type
TAbPasswordProperty = class( TStringProperty )
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
implementation
uses
{$IFDEF UsingClx}
AbQDgPwd;
{$ELSE}
AbDlgPwd;
{$ENDIF}
function TAbPasswordProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog];
end;
procedure TAbPasswordProperty.Edit;
var
D : TPasswordDlg;
begin
D := TPasswordDlg.Create( Application );
try
D.Edit1.Text := Value;
D.ShowModal;
if D.ModalResult = mrOK then
Value := D.Edit1.Text;
finally
D.Free;
end;
end;
end.

BIN
Abbrevia/source/AbPeVer.dfm Normal file

Binary file not shown.

347
Abbrevia/source/AbPeVer.pas Normal file
View File

@@ -0,0 +1,347 @@
(* ***** 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: AbPeVer.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - Version *}
{* Use AbQPeVer.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbPeVer;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
{$IFDEF MSWINDOWS}
Windows,
ShellAPI,
{$ENDIF}
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
{$IFDEF UsingClx}
QGraphics,
QForms,
QControls,
QStdCtrls,
QButtons,
QExtCtrls,
QDialogs,
{$ELSE}
Graphics,
Forms,
Controls,
StdCtrls,
Buttons,
ExtCtrls,
Dialogs,
{$ENDIF}
DesignIntf,
DesignEditors,
SysUtils,
Classes;
type
TAbAboutBox = class(TForm)
lblVersion: TLabel;
Panel1: TPanel;
Image1: TImage;
btnOK: TButton;
Panel2: TPanel;
WebLbl: TLabel;
NewsLbl: TLabel;
Bevel1: TBevel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Label10: TLabel;
Label11: TLabel;
procedure FormCreate(Sender: TObject);
procedure btnOKClick(Sender: TObject);
procedure WebLblClick(Sender: TObject);
procedure WebLblMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure NewsLblClick(Sender: TObject);
procedure NewsLblMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Panel2MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
public
{ Public declarations }
end;
TAbVersionProperty = class( TStringProperty )
public
function GetAttributes: TPropertyAttributes;
override;
procedure Edit;
override;
end;
var
AbAboutBox : TAbAboutBox;
implementation
{$IFNDEF UsingCLX}
{$R *.dfm}
{$ENDIF}
uses
AbArcTyp,
AbConst,
AbResString;
{$IFDEF LINUX}
const
{ String Constants }
sCannotStartBrowser = 'Unable to start web browser. Make sure you have it properly set-up on your system.';
const
MaxBrowsers = 1;
type
ECannotStartBrowser = class(Exception);
type
TBrowserStartCmd = record
Command : string [64];
Parameters : string [255];
XTerm : Boolean; { Start browser in an XTerm }
end;
const
{ The list of browsers we can launch. }
BrowserList : array [1..MaxBrowsers] of TBrowserStartCmd =
((Command : 'netscape'; Parameters : '<site>'; Xterm : False));
procedure GetCurrentPath (PathList : TStringList);
var
WorkPath : PChar;
StartPos : PChar;
CurrentPath : PChar;
State : (Scanning, GotColon);
begin
WorkPath := getenv ('PATH');
PathList.Clear;
StartPos := WorkPath;
State := Scanning;
while (WorkPath^ <> #0) do begin
case State of
Scanning :
begin
if (WorkPath^ = ':') then begin
State := GotColon;
if (WorkPath <> StartPos) then begin
CurrentPath := StrAlloc(WorkPath - StartPos + 1);
StrLCopy(CurrentPath, StartPos, WorkPath-StartPos);
PathList.Add (CurrentPath);
StrDispose(CurrentPath);
end;
end;
end;
GotColon :
begin
if (WorkPath^ <> ':') then begin
StartPos := WorkPath;
State := Scanning;
end;
end;
end;{case}
inc(WorkPath);
end;
if (State = Scanning) and (WorkPath <> StartPos) then begin
CurrentPath := StrAlloc(WorkPath - StartPos + 1);
StrLCopy(CurrentPath, StartPos, WorkPath-StartPos);
PathList.Add (CurrentPath);
StrDispose(CurrentPath);
end;
end;
function IsBrowserPresent (PathList : TStringList;
Browser : string) : Boolean;
var
i : integer;
begin
Result := False;
for i := 0 to PathList.Count - 1 do begin
if FileExists (PathList[i] + '/' + Browser) then begin
Result := True;
exit;
end;
end;
end;
procedure CallBrowser (Browser : string;
Parameters : string;
Website : string;
XTerm : Boolean);
begin
if Pos ('<site>', Parameters) > 0 then begin
Parameters := Copy (Parameters, 1, Pos ('<site>', Parameters) - 1) +
Website +
Copy (Parameters, Pos ('<site>', Parameters) + 6, 255);
end else
Parameters := Parameters + ' ' + Website;
if XTerm then begin
Parameters := '-e ' + Browser + ' ' + Parameters;
Browser := 'xterm';
end;
Libc.system (PChar (Browser + ' ' + Parameters + ' &'));
end;
procedure StartBrowser (Website : string);
var
PathList : TStringList;
i : integer;
begin
PathList := TStringList.Create;
try
GetCurrentPath (PathList);
for i := 1 to MaxBrowsers do begin
if IsBrowserPresent (PathList, BrowserList[i].Command) then begin
CallBrowser (BrowserList[i].Command, BrowserList[i].Parameters,
Website, BrowserList[i].XTerm);
exit;
end;
end;
raise ECannotStartBrowser.Create(sCannotStartBrowser);
finally
PathList.Free;
end;
end;
{$ENDIF}
procedure TAbAboutBox.FormCreate(Sender: TObject);
begin
Top := (Screen.Height - Height ) div 3;
Left := (Screen.Width - Width ) div 2;
lblVersion.Caption := Format(AbVersionFormatS, [AbVersionS] );
end;
function TAbVersionProperty.GetAttributes: TPropertyAttributes;
begin
Result := [paDialog, paReadOnly];
end;
procedure TAbVersionProperty.Edit;
begin
with TAbAboutBox.Create( Application ) do
try
ShowModal;
finally
Free;
end;
end;
procedure TAbAboutBox.btnOKClick(Sender: TObject);
begin
Close;
end;
procedure TAbAboutBox.WebLblClick(Sender: TObject);
begin
{$IFDEF MSWINDOWS }
if ShellExecute(0, 'open', 'http://www.sourceforge.net/projects/tpabbrevia', '', '',
SW_SHOWNORMAL) <= 32 then
ShowMessage('Unable to start web browser');
{$ENDIF MSWINDOWS }
{$IFDEF LINUX }
try
StartBrowser('http://www.sourceforge.net/projects/tpabbrevia');
except
on ECannotStartBrowser do
ShowMessage('Unable to start web browser');
end;
{$ENDIF LINUX }
WebLbl.Font.Color := clNavy;
end;
procedure TAbAboutBox.WebLblMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
WebLbl.Font.Color := clRed;
end;
procedure TAbAboutBox.NewsLblClick(Sender: TObject);
begin
{$IFDEF MSWINDOWS }
if ShellExecute(0, 'open', 'http://www.sourceforge.net/forum/forum.php?forum_id=241865', '', '',
SW_SHOWNORMAL) <= 32 then
ShowMessage('Unable to start web browser');
{$ENDIF MSWINDOWS }
{$IFDEF LINUX }
try
StartBrowser('http://www.sourceforge.net/forum/forum.php?forum_id=241865');
except
on ECannotStartBrowser do
ShowMessage('Unable to start web browser');
end;
{$ENDIF LINUX }
NewsLbl.Font.Color := clNavy;
end;
procedure TAbAboutBox.NewsLblMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
NewsLbl.Font.Color := clRed;
end;
procedure TAbAboutBox.Panel2MouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
NewsLbl.Font.Color := clNavy;
end;
procedure TAbAboutBox.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
WebLbl.Font.Color := clNavy;
NewsLbl.Font.Color := clNavy;
end;
end.

View File

@@ -0,0 +1,39 @@
(* ***** 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: AbQCView.pas *}
{*********************************************************}
{* ABBREVIA: Cabinet archive viewer component (CLX) *}
{* Use AbCView.pas for VCL *}
{*********************************************************}
Unit AbQCView;
{$DEFINE UsingCLX}
{$I AbCView.pas}

View File

@@ -0,0 +1,39 @@
(* ***** 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: AbQCmpnd.pas *}
{*********************************************************}
{* ABBREVIA: Compound File classes and component (CLX) *}
{* Use AbCompnd.pas for VCL *}
{*********************************************************}
unit AbQCmpnd;
{$DEFINE UsingCLX}
{$I AbCompnd.pas}

View File

@@ -0,0 +1,40 @@
(* ***** 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: AbQDgDir.pas *}
{*********************************************************}
{* ABBREVIA: Dialog - Directory (CLX) *}
{* Use AbDlgDir.pas for VCL *}
{*********************************************************}
{$DEFINE UsingClx }
unit AbQDgDir;
{$R *.xfm}
{$I AbDlgDir.pas}

Binary file not shown.

View File

@@ -0,0 +1,40 @@
(* ***** 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: AbQDgPwd.pas *}
{*********************************************************}
{* ABBREVIA: Dialog - Password (CLX) *}
{* Use AbDlgPwd.pas for VCL *}
{*********************************************************}
{$DEFINE UsingClx}
unit AbQDgPwd;
{$R *.xfm}
{$I AbDlgPwd.pas}

Binary file not shown.

View File

@@ -0,0 +1,39 @@
(* ***** 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: AbQCmpnd.pas *}
{*********************************************************}
{* ABBREVIA: Compound File classes and component (CLX) *}
{* Use AbCompnd.pas for VCL *}
{*********************************************************}
unit AbQHexVw;
{$DEFINE UsingCLX}
{$I AbHexVw.pas}

View File

@@ -0,0 +1,38 @@
(* ***** 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: AbQMeter.pas *}
{*********************************************************}
{* ABBREVIA: Progress meter (CLX) *}
{* Use AbMeter.pas for VCL *}
{*********************************************************}
{$DEFINE UsingCLX}
unit AbQMeter;
{$I AbMeter.pas}

View File

@@ -0,0 +1,43 @@
(* ***** 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: AbQPeCol.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - ZipView column headings *}
{* (CLX) *}
{* Use AbPeCol.pas for VCL *}
{*********************************************************}
{$DEFINE UsingClx}
unit AbQPeCol;
{$R *.xfm}
{$I AbPeCol.pas}

Binary file not shown.

View File

@@ -0,0 +1,37 @@
(* ***** 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: AbPeDir.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - Directory (CLX) *}
{* Use AbPeDir.pas for VCL *}
{*********************************************************}
{$DEFINE UsingCLX}
unit AbQPeDir;
{$I AbPeDir.pas}

View File

@@ -0,0 +1,38 @@
(* ***** 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: AbQPeFn.PAS *}
{*********************************************************}
{* ABBREVIA: Property Editor - FileName (CLX) *}
{* Use AbPeFn.pas for VCL *}
{*********************************************************}
{$DEFINE UsingClx}
unit AbQPeFn;
{$I AbPeFn.pas}

View File

@@ -0,0 +1,39 @@
(* ***** 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: AbQPePas.pas *}
{*********************************************************}
{* ABBREVIA: Password property editor (CLX) *}
{* Use AbPePass.pas for VCL *}
{*********************************************************}
{$DEFINE UsingClx}
unit AbQPePas;
{$I AbPePass.pas}

View File

@@ -0,0 +1,40 @@
(* ***** 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: AbQPeVer.pas *}
{*********************************************************}
{* ABBREVIA: Property Editor - Version (CLX) *}
{* See AbPeVer.pas for the VCL header *}
{*********************************************************}
{$DEFINE UsingClx}
unit AbQPeVer;
{$R *.xfm}
{$I AbPeVer.pas}

Binary file not shown.

View File

@@ -0,0 +1,38 @@
(* ***** 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: AbQView.pas *}
{*********************************************************}
{* ABBREVIA: Base archive viewer component (CLX) *}
{* Use AbView.pas for VCL *}
{*********************************************************}
{$DEFINE UsingCLX}
unit AbQView;
{$I AbView.pas}

View File

@@ -0,0 +1,39 @@
(* ***** 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: AbQZView.pas *}
{*********************************************************}
{* ABBREVIA: Zip archive viewer component (CLX) *}
{* Use AbZView.pas for VCL *}
{*********************************************************}
{$DEFINE UsingCLX}
unit AbQZView;
{$I AbZView.pas}

View File

@@ -0,0 +1,40 @@
(* ***** 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: AbQZpOut.pas *}
{*********************************************************}
{* ABBREVIA: Visual Component with Zip and unzip support *}
{* (CLX) *}
{* Use AbZipOut.pas for VCL *}
{*********************************************************}
{$DEFINE UsingCLX}
unit AbQZpOut;
{$I AbZipOut.pas}

188
Abbrevia/source/AbReg.pas Normal file
View File

@@ -0,0 +1,188 @@
(* ***** 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: AbReg.pas *}
{*********************************************************}
{* ABBREVIA: Registrations (VCL) *}
{*********************************************************}
unit AbReg;
{$I AbDefine.inc}
{$UNDEF UsingClx }
{$R AbReg.res}
interface
uses
Classes,
{$IFDEF LCL}
LResources,
{$ENDIF}
{$IFDEF MSWINDOWS}
AbCBrows, AbCabExt, AbCabMak, AbCabKit,
{$ENDIF}
AbZBrows, AbUnzper, AbZipper, AbZipKit, AbSelfEx;
procedure Register;
implementation
{$IFNDEF FPC}
uses
AbUtils,
AbPeDir,
AbPeFn,
AbPePass,
AbPeVer,
AbPeCol,
DesignIntf,
DesignEditors,
SysUtils;
{$ENDIF}
procedure Register;
begin
{$IFNDEF FPC}
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',
TAbVersionProperty );
{$ENDIF}
RegisterComponents( 'Abbrevia',
[ TAbZipBrowser,
TAbUnzipper,
TAbZipper,
TAbZipKit,
{$IFDEF MSWINDOWS}
TAbCabBrowser,
TAbCabExtractor,
TAbMakeCab,
TAbCabKit,
{$ENDIF}
TAbMakeSelfExe ]);
end;
{$IFDEF LCL}
initialization
{$I abbrevia.lrs}
{$ENDIF}
end.

View File

@@ -0,0 +1,235 @@
(* ***** 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: AbRegClx.pas *}
{*********************************************************}
{* ABBREVIA: Registrations (CLX) *}
{*********************************************************}
unit AbRegClx;
{$I AbDefine.inc}
{$DEFINE UsingCLX}
{$R AbReg.res}
interface
{$IFDEF LINUX}
!! Error, this unit is for CLX on Windows, use AbRegLinux.pas for Linux
{$ENDIF}
uses
Classes,
AbCBrows, AbCabExt, AbCabMak, AbCabKit,
AbZBrows, AbUnzper, AbZipper, AbZipKit, AbSelfEx,
AbQCView, AbQZpOut, AbQView, AbQZView, AbQMeter;
procedure Register;
implementation
uses
AbUtils,
AbQPeDir,
AbQPeFn,
AbQPePas,
AbQPeVer,
AbQPeCol,
AbQDgDir,
AbQDgPwd,
DesignIntf,
DesignEditors,
SysUtils;
procedure Register;
begin
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',
TAbColHeadingsProperty );
{$IFDEF MSWINDOWS}
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbCabView, 'Headings',
TAbColHeadingsProperty );
{$ENDIF}
RegisterComponents( 'Abbrevia',
[ TAbZipBrowser,
TAbUnzipper,
TAbZipper,
TAbZipKit,
TAbZipView,
TAbZipOutline,
{$IFDEF MSWINDOWS}
TAbCabBrowser,
TAbCabExtractor,
TAbMakeCab,
TAbCabKit,
TAbCabView,
{$ENDIF}
TAbMeter,
TAbMakeSelfExe ]);
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',
TAbColHeadingsProperty );
RegisterComponents( 'Abbrevia',
[
TAbMeter,
TAbCabView,
TAbZipView,
TAbZipOutline
]);
end;
end.

View File

@@ -0,0 +1,153 @@
(* ***** 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: AbRegLinux.pas *}
{*********************************************************}
{* ABBREVIA: Registrations *}
{*********************************************************}
unit AbRegLinux;
{$I AbDefine.inc}
{$R AbReg.res}
interface
{$IFDEF MSWINDOWS}
!! Error, this unit is for CLX on Linux, use AbRegClx.pas for Windows
{$ENDIF}
uses
Classes,
AbQZpOut, AbQView, AbQZView, AbQMeter;
procedure Register;
implementation
uses
AbUtils,
AbQPeDir,
AbQPeFn,
AbQPePas,
AbQPeVer,
AbQPeCol,
AbZBrows,
AbZipper,
AbUnzper,
AbZipKit,
AbSelfEx,
DesignIntf,
DesignEditors;
procedure Register;
begin
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',
TAbColHeadingsProperty );
RegisterComponents( 'Abbrevia',
[TAbZipBrowser,
TAbUnzipper,
TAbZipper,
TAbZipKit,
TAbZipOutline,
TAbZipView,
TAbMeter,
TAbMakeSelfExe]);
end;
end.

View File

@@ -0,0 +1,247 @@
(* ***** 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: AbRegVcl.pas *}
{*********************************************************}
{* ABBREVIA: Registrations (VCL) *}
{*********************************************************}
unit AbRegVcl;
{$I AbDefine.inc}
{$UNDEF UsingClx }
{$R AbReg.res}
interface
uses
Classes,
AbCBrows, AbCabExt, AbCabMak, AbCabKit, AbCView,
AbCompnd, AbHexVw, AbZBrows, AbUnzper, AbZipper, AbZipKit, AbZipOut,
AbView, AbComCtrls, AbZView, AbMeter, AbSelfEx, AbZipExt;
procedure Register;
implementation
uses
AbConst,
AbUtils,
AbPeDir,
AbPeFn,
AbPePass,
AbPeVer,
AbPeCol,
DesignIntf,
DesignEditors,
Graphics,
ToolsAPI,
SysUtils,
Windows;
procedure Register;
begin
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'FileName',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'SelfExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'StubExe',
TAbExeNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'ZipFile',
TAbFileNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbListView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbTreeView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMeter, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbProgressBar, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeSelfExe, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipBrowser, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbUnZipper, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipKit, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbZipOutline, 'Password',
TAbPasswordProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbZipView, 'Headings',
TAbColHeadingsProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'FileName',
TAbCabNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'BaseDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'LogFile',
TAbLogNameProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'TempDirectory',
TAbDirectoryProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabBrowser, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbMakeCab, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabExtractor, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabKit, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( string ), TAbCabView, 'Version',
TAbVersionProperty );
RegisterPropertyEditor( TypeInfo( TAbColHeadings ), TAbCabView, 'Headings',
TAbColHeadingsProperty );
RegisterComponents( 'Abbrevia',
[ TAbZipBrowser,
TAbUnzipper,
TAbZipper,
TAbZipKit,
TAbZipView,
TAbZipOutline,
TAbTreeView,
TAbListView,
TAbCabBrowser,
TAbCabExtractor,
TAbMakeCab,
TAbCabKit,
TAbCabView,
TAbProgressBar,
TAbMeter,
TAbMakeSelfExe ]);
end;
{$IF DECLARED(IOTAAboutBoxServices)}
var
AboutBoxIndex: Integer = -1;
procedure RegisterAboutBox;
begin
SplashScreenServices.AddPluginBitmap(
'Abbrevia: Advanced data compression toolkit, v' + AbVersionS,
LoadBitmap(HInstance, 'SPLASH'));
AboutBoxIndex := (BorlandIDEServices as IOTAAboutBoxServices).AddPluginInfo(
'Abbrevia ' + AbVersionS,
'Abbrevia: Advanced data compression toolkit, v' + AbVersionS + sLineBreak +
'http://tpabbrevia.sourceforge.net/' + sLineBreak +
sLineBreak +
'Copyright (c) 1997-2011 Abbrevia development team' + sLineBreak +
'Covered under the Mozilla Public License (MPL) v1.1' + sLineBreak +
'Abbrevia includes source code from bzip2, the LZMA SDK,' + sLineBreak +
'Dag <20>gren''s version of PPMd, and the WavPack SDK.',
LoadBitmap(HInstance, 'SPLASH'));
end;
procedure UnregisterAboutBox;
begin
if AboutBoxIndex <> -1 then
(BorlandIDEServices as IOTAAboutBoxServices).RemovePluginInfo(AboutBoxIndex);
end;
initialization
RegisterAboutBox;
finalization
UnRegisterAboutBox;
{$IFEND}
end.

View File

@@ -0,0 +1,250 @@
(* ***** 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):
* Roman Kassebaum
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* Abbrevia: AbResString.pas *}
{*********************************************************}
{* Abbrevia: Resource strings *}
{*********************************************************}
unit AbResString;
{$I AbDefine.inc}
interface
resourcestring
AbErrZipInvalidS = 'Invalid file - not a PKZip file';
AbZipVersionNeededS = 'Cannot extract file - newer version required';
AbUnknownCompressionMethodS = 'Cannot extract file - unsupported compression method';
AbNoExtractionMethodS = 'Cannot extract file - no extraction support provided';
AbInvalidPasswordS = 'Cannot extract file - invalid password';
AbNoInsertionMethodS = 'Cannot insert file - no insertion support provided';
AbInvalidFactorS = 'Invalid Reduce Factor';
AbDuplicateNameS = 'Cannot insert file - duplicates stored name';
AbUnsupportedCompressionMethodS = 'Cannot insert file - unsupported compression method';
AbUserAbortS = 'Process aborted by user';
AbArchiveBusyS = 'Archive is busy - cannot process new requests';
AbLastDiskRequestS = 'Insert the last disk in the spanned disk set';
AbDiskRequestS = 'Insert floppy';
AbImageRequestS = 'Image file name';
AbBadSpanStreamS = 'Spanned archives must be opened as file streams';
AbDiskNumRequestS = 'Insert disk number %d of the spanned disk set';
AbImageNumRequestS = 'Insert span number %d of the spanned file set';
AbNoOverwriteSpanStreamS = 'Cannot update an existing spanned disk set';
AbNoSpannedSelfExtractS = 'Cannot make a self-extracting spanned disk set';
AbBlankDiskS = 'Insert a blank floppy disk';
AbStreamFullS = 'Stream write error';
AbNoSuchDirectoryS = 'Directory does not exist';
AbInflateBlockErrorS = 'Cannot inflate block';
AbBadStreamTypeS = 'Invalid Stream';
AbTruncateErrorS = 'Error truncating Zip File';
AbZipBadCRCS = 'Failed CRC Check';
AbZipBadStubS = 'Stub must be an executable';
AbFileNotFoundS = 'File not found';
AbInvalidLFHS = 'Invalid Local File Header entry';
AbNoArchiveS = 'Archive does not exist - Filename is blank';
AbReadErrorS = 'Error reading archive';
AbInvalidIndexS = 'Invalid archive item index';
AbInvalidThresholdS = 'Invalid archive size threshold';
AbUnhandledFileTypeS = 'Unhandled Archive Type';
AbSpanningNotSupportedS = 'Spanning not supported by this Archive type';
AbLogCreateErrorS = 'Error creating Log File';
AbMoveFileErrorS = 'Error Moving File %s to %s';
AbFileSizeTooBigS = 'File size is too big for archive type';
AbNoCabinetDllErrorS = 'Cannot load cabinet.dll';
AbFCIFileOpenErrorS = 'FCI cannot open file';
AbFCIFileReadErrorS = 'FCI cannot read file';
AbFCIFileWriteErrorS = 'FCI cannot write file';
AbFCIFileCloseErrorS = 'FCI close file error';
AbFCIFileSeekErrorS = 'FCI file seek error';
AbFCIFileDeleteErrorS = 'FCI file delete error';
AbFCIAddFileErrorS = 'FCI cannot add file';
AbFCICreateErrorS = 'FCI cannot create context';
AbFCIFlushCabinetErrorS = 'FCI cannot flush cabinet';
AbFCIFlushFolderErrorS = 'FCI cannot flush folder';
AbFDICopyErrorS = 'FDI cannot enumerate files';
AbFDICreateErrorS = 'FDI cannot create context';
AbInvalidCabTemplateS = 'Invalid cab file template';
AbInvalidCabFileS = 'Invalid file - not a cabinet file';
AbZipStored = 'Stored';
AbZipShrunk = 'Shrunk';
AbZipReduced = 'Reduced';
AbZipImploded = 'Imploded';
AbZipTokenized = 'Tokenized';
AbZipDeflated = 'Deflated';
AbZipDeflate64 = 'Enhanced Deflation';
AbZipDCLImploded = 'DCL Imploded';
AbZipBzip2 = 'Bzip2';
AbZipLZMA = 'LZMA';
AbZipIBMTerse = 'IBM Terse';
AbZipLZ77 = 'IBM LZ77';
AbZipJPEG = 'JPEG';
AbZipWavPack = 'WavPack';
AbZipPPMd = 'PPMd';
AbZipUnknown = 'Unknown (%d)';
AbZipBestMethod = 'Best Method';
AbVersionFormatS = 'Version %s';
AbCompressedSizeFormatS = 'Compressed Size: %d';
AbUncompressedSizeFormatS = 'Uncompressed Size: %d';
AbCompressionMethodFormatS = 'Compression Method: %s';
AbCompressionRatioFormatS = 'Compression Ratio: %2.0f%%';
AbCRCFormatS = 'CRC: %x';
AbReadOnlyS = 'r';
AbHiddenS = 'h';
AbSystemS = 's';
AbArchivedS = 'a';
AbEFAFormatS = 'External File Attributes: %s';
AbIFAFormatS = 'File Type: %s';
AbTextS = 'Text';
AbBinaryS = 'Binary';
AbEncryptionFormatS = 'Encryption: %s';
AbEncryptedS = 'Encrypted';
AbNotEncryptedS = 'Not Encrypted';
AbUnknownS = 'Unknown';
AbTimeStampFormatS = 'Time Stamp: %s';
AbMadeByFormatS = 'Made by Version: %f';
AbNeededFormatS = 'Version Needed to Extract: %f';
AbCommentFormatS = 'Comment: %s';
AbDefaultExtS = '*.zip';
AbFilterS = 'PKZip Archives (*.zip)|*.zip|Self Extracting Archives (*.exe)|*.exe|All Files (*.*)|*.*';
AbFileNameTitleS = 'Select File Name';
AbOKS = 'OK';
AbCancelS = 'Cancel';
AbSelectDirectoryS = 'Select Directory';
AbEnterPasswordS = 'Enter Password';
AbPasswordS = '&Password';
AbVerifyS = '&Verify';
AbCabExtS = '*.cab';
AbCabFilterS = 'Cabinet Archives (*.cab)|*.CAB|All Files (*.*)|*.*';
AbLogExtS = '*.txt';
AbLogFilterS = 'Text Files (*.txt)|*.TXT|All Files (*.*)|*.*';
AbExeExtS = '*.exe';
AbExeFilterS = 'Self-Extracting Zip Files (*.exe)|*.EXE|All Files (*.*)|*.*';
AbVMSReadTooManyBytesS = 'VMS: request to read too many bytes [%d]';
AbVMSInvalidOriginS = 'VMS: invalid origin %d, should be 0, 1, 2';
AbVMSErrorOpenSwapS = 'VMS: Cannot open swap file %s';
AbVMSSeekFailS = 'VMS: Failed to seek in swap file %s';
AbVMSReadFailS = 'VMS: Failed to read %d bytes from swap file %s';
AbVMSWriteFailS = 'VMS: Failed to write %d bytes to swap file %s';
AbVMSWriteTooManyBytesS = 'VMS: request to write too many bytes [%d]';
AbBBSReadTooManyBytesS = 'BBS: request to read too many bytes [%d]';
AbBBSSeekOutsideBufferS = 'BBS: New position is outside the buffer';
AbBBSInvalidOriginS = 'BBS: Invalid Origin value';
AbBBSWriteTooManyBytesS = 'BBS: request to write too many bytes [%d]';
AbSWSNotEndofStreamS = 'TabSlidingWindowStream.Write: Not at end of stream';
AbSWSSeekFailedS = 'TabSlidingWindowStream.bsWriteChunk: seek failed';
AbSWSWriteFailedS = 'TabSlidingWindowStream.bsWriteChunk: write failed';
AbSWSInvalidOriginS = 'TabSlidingWindowStream.Seek: invalid origin';
AbSWSInvalidNewOriginS = 'TabSlidingWindowStream.Seek: invalid new position';
AbItemNameHeadingS = 'Name';
AbPackedHeadingS = 'Packed';
AbMethodHeadingS = 'Method';
AbRatioHeadingS = 'Ratio (%)';
AbCRCHeadingS = 'CRC32';
AbFileAttrHeadingS = 'Attributes';
AbFileFormatHeadingS = 'Format';
AbEncryptionHeadingS = 'Encrypted';
AbTimeStampHeadingS = 'Time Stamp';
AbFileSizeHeadingS = 'Size';
AbVersionMadeHeadingS = 'Version Made';
AbVersionNeededHeadingS = 'Version Needed';
AbPathHeadingS = 'Path';
AbPartialHeadingS = 'Partial';
AbExecutableHeadingS = 'Executable';
AbFileTypeHeadingS = 'Type';
AbLastModifiedHeadingS = 'Modified';
AbCabMethod0S = 'None';
AbCabMethod1S = 'MSZip';
AbLtAddS = ' added ';
AbLtDeleteS = ' deleted ';
AbLtExtractS = ' extracted ';
AbLtFreshenS = ' freshened ';
AbLtMoveS = ' moved ';
AbLtReplaceS = ' replaced ';
AbLtStartS = ' logging ';
AbGzipInvalidS = 'Invalid Gzip';
AbGzipBadCRCS = 'Bad CRC';
AbGzipBadFileSizeS = 'Bad File Size';
AbTarInvalidS = 'Invalid Tar';
AbTarBadFileNameS = 'File name too long';
AbTarBadLinkNameS = 'Symbolic link path too long';
AbTarBadOpS = 'Unsupported Operation';
AbUnhandledEntityS = 'Unhandled Entity';
{ pre-defined "operating system" (really more FILE system) identifiers for the
Gzip header }
AbGzOsFat = 'FAT File System (MS-DOS, OS/2, NT/Win32)';
AbGzOsAmiga = 'Amiga';
AbGzOsVMS = 'VMS (or OpenVMS)';
AbGzOsUnix = 'Unix';
AbGzOsVM_CMS = 'VM/CMS';
AbGzOsAtari = 'Atari TOS';
AbGzOsHPFS = 'HPFS File System (OS/2, NT)';
AbGzOsMacintosh = 'Macintosh';
AbGzOsZ_System = 'Z-System';
AbGzOsCP_M = 'CP/M';
AbGzOsTOPS_20 = 'TOPS-20';
AbGzOsNTFS = 'NTFS File System (NT)';
AbGzOsQDOS = 'QDOS';
AbGzOsAcornRISCOS = 'Acorn RISCOS';
AbGzOsVFAT = 'VFAT File System (Win95, NT)';
AbGzOsMVS = 'MVS';
AbGzOsBeOS = 'BeOS (BeBox or PowerMac)';
AbGzOsTandem = 'Tandem/NSK';
AbGzOsTHEOS = 'THEOS';
AbGzOsunknown = 'unknown';
AbGzOsUndefined = 'ID undefined by gzip';
{ Compound File specific error messages }
resourcestring
AbCmpndIndexOutOfBounds = 'Index out of bounds';
AbCmpndBusyUpdating = 'Compound file is busy updating';
AbCmpndInvalidFile = 'Invalid compound file';
AbCmpndFileNotFound = 'File/Directory not found';
AbCmpndFolderNotEmpty = 'Folder not empty';
AbCmpndExceedsMaxFileSize = 'File size exceeds maximum allowable';
implementation
end.

397
Abbrevia/source/AbSWStm.pas Normal file
View File

@@ -0,0 +1,397 @@
(* ***** 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: AbSWStm.pas *}
{*********************************************************}
{* ABBREVIA: TabSlidingWindowStream class *}
{*********************************************************}
unit AbSWStm;
{$I AbDefine.inc}
{Notes: The TabSlidingWindowStream class provides a simple buffered
stream for sliding window compression/decompression routines.
The sliding window stream is limited when compared with a true
buffered stream:
- it is assumed that the underlying stream is just going to
be written to and is initially empty
- the buffer is fixed in size to 40KB
- write operations can only occur at the end of the stream
- the stream can only be positioned with a certain limited
range
- we can only read up to 32KB
- we can only write up to 32KB
The stream is written as a wrapper around another stream
(presumably a file stream) which is used for actual reads to
the buffer and writes from the buffer.
The stream buffer is organized as five 8KB chunks in an
array. The last chunk is the only one used for writing, the
other four are a 32KB buffer for reading. As the final chunk
gets filled, the class will drop off the first chunk (writing
it to the underlying stream, and shift the other chunks in the
array.}
{Define this if you wish to see a trace of the stream usage in a file
called C:\SlideWin.LOG}
{.$DEFINE DebugTrace}
interface
uses
SysUtils,
Classes;
const
abSWChunkCount = 5;
type
TabSlidingWindowStream = class(TStream)
protected {private}
bsChunks : array [0..pred(abSWChunkCount)] of PByteArray;
bsBufferStart : longint;
bsLastPos : integer;
bsCurChunk : integer;
bsPosInChunk : integer;
bsPosInBuffer : longint;
bsSize : Longint; {count of bytes in stream}
bsDirty : boolean; {whether the buffer is dirty or not}
bsStream : TStream; {actual stream containing data}
{$IFDEF DebugTrace}
bsF : System.Text;
{$ENDIF}
protected
procedure bsWriteChunk(aIndex : integer);
procedure bsSlide;
public
constructor Create(aStream : TStream);
{-create the buffered stream}
destructor Destroy; override;
{-destroy the buffered stream}
procedure Flush;
{-ensures that all dirty buffered data is flushed}
function Read(var Buffer; Count : Longint) : Longint; override;
{-read from the stream into a buffer}
function Seek(Offset : Longint; Origin : Word) : Longint; override;
{-seek to a particular point in the stream}
function Write(const Buffer; Count : Longint) : Longint; override;
{-write to the stream from a buffer}
end;
implementation
const
ChunkSize = 8192; {cannot be greater than MaxInt}
{===Helper routines==================================================}
procedure RaiseException(const S : string);
begin
raise Exception.Create(S);
end;
{====================================================================}
{===TabSlidingWindowStream===========================================}
constructor TabSlidingWindowStream.Create(aStream : TStream);
var
i : integer;
begin
inherited Create;
{save the actual stream}
bsStream := aStream;
{allocate the chunks-they must be set to binary zeros}
for i := 0 to pred(abSWChunkCount) do
bsChunks[i] := AllocMem(ChunkSize);
{set the page/buffer variables to the start of the stream; remember
we only write to the last chunk--the previous chunks are set to
binary zeros}
aStream.Position := 0;
bsSize := 0;
bsBufferStart := -ChunkSize * pred(abSWChunkCount);
bsPosInBuffer := ChunkSize * pred(abSWChunkCount);
bsCurChunk := pred(abSWChunkCount);
bsPosInChunk := 0;
bsDirty := false;
{$IFDEF DebugTrace}
System.Assign(bsF, 'c:\SlideWin.LOG');
if FileExists('c:\SlideWin.LOG') then
System.Append(bsF)
else
System.Rewrite(bsF);
writeln(bsF, '---NEW LOG---');
{$ENDIF}
end;
{--------}
destructor TabSlidingWindowStream.Destroy;
var
i : integer;
begin
{destroy the buffer, after writing it to the actual stream}
if bsDirty then
Flush;
for i := 0 to pred(abSWChunkCount) do
if (bsChunks[i] <> nil) then
FreeMem(bsChunks[i], ChunkSize);
{$IFDEF DebugTrace}
System.Close(bsF);
{$ENDIF}
{let our ancestor clean up}
inherited Destroy;
end;
{--------}
procedure TabSlidingWindowStream.bsSlide;
var
SavePtr : PByteArray;
i : integer;
begin
{write out the first chunk}
bsWriteChunk(0);
{slide the chunks around}
SavePtr := bsChunks[0];
for i := 0 to abSWChunkCount-2 do
bsChunks[i] := bsChunks[i+1];
bsChunks[pred(abSWChunkCount)] := SavePtr;
{advance the buffer start position}
inc(bsBufferStart, ChunkSize);
{reset the write position}
bsPosInChunk := 0;
bsPosInBuffer := ChunkSize * pred(abSWChunkCount);
bsLastPos := 0;
end;
{--------}
procedure TabSlidingWindowStream.bsWriteChunk(aIndex : integer);
var
SeekResult : longint;
BytesWrit : longint;
Offset : longint;
BytesToWrite : integer;
begin
Offset := bsBufferStart + (longint(aIndex) * ChunkSize);
if (Offset >= 0) then begin
SeekResult := bsStream.Seek(Offset, 0);
if (SeekResult = -1) then
RaiseException('TabSlidingWindowStream.bsWriteChunk: seek failed');
if (aIndex <> pred(abSWChunkCount)) then
BytesToWrite := ChunkSize
else
BytesToWrite := bsLastPos;
BytesWrit := bsStream.Write(bsChunks[aIndex]^, BytesToWrite);
if (BytesWrit <> BytesToWrite) then
RaiseException('TabSlidingWindowStream.bsWriteChunk: write failed');
end;
end;
{--------}
procedure TabSlidingWindowStream.Flush;
var
i : integer;
begin
if bsDirty then begin
for i := 0 to pred(abSWChunkCount) do
bsWriteChunk(i);
bsDirty := false;
end;
end;
{--------}
function TabSlidingWindowStream.Read(var Buffer; Count : Longint) : Longint;
var
BufPtr : PByte;
BytesToGo : Longint;
BytesToRead : integer;
begin
BufPtr := @Buffer;
{$IFDEF DebugTrace}
System.Writeln(bsF, 'Read: ', Count, ' bytes');
{$ENDIF}
{we do not support reads greater than 32KB bytes}
if (Count > 32*1024) then
Count := 32*1024;
{reading is complicated by the fact we can only read in chunks of
ChunkSize: we need to partition out the overall read into a
read from part of the chunk, zero or more reads from complete
chunks and then a possible read from part of a chunk}
{calculate the actual number of bytes we can read - this depends on
the current position and size of the stream as well as the number
of bytes requested}
BytesToGo := Count;
if (bsSize < (bsBufferStart + bsPosInBuffer + Count)) then
BytesToGo := bsSize - (bsBufferStart + bsPosInBuffer);
if (BytesToGo <= 0) then begin
Result := 0;
Exit;
end;
{remember to return the result of our calculation}
Result := BytesToGo;
{calculate the number of bytes we can read prior to the loop}
BytesToRead := ChunkSize - bsPosInChunk;
if (BytesToRead > BytesToGo) then
BytesToRead := BytesToGo;
{copy from the stream buffer to the caller's buffer}
if (BytesToRead = 1) then
BufPtr^ := bsChunks[bsCurChunk]^[bsPosInChunk]
else
Move(bsChunks[bsCurChunk]^[bsPosInChunk], BufPtr^, BytesToRead);
{calculate the number of bytes still to read}
dec(BytesToGo, BytesToRead);
{while we have bytes to read, read them}
while (BytesToGo > 0) do begin
{advance the pointer for the caller's buffer}
inc(BufPtr, BytesToRead);
{as we've exhausted this chunk, advance to the next}
inc(bsCurChunk);
bsPosInChunk := 0;
{calculate the number of bytes we can read in this cycle}
BytesToRead := ChunkSize;
if (BytesToRead > BytesToGo) then
BytesToRead := BytesToGo;
{copy from the stream buffer to the caller's buffer}
Move(bsChunks[bsCurChunk]^, BufPtr^, BytesToRead);
{calculate the number of bytes still to read}
dec(BytesToGo, BytesToRead);
end;
{remember our new position}
inc(bsPosInChunk, BytesToRead);
end;
{--------}
function TabSlidingWindowStream.Seek(Offset : Longint;
Origin : Word) : Longint;
{$IFDEF DebugTrace}
const
OriginStr : array [0..2] of string[7] = ('start', 'current', 'end');
{$ENDIF}
var
NewPos : Longint;
begin
{$IFDEF DebugTrace}
System.Writeln(bsF, 'Seek: ', Offset, ' bytes from ', OriginStr[Origin]);
{$ENDIF}
{calculate the new position}
case Origin of
soFromBeginning : NewPos := Offset;
soFromCurrent : NewPos := bsBufferStart + bsPosInBuffer + Offset;
soFromEnd : NewPos := bsSize + Offset;
else
NewPos := 0;
RaiseException('TabSlidingWindowStream.Seek: invalid origin');
end;
{if the new position is invalid, say so}
if (NewPos < bsBufferStart) or (NewPos > bsSize) then
RaiseException('TabSlidingWindowStream.Seek: invalid new position');
{calculate the chunk number and the position in buffer & chunk}
bsPosInBuffer := NewPos - bsBufferStart;
bsCurChunk := bsPosInBuffer div ChunkSize;
bsPosInChunk := bsPosInBuffer mod ChunkSize;
{return the new position}
Result := NewPos;
end;
{--------}
function TabSlidingWindowStream.Write(const Buffer; Count : Longint) : Longint;
var
BufPtr : PByte;
BytesToGo : Longint;
BytesToWrite: integer;
begin
BufPtr := @Buffer;
{$IFDEF DebugTrace}
System.Writeln(bsF, 'Write: ', Count, ' bytes');
{$ENDIF}
{we ONLY write at the end of the stream}
if ((bsBufferStart + bsPosInBuffer) <> bsSize) then
RaiseException('TabSlidingWindowStream.Write: Not at end of stream');
{we do not support writes greater than 32KB bytes}
if (Count > 32*1024) then
Count := 32*1024;
{writing is complicated by the fact we write in chunks of Chunksize
bytes: we need to partition out the overall write into a write
to part of the chunk, zero or more writes to complete chunks and
then a possible write to part of a chunk; every time we fill a
chunk we have toi slide the buffer}
{when we write to this stream we always assume that we can write the
requested number of bytes: if we can't (eg, the disk is full) we'll
get an exception somewhere eventually}
BytesToGo := Count;
{remember to return the result of our calculation}
Result := BytesToGo;
{calculate the number of bytes we can write prior to the loop}
BytesToWrite := ChunkSize - bsPosInChunk;
if (BytesToWrite > BytesToGo) then
BytesToWrite := BytesToGo;
{copy from the caller's buffer to the stream buffer}
if (BytesToWrite = 1) then
bsChunks[pred(abSWChunkCount)]^[bsPosInChunk] := BufPtr^
else
Move(BufPtr^,
bsChunks[pred(abSWChunkCount)]^[bsPosInChunk],
BytesToWrite);
{mark our buffer as requiring a save to the actual stream}
bsDirty := true;
{calculate the number of bytes still to write}
dec(BytesToGo, BytesToWrite);
{while we have bytes to write, write them}
while (BytesToGo > 0) do begin
{slide the buffer}
bsSlide;
{advance the pointer for the caller's buffer}
inc(BufPtr, BytesToWrite);
{calculate the number of bytes we can write in this cycle}
BytesToWrite := ChunkSize;
if (BytesToWrite > BytesToGo) then
BytesToWrite := BytesToGo;
{copy from the caller's buffer to our buffer}
Move(BufPtr^,
bsChunks[pred(abSWChunkCount)]^,
BytesToWrite);
{calculate the number of bytes still to write}
dec(BytesToGo, BytesToWrite);
end;
{remember our new position}
inc(bsPosInChunk, BytesToWrite);
bsPosInBuffer := (longint(ChunkSize) * pred(abSWChunkCount)) + bsPosInChunk;
bsLastPos := bsPosInChunk;
{make sure the stream size is correct}
inc(bsSize, Result);
{if we're at the end of the chunk, slide the buffer ready for next
time we write}
if (bsPosInChunk = ChunkSize) then
bsSlide;
end;
{====================================================================}
end.

View File

@@ -0,0 +1,140 @@
(* ***** 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: AbSelfEx.pas *}
{*********************************************************}
{* ABBREVIA: Component for building self-extracting zips *}
{*********************************************************}
unit AbSelfEx;
{$I AbDefine.inc}
interface
uses
Classes,
AbBase;
type
TAbGetFileEvent = procedure(Sender : TObject; var aFilename : string;
var Abort : Boolean) of object;
type
TAbMakeSelfExe = class(TAbBaseComponent)
protected {private}
FStubExe : string;
FZipFile : string;
FSelfExe : string;
FStubStream : TFileStream;
FZipStream : TFileStream;
FSelfStream : TFileStream;
FOnGetStubExe : TAbGetFileEvent;
FOnGetZipFile : TAbGetFileEvent;
procedure DoGetStubExe(var Abort : Boolean);
procedure DoGetZipFile(var Abort : Boolean);
public
function Execute : Boolean;
published
property SelfExe : string
read FSelfExe
write FSelfExe;
property StubExe : string
read FStubExe
write FStubExe;
property ZipFile : string
read FZipFile
write FZipFile;
property OnGetStubExe : TAbGetFileEvent
read FOnGetStubExe
write FOnGetStubExe;
property OnGetZipFile : TAbGetFileEvent
read FOnGetZipFile
write FOnGetZipFile;
property Version;
end;
implementation
uses
SysUtils,
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
AbExcept, AbZipTyp;
{ -------------------------------------------------------------------------- }
function TAbMakeSelfExe.Execute : Boolean;
var
Abort : Boolean;
begin
Abort := False;
if (FStubExe = '') then
DoGetStubExe(Abort);
if Abort then
raise EAbUserAbort.Create;
if not FileExists(FStubExe) then
raise EAbFileNotFound.Create;
if (FZipFile = '') then
DoGetZipFile(Abort);
if Abort then
raise EAbUserAbort.Create;
if not FileExists(FZipFile) then
raise EAbFileNotFound.Create;
FStubStream := TFileStream.Create(FStubExe, fmOpenRead or fmShareDenyWrite);
FZipStream := TFileStream.Create(FZipFile, fmOpenRead or fmShareDenyWrite);
if (FSelfExe = '') then
FSelfExe := ChangeFileExt(FZipFile, '.exe');
FSelfStream := TFileStream.Create(FSelfExe, fmCreate or fmShareExclusive);
try
MakeSelfExtracting(FStubStream, FZipStream, FSelfStream);
Result := True;
finally
FStubStream.Free;
FZipStream.Free;
FSelfStream.Free;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbMakeSelfExe.DoGetStubExe(var Abort: Boolean);
begin
if Assigned(FOnGetStubExe) then
FOnGetStubExe(Self, FStubExe, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbMakeSelfExe.DoGetZipFile(var Abort : Boolean);
begin
if Assigned(FOnGetZipFile) then
FOnGetZipFile(Self, FZipFile, Abort);
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,398 @@
(* ***** 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):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbSpanSt.pas *}
{*********************************************************}
{* ABBREVIA: TAbSpan*Stream Classes *}
{*********************************************************}
{* Streams to handle splitting ZIP files or spanning *}
{* them to diskettes *}
{*********************************************************}
unit AbSpanSt;
{$I AbDefine.inc}
interface
uses
Classes,
AbArcTyp;
type
{ TAbSpanBaseStream interface ============================================== }
TAbSpanBaseStream = class(TStream)
protected {private}
FArchiveName: string;
FOnRequestImage: TAbRequestImageEvent;
protected {methods}
function GetImageName( ImageNumber: Integer ): string;
public {methods}
constructor Create( const ArchiveName: string );
public {events}
property OnRequestImage : TAbRequestImageEvent
read FOnRequestImage
write FOnRequestImage;
end;
{ TAbSpanReadStream interface ============================================== }
TAbSpanReadStream = class(TAbSpanBaseStream)
protected {private}
FCurrentImage: LongWord;
FIsSplit: Boolean;
FLastImage: LongWord;
FStream: TStream;
FOnRequestNthDisk : TAbRequestNthDiskEvent;
protected {methods}
procedure GotoImage( ImageNumber: Integer );
procedure SetOnRequestImage(Value: TAbRequestImageEvent);
public {methods}
constructor Create( const ArchiveName: string; CurrentImage: LongWord;
Stream: TStream );
destructor Destroy;
override;
function Read(var Buffer; Count: Longint): Longint;
override;
function Write(const Buffer; Count: Longint): Longint;
override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
override;
procedure SeekImage( Image: LongWord; const Offset: Int64);
public {events}
property OnRequestImage
write SetOnRequestImage;
property OnRequestNthDisk : TAbRequestNthDiskEvent
read FOnRequestNthDisk
write FOnRequestNthDisk;
end;
{ TAbSpanWriteStream interface ============================================= }
TAbSpanWriteStream = class(TAbSpanBaseStream)
protected {private}
FCurrentImage: LongWord;
FImageSize: Int64;
FStream: TStream;
FThreshold: Int64;
FOnRequestBlankDisk : TAbRequestDiskEvent;
protected {methods}
procedure NewImage;
public {methods}
constructor Create( const ArchiveName: string; Stream: TStream;
Threshold: Int64 );
destructor Destroy;
override;
function Read(var Buffer; Count: Longint): Longint;
override;
function Write(const Buffer; Count: Longint): Longint;
override;
function WriteUnspanned(const Buffer; Count: Longint;
FailOnSpan: Boolean = False): Boolean;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
override;
function ReleaseStream: TStream;
public {properties}
property CurrentImage : LongWord
read FCurrentImage;
public {events}
property OnRequestBlankDisk : TAbRequestDiskEvent
read FOnRequestBlankDisk
write FOnRequestBlankDisk;
end;
implementation
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
Math, RTLConsts, SysUtils, AbUtils, AbExcept;
{============================================================================}
{ TAbSpanBaseStream implementation ========================================= }
constructor TAbSpanBaseStream.Create( const ArchiveName: string );
begin
inherited Create;
FArchiveName := ArchiveName;
end;
{------------------------------------------------------------------------------}
function TAbSpanBaseStream.GetImageName( ImageNumber: Integer ): string;
var
Abort : Boolean;
Ext : string;
begin
{generate default name}
Ext := ExtractFileExt(FArchiveName);
if (Length(Ext) < 2) then
Ext := '.' + Format('%.2d', [ImageNumber])
else
Ext := Ext[1] + Ext[2] + Format('%.2d', [ImageNumber]);
Result := ChangeFileExt(FArchiveName, Ext);
{call event}
if Assigned(FOnRequestImage) then begin
Abort := False;
FOnRequestImage(Self, ImageNumber, Result, Abort);
if Abort then
raise EAbUserAbort.Create;
end;
end;
{============================================================================}
{ TAbSpanReadStream implementation ========================================= }
constructor TAbSpanReadStream.Create( const ArchiveName: string;
CurrentImage: LongWord; Stream: TStream );
begin
inherited Create(ArchiveName);
FCurrentImage := CurrentImage;
FIsSplit := FileExists(GetImageName(1)) or not AbDriveIsRemovable(ArchiveName);
FLastImage := CurrentImage;
FStream := Stream;
end;
{------------------------------------------------------------------------------}
destructor TAbSpanReadStream.Destroy;
begin
FreeAndNil(FStream);
inherited;
end;
{------------------------------------------------------------------------------}
procedure TAbSpanReadStream.GotoImage( ImageNumber: Integer );
var
Abort: Boolean;
ImageName: string;
begin
{ switch to the requested image. ImageNumber is passed in as 0-based to
match the zip spec, but all of the callbacks receive 1-based values. }
FreeAndNil(FStream);
FCurrentImage := ImageNumber;
Inc(ImageNumber);
ImageName := FArchiveName;
if FIsSplit then begin
{ the last image uses the original filename }
if FCurrentImage <> FLastImage then
ImageName := GetImageName(ImageNumber)
end
else if Assigned(FOnRequestNthDisk) then begin
Abort := False;
repeat
FOnRequestNthDisk(Self, ImageNumber, Abort);
if Abort then
raise EAbUserAbort.Create;
until AbGetDriveFreeSpace(ImageName) <> -1;
end
else
raise EAbUserAbort.Create;
FStream := TFileStream.Create(ImageName, fmOpenRead or fmShareDenyWrite);
end;
{------------------------------------------------------------------------------}
function TAbSpanReadStream.Read(var Buffer; Count: Longint): Longint;
var
BytesRead, BytesLeft: LongInt;
PBuf: PByte;
begin
{ read until the buffer's full, switching images if necessary }
Result := 0;
if FStream = nil then
Exit;
PBuf := @Buffer;
BytesLeft := Count;
while Result < Count do begin
BytesRead := FStream.Read(PBuf^, BytesLeft);
Inc(Result, BytesRead);
Inc(PBuf, BytesRead);
Dec(BytesLeft, BytesRead);
if BytesRead < BytesLeft then begin
if FCurrentImage <> FLastImage then
GotoImage(FCurrentImage + 1)
else
Break;
end;
end;
end;
{------------------------------------------------------------------------------}
function TAbSpanReadStream.Write(const Buffer; Count: Longint): Longint;
begin
raise EAbException.Create('TAbSpanReadStream.Write unsupported');
end;
{------------------------------------------------------------------------------}
function TAbSpanReadStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
if FStream = nil then
Result := 0
else if (Offset = 0) and (Origin = soCurrent) then
Result := FStream.Position
else
raise EAbException.Create('TAbSpanReadStream.Seek unsupported');
end;
{------------------------------------------------------------------------------}
procedure TAbSpanReadStream.SeekImage( Image: LongWord; const Offset: Int64);
begin
if FStream = nil then
Exit;
if FCurrentImage <> Image then
GotoImage(Image);
FStream.Position := Offset;
end;
{------------------------------------------------------------------------------}
procedure TAbSpanReadStream.SetOnRequestImage(Value: TAbRequestImageEvent);
begin
FOnRequestImage := Value;
FIsSplit := FileExists(GetImageName(1)) or not AbDriveIsRemovable(FArchiveName);
end;
{============================================================================}
{ TAbSpanWriteStream implementation ======================================== }
constructor TAbSpanWriteStream.Create( const ArchiveName: string;
Stream: TStream; Threshold: Int64 );
begin
inherited Create(ArchiveName);
FCurrentImage := 0;
FStream := Stream;
FThreshold := Threshold;
end;
{------------------------------------------------------------------------------}
destructor TAbSpanWriteStream.Destroy;
begin
FStream.Free;
inherited;
end;
{------------------------------------------------------------------------------}
procedure TAbSpanWriteStream.NewImage;
var
Abort: Boolean;
begin
{ start a new span or blank disk. FCurrentImage is 0-based to match the zip
spec, but all of the callbacks receive 1-based values. }
FreeAndNil(FStream);
Inc(FCurrentImage);
if FThreshold > 0 then
RenameFile(FArchiveName, GetImageName(FCurrentImage))
else begin
if Assigned(FOnRequestBlankDisk) then begin
Abort := False;
repeat
FOnRequestBlankDisk(Self, Abort);
if Abort then
raise EAbUserAbort.Create;
until AbGetDriveFreeSpace(FArchiveName) <> -1;
end
else
raise EAbUserAbort.Create;
AbSetSpanVolumeLabel(AbDrive(FArchiveName), FCurrentImage);
end;
FStream := TFileStream.Create(FArchiveName, fmCreate or fmShareDenyWrite);
FImageSize := 0;
end;
{------------------------------------------------------------------------------}
function TAbSpanWriteStream.Read(var Buffer; Count: Longint): Longint;
begin
raise EAbException.Create('TAbSpanWriteStream.Read unsupported');
end;
{------------------------------------------------------------------------------}
function TAbSpanWriteStream.Write(const Buffer; Count: Longint): Longint;
var
BytesWritten, BytesLeft: LongInt;
PBuf: PByte;
begin
{ write until the buffer is done, starting new spans if necessary }
Result := 0;
if FStream = nil then
Exit;
PBuf := @Buffer;
BytesLeft := Count;
while Result < Count do begin
if FThreshold > 0 then
BytesWritten := FStream.Write(PBuf^, Min(BytesLeft, FThreshold - FImageSize))
else
BytesWritten := FStream.Write(PBuf^, BytesLeft);
Inc(FImageSize, BytesWritten);
Inc(Result, BytesWritten);
Inc(PBuf, BytesWritten);
Dec(BytesLeft, BytesWritten);
if BytesWritten < BytesLeft then
NewImage;
end;
end;
{------------------------------------------------------------------------------}
function TAbSpanWriteStream.WriteUnspanned(const Buffer; Count: Longint;
FailOnSpan: Boolean = False): Boolean;
var
BytesWritten: LongInt;
begin
{ write as a contiguous block, starting a new span if there isn't room.
FailOnSpan (and result = false) can be used to update data before it's
written again }
if FStream = nil then
raise EWriteError.Create(SWriteError);
if (FThreshold > 0) and (FThreshold - FImageSize < Count) then
BytesWritten := 0
else
BytesWritten := FStream.Write(Buffer, Count);
if BytesWritten < Count then begin
if BytesWritten > 0 then
FStream.Size := FStream.Size - BytesWritten;
NewImage;
if FailOnSpan then
BytesWritten := 0
else begin
BytesWritten := Count;
FStream.WriteBuffer(Buffer, Count);
end;
end;
Inc(FImageSize, BytesWritten);
Result := (BytesWritten = Count);
end;
{------------------------------------------------------------------------------}
function TAbSpanWriteStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
if FStream = nil then
Result := 0
else if (Offset = 0) and (Origin = soCurrent) then
Result := FStream.Position
else
raise EAbException.Create('TAbSpanWriteStream.Seek unsupported');
end;
{------------------------------------------------------------------------------}
function TAbSpanWriteStream.ReleaseStream: TStream;
begin
Result := FStream;
FStream := nil;
end;
{------------------------------------------------------------------------------}
end.

2234
Abbrevia/source/AbTarTyp.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,197 @@
(* ***** 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 Craig Peterson
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbUnzOutStm.pas *}
{*********************************************************}
{* ABBREVIA: UnZip output stream; progress and CRC32 *}
{*********************************************************}
unit AbUnzOutStm;
{$I AbDefine.inc}
interface
uses
SysUtils, Classes, AbArcTyp;
type
// Fixed-length read-only stream, limits reads to the range between
// the input stream's starting position and a specified size. Seek/Position
// are adjusted to be 0 based.
TAbUnzipSubsetStream = class( TStream )
private
FStream : TStream;
FStartPos: Int64;
FCurPos: Int64;
FEndPos: Int64;
public
constructor Create(aStream: TStream; aStreamSize: Int64);
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
end;
// Write-only output stream, computes CRC32 and calls progress event
TAbUnzipOutputStream = class( TStream )
private
FBytesWritten : Int64;
FCRC32 : LongInt;
FCurrentProgress : Byte;
FStream : TStream;
FUncompressedSize : Int64;
FOnProgress : TAbProgressEvent;
function GetCRC32 : LongInt;
public
constructor Create(aStream : TStream);
function Read(var Buffer; Count: Longint): Longint; override;
function Write(const Buffer; Count: Longint): Longint; override;
function Seek(const Offset: Int64; Origin: TSeekOrigin): Int64; override;
property CRC32 : LongInt
read GetCRC32;
property Stream : TStream
read FStream
write FStream;
property UncompressedSize : Int64
read FUncompressedSize
write FUncompressedSize;
property OnProgress : TAbProgressEvent
read FOnProgress
write FOnProgress;
end;
implementation
uses
Math, AbExcept, AbUtils;
{ TAbUnzipSubsetStream implementation ====================================== }
{ -------------------------------------------------------------------------- }
constructor TAbUnzipSubsetStream.Create(aStream: TStream; aStreamSize: Int64);
begin
inherited Create;
FStream := aStream;
FStartPos := FStream.Position;
FCurPos := FStartPos;
FEndPos := FStartPos + aStreamSize;
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipSubsetStream.Read(var Buffer; Count: Longint): Longint;
begin
if Count > FEndPos - FCurPos then
Count := FEndPos - FCurPos;
if Count > 0 then begin
Result := FStream.Read(Buffer, Count);
Inc(FCurPos, Result);
end
else
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipSubsetStream.Write(const Buffer; Count: Longint): Longint;
begin
raise EAbException.Create('TAbUnzipSubsetStream.Write not supported');
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipSubsetStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
var
OldPos: Int64;
begin
OldPos := FCurPos;
case Origin of
soBeginning: FCurPos := FStartPos + Offset;
soCurrent: FCurPos := FCurPos + Offset;
soEnd: FCurPos := FEndPos + Offset;
end;
if FCurPos < FStartPos then
FCurPos := FStartPos;
if FCurPos > FEndPos then
FCurPos := FEndPos;
if OldPos <> FCurPos then
FStream.Position := FCurPos;
Result := FCurPos - FStartPos;
end;
{ -------------------------------------------------------------------------- }
{ TAbUnzipOutputStream implementation ====================================== }
{ -------------------------------------------------------------------------- }
constructor TAbUnzipOutputStream.Create(aStream: TStream);
begin
inherited Create;
FStream := aStream;
FCRC32 := -1;
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipOutputStream.Read(var Buffer; Count: Integer): Longint;
begin
raise EAbException.Create('TAbUnzipOutputStream.Read not supported');
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipOutputStream.Write(const Buffer; Count: Longint): Longint;
var
Abort : Boolean;
NewProgress : Byte;
begin
AbUpdateCRC( FCRC32, Buffer, Count );
Result := FStream.Write(Buffer, Count);
Inc( FBytesWritten, Result );
if Assigned( FOnProgress ) then begin
Abort := False;
NewProgress := AbPercentage(FBytesWritten, FUncompressedSize);
if (NewProgress <> FCurrentProgress) then begin
FOnProgress( NewProgress, Abort );
FCurrentProgress := NewProgress;
end;
if Abort then
raise EAbUserAbort.Create;
end;
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipOutputStream.Seek(const Offset: Int64; Origin: TSeekOrigin): Int64;
begin
Result := FStream.Seek(Offset, Origin);
end;
{ -------------------------------------------------------------------------- }
function TAbUnzipOutputStream.GetCRC32: LongInt;
begin
Result := not FCRC32;
end;
end.

1211
Abbrevia/source/AbUnzPrc.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,282 @@
(* ***** 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: ABUnzper.pas *}
{*********************************************************}
{* ABBREVIA: Non-visual Component with UnZip support *}
{*********************************************************}
unit AbUnzper;
{$I AbDefine.inc}
interface
uses
Classes,
AbZBrows, AbArcTyp, AbZipTyp;
type
TAbCustomUnZipper = class(TAbCustomZipBrowser)
protected {private}
FExtractOptions : TAbExtractOptions;
FOnConfirmOverwrite : TAbConfirmOverwriteEvent;
FOnNeedPassword : TAbNeedPasswordEvent;
FPasswordRetries : Byte;
protected {methods}
procedure DoConfirmOverwrite(var Name : string;
var Confirm : Boolean);
virtual;
procedure DoNeedPassword(Sender : TObject;
var NewPassword : AnsiString);
virtual;
procedure InitArchive; override;
procedure SetExtractOptions(Value : TAbExtractOptions);
procedure SetPasswordRetries(Value : Byte);
procedure UnzipProc(Sender : TObject; Item : TAbArchiveItem;
const NewName : string );
procedure UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;
OutStream : TStream);
procedure TestItemProc(Sender : TObject; Item : TAbArchiveItem);
procedure SetFileName(const aFileName : string);
override;
protected {properties}
property ExtractOptions : TAbExtractOptions
read FExtractOptions
write SetExtractOptions
default AbDefExtractOptions;
property OnConfirmOverwrite : TAbConfirmOverwriteEvent
read FOnConfirmOverwrite
write FOnConfirmOverwrite;
property OnNeedPassword : TAbNeedPasswordEvent
read FOnNeedPassword
write FOnNeedPassword;
property PasswordRetries : Byte
read FPasswordRetries
write SetPasswordRetries
default AbDefPasswordRetries;
public {methods}
constructor Create( AOwner : TComponent );
override;
destructor Destroy;
override;
procedure ExtractAt(Index : Integer; const NewName : string);
procedure ExtractFiles(const FileMask : string);
procedure ExtractFilesEx(const FileMask, ExclusionMask : string);
procedure ExtractToStream(const aFileName : string; ToStream : TStream);
procedure ExtractTaggedItems;
procedure TestTaggedItems;
end;
TAbUnZipper = class(TAbCustomUnZipper)
published
property ArchiveProgressMeter;
property ItemProgressMeter;
property BaseDirectory;
property ExtractOptions;
property LogFile;
property Logging;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmOverwrite;
property OnConfirmProcessItem;
property OnLoad;
property OnNeedPassword;
property OnRequestImage;
property OnProcessItemFailure;
property OnRequestLastDisk;
property OnRequestNthDisk;
property Password;
property PasswordRetries;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
implementation
uses
SysUtils,
AbUtils,
AbExcept,
AbUnzPrc;
{ -------------------------------------------------------------------------- }
constructor TAbCustomUnZipper.Create( AOwner : TComponent );
begin
inherited Create(AOwner);
ExtractOptions := AbDefExtractOptions;
PasswordRetries := AbDefPasswordRetries;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomUnZipper.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.DoConfirmOverwrite(var Name : string;
var Confirm : Boolean);
begin
Confirm := True;
if Assigned(FOnConfirmOverwrite) then
FOnConfirmOverwrite( Name, Confirm );
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.DoNeedPassword(Sender : TObject;
var NewPassword : AnsiString);
begin
if Assigned(FOnNeedPassword) then begin
FOnNeedPassword(Self, NewPassword);
Password := NewPassword;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.ExtractAt(Index : Integer; const NewName : string);
{extract a file from the archive that match the index}
begin
if (FArchive <> nil) then
FArchive.ExtractAt(Index, NewName)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.ExtractFiles(const FileMask : string);
{extract all files from the archive that match the mask}
begin
if (FArchive <> nil) then
FArchive.ExtractFiles( FileMask )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.ExtractFilesEx(const FileMask, ExclusionMask : string);
{extract files matching FileMask except those matching ExclusionMask}
begin
if (FArchive <> nil) then
FArchive.ExtractFilesEx(FileMask, ExclusionMask)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.ExtractToStream(const aFileName : string;
ToStream : TStream);
begin
if (FArchive <> nil) then
FArchive.ExtractToStream(aFileName, ToStream)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.ExtractTaggedItems;
{extract all tagged items from the archive}
begin
if (FArchive <> nil) then
FArchive.ExtractTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.InitArchive;
begin
inherited InitArchive;
if FArchive <> nil then begin
FArchive.ExtractOptions := FExtractOptions;
FArchive.OnConfirmOverwrite := DoConfirmOverwrite;
end;
if FArchive is TAbZipArchive then begin
TAbZipArchive(FArchive).PasswordRetries := FPasswordRetries;
TAbZipArchive(FArchive).OnNeedPassword := DoNeedPassword;
TAbZipArchive(FArchive).TestHelper := TestItemProc;
TAbZipArchive(FArchive).ExtractHelper := UnzipProc;
TAbZipArchive(FArchive).ExtractToStreamHelper := UnzipToStreamProc;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.SetExtractOptions(Value : TAbExtractOptions);
begin
FExtractOptions := Value;
if (FArchive <> nil) then
FArchive.ExtractOptions := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.SetPasswordRetries(Value : Byte);
begin
FPasswordRetries := Value;
if FArchive is TAbZipArchive then
TAbZipArchive(FArchive).PasswordRetries := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.TestTaggedItems;
{Test specified items}
begin
if (FArchive <> nil) then
FArchive.TestTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.UnzipProc(Sender : TObject;
Item : TAbArchiveItem;
const NewName : string);
begin
AbUnzip( TAbZipArchive(Sender), TAbZipItem(Item), NewName);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.UnzipToStreamProc(Sender : TObject;
Item : TAbArchiveItem;
OutStream : TStream);
begin
AbUnzipToStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.TestItemProc(Sender : TObject;
Item : TAbArchiveItem);
begin
AbTestZipItem(TAbZipArchive(Sender), TAbZipItem(Item));
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomUnZipper.SetFileName(const aFileName: string);
begin
if aFileName <> '' then
begin
if not FileExists(aFileName) then
raise EAbFileNotFound.Create;
if AbFileGetSize(aFileName) <= 0 then
raise EAbBadStream.Create;
end;
inherited SetFileName(aFileName);
end;
end.

1403
Abbrevia/source/AbUtils.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,540 @@
(* ***** 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: AbVMStrm.pas *}
{*********************************************************}
{* ABBREVIA: Virtual Memory Stream *}
{*********************************************************}
unit AbVMStrm;
{$I AbDefine.inc}
interface
uses
Classes;
const
AB_VMSPageSize = 4096; {must be a power of two}
AB_VMSMaxPages = 2048; {makes 8MB with the above value}
type
PvmsPage = ^TvmsPage;
TvmsPage = packed record
vpStmOfs : Int64; {value will be multiple of AB_VMSPageSize}
vpLRU : integer; {'time' page was last accessed}
vpDirty : Boolean; {has the page been changed?}
vpData : array [0..pred(AB_VMSPageSize)] of byte; {stream data}
end;
type
TAbVirtualMemoryStream = class(TStream)
protected {private}
vmsCachePage : PvmsPage; {the latest page used}
vmsLRU : Longint; {'tick' value}
vmsMaxMemToUse : Longword; {maximum memory to use for data}
vmsMaxPages : Integer; {maximum data pages}
vmsPageList : TList; {page array, sorted by offset}
vmsPosition : Int64; {position of stream}
vmsSize : Int64; {size of stream}
vmsSwapFileDir : string; {swap file directory}
vmsSwapFileName : string; {swap file name}
vmsSwapFileSize : Int64; {size of swap file}
vmsSwapStream : TFileStream;{swap file stream}
protected
procedure vmsSetMaxMemToUse(aNewMem : Longword);
function vmsAlterPageList(aNewMem : Longword) : Longword;
procedure vmsFindOldestPage(out OldestInx : Longint;
out OldestPage: PvmsPage);
function vmsGetNextLRU : Longint;
function vmsGetPageForOffset(aOffset : Int64) : PvmsPage;
procedure vmsSwapFileCreate;
procedure vmsSwapFileDestroy;
procedure vmsSwapFileRead(aPage : PvmsPage);
procedure vmsSwapFileWrite(aPage : PvmsPage);
public
constructor Create;
{-create the virtual memory stream}
destructor Destroy; override;
{-destroy the virtual memory stream}
function Read(var Buffer; Count : Longint) : Longint; override;
{-read from the stream into a buffer}
function Write(const Buffer; Count : Longint) : Longint; override;
{-write to the stream from a buffer}
function Seek(const Offset : Int64; Origin : TSeekOrigin) : Int64; override;
{-seek to a particular point in the stream}
procedure SetSize(const NewSize : Int64); override;
{-set the stream size}
property MaxMemToUse : Longword
read vmsMaxMemToUse write vmsSetMaxMemToUse;
{-maximum memory to use for data before swapping to disk}
property SwapFileDirectory : string
read vmsSwapFileDir write vmsSwapFileDir;
end;
implementation
uses
{$IFDEF MSWINDOWS}
Windows, // Fix warning about unexpanded inline functions
{$ENDIF}
SysUtils,
AbExcept,
AbUtils;
const
LastLRUValue = $7FFFFFFF;
{===TAbVirtualMemoryStream===========================================}
constructor TAbVirtualMemoryStream.Create;
var
Page : PvmsPage;
begin
inherited Create;
{create the page array}
vmsPageList := TList.Create;
{create the first page}
New(Page);
with Page^ do begin
vpStmOfs := 0;
vpLRU := vmsGetNextLRU;
vpDirty := False;
FillChar(vpData, AB_VMSPageSize, 0);
end;
vmsPageList.Insert(0, pointer(Page));
{prime the cache, from now on the cache will never be nil}
vmsCachePage := Page;
{default to using all allowed pages}
MaxMemToUse := AB_VMSMaxPages * AB_VMSPageSize;
end;
{--------}
destructor TAbVirtualMemoryStream.Destroy;
var
Inx : integer;
begin
{destroy the swap file}
vmsSwapFileDestroy;
{throw away all pages in the list}
if (vmsPageList <> nil) then begin
for Inx := 0 to pred(vmsPageList.Count) do
Dispose(PvmsPage(vmsPageList[Inx]));
vmsPageList.Destroy;
end;
{let our ancestor clean up}
inherited Destroy;
end;
{--------}
function TAbVirtualMemoryStream.Read(var Buffer; Count : Longint) : Longint;
var
BufPtr : PByte;
Page : PvmsPage;
PageDataInx : integer;
Posn : int64;
BytesToGo : int64;
BytesToRead : int64;
StartOfs : int64;
begin
{reading is complicated by the fact we can only read in chunks of
AB_VMSPageSize: we need to partition out the overall read into a read
from a partial page, zero or more reads from complete pages and
then a possible read from a partial page}
{initialise some variables, note that the complex calc in the
expression for PageDataInx is the offset of the start of the page
where Posn is found.}
BufPtr := @Buffer;
Posn := vmsPosition;
PageDataInx := Posn - (Posn and (not pred(AB_VMSPageSize)));
BytesToRead := AB_VMSPageSize - PageDataInx;
{calculate the actual number of bytes to read - this depends on the
current position and size of the stream}
BytesToGo := Count;
if (vmsSize < (vmsPosition + Count)) then
BytesToGo := vmsSize - vmsPosition;
if (BytesToGo < 0) then
BytesToGo := 0;
Result := BytesToGo;
{while we have bytes to read, read them}
while (BytesToGo <> 0) do begin
if (BytesToRead > BytesToGo) then
BytesToRead := BytesToGo;
StartOfs := Posn and (not pred(AB_VMSPageSize));
if (vmsCachePage^.vpStmOfs = StartOfs) then
Page := vmsCachePage
else
Page := vmsGetPageForOffset(StartOfs);
Move(Page^.vpData[PageDataInx], BufPtr^, BytesToRead);
dec(BytesToGo, BytesToRead);
inc(Posn, BytesToRead);
inc(BufPtr, BytesToRead);
PageDataInx := 0;
BytesToRead := AB_VMSPageSize;
end;
{remember our new position}
vmsPosition := Posn;
end;
{--------}
function TAbVirtualMemoryStream.Seek(const Offset : Int64;
Origin : TSeekOrigin) : Int64;
begin
case Origin of
soBeginning : vmsPosition := Offset;
soCurrent : inc(vmsPosition, Offset);
soEnd : vmsPosition := vmsSize + Offset;
else
raise EAbVMSInvalidOrigin.Create( Integer(Origin));
end;
Result := vmsPosition;
end;
{--------}
procedure TAbVirtualMemoryStream.SetSize(const NewSize : Int64);
var
Page : PvmsPage;
Inx : integer;
NewFileSize : Int64;
begin
if (NewSize < vmsSize) then begin
{go through the page list discarding pages whose offset is greater
than our new size; don't bother saving any data from them since
it be beyond the end of the stream anyway}
{never delete the last page here}
for Inx := pred(vmsPageList.Count) downto 1 do begin
Page := PvmsPage(vmsPageList[Inx]);
if (Page^.vpStmOfs >= NewSize) then begin
Dispose(Page);
vmsPageList.Delete(Inx);
end else begin
Break;
end;
end;
{ Reset cache to the first page in case the cached page was deleted. }
vmsCachePage := vmsPageList[0];
{force the swap file file size in range, it'll be a multiple of
AB_VMSPageSize}
NewFileSize := pred(NewSize + AB_VMSPageSize) and
(not pred(AB_VMSPageSize));
if (NewFileSize < vmsSwapFileSize) then
vmsSwapFileSize := NewFileSize;
{ignore the swap file itself}
end;
vmsSize := NewSize;
if (vmsPosition > NewSize) then
vmsPosition := NewSize;
end;
{--------}
function TAbVirtualMemoryStream.vmsAlterPageList(aNewMem : Longword) : Longword;
var
NumPages : Longint;
Page : PvmsPage;
i : integer;
OldestPageNum : Longint;
begin
{calculate the max number of pages required}
if aNewMem = 0 then
NumPages := 1 // always have at least one page
else
NumPages := pred(aNewMem + AB_VMSPageSize) div AB_VMSPageSize;
if (NumPages > AB_VMSMaxPages) then
NumPages := AB_VMSMaxPages;
{if the maximum number of pages means we have to shrink the current
list, do so, tossing out the oldest pages first}
if (NumPages < vmsPageList.Count) then
begin
for i := 1 to (vmsPageList.Count - NumPages) do begin
{find the oldest page}
vmsFindOldestPage(OldestPageNum, Page);
{if it is dirty, write it out to the swap file}
if Page^.vpDirty then begin
vmsSwapFileWrite(Page);
end;
{remove it from the page list}
vmsPageList.Delete(OldestPageNum);
{free the page memory}
Dispose(Page);
end;
{ Reset cache to the first page in case the cached page was deleted. }
vmsCachePage := vmsPageList[0];
end;
{remember our new max number of pages}
vmsMaxPages := NumPages;
Result := NumPages * AB_VMSPageSize;
end;
{--------}
procedure TAbVirtualMemoryStream.vmsFindOldestPage(out OldestInx : Longint;
out OldestPage: PvmsPage);
var
OldestLRU : Longint;
Inx : integer;
Page : PvmsPage;
begin
OldestInx := -1;
OldestLRU := LastLRUValue;
for Inx := 0 to pred(vmsPageList.Count) do begin
Page := PvmsPage(vmsPageList[Inx]);
if (Page^.vpLRU < OldestLRU) then begin
OldestInx := Inx;
OldestLRU := Page^.vpLRU;
OldestPage := Page;
end;
end;
end;
{--------}
function TAbVirtualMemoryStream.vmsGetNextLRU : Longint;
var
Inx : integer;
begin
if (vmsLRU = LastLRUValue) then begin
{reset all LRUs in list}
for Inx := 0 to pred(vmsPageList.Count) do
PvmsPage(vmsPageList[Inx])^.vpLRU := 0;
vmsLRU := 0;
end;
inc(vmsLRU);
Result := vmsLRU;
end;
{--------}
function TAbVirtualMemoryStream.vmsGetPageForOffset(aOffset : Int64) : PvmsPage;
var
Page : PvmsPage;
PageOfs : Int64;
L, M, R : integer;
OldestPageNum : integer;
CreatedNewPage: boolean;
begin
{using a sequential or a binary search (depending on the number of
pages), try to find the page in the cache; we'll do a sequential
search if the number of pages is very small, eg less than 4}
if (vmsPageList.Count < 4) then begin
L := vmsPageList.Count;
for M := 0 to pred(vmsPageList.Count) do begin
Page := PvmsPage(vmsPageList[M]);
PageOfs := Page^.vpStmOfs;
if (aOffset < PageOfs) then begin
L := M;
Break;
end;
if (aOffset = PageOfs) then begin
Page^.vpLRU := vmsGetNextLRU;
vmsCachePage := Page;
Result := Page;
Exit;
end;
end;
end
else {we need to do a binary search} begin
L := 0;
R := pred(vmsPageList.Count);
repeat
M := (L + R) div 2;
Page := PvmsPage(vmsPageList[M]);
PageOfs := Page^.vpStmOfs;
if (aOffset < PageOfs) then
R := pred(M)
else if (aOffset > PageOfs) then
L := succ(M)
else {aOffset = PageOfs} begin
Page^.vpLRU := vmsGetNextLRU;
vmsCachePage := Page;
Result := Page;
Exit;
end;
until (L > R);
end;
{if we get here the page for the offset is not present in the page
list, and once created/loaded, the page should be inserted at L}
{enter a try..except block so that if a new page is created and an
exception occurs, the page is freed}
CreatedNewPage := false;
Result := nil;
try
{if there is room to insert a new page, create one ready}
if (vmsPageList.Count < vmsMaxPages) then begin
New(Page);
CreatedNewPage := true;
end
{otherwise there is no room for the insertion, so find the oldest
page in the list and discard it}
else {vmsMaxPages <= vmsPageList.Count} begin
{find the oldest page}
vmsFindOldestPage(OldestPageNum, Page);
{if it is dirty, write it out to the swap file}
if Page^.vpDirty then begin
vmsSwapFileWrite(Page);
end;
{remove it from the page list}
vmsPageList.Delete(OldestPageNum);
{patch up the insertion point, in case the page just deleted was
before it}
if (OldestPageNum < L) then
dec(L);
end;
{set all the page fields}
with Page^ do begin
vpStmOfs := aOffset;
vpLRU := vmsGetNextLRU;
vpDirty := False;
vmsSwapFileRead(Page);
end;
{insert the page into the correct spot}
vmsPageList.Insert(L, pointer(Page));
{return the page, remembering to save it in the cache}
vmsCachePage := Page;
Result := Page;
except
if CreatedNewPage then
Dispose(Page);
end;{try..except}
end;
{--------}
procedure TAbVirtualMemoryStream.vmsSetMaxMemToUse(aNewMem : Longword);
begin
vmsMaxMemToUse := vmsAlterPageList(aNewMem);
end;
{--------}
procedure TAbVirtualMemoryStream.vmsSwapFileCreate;
begin
if (vmsSwapStream = nil) then begin
vmsSwapFileName := AbCreateTempFile(vmsSwapFileDir);
try
vmsSwapStream := TFileStream.Create(vmsSwapFileName, fmCreate);
except
DeleteFile(vmsSwapFileName);
raise EAbVMSErrorOpenSwap.Create( vmsSwapFileName );
end;
vmsSwapFileSize := 0;
end;
end;
{--------}
procedure TAbVirtualMemoryStream.vmsSwapFileDestroy;
begin
if (vmsSwapStream <> nil) then begin
FreeAndNil(vmsSwapStream);
DeleteFile(vmsSwapFileName);
end;
end;
{--------}
procedure TAbVirtualMemoryStream.vmsSwapFileRead(aPage : PvmsPage);
var
BytesRead : Longint;
SeekResult: Int64;
begin
if (vmsSwapStream = nil) or (aPage^.vpStmOfs >= vmsSwapFileSize) then begin
{there is nothing to be read from the disk (either the swap file
doesn't exist or it's too small) so zero out the page data}
FillChar(aPage^.vpData, AB_VMSPageSize, 0)
end
else {there is something to be read from the swap file} begin
SeekResult := vmsSwapStream.Seek(aPage^.vpStmOfs, soBeginning);
if (SeekResult = -1) then
raise EAbVMSSeekFail.Create( vmsSwapFileName );
BytesRead := vmsSwapStream.Read(aPage^.vpData, AB_VMSPageSize);
if (BytesRead <> AB_VMSPageSize) then
raise EAbVMSReadFail.Create( AB_VMSPageSize, vmsSwapFileName );
end;
end;
{--------}
procedure TAbVirtualMemoryStream.vmsSwapFileWrite(aPage : PvmsPage);
var
NewPos : Int64;
SeekResult: Int64;
BytesWritten : Longint;
begin
if (vmsSwapStream = nil) then
vmsSwapFileCreate;
SeekResult := vmsSwapStream.Seek(aPage^.vpStmOfs, soBeginning);
if (SeekResult = -1) then
raise EAbVMSSeekFail.Create( vmsSwapFileName );
BytesWritten := vmsSwapStream.Write(aPage^.vpData, AB_VMSPageSize);
if BytesWritten <> AB_VMSPageSize then
raise EAbVMSWriteFail.Create( AB_VMSPageSize, vmsSwapFileName );
NewPos := aPage^.vpStmOfs + AB_VMSPageSize;
if (NewPos > vmsSwapFileSize) then
vmsSwapFileSize := NewPos;
end;
{--------}
function TAbVirtualMemoryStream.Write(const Buffer; Count : Longint) : Longint;
var
BufPtr : PByte;
Page : PvmsPage;
PageDataInx : integer;
Posn : Int64;
BytesToGo : Int64;
BytesToWrite: Int64;
StartOfs : Int64;
begin
{writing is complicated by the fact we can only write in chunks of
AB_VMSPageSize: we need to partition out the overall write into a
write to a partial page, zero or more writes to complete pages and
then a possible write to a partial page}
{initialise some variables, note that the complex calc in the
expression for PageDataInx is the offset of the start of the page
where Posn is found.}
BufPtr := @Buffer;
Posn := vmsPosition;
PageDataInx := Posn - (Posn and (not pred(AB_VMSPageSize)));
BytesToWrite := AB_VMSPageSize - PageDataInx;
{calculate the actual number of bytes to write}
BytesToGo := Count;
Result := BytesToGo;
{while we have bytes to write, write them}
while (BytesToGo <> 0) do begin
if (BytesToWrite > BytesToGo) then
BytesToWrite := BytesToGo;
StartOfs := Posn and (not pred(AB_VMSPageSize));
if (vmsCachePage^.vpStmOfs = StartOfs) then
Page := vmsCachePage
else
Page := vmsGetPageForOffset(StartOfs);
Move(BufPtr^, Page^.vpData[PageDataInx], BytesToWrite);
Page^.vpDirty := True;
dec(BytesToGo, BytesToWrite);
inc(Posn, BytesToWrite);
inc(BufPtr, BytesToWrite);
PageDataInx := 0;
BytesToWrite := AB_VMSPageSize;
end;
{remember our new position}
vmsPosition := Posn;
{if we've grown the stream, make a note of it}
if (vmsPosition > vmsSize) then
vmsSize := vmsPosition;
end;
{====================================================================}
end.

1657
Abbrevia/source/AbView.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,439 @@
(* ***** 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 Craig Peterson
*
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbWavPack.pas *}
{*********************************************************}
{* ABBREVIA: WavPack decompression procedures *}
{*********************************************************}
unit AbWavPack;
{$I AbDefine.inc}
interface
uses
Classes;
// Decompress a WavPack compressed stream from aSrc and write to aDes.
// aSrc must not allow reads past the compressed data.
procedure DecompressWavPack(aSrc, aDes: TStream);
implementation
uses
AbCrtl,
Math,
SysUtils;
// Compile using
// bcc32 -DWIN32 -DNO_USE_FSTREAMS -c -w-8004 -w-8012 -w-8017 -w-8057 -w-8065 *.c
//
// In wavpack_local.h remove the line "#define FASTCALL __fastcall"
{ C runtime library ======================================================== }
function fabs(x: Double): Double; cdecl;
begin
if x < 0 then Result := -1
else Result := x
end;
function floor(x: Double): Integer; cdecl;
begin
Result := Floor(x);
end;
function labs(n: Integer): Integer; cdecl;
begin
if n < 0 then Result := -n
else Result := n;
end;
function _stricmp(str1, str2: PAnsiChar): Integer; cdecl;
external 'msvcrt.dll' name '_stricmp';
function strncmp(str1, str2: PAnsiChar; num: Integer): Integer; cdecl;
external 'msvcrt.dll' {$IFDEF BCB}name '_strncmp'{$ENDIF};
{ Forward declarations ===================================================== }
// bits.c
procedure bs_open_read; external;
procedure bs_close_read; external;
procedure bs_open_write; external;
procedure bs_close_write; external;
procedure little_endian_to_native; external;
procedure native_to_little_endian; external;
// extra1.c
procedure execute_mono; external;
// extra2.c
procedure execute_stereo; external;
// float.c
procedure float_values; external;
procedure read_float_info; external;
procedure scan_float_data; external;
procedure send_float_data; external;
procedure WavpackFloatNormalize; external;
procedure write_float_info; external;
// metadata.c
procedure add_to_metadata; external;
procedure copy_metadata; external;
procedure free_metadata; external;
procedure process_metadata; external;
procedure read_metadata_buff; external;
procedure write_metadata_block; external;
// pack.c
procedure pack_block; external;
procedure pack_init; external;
// tags.c
procedure load_tag; external;
procedure valid_tag; external;
// unpack.c
procedure check_crc_error; external;
procedure free_tag; external;
procedure unpack_init; external;
procedure unpack_samples; external;
// unpack3.c
procedure free_stream3; external;
procedure get_version3; external;
procedure get_sample_index3; external;
procedure open_file3; external;
procedure seek_sample3; external;
procedure unpack_samples3; external;
// words.c
procedure exp2s; external;
procedure flush_word; external;
procedure get_word; external;
procedure get_words_lossless; external;
procedure init_words; external;
procedure log2s; external;
procedure log2buffer; external;
procedure nosend_word; external;
procedure read_hybrid_profile; external;
procedure read_entropy_vars; external;
procedure restore_weight; external;
procedure scan_word; external;
procedure send_word; external;
procedure send_words_lossless; external;
procedure store_weight; external;
procedure write_entropy_vars; external;
procedure write_hybrid_profile; external;
{ Linker derectives ======================================================== }
{$IF DEFINED(WIN32)}
{$L Win32\wv_bits.obj}
{$L Win32\wv_extra1.obj}
{$L Win32\wv_extra2.obj}
{$L Win32\wv_float.obj}
{$L Win32\wv_metadata.obj}
{$L Win32\wv_pack.obj}
{$L Win32\wv_tags.obj}
{$L Win32\wv_unpack.obj}
{$L Win32\wv_unpack3.obj}
{$L Win32\wv_words.obj}
{$L Win32\wv_wputils.obj}
{$ELSEIF DEFINED(WIN64)}
{$L Win64\wv_bits.obj}
{$L Win64\wv_extra1.obj}
{$L Win64\wv_extra2.obj}
{$L Win64\wv_float.obj}
{$L Win64\wv_metadata.obj}
{$L Win64\wv_pack.obj}
{$L Win64\wv_tags.obj}
{$L Win64\wv_unpack.obj}
{$L Win64\wv_unpack3.obj}
{$L Win64\wv_words.obj}
{$L Win64\wv_wputils.obj}
{$IFEND}
{ wavpack_local.h ========================================================== }
const
OPEN_WVC = $1; // open/read "correction" file
OPEN_TAGS = $2; // read ID3v1 / APEv2 tags (seekable file)
OPEN_WRAPPER = $4; // make audio wrapper available (i.e. RIFF)
OPEN_2CH_MAX = $8; // open multichannel as stereo (no downmix)
OPEN_NORMALIZE = $10; // normalize floating point data to +/- 1.0
OPEN_STREAMING = $20; // "streaming" mode blindly unpacks blocks
// w/o regard to header file position info
OPEN_EDIT_TAGS = $40; // allow editing of tags
type
int32_t = LongInt;
uint32_t = LongWord;
WavpackStreamReader = record
read_bytes: function(id, data: Pointer; bcount: int32_t): int32_t; cdecl;
get_pos: function(id: Pointer): uint32_t; cdecl;
set_pos_abs: function(id: Pointer; pos: uint32_t): Integer; cdecl;
set_pos_rel: function(id: Pointer; delta: int32_t; mode: Integer): Integer; cdecl;
push_back_byte: function(id: Pointer; c: Integer): Integer; cdecl;
get_length: function(id: Pointer): uint32_t; cdecl;
can_seek: function(id: Pointer): Integer; cdecl;
write_bytes: function(id, data: Pointer; bcount: int32_t): int32_t; cdecl;
end;
WavpackContext = Pointer;
{ wputils.c ================================================================ }
function WavpackOpenFileInputEx(const reader: WavpackStreamReader;
wv_id, wvc_id: Pointer; error: PAnsiChar; flags, norm_offset: Integer): WavpackContext;
cdecl; external;
function WavpackGetWrapperBytes(wpc: WavpackContext): uint32_t; cdecl; external;
function WavpackGetWrapperData(wpc: WavpackContext): PByte; cdecl; external;
procedure WavpackFreeWrapper (wpc: WavpackContext); cdecl; external;
procedure WavpackSeekTrailingWrapper(wpc: WavpackContext); cdecl; external;
function WavpackGetNumSamples(wpc: WavpackContext): uint32_t; cdecl; external;
function WavpackGetNumChannels(wpc: WavpackContext): Integer; cdecl; external;
function WavpackGetBytesPerSample (wpc: WavpackContext): Integer; cdecl; external;
function WavpackUnpackSamples(wpc: WavpackContext; buffer: Pointer;
samples: uint32_t): uint32_t; cdecl; external;
function WavpackCloseFile(wpc: WavpackContext): WavpackContext; cdecl; external;
{ TWavPackStream implementation ============================================ }
type
PWavPackStream = ^TWavPackStream;
TWavPackStream = record
HasPushedByte: Boolean;
PushedByte: Byte;
Stream: TStream;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_read_bytes(id, data: Pointer; bcount: int32_t): int32_t; cdecl;
begin
if PWavPackStream(id).HasPushedByte then begin
PByte(data)^ := PWavPackStream(id).PushedByte;
PWavPackStream(id).HasPushedByte := False;
Inc(PByte(data));
Dec(bcount);
if bcount = 0 then
Result := 1
else
Result := PWavPackStream(id).Stream.Read(data^, bcount) + 1;
end
else
Result := PWavPackStream(id).Stream.Read(data^, bcount);
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_get_pos(id: Pointer): uint32_t; cdecl;
begin
Result := PWavPackStream(id).Stream.Position;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_set_pos_abs(id: Pointer; pos: uint32_t): Integer; cdecl;
begin
PWavPackStream(id).Stream.Position := pos;
Result := 0;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_set_pos_rel(id: Pointer; delta: int32_t;
mode: Integer): Integer; cdecl;
begin
PWavPackStream(id).Stream.Seek(delta, mode);
Result := 1;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_push_back_byte(id: Pointer; c: Integer): Integer; cdecl;
begin
Assert(not PWavPackStream(id).HasPushedByte);
PWavPackStream(id).HasPushedByte := True;
PWavPackStream(id).PushedByte := Byte(c);
Result := 1;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_get_length(id: Pointer): uint32_t; cdecl;
begin
Result := PWavPackStream(id).Stream.Size;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_can_seek(id: Pointer): Integer; cdecl;
begin
Result := 1;
end;
{ -------------------------------------------------------------------------- }
function TWavPackStream_write_bytes(id, data: Pointer;
bcount: int32_t): int32_t; cdecl;
begin
Result := PWavPackStream(id).Stream.Write(data^, bcount);
end;
{ Decompression routines =================================================== }
{ -------------------------------------------------------------------------- }
// Reformat samples from longs in processor's native endian mode to
// little-endian data with (possibly) less than 4 bytes / sample.
//
// Based on wvunpack.c::format_samples.
// Conversions simplified since we only support little-endian processors
function FormatSamples(bps: Integer; dst, src: PByte; samcnt: uint32_t): PByte;
var
sample: LongWord;
begin
while samcnt > 0 do begin
Dec(samcnt);
// Get next sample
sample := PLongWord(src)^;
// Convert and write to output
case bps of
1: begin
dst^ := sample + 128;
end;
2: begin
PWord(dst)^ := sample;
end;
3: begin
PByteArray(dst)[0] := sample;
PByteArray(dst)[1] := sample shr 8;
PByteArray(dst)[2] := sample shr 16;
end;
4: begin
PLongWord(dst)^ := sample;
end;
end;
Inc(src, SizeOf(LongWord));
Inc(dst, bps);
end;
Result := dst;
end;
{ -------------------------------------------------------------------------- }
// Decompress a WavPack compressed stream from aSrc and write to aDes.
// aSrc must not allow reads past the compressed data.
//
// Based on wvunpack.c::unpack_file()
procedure DecompressWavPack(aSrc, aDes: TStream);
type
PtrInt = {$IF DEFINED(CPUX64)}Int64{$ELSE}LongInt{$IFEND};
const
OutputBufSize = 256 * 1024;
var
StreamReader: WavpackStreamReader;
Context: WavpackContext;
Src: TWavpackStream;
Error: array[0..79] of AnsiChar;
SamplesToUnpack, SamplesUnpacked: uint32_t;
NumChannels, bps, BytesPerSample: Integer;
OutputBuf, OutputPtr: PByte;
DecodeBuf: Pointer;
begin
OutputBuf := nil;
DecodeBuf := nil;
StreamReader.read_bytes := TWavPackStream_read_bytes;
StreamReader.get_pos := TWavPackStream_get_pos;
StreamReader.set_pos_abs := TWavPackStream_set_pos_abs;
StreamReader.set_pos_rel := TWavPackStream_set_pos_rel;
StreamReader.push_back_byte := TWavPackStream_push_back_byte;
StreamReader.get_length := TWavPackStream_get_length;
StreamReader.can_seek := TWavPackStream_can_seek;
StreamReader.write_bytes := TWavPackStream_write_bytes;
FillChar(Src, SizeOf(Src), 0);
Src.Stream := aSrc;
Context := WavpackOpenFileInputEx(StreamReader, @Src, nil, Error, OPEN_WRAPPER, 0);
if Context = nil then
raise Exception.Create('WavPack decompression failed: ' + Error);
try
// Write .wav header
if WavpackGetWrapperBytes(Context) > 0 then begin
aDes.WriteBuffer(WavpackGetWrapperData(Context)^, WavpackGetWrapperBytes(Context));
WavpackFreeWrapper(Context);
end;
NumChannels := WavpackGetNumChannels(Context);
bps := WavpackGetBytesPerSample(Context);
BytesPerSample := NumChannels * bps;
GetMem(OutputBuf, OutputBufSize);
OutputPtr := OutputBuf;
GetMem(DecodeBuf, 4096 * NumChannels * SizeOf(Integer));
repeat
// Unpack samples
SamplesToUnpack := (OutputBufSize - (PtrInt(OutputPtr) - PtrInt(OutputBuf))) div BytesPerSample;
if (SamplesToUnpack > 4096) then
SamplesToUnpack := 4096;
SamplesUnpacked := WavpackUnpackSamples(Context, DecodeBuf, SamplesToUnpack);
// Convert from 32-bit integers down to appriopriate bit depth
// and copy to output buffer.
if (SamplesUnpacked > 0) then
OutputPtr := FormatSamples(bps, OutputPtr, DecodeBuf,
SamplesUnpacked * uint32_t(NumChannels));
// Write output when it's full or when we're done
if (SamplesUnpacked = 0) or
((OutputBufSize - (PtrInt(OutputPtr) - PtrInt(OutputBuf))) < BytesPerSample) then begin
aDes.WriteBuffer(OutputBuf^, PtrInt(OutputPtr) - PtrInt(OutputBuf));
OutputPtr := OutputBuf;
end;
until (SamplesUnpacked = 0);
// Write .wav footer
while WavpackGetWrapperBytes(Context) > 0 do begin
try
aDes.WriteBuffer(WavpackGetWrapperData(Context)^,
WavpackGetWrapperBytes(Context));
finally
WavpackFreeWrapper(Context);
end;
// Check for more RIFF data
WavpackUnpackSamples (Context, DecodeBuf, 1);
end;
finally
if DecodeBuf <> nil then
FreeMemory(DecodeBuf);
if OutputBuf <> nil then
FreeMemory(OutputBuf);
WavpackCloseFile(Context);
end;
end;
end.

View File

@@ -0,0 +1,366 @@
(* ***** 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):
* Craig Peterson <capeterson@users.sourceforge.net>
*
* ***** END LICENSE BLOCK ***** *)
{*********************************************************}
{* ABBREVIA: AbZBrows.pas *}
{*********************************************************}
{* ABBREVIA: Zip file Browser Component *}
{*********************************************************}
unit AbZBrows;
{$I AbDefine.inc}
interface
uses
Classes,
AbArcTyp, AbBrowse, AbSpanSt, AbZipTyp;
type
TAbCustomZipBrowser = class(TAbBaseBrowser)
private
function GetTarAutoHandle: Boolean;
procedure SetTarAutoHandle(const Value: Boolean);
protected {private}
FPassword : AnsiString;
FOnRequestLastDisk : TAbRequestDiskEvent;
FOnRequestNthDisk : TAbRequestNthDiskEvent;
FOnRequestBlankDisk : TAbRequestDiskEvent;
FTarAutoHandle : Boolean;
protected {methods}
function GetItem(Index : Integer) : TAbZipItem; virtual;
function GetStream: TStream;
function GetZipfileComment : AnsiString;
procedure InitArchive;
override;
procedure SetFileName(const aFileName : string);
override;
procedure SetStream(aValue: TStream);
procedure SetOnRequestLastDisk(Value : TAbRequestDiskEvent);
procedure SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);
procedure SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);
procedure SetPassword(const Value : AnsiString);
procedure SetZipfileComment(const Value : AnsiString);
virtual;
protected {properties}
property Password : AnsiString
read FPassword
write SetPassword;
protected {events}
property OnRequestLastDisk : TAbRequestDiskEvent
read FOnRequestLastDisk
write SetOnRequestLastDisk;
property OnRequestNthDisk : TAbRequestNthDiskEvent
read FOnRequestNthDisk
write SetOnRequestNthDisk;
property OnRequestBlankDisk : TAbRequestDiskEvent
read FOnRequestBlankDisk
write SetOnRequestBlankDisk;
public {methods}
constructor Create(AOwner : TComponent); override;
destructor Destroy; override;
public {properties}
property Items[Index : Integer] : TAbZipItem
read GetItem; default;
property Stream : TStream // This can be used instead of Filename
read GetStream write SetStream;
property ZipArchive : {TAbZipArchive} TAbArchive
read FArchive;
property ZipfileComment : AnsiString
read GetZipfileComment
write SetZipfileComment;
property TarAutoHandle : Boolean
read GetTarAutoHandle
write SetTarAutoHandle;
end;
TAbZipBrowser = class(TAbCustomZipBrowser)
published
property ArchiveProgressMeter;
property ItemProgressMeter;
property BaseDirectory;
property LogFile;
property Logging;
property OnArchiveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmProcessItem;
property OnLoad;
property OnProcessItemFailure;
property OnRequestLastDisk;
property OnRequestNthDisk;
property Version;
property TarAutoHandle;
property FileName; {must be after OnLoad}
end;
implementation
uses
SysUtils, AbBzip2Typ, AbExcept, AbGzTyp, AbTarTyp, AbUtils;
{ TAbCustomZipBrowser implementation ======================================= }
{ -------------------------------------------------------------------------- }
constructor TAbCustomZipBrowser.Create(AOwner : TComponent);
begin
inherited Create(AOwner);
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomZipBrowser.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomZipBrowser.GetItem(Index : Integer) : TAbZipItem;
begin
Result := TAbZipItem(ZipArchive.ItemList[Index]);
end;
{ -------------------------------------------------------------------------- }
function TAbCustomZipBrowser.GetStream: TStream;
begin
if FArchive <> nil then
Result := FArchive.FStream
else
Result := nil
end;
{ -------------------------------------------------------------------------- }
function TAbCustomZipBrowser.GetTarAutoHandle: Boolean;
begin
Result := False;
if FArchive is TAbGzipArchive then
Result := TAbGzipArchive(FArchive).TarAutoHandle
else if FArchive is TAbBzip2Archive then
Result := TAbBzip2Archive(FArchive).TarAutoHandle;
end;
{ -------------------------------------------------------------------------- }
function TAbCustomZipBrowser.GetZipfileComment : AnsiString;
begin
if FArchive is TAbZipArchive then
Result := TAbZipArchive(FArchive).ZipfileComment
else
Result := '';
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.InitArchive;
begin
inherited InitArchive;
if FArchive is TAbZipArchive then begin
{properties}
TAbZipArchive(FArchive).Password := FPassword;
{events}
TAbZipArchive(FArchive).OnRequestLastDisk := FOnRequestLastDisk;
TAbZipArchive(FArchive).OnRequestNthDisk := FOnRequestNthDisk;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetFileName(const aFileName : string);
var
ArcType : TAbArchiveType;
begin
FFileName := aFileName;
if csDesigning in ComponentState then
Exit;
try
if Assigned(FArchive) then begin
FArchive.Save;
end;
except
end;
FArchive.Free;
FArchive := nil;
if FileName <> '' then begin
if FileExists(FileName) then begin { open it }
ArcType := ArchiveType;
if not ForceType then
ArcType := AbDetermineArcType(FileName, atUnknown);
case ArcType of
atZip, atSpannedZip, atSelfExtZip : begin
FArchive := TAbZipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
InitArchive;
end;
atTar : begin
FArchive := TAbTarArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
inherited InitArchive;
end;
atGZip : begin
FArchive := TAbGzipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := False;
inherited InitArchive;
end;
atGZippedTar : begin
FArchive := TAbGzipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := True;
inherited InitArchive;
end;
atBzip2 : begin
FArchive := TAbBzip2Archive.Create(FileName, fmOpenRead or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := False;
inherited InitArchive;
end;
atBzippedTar : begin
FArchive := TAbBzip2Archive.Create(FileName, fmOpenRead or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := True;
inherited InitArchive;
end;
else
raise EAbUnhandledType.Create;
end {case};
FArchive.Load;
FArchiveType := ArcType;
end;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetStream(aValue: TStream);
var
ArcType : TAbArchiveType;
begin
FFileName := '';
try
if FArchive <> nil then
FArchive.Save;
except
end;
FreeAndNil(FArchive);
if aValue <> nil then begin
ArcType := ArchiveType;
if not ForceType then
ArcType := AbDetermineArcType(aValue);
case ArcType of
atZip, atSpannedZip, atSelfExtZip : begin
FArchive := TAbZipArchive.CreateFromStream(aValue, '');
end;
atTar : begin
FArchive := TAbTarArchive.CreateFromStream(aValue, '');
end;
atGZip, atGZippedTar : begin
FArchive := TAbGzipArchive.CreateFromStream(aValue, '');
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := (ArcType = atGZippedTar);
end;
atBzip2, atBzippedTar : begin
FArchive := TAbBzip2Archive.CreateFromStream(aValue, '');
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := (ArcType = atBzippedTar);
end;
else
raise EAbUnhandledType.Create;
end {case};
InitArchive;
FArchive.Load;
FArchiveType := ArcType;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetOnRequestBlankDisk(Value : TAbRequestDiskEvent);
begin
FOnRequestBlankDisk := Value;
if FArchive is TAbZipArchive then
TAbZipArchive(FArchive).OnRequestBlankDisk := FOnRequestBlankDisk;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetOnRequestLastDisk(Value : TAbRequestDiskEvent);
begin
FOnRequestLastDisk := Value;
if FArchive is TAbZipArchive then
TAbZipArchive(FArchive).OnRequestLastDisk := FOnRequestLastDisk;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetOnRequestNthDisk(Value : TAbRequestNthDiskEvent);
begin
FOnRequestNthDisk := Value;
if FArchive is TAbZipArchive then
TAbZipArchive(FArchive).OnRequestNthDisk := FOnRequestNthDisk;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetPassword(const Value : AnsiString);
begin
FPassword := Value;
if FArchive is TAbZipArchive then
TAbZipArchive(FArchive).Password := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipBrowser.SetTarAutoHandle(const Value: Boolean);
begin
FTarAutoHandle := Value;
if FArchive is TAbGzipArchive then begin
if TAbGzipArchive(FArchive).TarAutoHandle <> Value then begin
TAbGzipArchive(FArchive).TarAutoHandle := Value;
InitArchive;
FArchive.Load;
DoChange;
end;
end;
if FArchive is TAbBzip2Archive then begin
if TAbBzip2Archive(FArchive).TarAutoHandle <> Value then begin
TAbBzip2Archive(FArchive).TarAutoHandle := Value;
InitArchive;
FArchive.Load;
DoChange;
end;
end;
end;
procedure TAbCustomZipBrowser.SetZipfileComment(const Value : AnsiString);
begin
{NOP - descendents wishing to set this property should override}
end;
{ -------------------------------------------------------------------------- }
end.

315
Abbrevia/source/AbZLTyp.pas Normal file
View File

@@ -0,0 +1,315 @@
(* ***** 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: AbZLTyp.pas *}
{*********************************************************}
{* ABBREVIA: TAbZlItem class *}
{*********************************************************}
{* Misc. constants, types, and routines for working *}
{* with ZLib compressed data *}
{* See: RFC 1950 *}
{* "ZLIB Compressed Data Format Specification *}
{* version 3.3" for more information on ZLib *}
{*********************************************************}
unit AbZLTyp;
{$I AbDefine.inc}
interface
uses
SysUtils, Classes, AbUtils, AbArcTyp, AbZipPrc, AbDfBase, AbDfDec, AbDfEnc;
const
AB_ZL_PRESET_DICT = $20;
AB_ZL_DEF_COMPRESSIONMETHOD = $8; { Deflate }
AB_ZL_DEF_COMPRESSIONINFO = $7; { 32k window for Deflate }
AB_ZL_FASTEST_COMPRESSION = $0;
AB_ZL_FAST_COMPRESSION = $1;
AB_ZL_DEFAULT_COMPRESSION = $2;
AB_ZL_MAXIMUM_COMPRESSION = $3;
AB_ZL_FCHECK_MASK = $1F;
AB_ZL_CINFO_MASK = $F0; { mask out leftmost 4 bits }
AB_ZL_FLEVEL_MASK = $C0; { mask out leftmost 2 bits }
AB_ZL_CM_MASK = $0F; { mask out rightmost 4 bits }
type
TAbZLHeader = packed record
CMF : Byte;
FLG : Byte;
end;
TAbZLItem = class(TAbArchiveItem)
private
function GetCompressionInfo: Byte;
function GetCompressionLevel: Byte;
function GetIsPresetDictionaryPresent: Boolean;
procedure SetCompressionInfo(Value: Byte);
procedure SetCompressionLevel(Value: Byte);
function GetCompressionMethod: Byte;
procedure SetCompressionMethod(Value: Byte);
function GetFCheck: Byte;
procedure MakeFCheck;
protected { private }
FZLHeader : TAbZlHeader;
FAdler32 : LongInt;
public
constructor Create;
property IsPresetDictionaryPresent : Boolean
read GetIsPresetDictionaryPresent;
property CompressionLevel : Byte
read GetCompressionLevel write SetCompressionLevel;
property CompressionInfo : Byte
read GetCompressionInfo write SetCompressionInfo;
property CompressionMethod : Byte
read GetCompressionMethod write SetCompressionMethod;
property Adler32 : LongInt
read FAdler32 write FAdler32;
property FCheck : Byte
read GetFCheck;
procedure SaveZLHeaderToStream(AStream : TStream);
procedure ReadZLHeaderFromStream(AStream : TStream);
end;
TAbZLStreamHelper = class(TAbArchiveStreamHelper)
protected { private }
FItem : TAbZLItem;
public
constructor Create(AStream : TStream);
destructor Destroy; override;
property Item : TAbZLItem
read FItem;
procedure ExtractItemData(AStream : TStream); override;
function FindFirstItem : Boolean; override;
function FindNextItem : Boolean; override;
procedure ReadHeader; override;
procedure ReadTail; override;
function SeekItem(Index : Integer): Boolean; override;
procedure WriteArchiveHeader; override;
procedure WriteArchiveItem(AStream : TStream); override;
procedure WriteArchiveTail; override;
function GetItemCount : Integer; override;
end;
implementation
{ TAbZLStreamHelper }
constructor TAbZLStreamHelper.Create(AStream: TStream);
begin
inherited Create(AStream);
FItem := TAbZLItem.Create;
end;
destructor TAbZLStreamHelper.Destroy;
begin
FItem.Free;
inherited Destroy;
end;
procedure TAbZLStreamHelper.ExtractItemData(AStream: TStream);
{ assumes already positioned appropriately }
var
Hlpr : TAbDeflateHelper;
begin
Hlpr := TAbDeflateHelper.Create;
Hlpr.Options := Hlpr.Options or dfc_UseAdler32;
if not FItem.IsPresetDictionaryPresent then
Inflate(FStream, AStream, Hlpr)
else
raise Exception.Create('preset dictionaries unsupported');
Hlpr.Free;
end;
function TAbZLStreamHelper.FindFirstItem: Boolean;
var
ZLH : TAbZLHeader;
begin
FStream.Seek(0, soBeginning);
Result := FStream.Read(ZLH, SizeOf(TAbZLHeader)) = SizeOf(TAbZLHeader);
FItem.FZLHeader := ZLH;
FStream.Seek(0, soBeginning);
end;
function TAbZLStreamHelper.FindNextItem: Boolean;
begin
{ only one item in a ZLib Stream }
Result := FindFirstItem;
end;
function TAbZLStreamHelper.GetItemCount: Integer;
begin
{ only one item in a ZLib Stream }
Result := 1;
end;
procedure TAbZLStreamHelper.ReadHeader;
{ assumes already positioned appropriately }
var
ZLH : TAbZLHeader;
begin
FStream.Read(ZLH, SizeOf(TAbZlHeader));
FItem.FZLHeader := ZLH;
end;
procedure TAbZLStreamHelper.ReadTail;
{ assumes already positioned appropriately }
var
Adler: LongInt;
begin
FStream.Read(Adler, SizeOf(LongInt));
FItem.Adler32 := Adler;
end;
function TAbZLStreamHelper.SeekItem(Index: Integer): Boolean;
begin
{ only one item in a ZLib Stream }
if Index <> 1 then
Result := False
else
Result := FindFirstItem;
end;
procedure TAbZLStreamHelper.WriteArchiveHeader;
begin
Item.SaveZLHeaderToStream(FStream);
end;
procedure TAbZLStreamHelper.WriteArchiveItem(AStream: TStream);
var
Hlpr : TAbDeflateHelper;
begin
{ Compress file }
Hlpr := TAbDeflateHelper.Create;
Hlpr.Options := Hlpr.Options or dfc_UseAdler32;
Item.Adler32 := AbDfEnc.Deflate(AStream, FStream, Hlpr);
Hlpr.Free;
end;
procedure TAbZLStreamHelper.WriteArchiveTail;
var
Ad32 : LongInt;
begin
Ad32 := AbSwapLongEndianness(Item.Adler32);
FStream.Write(Ad32, SizeOf(LongInt));
end;
{ TAbZLItem }
constructor TAbZLItem.Create;
begin
{ Set default Values for fields }
FillChar(FZLHeader, SizeOf(TAbZlHeader), #0);
FZLHeader.CMF := (AB_ZL_DEF_COMPRESSIONINFO shl 4); { 32k Window size }
FZLHeader.CMF := FZLHeader.CMF or AB_ZL_DEF_COMPRESSIONMETHOD; { Deflate }
FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_PRESET_DICT; { no preset dictionary}
FZLHeader.FLG := FZLHeader.FLG or (AB_ZL_DEFAULT_COMPRESSION shl 6); { assume default compression }
MakeFCheck;
end;
function TAbZLItem.GetCompressionInfo: Byte;
begin
Result := FZLHeader.CMF shr 4;
end;
function TAbZLItem.GetCompressionLevel: Byte;
begin
Result := FZLHeader.FLG shr 6;
end;
function TAbZLItem.GetCompressionMethod: Byte;
begin
Result := FZLHeader.CMF and AB_ZL_CM_MASK;
end;
function TAbZLItem.GetFCheck: Byte;
begin
Result := FZLHeader.FLG and AB_ZL_FCHECK_MASK;
end;
function TAbZLItem.GetIsPresetDictionaryPresent: Boolean;
begin
Result := (FZLHeader.FLG and AB_ZL_PRESET_DICT) = AB_ZL_PRESET_DICT;
end;
procedure TAbZLItem.MakeFCheck;
{ create the FCheck value for the current Header }
var
zlh : Word;
begin
FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_FCHECK_MASK;
zlh := (FZLHeader.CMF * 256) + FZLHeader.FLG;
Inc(FZLHeader.FLG, 31 - (zlh mod 31));
end;
procedure TAbZLItem.ReadZLHeaderFromStream(AStream: TStream);
begin
AStream.Read(FZLHeader, SizeOf(TAbZLHeader));
end;
procedure TAbZLItem.SaveZLHeaderToStream(AStream: TStream);
begin
MakeFCheck;
AStream.Write(FZLHeader, SizeOf(TAbZlHeader));
end;
procedure TAbZLItem.SetCompressionInfo(Value: Byte);
begin
FZLHeader.CMF := FZLHeader.CMF and not AB_ZL_CINFO_MASK;
FZLHeader.CMF := FZLHeader.CMF or (Value shl 4); { shift value and add to bit field }
end;
procedure TAbZLItem.SetCompressionLevel(Value: Byte);
var
Temp : Byte;
begin
Temp := Value;
if not Temp in [AB_ZL_FASTEST_COMPRESSION..AB_ZL_MAXIMUM_COMPRESSION] then
Temp := AB_ZL_DEFAULT_COMPRESSION;
FZLHeader.FLG := FZLHeader.FLG and not AB_ZL_FLEVEL_MASK;
FZLHeader.FLG := FZLHeader.FLG or (Temp shl 6); { shift value and add to bit field }
end;
procedure TAbZLItem.SetCompressionMethod(Value: Byte);
begin
if Value > AB_ZL_CM_MASK then Value := (Value shl 4) shr 4;
FZLHeader.CMF := FZLHeader.CMF and not AB_ZL_CM_MASK;
FZLHeader.CMF := FZLHeader.CMF or Value;
end;
end.

229
Abbrevia/source/AbZView.pas Normal file
View File

@@ -0,0 +1,229 @@
(* ***** 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: AbZView.pas *}
{*********************************************************}
{* ABBREVIA: Zip archive viewer component *}
{* Use AbQZView.pas for CLX *}
{*********************************************************}
{$IFNDEF UsingCLX}
unit AbZView;
{$ENDIF}
{$I AbDefine.inc}
interface
uses
Classes,
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF UsingCLX }
QControls,
AbQView,
{$ELSE}
Controls,
AbView,
{$ENDIF}
AbZBrows,
AbZipTyp;
type
TAbIncludeItemEvent = procedure (Sender: TObject;
Item: TAbZipItem;
var Include: Boolean) of object;
TAbZipView = class(TAbBaseViewer)
protected
FZipComponent : TAbCustomZipBrowser;
FOnIncludeItem: TAbIncludeItemEvent;
function GetItem(RowNum : Longint) : TAbZipItem;
procedure SetZipComponent(Value : TAbCustomZipBrowser);
procedure Notification(AComponent : TComponent; Operation : TOperation);
override;
procedure DoChange(Sender : TObject);
override;
public
property Items[RowNum : Longint] : TAbZipItem
read GetItem;
published {properties}
property Align;
property Anchors;
property Attributes;
{$IFNDEF UsingCLX}
property BevelEdges;
property BevelInner;
property BevelKind;
property BevelOuter;
property BevelWidth;
{$ENDIF}
property BorderStyle;
property Color;
property Colors;
{$IFNDEF UsingCLX}
property Ctl3D;
property ParentCtl3D;
property DragCursor;
{$ENDIF}
property Cursor;
property Headings;
property DefaultColWidth;
property DefaultRowHeight;
property DisplayOptions;
property HeaderRowHeight;
property SortAttributes;
property DragMode;
{$IFDEF HasGridDrawingStyle}
property DrawingStyle;
{$ENDIF}
property Enabled;
property Font;
{$IFDEF HasGridDrawingStyle}
property GradientEndColor;
property GradientStartColor;
{$ENDIF}
property ParentColor;
property ParentFont;
property ParentShowHint;
property PopupMenu;
property ShowHint;
property TabOrder;
property TabStop;
{$IFDEF HasTouch}
property Touch;
{$ENDIF}
property Version;
property ZipComponent : TAbCustomZipBrowser
read FZipComponent write SetZipComponent;
published {Events}
property OnChange;
property OnClick;
property OnDblClick;
property OnEnter;
property OnExit;
{$IFDEF HasTouch}
property OnGesture;
{$ENDIF}
property OnKeyDown;
property OnKeyPress;
property OnKeyUp;
{$IFDEF HasOnMouseActivate}
property OnMouseActivate;
{$ENDIF}
property OnMouseDown;
{$IFDEF HasOnMouseEnter}
property OnMouseEnter;
property OnMouseLeave;
{$ENDIF}
property OnMouseMove;
property OnMouseUp;
property OnSorted;
property OnDrawSortArrow;
property OnIncludeItem: TAbIncludeItemEvent
read FOnIncludeItem
write FOnIncludeItem;
end;
implementation
uses
AbArcTyp;
{ ===== TAbZipView ========================================================= }
function TAbZipView.GetItem(RowNum : Longint) : TAbZipItem;
begin
if Assigned(FItemList) then
Result := TAbZipItem(FItemList.Items[FRowMap[RowNum]])
else
Result := nil;
end;
{ -------------------------------------------------------------------------- }
procedure TAbZipView.Notification(AComponent : TComponent; Operation : TOperation);
begin
inherited Notification(AComponent, Operation);
if Operation = opRemove then
if Assigned(FZipComponent) and (AComponent = FZipComponent) then begin
FZipComponent := nil;
Refresh;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbZipView.SetZipComponent(Value : TAbCustomZipBrowser);
begin
if Value <> nil then begin
FZipComponent := Value;
if not (csDesigning in ComponentState) then begin
FZipComponent.OnChange := DoChange;
FZipComponent.OnLoad := DoLoad;
DoChange(Self);
end;
end
else
FZipComponent := nil;
end;
{ -------------------------------------------------------------------------- }
procedure TAbZipView.DoChange(Sender : TObject);
var
i : Integer;
TheArchive : TAbArchive;
Include : Boolean;
begin
FItemList.Clear;
if Assigned(FZipComponent) then begin
{ let's make this a bit easier to read }
TheArchive := FZipComponent.FArchive;
if Assigned(TheArchive) then begin
for i := 0 to Pred(TheArchive.ItemList.Count) do begin
if Assigned(FOnIncludeItem) then begin
FOnIncludeItem(self, TAbZipItem(TheArchive.ItemList[i]), Include);
if Include then
FItemList.Add(TheArchive.ItemList[i]);
end
else begin
{ if it doesn't look like a folder place holder... }
if TAbZipItem(TheArchive.ItemList[i]).DiskFileName <>
TAbZipItem(TheArchive.ItemList[i]).DiskPath then
{ ...add it to the display list }
FItemList.Add(TheArchive.ItemList[i]);
end;
end;
end
else
FItemList.Clear;
end
else
FItemList.Clear;
inherited DoChange(Sender);
end;
end.

View File

@@ -0,0 +1,144 @@
(* ***** 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: AbZipExt.pas *}
{*********************************************************}
{* ABBREVIA: Zip file registration *}
{*********************************************************}
unit AbZipExt;
{$I AbDefine.inc}
interface
uses
SysUtils, Classes;
function AbExistingZipAssociation : Boolean;
function AbGetZipAssociation(var App, ID, FileType : string) : Boolean;
function AbRegisterZipExtension(const App : string;
ID, FileType : string;
Replace : Boolean) : Boolean;
implementation
uses
{$IFDEF MSWINDOWS}
Windows,
Messages,
Registry,
ShellAPI,
{$ENDIF}
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
AbConst;
const
ZipExt = '.zip';
DefZipID = 'Zip';
DefZipType = 'Zip File';
OpenCommand = 'Shell\Open\Command';
DefaultIcon = 'DefaultIcon';
var
Reg : TRegistry;
{ -------------------------------------------------------------------------- }
function AbExistingZipAssociation : Boolean;
var
App, ID, FileType : string;
begin
Result := False;
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.OpenKey('',False);
if Reg.OpenKey(ZipExt, False) then begin
ID := Reg.ReadString('');
if Reg.OpenKey('\' + ID, False) then begin
FileType := Reg.ReadString('');
if Reg.OpenKey(OpenCommand, False) then begin
App := Reg.ReadString('');
if (App <> '') then
Result := True;
end;
end;
end;
Reg.Free;
end;
{ -------------------------------------------------------------------------- }
function AbGetZipAssociation(var App, ID, FileType : string) : Boolean;
begin
Result := False;
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.OpenKey('',False);
if Reg.OpenKey(ZipExt, False) then begin
ID := Reg.ReadString('');
if Reg.OpenKey('\' + ID, False) then begin
FileType := Reg.ReadString('');
if Reg.OpenKey(OpenCommand, False) then begin
App := Reg.ReadString('');
Result := True;
end;
end;
end;
Reg.Free;
end;
{ -------------------------------------------------------------------------- }
function AbRegisterZipExtension(const App : string;
ID, FileType : string;
Replace : Boolean) : Boolean;
begin
Result := False;
if AbExistingZipAssociation and not Replace then
Exit;
try
if (ID = '') then
ID := DefZipID;
if (FileType = '') then
FileType := DefZipType;
Reg := TRegistry.Create;
Reg.RootKey := HKEY_CLASSES_ROOT;
Reg.OpenKey('',False);
Reg.OpenKey(ZipExt, True);
Reg.WriteString('', ID);
Reg.OpenKey('\' + ID, True);
Reg.WriteString('', FileType);
Reg.OpenKey(OpenCommand, True);
Reg.WriteString('', App);
Reg.OpenKey('\' + DefaultIcon, True);
Reg.WriteString('', App + ',0');
Result := True;
finally
Reg.Free;
end;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,284 @@
(* ***** 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: AbZipKit.pas *}
{*********************************************************}
{* ABBREVIA: TABZipKit component *}
{*********************************************************}
unit AbZipKit;
{$I AbDefine.inc}
interface
uses
Classes, AbZipper, AbArcTyp, AbZipTyp;
type
TAbCustomZipKit = class(TAbCustomZipper)
protected {private}
FExtractOptions : TAbExtractOptions;
FOnConfirmOverwrite : TAbConfirmOverwriteEvent;
FOnNeedPassword : TAbNeedPasswordEvent;
FPasswordRetries : Byte;
protected {methods}
procedure DoConfirmOverwrite(var Name : string; var Confirm : Boolean);
virtual;
procedure DoNeedPassword(Sender : TObject; var NewPassword : AnsiString);
virtual;
procedure InitArchive;
override;
procedure SetExtractOptions(Value : TAbExtractOptions);
procedure SetPasswordRetries(Value : Byte);
procedure UnzipProc(Sender : TObject; Item : TAbArchiveItem;
const NewName : string );
procedure UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;
OutStream : TStream);
procedure TestItemProc(Sender : TObject; Item : TAbArchiveItem);
protected {properties}
property ExtractOptions : TAbExtractOptions
read FExtractOptions
write SetExtractOptions
default AbDefExtractOptions;
property PasswordRetries : Byte
read FPasswordRetries
write SetPasswordRetries
default AbDefPasswordRetries;
protected {events}
property OnConfirmOverwrite : TAbConfirmOverwriteEvent
read FOnConfirmOverwrite
write FOnConfirmOverwrite;
property OnNeedPassword : TAbNeedPasswordEvent
read FOnNeedPassword
write FOnNeedPassword;
public {methods}
constructor Create(AOwner : TComponent);
override;
destructor Destroy;
override;
procedure ExtractAt(Index : Integer; const NewName : string);
procedure ExtractFiles(const FileMask : string);
{extract all files from the archive that match the mask}
procedure ExtractFilesEx(const FileMask, ExclusionMask : string);
{extract files matching FileMask except those matching ExclusionMask}
procedure ExtractTaggedItems;
{extract all tagged items from the archive}
procedure ExtractToStream(const aFileName : string; ToStream : TStream);
{extract the specified item to TStream descendant}
procedure TestTaggedItems;
{test all tagged items in the archive}
public {property}
property Spanned;
end;
TAbZipKit = class(TAbCustomZipKit)
published
property ArchiveProgressMeter;
property ArchiveSaveProgressMeter;
property AutoSave;
property BaseDirectory;
property CompressionMethodToUse;
property DeflationOption;
{$IFDEF MSWINDOWS}
property DOSMode;
{$ENDIF}
property ExtractOptions;
property SpanningThreshold;
property ItemProgressMeter;
property LogFile;
property Logging;
property OnArchiveProgress;
property OnArchiveSaveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmOverwrite;
property OnConfirmProcessItem;
property OnConfirmSave;
property OnLoad;
property OnNeedPassword;
property OnProcessItemFailure;
property OnRequestBlankDisk;
property OnRequestImage;
property OnRequestLastDisk;
property OnRequestNthDisk;
property OnSave;
property Password;
property PasswordRetries;
property StoreOptions;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
implementation
uses
AbExcept,
AbUnzPrc,
AbZBrows;
{ -------------------------------------------------------------------------- }
constructor TAbCustomZipKit.Create( AOwner : TComponent );
begin
inherited Create( AOwner );
PasswordRetries := AbDefPasswordRetries;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomZipKit.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.DoConfirmOverwrite( var Name : string;
var Confirm : Boolean );
begin
Confirm := True;
if Assigned( FOnConfirmOverwrite ) then
FOnConfirmOverwrite( Name, Confirm );
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.DoNeedPassword( Sender : TObject;
var NewPassword : AnsiString );
begin
if Assigned( FOnNeedPassword ) then begin
FOnNeedPassword( Self, NewPassword );
FPassword := NewPassword;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.ExtractAt(Index : Integer; const NewName : string);
{extract a file from the archive that match the index}
begin
if (FArchive <> nil) then
FArchive.ExtractAt( Index, NewName )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.ExtractFiles(const FileMask : string);
{extract all files from the archive that match the mask}
begin
if (FArchive <> nil) then
FArchive.ExtractFiles( FileMask )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.ExtractFilesEx(const FileMask, ExclusionMask : string);
{extract files matching FileMask except those matching ExclusionMask}
begin
if (FArchive <> nil) then
FArchive.ExtractFilesEx( FileMask, ExclusionMask )
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.ExtractTaggedItems;
{extract all tagged items from the archive}
begin
if (FArchive <> nil) then
FArchive.ExtractTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.ExtractToStream(const aFileName : string;
ToStream : TStream);
begin
if (FArchive <> nil) then
FArchive.ExtractToStream(aFileName, ToStream)
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.InitArchive;
begin
inherited InitArchive;
if (FArchive <> nil) then begin
FArchive.ExtractOptions := FExtractOptions;
FArchive.OnConfirmOverwrite := DoConfirmOverwrite;
end;
if FArchive is TAbZipArchive then begin
{properties}
TAbZipArchive(FArchive).PasswordRetries := FPasswordRetries;
{events}
TAbZipArchive(FArchive).OnNeedPassword := DoNeedPassword;
TAbZipArchive(FArchive).ExtractHelper := UnzipProc;
TAbZipArchive(FArchive).ExtractToStreamHelper := UnzipToStreamProc;
TAbZipArchive(FArchive).TestHelper := TestItemProc;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.SetExtractOptions( Value : TAbExtractOptions );
begin
FExtractOptions := Value;
if (FArchive <> nil) then
FArchive.ExtractOptions := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.SetPasswordRetries( Value : Byte );
begin
FPasswordRetries := Value;
if (FArchive <> nil) then
(FArchive as TAbZipArchive).PasswordRetries := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.TestTaggedItems;
{test all tagged items in the archive}
begin
if (FArchive <> nil) then
FArchive.TestTaggedItems
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.UnzipProc( Sender : TObject; Item : TAbArchiveItem;
const NewName : string );
begin
AbUnzip( TAbZipArchive(Sender), TAbZipItem(Item), NewName);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.UnzipToStreamProc(Sender : TObject; Item : TAbArchiveItem;
OutStream : TStream);
begin
AbUnzipToStream(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipKit.TestItemProc(Sender : TObject; Item : TAbArchiveItem);
begin
AbTestZipItem(TAbZipArchive(Sender), TAbZipItem(Item));
end;
{ -------------------------------------------------------------------------- }
end.

2375
Abbrevia/source/AbZipOut.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,339 @@
(* ***** 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: AbZipPrc.pas *}
{*********************************************************}
{* ABBREVIA: TABZipHelper class *}
{*********************************************************}
unit AbZipPrc;
{$I AbDefine.inc}
interface
uses
Classes,
AbZipTyp;
procedure AbZip( Sender : TAbZipArchive; Item : TAbZipItem;
OutStream : TStream );
procedure AbZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;
OutStream, InStream : TStream);
procedure DeflateStream( UncompressedStream, CompressedStream : TStream );
{-Deflates everything in UncompressedStream to CompressedStream
no encryption is tried, no check on CRC is done, uses the whole
compressedstream - no Progress events - no Frills! }
implementation
uses
{$IFDEF MSWINDOWS}
Windows,
{$ENDIF}
{$IFDEF LibcAPI}
Libc,
{$ENDIF}
SysUtils,
AbArcTyp,
AbExcept,
AbUtils,
AbDfCryS,
AbVMStrm,
AbDfBase,
AbDfEnc,
AbSpanSt;
{ ========================================================================== }
procedure DoDeflate(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);
const
DEFLATE_NORMAL_MASK = $00;
DEFLATE_MAXIMUM_MASK = $02;
DEFLATE_FAST_MASK = $04;
DEFLATE_SUPERFAST_MASK = $06;
var
Hlpr : TAbDeflateHelper;
begin
Item.CompressionMethod := cmDeflated;
Hlpr := TAbDeflateHelper.Create;
{anything dealing with store options, etc. should already be done.}
try {Hlpr}
Hlpr.StreamSize := InStream.Size;
{ set deflation level desired }
Hlpr.PKZipOption := '0';
case Archive.DeflationOption of
doNormal : begin
Hlpr.PKZipOption := 'n';
Item.GeneralPurposeBitFlag :=
Item.GeneralPurposeBitFlag or DEFLATE_NORMAL_MASK;
end;
doMaximum : begin
Hlpr.PKZipOption := 'x';
Item.GeneralPurposeBitFlag :=
Item.GeneralPurposeBitFlag or DEFLATE_MAXIMUM_MASK;
end;
doFast : begin
Hlpr.PKZipOption := 'f';
Item.GeneralPurposeBitFlag :=
Item.GeneralPurposeBitFlag or DEFLATE_FAST_MASK;
end;
doSuperFast : begin
Hlpr.PKZipOption := 's';
Item.GeneralPurposeBitFlag :=
Item.GeneralPurposeBitFlag or DEFLATE_SUPERFAST_MASK;
end;
end;
{ attach progress notification method }
Hlpr.OnProgressStep := Archive.DoInflateProgress;
{ provide encryption check value }
Item.CRC32 := Deflate(InStream, OutStream, Hlpr);
finally {Hlpr}
Hlpr.Free;
end; {Hlpr}
end;
{ ========================================================================== }
procedure DoStore(Archive : TAbZipArchive; Item : TAbZipItem; OutStream, InStream : TStream);
var
CRC32 : LongInt;
Percent : LongInt;
LastPercent : LongInt;
InSize : Int64;
DataRead : Int64;
Total : Int64;
Abort : Boolean;
Buffer : array [0..8191] of byte;
begin
{ setup }
Item.CompressionMethod := cmStored;
Abort := False;
CRC32 := -1;
Total := 0;
Percent := 0;
LastPercent := 0;
InSize := InStream.Size;
{ get first bufferful }
DataRead := InStream.Read(Buffer, SizeOf(Buffer));
{ while more data has been read and we're not told to bail }
while (DataRead <> 0) and not Abort do begin
{report the progress}
if Assigned(Archive.OnProgress) then begin
Total := Total + DataRead;
Percent := Round((100.0 * Total) / InSize);
if (LastPercent <> Percent) then
Archive.OnProgress(Percent, Abort);
LastPercent := Percent;
end;
{ update CRC}
AbUpdateCRCBuffer(CRC32, Buffer, DataRead);
{ write data (encrypting if needed) }
OutStream.WriteBuffer(Buffer, DataRead);
{ get next bufferful }
DataRead := InStream.Read(Buffer, SizeOf(Buffer));
end;
{ finish CRC calculation }
Item.CRC32 := not CRC32;
{ show final progress increment }
if (Percent < 100) and Assigned(Archive.OnProgress) then
Archive.OnProgress(100, Abort);
{ User wants to bail }
if Abort then begin
raise EAbUserAbort.Create;
end;
end;
{ ========================================================================== }
procedure DoZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;
OutStream, InStream : TStream);
var
ZipArchive : TAbZipArchive;
InStartPos : LongInt;
TempOut : TAbVirtualMemoryStream;
DestStrm : TStream;
begin
ZipArchive := TAbZipArchive(Sender);
{ configure Item }
Item.UncompressedSize := InStream.Size;
Item.GeneralPurposeBitFlag := Item.GeneralPurposeBitFlag and AbLanguageEncodingFlag;
if ZipArchive.Password <> '' then { encrypt the stream }
DestStrm := TAbDfEncryptStream.Create(OutStream,
LongInt(Item.LastModFileTime shl $10),
ZipArchive.Password)
else
DestStrm := OutStream;
try
if InStream.Size > 0 then begin
{ determine how to store Item based on specified CompressionMethodToUse }
case ZipArchive.CompressionMethodToUse of
smDeflated : begin
{ Item is to be deflated regarless }
{ deflate item }
DoDeflate(ZipArchive, Item, DestStrm, InStream);
end;
smStored : begin
{ Item is to be stored regardless }
{ store item }
DoStore(ZipArchive, Item, DestStrm, InStream);
end;
smBestMethod : begin
{ Item is to be archived using method producing best compression }
TempOut := TAbVirtualMemoryStream.Create;
try
TempOut.SwapFileDirectory := Sender.TempDirectory;
{ save starting points }
InStartPos := InStream.Position;
{ try deflating item }
DoDeflate(ZipArchive, Item, TempOut, InStream);
{ if deflated size > input size then got negative compression }
{ so storing the item is more efficient }
if TempOut.Size > InStream.Size then begin { store item instead }
{ reset streams to original positions }
InStream.Position := InStartPos;
TempOut.Free;
TempOut := TAbVirtualMemoryStream.Create;
TempOut.SwapFileDirectory := Sender.TempDirectory;
{ store item }
DoStore(ZipArchive, Item, TempOut, InStream);
end {if};
TempOut.Seek(0, soBeginning);
DestStrm.CopyFrom(TempOut, TempOut.Size);
finally
TempOut.Free;
end;
end;
end; { case }
end
else begin
{ InStream is zero length}
Item.CRC32 := 0;
{ ignore any storage indicator and treat as stored }
DoStore(ZipArchive, Item, DestStrm, InStream);
end;
finally
if DestStrm <> OutStream then
DestStrm.Free;
end;
{ update item }
Item.CompressedSize := OutStream.Size;
Item.InternalFileAttributes := 0; { don't care }
if (ZipArchive.Password <> '') then
Item.GeneralPurposeBitFlag := Item.GeneralPurposeBitFlag
or AbFileIsEncryptedFlag or AbHasDataDescriptorFlag;
end;
{ -------------------------------------------------------------------------- }
procedure AbZipFromStream(Sender : TAbZipArchive; Item : TAbZipItem;
OutStream, InStream : TStream);
var
FileTimeStamp : LongInt;
begin
// Set item properties for non-file streams
Item.ExternalFileAttributes := 0;
FileTimeStamp := DateTimeToFileDate(SysUtils.Now);
Item.LastModFileTime := LongRec(FileTimeStamp).Lo;
Item.LastModFileDate := LongRec(FileTimeStamp).Hi;
DoZipFromStream(Sender, Item, OutStream, InStream);
end;
{ -------------------------------------------------------------------------- }
procedure AbZip( Sender : TAbZipArchive; Item : TAbZipItem;
OutStream : TStream );
var
UncompressedStream : TStream;
SaveDir : string;
AttrEx : TAbAttrExRec;
begin
UncompressedStream := nil;
GetDir(0, SaveDir);
try {SaveDir}
if (Sender.BaseDirectory <> '') then
ChDir(Sender.BaseDirectory);
if not AbFileGetAttrEx(Item.DiskFileName, AttrEx) then
raise EAbFileNotFound.Create;
if ((AttrEx.Attr and faDirectory) <> 0) then
UncompressedStream := TMemoryStream.Create
else
UncompressedStream :=
TFileStream.Create(Item.DiskFileName, fmOpenRead or fmShareDenyWrite);
finally {SaveDir}
ChDir( SaveDir );
end; {SaveDir}
try {UncompressedStream}
{$IFDEF UNIX}
Item.ExternalFileAttributes := LongWord(AttrEx.Mode) shl 16 + LongWord(AttrEx.Attr);
{$ELSE}
Item.ExternalFileAttributes := AttrEx.Attr;
{$ENDIF}
Item.LastModTimeAsDateTime := AttrEx.Time;
DoZipFromStream(Sender, Item, OutStream, UncompressedStream);
finally {UncompressedStream}
UncompressedStream.Free;
end; {UncompressedStream}
end;
{ -------------------------------------------------------------------------- }
procedure DeflateStream( UncompressedStream, CompressedStream : TStream );
{-Deflates everything in CompressedStream to UncompressedStream
no encryption is tried, no check on CRC is done, uses the whole
Uncompressedstream - no Progress events - no Frills!
}
begin
Deflate(UncompressedStream, CompressedStream, nil);
end;
{ -------------------------------------------------------------------------- }
end.

2344
Abbrevia/source/AbZipTyp.pas Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,575 @@
(* ***** 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: AbZipper.pas *}
{*********************************************************}
{* ABBREVIA: Non-visual Component with Zip support *}
{*********************************************************}
unit AbZipper;
{$I AbDefine.inc}
interface
uses
Classes,
AbBrowse, AbZBrows, AbArcTyp, AbZipTyp;
type
TAbCustomZipper = class(TAbCustomZipBrowser)
protected {private}
FAutoSave : Boolean;
FCompressionMethodToUse : TAbZipSupportedMethod;
FDeflationOption : TAbZipDeflationOption;
FDOSMode : Boolean;
FOnConfirmSave : TAbArchiveConfirmEvent;
FOnSave : TAbArchiveEvent;
FOnArchiveSaveProgress : TAbArchiveProgressEvent;
FArchiveSaveProgressMeter : IAbProgressMeter;
FStoreOptions : TAbStoreOptions;
protected {methods}
procedure DoConfirmSave(Sender : TObject; var Confirm : Boolean);
virtual;
procedure DoSave(Sender : TObject);
virtual;
procedure DoArchiveSaveProgress(Sender : TObject; Progress : Byte;
var Abort : Boolean);
procedure InitArchive;
override;
procedure SetAutoSave(Value : Boolean);
procedure SetCompressionMethodToUse(Value : TAbZipSupportedMethod);
procedure SetDeflationOption(Value : TAbZipDeflationOption);
procedure SetDOSMode( Value : Boolean );
procedure SetFileName(const aFileName : string);
override;
procedure SetStoreOptions( Value : TAbStoreOptions );
procedure SetArchiveSaveProgressMeter(const Value: IAbProgressMeter);
procedure SetZipfileComment(const Value : AnsiString);
override;
procedure ZipProc(Sender : TObject; Item : TAbArchiveItem;
OutStream : TStream);
procedure ZipFromStreamProc(Sender : TObject; Item : TAbArchiveItem;
OutStream, InStream : TStream );
procedure Notification(Component: TComponent;
Operation: TOperation); override;
procedure ResetMeters; override;
protected {properties}
property AutoSave : Boolean
read FAutoSave
write SetAutoSave;
property CompressionMethodToUse : TAbZipSupportedMethod
read FCompressionMethodToUse
write SetCompressionMethodToUse
default AbDefCompressionMethodToUse;
property DeflationOption : TAbZipDeflationOption
read FDeflationOption
write SetDeflationOption
default AbDefDeflationOption;
property DOSMode : Boolean
read FDOSMode
write SetDOSMode;
property StoreOptions : TAbStoreOptions
read FStoreOptions
write SetStoreOptions
default AbDefStoreOptions;
property ArchiveSaveProgressMeter : IAbProgressMeter
read FArchiveSaveProgressMeter
write SetArchiveSaveProgressMeter;
protected {events}
property OnConfirmSave : TAbArchiveConfirmEvent
read FOnConfirmSave
write FOnConfirmSave;
property OnSave : TAbArchiveEvent
read FOnSave
write FOnSave;
property OnArchiveSaveProgress : TAbArchiveProgressEvent
read FOnArchiveSaveProgress
write FOnArchiveSaveProgress;
public {methods}
constructor Create(AOwner : TComponent);
override;
destructor Destroy;
override;
procedure AddFiles(const FileMask : string; SearchAttr : Integer);
procedure AddFilesEx(const FileMask, ExclusionMask : string; SearchAttr : Integer);
procedure AddFromStream(const NewName : string; FromStream : TStream);
procedure DeleteAt(Index : Integer);
procedure DeleteFiles(const FileMask : string);
procedure DeleteFilesEx(const FileMask, ExclusionMask : string);
procedure DeleteTaggedItems;
procedure FreshenFiles(const FileMask : string);
procedure FreshenFilesEx(const FileMask, ExclusionMask : string);
procedure FreshenTaggedItems;
procedure Move(aItem : TAbArchiveItem; const NewStoredPath : string);
procedure Save;
procedure Replace(aItem : TAbArchiveItem);
end;
type
TAbZipper = class(TAbCustomZipper)
published
property ArchiveProgressMeter;
property ArchiveSaveProgressMeter;
property ItemProgressMeter;
property AutoSave;
property BaseDirectory;
property CompressionMethodToUse;
property DeflationOption;
property DOSMode;
property SpanningThreshold;
property LogFile;
property Logging;
property OnArchiveProgress;
property OnArchiveSaveProgress;
property OnArchiveItemProgress;
property OnChange;
property OnConfirmProcessItem;
property OnConfirmSave;
property OnLoad;
property OnProcessItemFailure;
property OnRequestBlankDisk;
property OnRequestImage;
property OnRequestLastDisk;
property OnRequestNthDisk;
property OnSave;
property Password;
property StoreOptions;
property TempDirectory;
property Version;
property FileName; {must be after OnLoad}
end;
implementation
uses
SysUtils, AbUtils, AbTarTyp, AbGzTyp, AbBzip2Typ, AbExcept, AbZipPrc;
{ -------------------------------------------------------------------------- }
constructor TAbCustomZipper.Create( AOwner : TComponent );
begin
inherited Create( AOwner );
CompressionMethodToUse := AbDefCompressionMethodToUse;
DeflationOption := AbDefDeflationOption;
StoreOptions := AbDefStoreOptions;
end;
{ -------------------------------------------------------------------------- }
destructor TAbCustomZipper.Destroy;
begin
inherited Destroy;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFiles(const FileMask : string; SearchAttr : Integer);
{Add files to the archive where the disk filespec matches}
begin
if (FArchive <> nil) then
FArchive.AddFiles(FileMask, SearchAttr)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFilesEx(const FileMask, ExclusionMask : string;
SearchAttr : Integer);
{Add files that match Filemask except those matching ExclusionMask}
begin
if (FArchive <> nil) then
FArchive.AddFilesEx(FileMask, ExclusionMask, SearchAttr)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.AddFromStream(const NewName : string;
FromStream : TStream);
{Add stream directly to archive}
begin
if (FArchive <> nil) then begin
FromStream.Position := 0;
FArchive.AddFromStream(NewName, FromStream);
end else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteFiles(const FileMask : string);
{delete all files from the archive that match the file mask}
begin
if (FArchive <> nil) then
FArchive.DeleteFiles( FileMask )
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteAt(Index : Integer);
{delete item at Index}
begin
if (FArchive <> nil) then
FArchive.DeleteAt( Index )
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteFilesEx(const FileMask, ExclusionMask : string);
{Delete files that match Filemask except those matching ExclusionMask}
begin
if (FArchive <> nil) then
FArchive.DeleteFilesEx(FileMask, ExclusionMask)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DeleteTaggedItems;
{delete all tagged items from the archive}
begin
if (FArchive <> nil) then
FArchive.DeleteTaggedItems
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DoConfirmSave(Sender : TObject; var Confirm : Boolean);
begin
Confirm := True;
if Assigned(FOnConfirmSave) then
FOnConfirmSave(Self, Confirm);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DoSave(Sender : TObject);
begin
if Assigned(FOnSave) then
FOnSave(Self);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenFiles(const FileMask : string);
{freshen all items that match the file mask}
begin
if (FArchive <> nil) then
FArchive.FreshenFiles( FileMask )
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenFilesEx(const FileMask, ExclusionMask : string);
{freshen all items matching FileMask except those matching ExclusionMask}
begin
if (FArchive <> nil) then
FArchive.FreshenFilesEx( FileMask, ExclusionMask )
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.FreshenTaggedItems;
{freshen all tagged items}
begin
if (FArchive <> nil) then
FArchive.FreshenTaggedItems
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.InitArchive;
begin
inherited InitArchive;
if FArchive <> nil then begin
{properties}
FArchive.AutoSave := FAutoSave;
FArchive.DOSMode := FDOSMode;
FArchive.StoreOptions := FStoreOptions;
{events}
FArchive.OnArchiveSaveProgress := DoArchiveSaveProgress;
FArchive.OnConfirmSave := DoConfirmSave;
FArchive.OnSave := DoSave;
end;
if (FArchive is TAbZipArchive) then begin
{properties}
TAbZipArchive(FArchive).CompressionMethodToUse := FCompressionMethodToUse;
TAbZipArchive(FArchive).DeflationOption := FDeflationOption;
{events}
TAbZipArchive(FArchive).OnRequestBlankDisk := OnRequestBlankDisk;
TAbZipArchive(FArchive).InsertHelper := ZipProc;
TAbZipArchive(FArchive).InsertFromStreamHelper := ZipFromStreamProc;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Move(aItem : TAbArchiveItem; const NewStoredPath : string);
{renames the item}
begin
if (FArchive <> nil) then
FArchive.Move(aItem, NewStoredPath)
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Replace(aItem : TAbArchiveItem);
{replace the item}
begin
if (FArchive <> nil) then
FArchive.Replace( aItem )
else
raise EAbNoArchive.Create;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Save;
begin
if (FArchive <> nil) then begin
FArchive.Save;
DoChange;
end;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetAutoSave(Value : Boolean);
begin
FAutoSave := Value;
if (FArchive <> nil) then
FArchive.AutoSave := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetCompressionMethodToUse(
Value : TAbZipSupportedMethod);
begin
FCompressionMethodToUse := Value;
if (FArchive is TAbZipArchive) then
TAbZipArchive(FArchive).CompressionMethodToUse := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetDeflationOption(Value : TAbZipDeflationOption);
begin
FDeflationOption := Value;
if (FArchive is TAbZipArchive) then
TAbZipArchive(FArchive).DeflationOption := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetDOSMode(Value : Boolean);
begin
FDOSMode := Value;
if (FArchive <> nil) then
FArchive.DOSMode := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetFileName(const aFileName : string);
var
ArcType : TAbArchiveType;
begin
FFileName := aFileName;
if (csDesigning in ComponentState) then
Exit;
if Assigned(FArchive) then
begin
FArchive.Save;
FreeAndNil(FArchive);
end;
ArcType := ArchiveType;
if (FileName <> '') then
if FileExists(FileName) then begin { open it }
if not ForceType then
ArcType := AbDetermineArcType(FileName, atUnknown);
case ArcType of
atZip, atSpannedZip, atSelfExtZip : begin
FArchive := TAbZipArchive.Create(FileName, fmOpenRead or fmShareDenyNone);
InitArchive;
end;
atTar : begin
FArchive := TAbTarArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
inherited InitArchive;
end;
atGZip : begin
FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := False;
inherited InitArchive;
end;
atGZippedTar : begin
FArchive := TAbGzipArchive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := True;
inherited InitArchive;
end;
atBzip2 : begin
FArchive := TAbBzip2Archive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := False;
inherited InitArchive;
end;
atBzippedTar : begin
FArchive := TAbBzip2Archive.Create(FileName, fmOpenReadWrite or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := True;
inherited InitArchive;
end;
else
raise EAbUnhandledType.Create;
end {case};
FArchive.Load;
FArchiveType := ArcType;
end else begin { file doesn't exist, so create a new one }
if not ForceType then
ArcType := AbDetermineArcType(FileName, atUnknown);
case ArcType of
atZip : begin
FArchive := TAbZipArchive.Create(FileName, fmCreate);
InitArchive;
end;
atTar : begin
FArchive := TAbTarArchive.Create(FileName, fmCreate or fmShareDenyNone);
inherited InitArchive;
end;
atGZip : begin
FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := False;
inherited InitArchive;
end;
atGZippedTar : begin
FArchive := TAbGzipArchive.Create(FileName, fmCreate or fmShareDenyNone);
TAbGzipArchive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbGzipArchive(FArchive).IsGzippedTar := True;
inherited InitArchive;
end;
atBzip2 : begin
FArchive := TAbBzip2Archive.Create(FileName, fmCreate or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := False;
inherited InitArchive;
end;
atBzippedTar : begin
FArchive := TAbBzip2Archive.Create(FileName, fmCreate or fmShareDenyNone);
TAbBzip2Archive(FArchive).TarAutoHandle := FTarAutoHandle;
TAbBzip2Archive(FArchive).IsBzippedTar := True;
inherited InitArchive;
end;
else
raise EAbUnhandledType.Create;
end {case};
FArchiveType := ArcType;
end;
DoChange;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetStoreOptions(Value : TAbStoreOptions);
begin
FStoreOptions := Value;
if (FArchive <> nil) then
FArchive.StoreOptions := Value;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetArchiveSaveProgressMeter(const Value: IAbProgressMeter);
begin
ReferenceInterface(FArchiveSaveProgressMeter, opRemove);
FArchiveSaveProgressMeter := Value;
ReferenceInterface(FArchiveSaveProgressMeter, opInsert);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.SetZipfileComment(const Value : AnsiString);
begin
if (FArchive is TAbZipArchive) then
TAbZipArchive(FArchive).ZipfileComment := Value
else
raise EAbNoArchive.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ZipProc(Sender : TObject; Item : TAbArchiveItem;
OutStream : TStream);
begin
AbZip(TAbZipArchive(Sender), TAbZipItem(Item), OutStream);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ZipFromStreamProc(Sender : TObject; Item : TAbArchiveItem;
OutStream, InStream : TStream);
begin
if Assigned(InStream) then
AbZipFromStream(TAbZipArchive(Sender), TAbZipItem(Item),
OutStream, InStream)
else
raise EAbZipNoInsertion.Create;
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.DoArchiveSaveProgress(Sender : TObject;
Progress : Byte;
var Abort : Boolean);
begin
Abort := False;
if Assigned(FArchiveSaveProgressMeter) then
FArchiveSaveProgressMeter.DoProgress(Progress);
if Assigned(FOnArchiveSaveProgress) then
FOnArchiveSaveProgress(Self, Progress, Abort);
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.Notification(Component: TComponent;
Operation: TOperation);
begin
inherited Notification(Component, Operation);
if (Operation = opRemove) then
if Assigned(ArchiveSaveProgressMeter) and Component.IsImplementorOf(ArchiveSaveProgressMeter) then
ArchiveSaveProgressMeter := nil
end;
{ -------------------------------------------------------------------------- }
procedure TAbCustomZipper.ResetMeters;
begin
inherited ResetMeters;
if Assigned(FArchiveSaveProgressMeter) then
FArchiveSaveProgressMeter.Reset;
end;
{ -------------------------------------------------------------------------- }
end.

View File

@@ -0,0 +1,48 @@
(* ***** 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 ***** *)
library Abbrevia;
uses
ComServ,
_ZipKit in '_ZipKit.pas',
_ZipItem in '_ZipItem.pas',
_GZipItem in '_GZipItem.pas',
_TarItem in '_TarItem.pas',
Abbrevia_TLB in 'Abbrevia_TLB.pas';
exports
DllGetClassObject,
DllCanUnloadNow,
DllRegisterServer,
DllUnregisterServer,
DllInstall;
{$R *.TLB}
{$R *.RES}
begin
end.

View File

@@ -0,0 +1,183 @@
 <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{EDA07E3C-7B07-4B14-9B53-64A70EF3F00A}</ProjectGuid>
<MainSource>Abbrevia.dpr</MainSource>
<Base>True</Base>
<Config Condition="'$(Config)'==''">Release</Config>
<TargetedPlatforms>3</TargetedPlatforms>
<AppType>Library</AppType>
<FrameworkType>None</FrameworkType>
<ProjectVersion>13.4</ProjectVersion>
<Platform Condition="'$(Platform)'==''">Win32</Platform>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Base' or '$(Base)'!=''">
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Base)'=='true') or '$(Base_Win64)'!=''">
<Base_Win64>true</Base_Win64>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Base)'=='true') or '$(Base_Win32)'!=''">
<Base_Win32>true</Base_Win32>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_1)'!=''">
<Cfg_1>true</Cfg_1>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win64)'!=''">
<Cfg_1_Win64>true</Cfg_1_Win64>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_1)'=='true') or '$(Cfg_1_Win32)'!=''">
<Cfg_1_Win32>true</Cfg_1_Win32>
<CfgParent>Cfg_1</CfgParent>
<Cfg_1>true</Cfg_1>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_2)'!=''">
<Cfg_2>true</Cfg_2>
<CfgParent>Base</CfgParent>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win64' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win64)'!=''">
<Cfg_2_Win64>true</Cfg_2_Win64>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="('$(Platform)'=='Win32' and '$(Cfg_2)'=='true') or '$(Cfg_2_Win32)'!=''">
<Cfg_2_Win32>true</Cfg_2_Win32>
<CfgParent>Cfg_2</CfgParent>
<Cfg_2>true</Cfg_2>
<Base>true</Base>
</PropertyGroup>
<PropertyGroup Condition="'$(Base)'!=''">
<DCC_ExeOutput>.\$(Platform)</DCC_ExeOutput>
<DCC_UnitSearchPath>..\;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
<Manifest_File>None</Manifest_File>
<VerInfo_IncludeVerInfo>true</VerInfo_IncludeVerInfo>
<VerInfo_MajorVer>5</VerInfo_MajorVer>
<VerInfo_Locale>1033</VerInfo_Locale>
<DCC_E>false</DCC_E>
<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0.0.0;InternalName=;LegalCopyright=Copyright (c) Abbrevia Group 2011;LegalTrademarks=;OriginalFilename=;ProductName=Abbrevia;ProductVersion=5.0;Comments=</VerInfo_Keys>
<DCC_Namespace>System;Xml;Data;Datasnap;Web;Soap;System.Win;Winapi;Vcl;$(DCC_Namespace)</DCC_Namespace>
<DCC_ImageBase>00400000</DCC_ImageBase>
<DCC_S>false</DCC_S>
<GenDll>true</GenDll>
<DCC_N>false</DCC_N>
<DCC_F>false</DCC_F>
<DCC_K>false</DCC_K>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win64)'!=''">
<DCC_Namespace>Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
<Icon_MainIcon>Abbrevia_Icon.ico</Icon_MainIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Base_Win32)'!=''">
<Debugger_RunParams>/i:user /n Abbrevia.dll</Debugger_RunParams>
<Debugger_HostApplication>C:\Windows\System32\regsvr32.exe</Debugger_HostApplication>
<DCC_Namespace>Data.Win;Datasnap.Win;Web.Win;Soap.Win;Xml.Win;Bde;$(DCC_Namespace)</DCC_Namespace>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=1.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1)'!=''">
<DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
<DCC_DebugInformation>false</DCC_DebugInformation>
<DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
<DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win64)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0;InternalName=;LegalCopyright=Copyright (c) 2011 Abbrevia Group;LegalTrademarks=;OriginalFilename=Abbrevia.dll;ProductName=Abbrevia;ProductVersion=5.0;Comments=http://tpabbrevia.sourceforge.net/</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_1_Win32)'!=''">
<VerInfo_Keys>CompanyName=;FileDescription=Abbrevia COM components;FileVersion=5.0;InternalName=;LegalCopyright=Copyright (c) 2011 Abbrevia Group;LegalTrademarks=;OriginalFilename=Abbrevia.dll;ProductName=Abbrevia;ProductVersion=5.0;Comments=http://tpabbrevia.sourceforge.net/</VerInfo_Keys>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2)'!=''">
<DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
<DCC_Optimize>false</DCC_Optimize>
<DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win64)'!=''">
<DCC_RemoteDebug>true</DCC_RemoteDebug>
</PropertyGroup>
<PropertyGroup Condition="'$(Cfg_2_Win32)'!=''">
<DCC_DebugDCUs>true</DCC_DebugDCUs>
<VerInfo_Keys>CompanyName=;FileDescription=;FileVersion=5.0.0.0;InternalName=;LegalCopyright=;LegalTrademarks=;OriginalFilename=;ProductName=;ProductVersion=1.0.0.0;Comments=</VerInfo_Keys>
</PropertyGroup>
<ItemGroup>
<DelphiCompile Include="$(MainSource)">
<MainSource>MainSource</MainSource>
</DelphiCompile>
<DCCReference Include="_ZipKit.pas"/>
<DCCReference Include="_ZipItem.pas"/>
<DCCReference Include="_GZipItem.pas"/>
<DCCReference Include="_TarItem.pas"/>
<DCCReference Include="Abbrevia_TLB.pas"/>
<RidlCompile Include="Abbrevia.ridl"/>
<BuildConfiguration Include="Debug">
<Key>Cfg_2</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
<BuildConfiguration Include="Base">
<Key>Base</Key>
</BuildConfiguration>
<BuildConfiguration Include="Release">
<Key>Cfg_1</Key>
<CfgParent>Base</CfgParent>
</BuildConfiguration>
</ItemGroup>
<ProjectExtensions>
<Borland.Personality>Delphi.Personality.12</Borland.Personality>
<Borland.ProjectType/>
<BorlandProject>
<Delphi.Personality>
<Source>
<Source Name="MainSource">Abbrevia.dpr</Source>
</Source>
<VersionInfo>
<VersionInfo Name="IncludeVerInfo">False</VersionInfo>
<VersionInfo Name="AutoIncBuild">False</VersionInfo>
<VersionInfo Name="MajorVer">1</VersionInfo>
<VersionInfo Name="MinorVer">0</VersionInfo>
<VersionInfo Name="Release">0</VersionInfo>
<VersionInfo Name="Build">0</VersionInfo>
<VersionInfo Name="Debug">False</VersionInfo>
<VersionInfo Name="PreRelease">False</VersionInfo>
<VersionInfo Name="Special">False</VersionInfo>
<VersionInfo Name="Private">False</VersionInfo>
<VersionInfo Name="DLL">False</VersionInfo>
<VersionInfo Name="Locale">1033</VersionInfo>
<VersionInfo Name="CodePage">1252</VersionInfo>
</VersionInfo>
<VersionInfoKeys>
<VersionInfoKeys Name="CompanyName"/>
<VersionInfoKeys Name="FileDescription"/>
<VersionInfoKeys Name="FileVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="InternalName"/>
<VersionInfoKeys Name="LegalCopyright"/>
<VersionInfoKeys Name="LegalTrademarks"/>
<VersionInfoKeys Name="OriginalFilename"/>
<VersionInfoKeys Name="ProductName"/>
<VersionInfoKeys Name="ProductVersion">1.0.0.0</VersionInfoKeys>
<VersionInfoKeys Name="Comments"/>
</VersionInfoKeys>
</Delphi.Personality>
<Platforms>
<Platform value="Win64">True</Platform>
<Platform value="OSX32">False</Platform>
<Platform value="Win32">True</Platform>
</Platforms>
<ActiveXProjectInfo>
<version>1</version>
</ActiveXProjectInfo>
</BorlandProject>
<ProjectFileVersion>12</ProjectFileVersion>
</ProjectExtensions>
<Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
<Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
</Project>

View File

@@ -0,0 +1,671 @@
// ************************************************************************ //
// WARNING
// -------
// This file is generated by the Type Library importer or Type Libary Editor.
// Barring syntax errors, the Editor will parse modifications made to the file.
// However, when applying changes via the Editor this file will be regenerated
// and comments or formatting changes will be lost.
// ************************************************************************ //
// File generated on 12/6/2011 11:22:23 AM (- $Rev: 12980 $, 51698824).
[
uuid(AF804E20-4043-499E-BB14-237B9F26F89F),
version(3.0),
helpstring("TurboPower Abbrevia Compression Library v3.03"),
helpfile("C:\\Abbrevia\\COM\\abrv-com.hlp"),
helpcontext(0x00000001)
]
library Abbrevia
{
importlib("stdole2.tlb");
interface IZipItem;
interface IGZipItem;
interface ITarItem;
interface IZipKit;
dispinterface IZipKitEvents;
coclass ZipItem;
coclass GZipItem;
coclass TarItem;
coclass ZipKit;
[
uuid(6CABD61B-653C-4CEB-807C-C80E8DE8163D),
version(3.0)
]
enum TArchiveAction
{
aaFailed = 0,
aaNone = 1,
aaAdd = 2,
aaDelete = 3,
aaFreshen = 4,
aaMove = 5,
aaStreamAdd = 6
};
[
uuid(148F84A1-2B70-4A63-B561-FF0EE49E74B3),
version(3.0)
]
enum TArchiveStatus
{
asInvalid = 0,
asIdle = 1,
asBusy = 2
};
[
uuid(5D495174-DB09-4C59-A26D-FEBDE3EAE100),
version(3.0)
]
enum TErrorClass
{
eclAbbrevia = 0,
eclInOutError = 1,
eclFileError = 2,
eclFileCreateError = 3,
eclFileOpenError = 4,
eclOther = 5
};
[
uuid(6A4738B9-69F1-4717-8393-681FF21E8DB7),
version(3.0)
]
enum TFileAttributes
{
faReadOnly = 1,
faHidden = 2,
faSysFile = 4,
faVolumeID = 8,
faDirectory = 16,
faArchive = 32
};
[
uuid(F77BBE04-0859-4F18-9DEA-B2887C1F6AF7),
version(3.0)
]
enum TProcessType
{
ptAdd = 0,
ptDelete = 1,
ptExtract = 2,
ptFreshen = 3,
ptMove = 4,
ptReplace = 5
};
[
uuid(D78287A7-65FA-4391-8F5A-C7D3A11E9970),
version(3.0)
]
enum TStoreOptions
{
soStripDrive = 1,
soStripPath = 2,
soRemoveDots = 4,
soRecurse = 8,
soFreshen = 16,
soReplace = 32
};
[
uuid(192C6697-A38D-4F48-B32B-F33500460E62),
version(3.0)
]
enum TZipCompressionMethod
{
cmStored = 0,
cmShrunk = 1,
cmReduced1 = 2,
cmReduced2 = 3,
cmReduced3 = 4,
cmReduced4 = 5,
cmImploded = 6,
cmTokenized = 7,
cmDeflated = 8,
cmEnhancedDeflated = 9,
cmDCLImploded = 10,
cmBestMethod = 11
};
[
uuid(800F8CDC-2F0F-4020-BCBB-FEDA82D0EFEF),
version(3.0)
]
enum TZipDeflateOption
{
doInvalid = 0,
doNormal = 1,
doMaximum = 2,
doFast = 3,
doSuperFast = 4
};
[
uuid(D697ED2A-F088-409F-962A-57D8324EEDD6),
version(3.0)
]
enum TZipDictionarySize
{
dsInvalid = 0,
ds4K = 1,
ds8K = 2
};
[
uuid(B9889806-26F9-47E7-AC1F-906AA161B078),
version(3.0)
]
enum TZipExtractOptions
{
eoCreateDirs = 0,
eoRestorePath = 1
};
[
uuid(D40E0708-AE71-4A44-A6C8-430EDF760DE2),
version(3.0)
]
enum TZipSupportMethod
{
smStored = 0,
smDeflated = 1,
smBestMethod = 2
};
[
uuid(EFD2C909-BF04-4C54-9ACB-38D872B95C9F),
version(3.0)
]
enum TErrorCode
{
ecDuplicateName = 0,
ecInvalidPassword = 1,
ecNoSuchDirectory = 2,
ecUnknownCompressionMethod = 3,
ecUserAbort = 4,
ecZipBadCRC = 5,
ecZipVersionNumber = 6,
ecSpannedItemNotFound = 7
};
[
uuid(44EB05F9-CED9-46D0-84E2-BD3362977437),
version(3.0)
]
enum TArchiveType
{
atUnknown = 0,
atZip = 1,
atSelfExtZip = 2,
atTar = 3,
atGZip = 4,
atGZippedTar = 5,
atCab = 6
};
[
uuid(36568A72-3B4B-41C4-8E34-19931A8EAF63),
version(3.0)
]
enum TFileSystem
{
fsFAT = 0,
fsAmiga = 1,
fsVMS = 2,
fsUnix = 3,
fsVM_CMS = 4,
fsAtariTOS = 5,
fsHPFS = 6,
fsMacintosh = 7,
fsZSystem = 8,
fsCP_M = 9,
fsTOPS20 = 10,
fsNTFS = 11,
fsQDOS = 12,
fsAcornRISCOS = 13,
fsUnknown = 14,
fsUndefined = 15
};
[
uuid(851699A1-422A-4C65-8E08-D0499ACDD834),
version(3.0),
helpstring("Dispatch interface for ZipItem Object"),
helpcontext(0x00000005),
dual,
oleautomation
]
interface IZipItem: IDispatch
{
[propget, id(0x00000001)]
HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);
[propget, id(0x00000002)]
HRESULT _stdcall CompressedSize([out, retval] long* Value);
[propget, id(0x00000003)]
HRESULT _stdcall CRC32([out, retval] long* Value);
[propget, id(0x00000004)]
HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);
[propget, id(0x00000005)]
HRESULT _stdcall DiskPath([out, retval] BSTR* Value);
[propget, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);
[propput, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);
[propget, id(0x00000007)]
HRESULT _stdcall FileName([out, retval] BSTR* Value);
[propput, id(0x00000007)]
HRESULT _stdcall FileName([in] BSTR Value);
[propget, id(0x00000008)]
HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);
[propget, id(0x00000009)]
HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);
[propget, id(0x0000000A)]
HRESULT _stdcall StoredPath([out, retval] BSTR* Value);
[propget, id(0x0000000B)]
HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);
[propput, id(0x0000000B)]
HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);
[propget, id(0x0000000C)]
HRESULT _stdcall UnCompressedSize([out, retval] long* Value);
[propget, id(0x0000000D)]
HRESULT _stdcall CRC32St([out, retval] BSTR* Value);
[propget, id(0x0000000E)]
HRESULT _stdcall Password([out, retval] BSTR* Value);
[propput, id(0x0000000E)]
HRESULT _stdcall Password([in] BSTR Value);
[propget, id(0x0000000F)]
HRESULT _stdcall CompressionMethod([out, retval] enum TZipCompressionMethod* Value);
[propget, id(0x00000010)]
HRESULT _stdcall CompressionRatio([out, retval] double* Value);
[propget, id(0x00000011)]
HRESULT _stdcall DeflateOption([out, retval] enum TZipDeflateOption* Value);
[propget, id(0x00000012)]
HRESULT _stdcall DictionarySize([out, retval] enum TZipDictionarySize* Value);
[propget, id(0x00000013)]
HRESULT _stdcall DiskNumberStart([out, retval] long* Value);
[propget, id(0x00000014)]
HRESULT _stdcall ExtraField([out, retval] BSTR* Value);
[propput, id(0x00000014)]
HRESULT _stdcall ExtraField([in] BSTR Value);
[propget, id(0x00000015)]
HRESULT _stdcall FileComment([out, retval] BSTR* Value);
[propput, id(0x00000015)]
HRESULT _stdcall FileComment([in] BSTR Value);
[propget, id(0x00000016)]
HRESULT _stdcall InternalFileAttributes([out, retval] long* Value);
[propput, id(0x00000016)]
HRESULT _stdcall InternalFileAttributes([in] long Value);
[propget, id(0x00000017)]
HRESULT _stdcall VersionMadeBy([out, retval] long* Value);
[propget, id(0x00000018)]
HRESULT _stdcall VersionNeededToExtract([out, retval] long* Value);
};
[
uuid(8FA78CE0-FD29-441E-9777-93B63EF1A9EE),
version(3.0),
dual,
oleautomation
]
interface IGZipItem: IDispatch
{
[propget, id(0x00000001)]
HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);
[propget, id(0x00000002)]
HRESULT _stdcall CompressedSize([out, retval] long* Value);
[propget, id(0x00000003)]
HRESULT _stdcall CRC32([out, retval] long* Value);
[propget, id(0x00000004)]
HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);
[propget, id(0x00000005)]
HRESULT _stdcall DiskPath([out, retval] BSTR* Value);
[propget, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);
[propput, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);
[propget, id(0x00000007)]
HRESULT _stdcall FileName([out, retval] BSTR* Value);
[propput, id(0x00000007)]
HRESULT _stdcall FileName([in] BSTR Value);
[propget, id(0x00000008)]
HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);
[propget, id(0x00000009)]
HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);
[propget, id(0x0000000A)]
HRESULT _stdcall StoredPath([out, retval] BSTR* Value);
[propget, id(0x0000000B)]
HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);
[propput, id(0x0000000B)]
HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);
[propget, id(0x0000000C)]
HRESULT _stdcall UnCompressedSize([out, retval] long* Value);
[propget, id(0x0000000D)]
HRESULT _stdcall CRC32St([out, retval] BSTR* Value);
[propget, id(0x0000000E)]
HRESULT _stdcall Password([out, retval] BSTR* Value);
[propput, id(0x0000000E)]
HRESULT _stdcall Password([in] BSTR Value);
[propget, id(0x0000000F)]
HRESULT _stdcall CompressionMethod([out, retval] unsigned char* Value);
[propput, id(0x0000000F)]
HRESULT _stdcall CompressionMethod([in] unsigned char Value);
[propget, id(0x00000010)]
HRESULT _stdcall ExtraField([out, retval] BSTR* Value);
[propput, id(0x00000010)]
HRESULT _stdcall ExtraField([in] BSTR Value);
[propget, id(0x00000011)]
HRESULT _stdcall ExtraFlags([out, retval] unsigned char* Value);
[propput, id(0x00000011)]
HRESULT _stdcall ExtraFlags([in] unsigned char Value);
[propget, id(0x00000012)]
HRESULT _stdcall FileComment([out, retval] BSTR* Value);
[propput, id(0x00000012)]
HRESULT _stdcall FileComment([in] BSTR Value);
[propget, id(0x00000013)]
HRESULT _stdcall FileSystem([out, retval] enum TFileSystem* Value);
[propput, id(0x00000013)]
HRESULT _stdcall FileSystem([in] enum TFileSystem Value);
[propget, id(0x00000014)]
HRESULT _stdcall Flags([out, retval] unsigned char* Value);
[propput, id(0x00000014)]
HRESULT _stdcall Flags([in] unsigned char Value);
[propget, id(0x00000015)]
HRESULT _stdcall HeaderCRC([out, retval] long* Value);
};
[
uuid(729E9F52-C489-4A41-A770-4E2C5282AE39),
version(3.0),
dual,
oleautomation
]
interface ITarItem: IDispatch
{
[propget, id(0x00000001)]
HRESULT _stdcall Action([out, retval] enum TArchiveAction* Value);
[propget, id(0x00000002)]
HRESULT _stdcall CompressedSize([out, retval] long* Value);
[propget, id(0x00000003)]
HRESULT _stdcall CRC32([out, retval] long* Value);
[propget, id(0x00000004)]
HRESULT _stdcall DiskFileName([out, retval] BSTR* Value);
[propget, id(0x00000005)]
HRESULT _stdcall DiskPath([out, retval] BSTR* Value);
[propget, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([out, retval] enum TFileAttributes* Value);
[propput, id(0x00000006)]
HRESULT _stdcall ExternalFileAttributes([in] enum TFileAttributes Value);
[propget, id(0x00000007)]
HRESULT _stdcall FileName([out, retval] BSTR* Value);
[propput, id(0x00000007)]
HRESULT _stdcall FileName([in] BSTR Value);
[propget, id(0x00000008)]
HRESULT _stdcall IsEncrypted([out, retval] VARIANT_BOOL* Value);
[propget, id(0x00000009)]
HRESULT _stdcall LastModFileDateTime([out, retval] DATE* Value);
[propget, id(0x0000000A)]
HRESULT _stdcall StoredPath([out, retval] BSTR* Value);
[propget, id(0x0000000B)]
HRESULT _stdcall Tagged([out, retval] VARIANT_BOOL* Value);
[propput, id(0x0000000B)]
HRESULT _stdcall Tagged([in] VARIANT_BOOL Value);
[propget, id(0x0000000C)]
HRESULT _stdcall UnCompressedSize([out, retval] long* Value);
[propget, id(0x0000000D)]
HRESULT _stdcall CRC32St([out, retval] BSTR* Value);
[propget, id(0x0000000E)]
HRESULT _stdcall Password([out, retval] BSTR* Value);
[propput, id(0x0000000E)]
HRESULT _stdcall Password([in] BSTR Value);
[propget, id(0x0000000F)]
HRESULT _stdcall DevMajor([out, retval] long* Value);
[propput, id(0x0000000F)]
HRESULT _stdcall DevMajor([in] long Value);
[propget, id(0x00000010)]
HRESULT _stdcall DevMinor([out, retval] long* Value);
[propput, id(0x00000010)]
HRESULT _stdcall DevMinor([in] long Value);
[propget, id(0x00000011)]
HRESULT _stdcall GroupID([out, retval] long* Value);
[propput, id(0x00000011)]
HRESULT _stdcall GroupID([in] long Value);
[propget, id(0x00000012)]
HRESULT _stdcall GroupName([out, retval] BSTR* Value);
[propput, id(0x00000012)]
HRESULT _stdcall GroupName([in] BSTR Value);
[propget, id(0x00000013)]
HRESULT _stdcall LinkFlag([out, retval] unsigned char* Value);
[propput, id(0x00000013)]
HRESULT _stdcall LinkFlag([in] unsigned char Value);
[propget, id(0x00000014)]
HRESULT _stdcall LinkName([out, retval] BSTR* Value);
[propput, id(0x00000014)]
HRESULT _stdcall LinkName([in] BSTR Value);
[propget, id(0x00000015)]
HRESULT _stdcall Mode([out, retval] long* Value);
[propput, id(0x00000015)]
HRESULT _stdcall Mode([in] long Value);
[propget, id(0x00000016)]
HRESULT _stdcall UserID([out, retval] long* Value);
[propput, id(0x00000016)]
HRESULT _stdcall UserID([in] long Value);
[propget, id(0x00000017)]
HRESULT _stdcall UserName([out, retval] BSTR* Value);
[propput, id(0x00000017)]
HRESULT _stdcall UserName([in] BSTR Value);
};
[
uuid(B7480A7F-4E27-4B45-9FE6-224B60295A0C),
version(3.0),
helpstring("Dispatch interface for ZipKit Object"),
helpcontext(0x00000006),
dual,
oleautomation
]
interface IZipKit: IDispatch
{
[id(0x00000001)]
HRESULT _stdcall Add([in] BSTR FileMask, [in] BSTR ExclusionMask, [in] long SearchAttr);
[id(0x00000007)]
HRESULT _stdcall AddFromStream([in] BSTR FileName, [in] VARIANT Stream);
[propget, id(0x00000003)]
HRESULT _stdcall AutoSave([out, retval] VARIANT_BOOL* Value);
[propput, id(0x00000003)]
HRESULT _stdcall AutoSave([in] VARIANT_BOOL Value);
[propget, id(0x00000004)]
HRESULT _stdcall BaseDirectory([out, retval] BSTR* Value);
[propput, id(0x00000004)]
HRESULT _stdcall BaseDirectory([in] BSTR Value);
[id(0x00000005)]
HRESULT _stdcall ClearTags(void);
[propget, id(0x00000006)]
HRESULT _stdcall CompressionMethodToUse([out, retval] enum TZipSupportMethod* Value);
[propput, id(0x00000006)]
HRESULT _stdcall CompressionMethodToUse([in] enum TZipSupportMethod Value);
[propget, id(0x00000002)]
HRESULT _stdcall Count([out, retval] long* Value);
[propget, id(0x00000008)]
HRESULT _stdcall DeflateOption([out, retval] enum TZipDeflateOption* Value);
[propput, id(0x00000008)]
HRESULT _stdcall DeflateOption([in] enum TZipDeflateOption Value);
[id(0x00000009)]
HRESULT _stdcall Delete([in] BSTR FileMask, [in] BSTR ExclusionMask);
[id(0x0000000A)]
HRESULT _stdcall DeleteAt([in] long Index);
[id(0x0000000B)]
HRESULT _stdcall DeleteTaggedItems(void);
[propget, id(0x0000000C)]
HRESULT _stdcall DOSMode([out, retval] VARIANT_BOOL* Value);
[propput, id(0x0000000C)]
HRESULT _stdcall DOSMode([in] VARIANT_BOOL Value);
[id(0x0000000D)]
HRESULT _stdcall Extract([in] BSTR FileMask, [in] BSTR ExclusionMask);
[id(0x0000000E)]
HRESULT _stdcall ExtractAt([in] long Index, [in] BSTR NewName);
[propget, id(0x0000000F)]
HRESULT _stdcall ExtractOptions([out, retval] enum TZipExtractOptions* Value);
[propput, id(0x0000000F)]
HRESULT _stdcall ExtractOptions([in] enum TZipExtractOptions Value);
[id(0x00000010)]
HRESULT _stdcall ExtractTaggedItems(void);
[propget, id(0x00000011)]
HRESULT _stdcall FileName([out, retval] BSTR* Value);
[propput, id(0x00000011)]
HRESULT _stdcall FileName([in] BSTR Value);
[id(0x00000012)]
HRESULT _stdcall Find([in] BSTR FileName, [out, retval] long* Value);
[id(0x00000013)]
HRESULT _stdcall Freshen([in] BSTR FileMask, [in] BSTR ExclusionMask);
[id(0x00000014)]
HRESULT _stdcall FreshenTaggedItems(void);
[propget, id(0x00000000)]
HRESULT _stdcall Item([in] long Index, [out, retval] IDispatch** Value);
[propget, id(0x00000017)]
HRESULT _stdcall LogFile([out, retval] BSTR* Value);
[propput, id(0x00000017)]
HRESULT _stdcall LogFile([in] BSTR Value);
[propget, id(0x00000018)]
HRESULT _stdcall Logging([out, retval] VARIANT_BOOL* Value);
[propput, id(0x00000018)]
HRESULT _stdcall Logging([in] VARIANT_BOOL Value);
[propget, id(0x00000019)]
HRESULT _stdcall Password([out, retval] BSTR* Value);
[propput, id(0x00000019)]
HRESULT _stdcall Password([in] BSTR Value);
[propget, id(0x0000001A)]
HRESULT _stdcall PasswordRetries([out, retval] unsigned char* Value);
[propput, id(0x0000001A)]
HRESULT _stdcall PasswordRetries([in] unsigned char Value);
[id(0x0000001B)]
HRESULT _stdcall Replace([in] BSTR FileMask);
[id(0x0000001C)]
HRESULT _stdcall Save(void);
[propget, id(0x0000001D)]
HRESULT _stdcall Spanned([out, retval] VARIANT_BOOL* Value);
[propget, id(0x0000001E)]
HRESULT _stdcall SpanningThreshold([out, retval] long* Value);
[propput, id(0x0000001E)]
HRESULT _stdcall SpanningThreshold([in] long Value);
[propget, id(0x0000001F)]
HRESULT _stdcall Status([out, retval] enum TArchiveStatus* Value);
[propget, id(0x00000020)]
HRESULT _stdcall StoreOptions([out, retval] enum TStoreOptions* Value);
[propput, id(0x00000020)]
HRESULT _stdcall StoreOptions([in] enum TStoreOptions Value);
[id(0x00000021)]
HRESULT _stdcall TagItems([in] BSTR FileMask);
[propget, id(0x00000022)]
HRESULT _stdcall TempDirectory([out, retval] BSTR* Value);
[propput, id(0x00000022)]
HRESULT _stdcall TempDirectory([in] BSTR Value);
[id(0x00000023)]
HRESULT _stdcall TestTaggedItems(void);
[id(0x00000024)]
HRESULT _stdcall UntagItems([in] BSTR FileMask);
[propget, id(0x00000025)]
HRESULT _stdcall ZipFileComment([out, retval] BSTR* Value);
[propput, id(0x00000025)]
HRESULT _stdcall ZipFileComment([in] BSTR Value);
[id(0x00000026)]
HRESULT _stdcall License([in] BSTR Key, [out, retval] VARIANT_BOOL* Value);
[propget, id(0xFFFFFFFC), restricted, hidden]
HRESULT _stdcall _NewEnum([out, retval] IUnknown** Value);
[id(0x00000015)]
HRESULT _stdcall ExtractToStream([in] BSTR FileName, [out, retval] VARIANT* Value);
[propget, id(0x00000028)]
HRESULT _stdcall CompressionType([out, retval] enum TArchiveType* Value);
[propput, id(0x00000028)]
HRESULT _stdcall CompressionType([in] enum TArchiveType Value);
[propget, id(0x00000029)]
HRESULT _stdcall TarAutoHandle([out, retval] VARIANT_BOOL* Value);
[propput, id(0x00000029)]
HRESULT _stdcall TarAutoHandle([in] VARIANT_BOOL Value);
};
[
uuid(F094D5F4-3A52-45AE-9D86-4409611DD29E),
version(3.0),
helpstring("Events interface for ZipKit Object")
]
dispinterface IZipKitEvents
{
properties:
methods:
[id(0x00000001)]
void OnArchiveItemProgress([in] IDispatch* Item, [in] unsigned char Progress, [in, out] VARIANT_BOOL* Abort);
[id(0x00000002)]
void OnArchiveProgress([in] unsigned char Progress, [in, out] VARIANT_BOOL* Abort);
[id(0x00000003)]
void OnChange(void);
[id(0x00000004)]
void OnConfirmOverwrite([in, out] BSTR* Name, [in, out] VARIANT_BOOL* Confirm);
[id(0x00000005)]
void OnConfirmProcessItem([in] IDispatch* Item, [in] enum TProcessType ProcessType, [in, out] VARIANT_BOOL* Confirm);
[id(0x00000006)]
void OnConfirmSave([in, out] VARIANT_BOOL* Confirm);
[id(0x00000007)]
void OnLoad(void);
[id(0x00000008)]
void OnNeedPassword([in, out] BSTR* NewPassword);
[id(0x00000009)]
void OnProcessItemFailure([in] IDispatch* Item, [in] enum TProcessType ProcessType, [in] enum TErrorClass ErrorClass, [in] enum TErrorCode ErrorCode, [in] BSTR ErrorString);
[id(0x0000000A)]
void OnRequestBlankDisk([in, out] VARIANT_BOOL* Abort);
[id(0x0000000B)]
void OnRequestImage([in] long ImageNumber, [in, out] BSTR* ImageName, [in, out] VARIANT_BOOL* Abort);
[id(0x0000000C)]
void OnRequestLastDisk([in, out] VARIANT_BOOL* Abort);
[id(0x0000000D)]
void OnRequestNthDisk([in] long DiskNumber, [in, out] VARIANT_BOOL* Abort);
[id(0x0000000E)]
void OnSave(void);
};
[
uuid(650989D8-F0FF-4C71-83C3-92556F4329F5),
version(3.0)
]
coclass ZipItem
{
[default] interface IZipItem;
};
[
uuid(2B35BB50-D9C7-4669-B18E-943B5199FD8E),
version(3.0)
]
coclass GZipItem
{
[default] interface IGZipItem;
};
[
uuid(2DF3E624-0E6C-42CF-8041-676B9A06375E),
version(3.0)
]
coclass TarItem
{
[default] interface ITarItem;
};
[
uuid(730B4B32-9127-492A-BF02-196A7E6B4E1B),
version(3.0),
helpstring("ZipKit Object"),
helpcontext(0x00000006)
]
coclass ZipKit
{
[default] interface IZipKit;
[default, source] dispinterface IZipKitEvents;
};
};

Binary file not shown.

817
Abbrevia/source/COM/Abbrevia_TLB.pas generated Normal file
View File

@@ -0,0 +1,817 @@
(* ***** 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 ***** *)
unit Abbrevia_TLB;
// ************************************************************************ //
// WARNING
// -------
// The types declared in this file were generated from data read from a
// Type Library. If this type library is explicitly or indirectly (via
// another type library referring to this type library) re-imported, or the
// 'Refresh' command of the Type Library Editor activated while editing the
// Type Library, the contents of this file will be regenerated and all
// manual modifications will be lost.
// ************************************************************************ //
// $Rev: 491 $
// File generated on 7/23/2009 9:45:45 PM from Type Library described below.
// ************************************************************************ //
// Type Lib: C:\Abbrevia\COM\abbrevia.dll
// LIBID: {AF804E20-4043-499E-BB14-237B9F26F89F}
// LCID: 0
// Helpfile: C:\Abbrevia\COM\abrv-com.hlp
// HelpString: TurboPower Abbrevia Compression Library v3.03
// DepndLst:
// (1) v2.0 stdole, (C:\WINDOWS\System32\stdole2.tlb)
// ************************************************************************ //
{$TYPEDADDRESS OFF} // Unit must be compiled without type-checked pointers.
{$WARN SYMBOL_PLATFORM OFF}
{$WRITEABLECONST ON}
{$VARPROPSETTER ON}
interface
uses Windows, ActiveX, Classes, Graphics, StdVCL, Variants;
// *********************************************************************//
// GUIDS declared in the TypeLibrary. Following prefixes are used:
// Type Libraries : LIBID_xxxx
// CoClasses : CLASS_xxxx
// DISPInterfaces : DIID_xxxx
// Non-DISP interfaces: IID_xxxx
// *********************************************************************//
const
// TypeLibrary Major and minor versions
AbbreviaMajorVersion = 5;
AbbreviaMinorVersion = 0;
LIBID_Abbrevia: TGUID = '{AF804E20-4043-499E-BB14-237B9F26F89F}';
IID_IZipItem: TGUID = '{851699A1-422A-4C65-8E08-D0499ACDD834}';
IID_IGZipItem: TGUID = '{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}';
IID_ITarItem: TGUID = '{729E9F52-C489-4A41-A770-4E2C5282AE39}';
IID_IZipKit: TGUID = '{B7480A7F-4E27-4B45-9FE6-224B60295A0C}';
DIID_IZipKitEvents: TGUID = '{F094D5F4-3A52-45AE-9D86-4409611DD29E}';
CLASS_ZipItem: TGUID = '{650989D8-F0FF-4C71-83C3-92556F4329F5}';
CLASS_GZipItem: TGUID = '{2B35BB50-D9C7-4669-B18E-943B5199FD8E}';
CLASS_TarItem: TGUID = '{2DF3E624-0E6C-42CF-8041-676B9A06375E}';
CLASS_ZipKit: TGUID = '{730B4B32-9127-492A-BF02-196A7E6B4E1B}';
// *********************************************************************//
// Declaration of Enumerations defined in Type Library
// *********************************************************************//
// Constants for enum TArchiveAction
type
TArchiveAction = TOleEnum;
const
aaFailed = $00000000;
aaNone = $00000001;
aaAdd = $00000002;
aaDelete = $00000003;
aaFreshen = $00000004;
aaMove = $00000005;
aaStreamAdd = $00000006;
// Constants for enum TArchiveStatus
type
TArchiveStatus = TOleEnum;
const
asInvalid = $00000000;
asIdle = $00000001;
asBusy = $00000002;
// Constants for enum TErrorClass
type
TErrorClass = TOleEnum;
const
eclAbbrevia = $00000000;
eclInOutError = $00000001;
eclFileError = $00000002;
eclFileCreateError = $00000003;
eclFileOpenError = $00000004;
eclOther = $00000005;
// Constants for enum TFileAttributes
type
TFileAttributes = TOleEnum;
const
faReadOnly = $00000001;
faHidden = $00000002;
faSysFile = $00000004;
faVolumeID = $00000008;
faDirectory = $00000010;
faArchive = $00000020;
// Constants for enum TProcessType
type
TProcessType = TOleEnum;
const
ptAdd = $00000000;
ptDelete = $00000001;
ptExtract = $00000002;
ptFreshen = $00000003;
ptMove = $00000004;
ptReplace = $00000005;
// Constants for enum TStoreOptions
type
TStoreOptions = TOleEnum;
const
soStripDrive = $00000001;
soStripPath = $00000002;
soRemoveDots = $00000004;
soRecurse = $00000008;
soFreshen = $00000010;
soReplace = $00000020;
// Constants for enum TZipCompressionMethod
type
TZipCompressionMethod = TOleEnum;
const
cmStored = $00000000;
cmShrunk = $00000001;
cmReduced1 = $00000002;
cmReduced2 = $00000003;
cmReduced3 = $00000004;
cmReduced4 = $00000005;
cmImploded = $00000006;
cmTokenized = $00000007;
cmDeflated = $00000008;
cmEnhancedDeflated = $00000009;
cmDCLImploded = $0000000A;
cmBestMethod = $0000000B;
// Constants for enum TZipDeflateOption
type
TZipDeflateOption = TOleEnum;
const
doInvalid = $00000000;
doNormal = $00000001;
doMaximum = $00000002;
doFast = $00000003;
doSuperFast = $00000004;
// Constants for enum TZipDictionarySize
type
TZipDictionarySize = TOleEnum;
const
dsInvalid = $00000000;
ds4K = $00000001;
ds8K = $00000002;
// Constants for enum TZipExtractOptions
type
TZipExtractOptions = TOleEnum;
const
eoCreateDirs = $00000000;
eoRestorePath = $00000001;
// Constants for enum TZipSupportMethod
type
TZipSupportMethod = TOleEnum;
const
smStored = $00000000;
smDeflated = $00000001;
smBestMethod = $00000002;
// Constants for enum TErrorCode
type
TErrorCode = TOleEnum;
const
ecDuplicateName = $00000000;
ecInvalidPassword = $00000001;
ecNoSuchDirectory = $00000002;
ecUnknownCompressionMethod = $00000003;
ecUserAbort = $00000004;
ecZipBadCRC = $00000005;
ecZipVersionNumber = $00000006;
ecSpannedItemNotFound = $00000007;
// Constants for enum TArchiveType
type
TArchiveType = TOleEnum;
const
atUnknown = $00000000;
atZip = $00000001;
atSelfExtZip = $00000002;
atTar = $00000003;
atGZip = $00000004;
atGZippedTar = $00000005;
atCab = $00000006;
// Constants for enum TFileSystem
type
TFileSystem = TOleEnum;
const
fsFAT = $00000000;
fsAmiga = $00000001;
fsVMS = $00000002;
fsUnix = $00000003;
fsVM_CMS = $00000004;
fsAtariTOS = $00000005;
fsHPFS = $00000006;
fsMacintosh = $00000007;
fsZSystem = $00000008;
fsCP_M = $00000009;
fsTOPS20 = $0000000A;
fsNTFS = $0000000B;
fsQDOS = $0000000C;
fsAcornRISCOS = $0000000D;
fsUnknown = $0000000E;
fsUndefined = $0000000F;
type
// *********************************************************************//
// Forward declaration of types defined in TypeLibrary
// *********************************************************************//
IZipItem = interface;
IZipItemDisp = dispinterface;
IGZipItem = interface;
IGZipItemDisp = dispinterface;
ITarItem = interface;
ITarItemDisp = dispinterface;
IZipKit = interface;
IZipKitDisp = dispinterface;
IZipKitEvents = dispinterface;
// *********************************************************************//
// Declaration of CoClasses defined in Type Library
// (NOTE: Here we map each CoClass to its Default Interface)
// *********************************************************************//
ZipItem = IZipItem;
GZipItem = IGZipItem;
TarItem = ITarItem;
ZipKit = IZipKit;
// *********************************************************************//
// Interface: IZipItem
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {851699A1-422A-4C65-8E08-D0499ACDD834}
// *********************************************************************//
IZipItem = interface(IDispatch)
['{851699A1-422A-4C65-8E08-D0499ACDD834}']
function Get_Action: TArchiveAction; safecall;
function Get_CompressedSize: Integer; safecall;
function Get_CRC32: Integer; safecall;
function Get_DiskFileName: WideString; safecall;
function Get_DiskPath: WideString; safecall;
function Get_ExternalFileAttributes: TFileAttributes; safecall;
procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Get_IsEncrypted: WordBool; safecall;
function Get_LastModFileDateTime: TDateTime; safecall;
function Get_StoredPath: WideString; safecall;
function Get_Tagged: WordBool; safecall;
procedure Set_Tagged(Value: WordBool); safecall;
function Get_UnCompressedSize: Integer; safecall;
function Get_CRC32St: WideString; safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
function Get_CompressionMethod: TZipCompressionMethod; safecall;
function Get_CompressionRatio: Double; safecall;
function Get_DeflateOption: TZipDeflateOption; safecall;
function Get_DictionarySize: TZipDictionarySize; safecall;
function Get_DiskNumberStart: Integer; safecall;
function Get_ExtraField: WideString; safecall;
procedure Set_ExtraField(const Value: WideString); safecall;
function Get_FileComment: WideString; safecall;
procedure Set_FileComment(const Value: WideString); safecall;
function Get_InternalFileAttributes: Integer; safecall;
procedure Set_InternalFileAttributes(Value: Integer); safecall;
function Get_VersionMadeBy: Integer; safecall;
function Get_VersionNeededToExtract: Integer; safecall;
property Action: TArchiveAction read Get_Action;
property CompressedSize: Integer read Get_CompressedSize;
property CRC32: Integer read Get_CRC32;
property DiskFileName: WideString read Get_DiskFileName;
property DiskPath: WideString read Get_DiskPath;
property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;
property FileName: WideString read Get_FileName write Set_FileName;
property IsEncrypted: WordBool read Get_IsEncrypted;
property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;
property StoredPath: WideString read Get_StoredPath;
property Tagged: WordBool read Get_Tagged write Set_Tagged;
property UnCompressedSize: Integer read Get_UnCompressedSize;
property CRC32St: WideString read Get_CRC32St;
property Password: WideString read Get_Password write Set_Password;
property CompressionMethod: TZipCompressionMethod read Get_CompressionMethod;
property CompressionRatio: Double read Get_CompressionRatio;
property DeflateOption: TZipDeflateOption read Get_DeflateOption;
property DictionarySize: TZipDictionarySize read Get_DictionarySize;
property DiskNumberStart: Integer read Get_DiskNumberStart;
property ExtraField: WideString read Get_ExtraField write Set_ExtraField;
property FileComment: WideString read Get_FileComment write Set_FileComment;
property InternalFileAttributes: Integer read Get_InternalFileAttributes write Set_InternalFileAttributes;
property VersionMadeBy: Integer read Get_VersionMadeBy;
property VersionNeededToExtract: Integer read Get_VersionNeededToExtract;
end;
// *********************************************************************//
// DispIntf: IZipItemDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {851699A1-422A-4C65-8E08-D0499ACDD834}
// *********************************************************************//
IZipItemDisp = dispinterface
['{851699A1-422A-4C65-8E08-D0499ACDD834}']
property Action: TArchiveAction readonly dispid 1;
property CompressedSize: Integer readonly dispid 2;
property CRC32: Integer readonly dispid 3;
property DiskFileName: WideString readonly dispid 4;
property DiskPath: WideString readonly dispid 5;
property ExternalFileAttributes: TFileAttributes dispid 6;
property FileName: WideString dispid 7;
property IsEncrypted: WordBool readonly dispid 8;
property LastModFileDateTime: TDateTime readonly dispid 9;
property StoredPath: WideString readonly dispid 10;
property Tagged: WordBool dispid 11;
property UnCompressedSize: Integer readonly dispid 12;
property CRC32St: WideString readonly dispid 13;
property Password: WideString dispid 14;
property CompressionMethod: TZipCompressionMethod readonly dispid 15;
property CompressionRatio: Double readonly dispid 16;
property DeflateOption: TZipDeflateOption readonly dispid 17;
property DictionarySize: TZipDictionarySize readonly dispid 18;
property DiskNumberStart: Integer readonly dispid 19;
property ExtraField: WideString dispid 20;
property FileComment: WideString dispid 21;
property InternalFileAttributes: Integer dispid 22;
property VersionMadeBy: Integer readonly dispid 23;
property VersionNeededToExtract: Integer readonly dispid 24;
end;
// *********************************************************************//
// Interface: IGZipItem
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {8FA78CE0-FD29-441E-9777-93B63EF1A9EE}
// *********************************************************************//
IGZipItem = interface(IDispatch)
['{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}']
function Get_Action: TArchiveAction; safecall;
function Get_CompressedSize: Integer; safecall;
function Get_CRC32: Integer; safecall;
function Get_DiskFileName: WideString; safecall;
function Get_DiskPath: WideString; safecall;
function Get_ExternalFileAttributes: TFileAttributes; safecall;
procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Get_IsEncrypted: WordBool; safecall;
function Get_LastModFileDateTime: TDateTime; safecall;
function Get_StoredPath: WideString; safecall;
function Get_Tagged: WordBool; safecall;
procedure Set_Tagged(Value: WordBool); safecall;
function Get_UnCompressedSize: Integer; safecall;
function Get_CRC32St: WideString; safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
function Get_CompressionMethod: Byte; safecall;
procedure Set_CompressionMethod(Value: Byte); safecall;
function Get_ExtraField: WideString; safecall;
procedure Set_ExtraField(const Value: WideString); safecall;
function Get_ExtraFlags: Byte; safecall;
procedure Set_ExtraFlags(Value: Byte); safecall;
function Get_FileComment: WideString; safecall;
procedure Set_FileComment(const Value: WideString); safecall;
function Get_FileSystem: TFileSystem; safecall;
procedure Set_FileSystem(Value: TFileSystem); safecall;
function Get_Flags: Byte; safecall;
procedure Set_Flags(Value: Byte); safecall;
function Get_HeaderCRC: Integer; safecall;
property Action: TArchiveAction read Get_Action;
property CompressedSize: Integer read Get_CompressedSize;
property CRC32: Integer read Get_CRC32;
property DiskFileName: WideString read Get_DiskFileName;
property DiskPath: WideString read Get_DiskPath;
property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;
property FileName: WideString read Get_FileName write Set_FileName;
property IsEncrypted: WordBool read Get_IsEncrypted;
property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;
property StoredPath: WideString read Get_StoredPath;
property Tagged: WordBool read Get_Tagged write Set_Tagged;
property UnCompressedSize: Integer read Get_UnCompressedSize;
property CRC32St: WideString read Get_CRC32St;
property Password: WideString read Get_Password write Set_Password;
property CompressionMethod: Byte read Get_CompressionMethod write Set_CompressionMethod;
property ExtraField: WideString read Get_ExtraField write Set_ExtraField;
property ExtraFlags: Byte read Get_ExtraFlags write Set_ExtraFlags;
property FileComment: WideString read Get_FileComment write Set_FileComment;
property FileSystem: TFileSystem read Get_FileSystem write Set_FileSystem;
property Flags: Byte read Get_Flags write Set_Flags;
property HeaderCRC: Integer read Get_HeaderCRC;
end;
// *********************************************************************//
// DispIntf: IGZipItemDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {8FA78CE0-FD29-441E-9777-93B63EF1A9EE}
// *********************************************************************//
IGZipItemDisp = dispinterface
['{8FA78CE0-FD29-441E-9777-93B63EF1A9EE}']
property Action: TArchiveAction readonly dispid 1;
property CompressedSize: Integer readonly dispid 2;
property CRC32: Integer readonly dispid 3;
property DiskFileName: WideString readonly dispid 4;
property DiskPath: WideString readonly dispid 5;
property ExternalFileAttributes: TFileAttributes dispid 6;
property FileName: WideString dispid 7;
property IsEncrypted: WordBool readonly dispid 8;
property LastModFileDateTime: TDateTime readonly dispid 9;
property StoredPath: WideString readonly dispid 10;
property Tagged: WordBool dispid 11;
property UnCompressedSize: Integer readonly dispid 12;
property CRC32St: WideString readonly dispid 13;
property Password: WideString dispid 14;
property CompressionMethod: Byte dispid 15;
property ExtraField: WideString dispid 16;
property ExtraFlags: Byte dispid 17;
property FileComment: WideString dispid 18;
property FileSystem: TFileSystem dispid 19;
property Flags: Byte dispid 20;
property HeaderCRC: Integer readonly dispid 21;
end;
// *********************************************************************//
// Interface: ITarItem
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {729E9F52-C489-4A41-A770-4E2C5282AE39}
// *********************************************************************//
ITarItem = interface(IDispatch)
['{729E9F52-C489-4A41-A770-4E2C5282AE39}']
function Get_Action: TArchiveAction; safecall;
function Get_CompressedSize: Integer; safecall;
function Get_CRC32: Integer; safecall;
function Get_DiskFileName: WideString; safecall;
function Get_DiskPath: WideString; safecall;
function Get_ExternalFileAttributes: TFileAttributes; safecall;
procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Get_IsEncrypted: WordBool; safecall;
function Get_LastModFileDateTime: TDateTime; safecall;
function Get_StoredPath: WideString; safecall;
function Get_Tagged: WordBool; safecall;
procedure Set_Tagged(Value: WordBool); safecall;
function Get_UnCompressedSize: Integer; safecall;
function Get_CRC32St: WideString; safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
function Get_DevMajor: Integer; safecall;
procedure Set_DevMajor(Value: Integer); safecall;
function Get_DevMinor: Integer; safecall;
procedure Set_DevMinor(Value: Integer); safecall;
function Get_GroupID: Integer; safecall;
procedure Set_GroupID(Value: Integer); safecall;
function Get_GroupName: WideString; safecall;
procedure Set_GroupName(const Value: WideString); safecall;
function Get_LinkFlag: Byte; safecall;
procedure Set_LinkFlag(Value: Byte); safecall;
function Get_LinkName: WideString; safecall;
procedure Set_LinkName(const Value: WideString); safecall;
function Get_Mode: Integer; safecall;
procedure Set_Mode(Value: Integer); safecall;
function Get_UserID: Integer; safecall;
procedure Set_UserID(Value: Integer); safecall;
function Get_UserName: WideString; safecall;
procedure Set_UserName(const Value: WideString); safecall;
property Action: TArchiveAction read Get_Action;
property CompressedSize: Integer read Get_CompressedSize;
property CRC32: Integer read Get_CRC32;
property DiskFileName: WideString read Get_DiskFileName;
property DiskPath: WideString read Get_DiskPath;
property ExternalFileAttributes: TFileAttributes read Get_ExternalFileAttributes write Set_ExternalFileAttributes;
property FileName: WideString read Get_FileName write Set_FileName;
property IsEncrypted: WordBool read Get_IsEncrypted;
property LastModFileDateTime: TDateTime read Get_LastModFileDateTime;
property StoredPath: WideString read Get_StoredPath;
property Tagged: WordBool read Get_Tagged write Set_Tagged;
property UnCompressedSize: Integer read Get_UnCompressedSize;
property CRC32St: WideString read Get_CRC32St;
property Password: WideString read Get_Password write Set_Password;
property DevMajor: Integer read Get_DevMajor write Set_DevMajor;
property DevMinor: Integer read Get_DevMinor write Set_DevMinor;
property GroupID: Integer read Get_GroupID write Set_GroupID;
property GroupName: WideString read Get_GroupName write Set_GroupName;
property LinkFlag: Byte read Get_LinkFlag write Set_LinkFlag;
property LinkName: WideString read Get_LinkName write Set_LinkName;
property Mode: Integer read Get_Mode write Set_Mode;
property UserID: Integer read Get_UserID write Set_UserID;
property UserName: WideString read Get_UserName write Set_UserName;
end;
// *********************************************************************//
// DispIntf: ITarItemDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {729E9F52-C489-4A41-A770-4E2C5282AE39}
// *********************************************************************//
ITarItemDisp = dispinterface
['{729E9F52-C489-4A41-A770-4E2C5282AE39}']
property Action: TArchiveAction readonly dispid 1;
property CompressedSize: Integer readonly dispid 2;
property CRC32: Integer readonly dispid 3;
property DiskFileName: WideString readonly dispid 4;
property DiskPath: WideString readonly dispid 5;
property ExternalFileAttributes: TFileAttributes dispid 6;
property FileName: WideString dispid 7;
property IsEncrypted: WordBool readonly dispid 8;
property LastModFileDateTime: TDateTime readonly dispid 9;
property StoredPath: WideString readonly dispid 10;
property Tagged: WordBool dispid 11;
property UnCompressedSize: Integer readonly dispid 12;
property CRC32St: WideString readonly dispid 13;
property Password: WideString dispid 14;
property DevMajor: Integer dispid 15;
property DevMinor: Integer dispid 16;
property GroupID: Integer dispid 17;
property GroupName: WideString dispid 18;
property LinkFlag: Byte dispid 19;
property LinkName: WideString dispid 20;
property Mode: Integer dispid 21;
property UserID: Integer dispid 22;
property UserName: WideString dispid 23;
end;
// *********************************************************************//
// Interface: IZipKit
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {B7480A7F-4E27-4B45-9FE6-224B60295A0C}
// *********************************************************************//
IZipKit = interface(IDispatch)
['{B7480A7F-4E27-4B45-9FE6-224B60295A0C}']
procedure Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer); safecall;
procedure AddFromStream(const FileName: WideString; Stream: OleVariant); safecall;
function Get_AutoSave: WordBool; safecall;
procedure Set_AutoSave(Value: WordBool); safecall;
function Get_BaseDirectory: WideString; safecall;
procedure Set_BaseDirectory(const Value: WideString); safecall;
procedure ClearTags; safecall;
function Get_CompressionMethodToUse: TZipSupportMethod; safecall;
procedure Set_CompressionMethodToUse(Value: TZipSupportMethod); safecall;
function Get_Count: Integer; safecall;
function Get_DeflateOption: TZipDeflateOption; safecall;
procedure Set_DeflateOption(Value: TZipDeflateOption); safecall;
procedure Delete(const FileMask: WideString; const ExclusionMask: WideString); safecall;
procedure DeleteAt(Index: Integer); safecall;
procedure DeleteTaggedItems; safecall;
function Get_DOSMode: WordBool; safecall;
procedure Set_DOSMode(Value: WordBool); safecall;
procedure Extract(const FileMask: WideString; const ExclusionMask: WideString); safecall;
procedure ExtractAt(Index: Integer; const NewName: WideString); safecall;
function Get_ExtractOptions: TZipExtractOptions; safecall;
procedure Set_ExtractOptions(Value: TZipExtractOptions); safecall;
procedure ExtractTaggedItems; safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Find(const FileName: WideString): Integer; safecall;
procedure Freshen(const FileMask: WideString; const ExclusionMask: WideString); safecall;
procedure FreshenTaggedItems; safecall;
function Get_Item(Index: Integer): IDispatch; safecall;
function Get_LogFile: WideString; safecall;
procedure Set_LogFile(const Value: WideString); safecall;
function Get_Logging: WordBool; safecall;
procedure Set_Logging(Value: WordBool); safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
function Get_PasswordRetries: Byte; safecall;
procedure Set_PasswordRetries(Value: Byte); safecall;
procedure Replace(const FileMask: WideString); safecall;
procedure Save; safecall;
function Get_Spanned: WordBool; safecall;
function Get_SpanningThreshold: Integer; safecall;
procedure Set_SpanningThreshold(Value: Integer); safecall;
function Get_Status: TArchiveStatus; safecall;
function Get_StoreOptions: TStoreOptions; safecall;
procedure Set_StoreOptions(Value: TStoreOptions); safecall;
procedure TagItems(const FileMask: WideString); safecall;
function Get_TempDirectory: WideString; safecall;
procedure Set_TempDirectory(const Value: WideString); safecall;
procedure TestTaggedItems; safecall;
procedure UntagItems(const FileMask: WideString); safecall;
function Get_ZipFileComment: WideString; safecall;
procedure Set_ZipFileComment(const Value: WideString); safecall;
function License(const Key: WideString): WordBool; safecall;
function Get__NewEnum: IUnknown; safecall;
function ExtractToStream(const FileName: WideString): OleVariant; safecall;
function Get_CompressionType: TArchiveType; safecall;
procedure Set_CompressionType(Value: TArchiveType); safecall;
function Get_TarAutoHandle: WordBool; safecall;
procedure Set_TarAutoHandle(Value: WordBool); safecall;
property AutoSave: WordBool read Get_AutoSave write Set_AutoSave;
property BaseDirectory: WideString read Get_BaseDirectory write Set_BaseDirectory;
property CompressionMethodToUse: TZipSupportMethod read Get_CompressionMethodToUse write Set_CompressionMethodToUse;
property Count: Integer read Get_Count;
property DeflateOption: TZipDeflateOption read Get_DeflateOption write Set_DeflateOption;
property DOSMode: WordBool read Get_DOSMode write Set_DOSMode;
property ExtractOptions: TZipExtractOptions read Get_ExtractOptions write Set_ExtractOptions;
property FileName: WideString read Get_FileName write Set_FileName;
property Item[Index: Integer]: IDispatch read Get_Item;
property LogFile: WideString read Get_LogFile write Set_LogFile;
property Logging: WordBool read Get_Logging write Set_Logging;
property Password: WideString read Get_Password write Set_Password;
property PasswordRetries: Byte read Get_PasswordRetries write Set_PasswordRetries;
property Spanned: WordBool read Get_Spanned;
property SpanningThreshold: Integer read Get_SpanningThreshold write Set_SpanningThreshold;
property Status: TArchiveStatus read Get_Status;
property StoreOptions: TStoreOptions read Get_StoreOptions write Set_StoreOptions;
property TempDirectory: WideString read Get_TempDirectory write Set_TempDirectory;
property ZipFileComment: WideString read Get_ZipFileComment write Set_ZipFileComment;
property _NewEnum: IUnknown read Get__NewEnum;
property CompressionType: TArchiveType read Get_CompressionType write Set_CompressionType;
property TarAutoHandle: WordBool read Get_TarAutoHandle write Set_TarAutoHandle;
end;
// *********************************************************************//
// DispIntf: IZipKitDisp
// Flags: (4416) Dual OleAutomation Dispatchable
// GUID: {B7480A7F-4E27-4B45-9FE6-224B60295A0C}
// *********************************************************************//
IZipKitDisp = dispinterface
['{B7480A7F-4E27-4B45-9FE6-224B60295A0C}']
procedure Add(const FileMask: WideString; const ExclusionMask: WideString; SearchAttr: Integer); dispid 1;
procedure AddFromStream(const FileName: WideString; Stream: OleVariant); dispid 7;
property AutoSave: WordBool dispid 3;
property BaseDirectory: WideString dispid 4;
procedure ClearTags; dispid 5;
property CompressionMethodToUse: TZipSupportMethod dispid 6;
property Count: Integer readonly dispid 2;
property DeflateOption: TZipDeflateOption dispid 8;
procedure Delete(const FileMask: WideString; const ExclusionMask: WideString); dispid 9;
procedure DeleteAt(Index: Integer); dispid 10;
procedure DeleteTaggedItems; dispid 11;
property DOSMode: WordBool dispid 12;
procedure Extract(const FileMask: WideString; const ExclusionMask: WideString); dispid 13;
procedure ExtractAt(Index: Integer; const NewName: WideString); dispid 14;
property ExtractOptions: TZipExtractOptions dispid 15;
procedure ExtractTaggedItems; dispid 16;
property FileName: WideString dispid 17;
function Find(const FileName: WideString): Integer; dispid 18;
procedure Freshen(const FileMask: WideString; const ExclusionMask: WideString); dispid 19;
procedure FreshenTaggedItems; dispid 20;
property Item[Index: Integer]: IDispatch readonly dispid 0;
property LogFile: WideString dispid 23;
property Logging: WordBool dispid 24;
property Password: WideString dispid 25;
property PasswordRetries: Byte dispid 26;
procedure Replace(const FileMask: WideString); dispid 27;
procedure Save; dispid 28;
property Spanned: WordBool readonly dispid 29;
property SpanningThreshold: Integer dispid 30;
property Status: TArchiveStatus readonly dispid 31;
property StoreOptions: TStoreOptions dispid 32;
procedure TagItems(const FileMask: WideString); dispid 33;
property TempDirectory: WideString dispid 34;
procedure TestTaggedItems; dispid 35;
procedure UntagItems(const FileMask: WideString); dispid 36;
property ZipFileComment: WideString dispid 37;
function License(const Key: WideString): WordBool; dispid 38;
property _NewEnum: IUnknown readonly dispid $FFFFFFFC;
function ExtractToStream(const FileName: WideString): OleVariant; dispid 21;
property CompressionType: TArchiveType dispid 40;
property TarAutoHandle: WordBool dispid 41;
end;
// *********************************************************************//
// DispIntf: IZipKitEvents
// Flags: (4096) Dispatchable
// GUID: {F094D5F4-3A52-45AE-9D86-4409611DD29E}
// *********************************************************************//
IZipKitEvents = dispinterface
['{F094D5F4-3A52-45AE-9D86-4409611DD29E}']
procedure OnArchiveItemProgress(const Item: IDispatch; Progress: Byte; var Abort: WordBool); dispid 1;
procedure OnArchiveProgress(Progress: Byte; var Abort: WordBool); dispid 2;
procedure OnChange; dispid 3;
procedure OnConfirmOverwrite(var Name: WideString; var Confirm: WordBool); dispid 4;
procedure OnConfirmProcessItem(const Item: IDispatch; ProcessType: TProcessType;
var Confirm: WordBool); dispid 5;
procedure OnConfirmSave(var Confirm: WordBool); dispid 6;
procedure OnLoad; dispid 7;
procedure OnNeedPassword(var NewPassword: WideString); dispid 8;
procedure OnProcessItemFailure(const Item: IDispatch; ProcessType: TProcessType;
ErrorClass: TErrorClass; ErrorCode: TErrorCode;
const ErrorString: WideString); dispid 9;
procedure OnRequestBlankDisk(var Abort: WordBool); dispid 10;
procedure OnRequestImage(ImageNumber: Integer; var ImageName: WideString; var Abort: WordBool); dispid 11;
procedure OnRequestLastDisk(var Abort: WordBool); dispid 12;
procedure OnRequestNthDisk(DiskNumber: Integer; var Abort: WordBool); dispid 13;
procedure OnSave; dispid 14;
end;
// *********************************************************************//
// The Class CoZipItem provides a Create and CreateRemote method to
// create instances of the default interface IZipItem exposed by
// the CoClass ZipItem. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoZipItem = class
class function Create: IZipItem;
class function CreateRemote(const MachineName: string): IZipItem;
end;
// *********************************************************************//
// The Class CoGZipItem provides a Create and CreateRemote method to
// create instances of the default interface IGZipItem exposed by
// the CoClass GZipItem. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoGZipItem = class
class function Create: IGZipItem;
class function CreateRemote(const MachineName: string): IGZipItem;
end;
// *********************************************************************//
// The Class CoTarItem provides a Create and CreateRemote method to
// create instances of the default interface ITarItem exposed by
// the CoClass TarItem. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoTarItem = class
class function Create: ITarItem;
class function CreateRemote(const MachineName: string): ITarItem;
end;
// *********************************************************************//
// The Class CoZipKit provides a Create and CreateRemote method to
// create instances of the default interface IZipKit exposed by
// the CoClass ZipKit. The functions are intended to be used by
// clients wishing to automate the CoClass objects exposed by the
// server of this typelibrary.
// *********************************************************************//
CoZipKit = class
class function Create: IZipKit;
class function CreateRemote(const MachineName: string): IZipKit;
end;
implementation
uses ComObj;
class function CoZipItem.Create: IZipItem;
begin
Result := CreateComObject(CLASS_ZipItem) as IZipItem;
end;
class function CoZipItem.CreateRemote(const MachineName: string): IZipItem;
begin
Result := CreateRemoteComObject(MachineName, CLASS_ZipItem) as IZipItem;
end;
class function CoGZipItem.Create: IGZipItem;
begin
Result := CreateComObject(CLASS_GZipItem) as IGZipItem;
end;
class function CoGZipItem.CreateRemote(const MachineName: string): IGZipItem;
begin
Result := CreateRemoteComObject(MachineName, CLASS_GZipItem) as IGZipItem;
end;
class function CoTarItem.Create: ITarItem;
begin
Result := CreateComObject(CLASS_TarItem) as ITarItem;
end;
class function CoTarItem.CreateRemote(const MachineName: string): ITarItem;
begin
Result := CreateRemoteComObject(MachineName, CLASS_TarItem) as ITarItem;
end;
class function CoZipKit.Create: IZipKit;
begin
Result := CreateComObject(CLASS_ZipKit) as IZipKit;
end;
class function CoZipKit.CreateRemote(const MachineName: string): IZipKit;
begin
Result := CreateRemoteComObject(MachineName, CLASS_ZipKit) as IZipKit;
end;
end.

View File

@@ -0,0 +1,17 @@
The COM DLLs for v5.0 are compiled using Delphi XE2 (including extended RTTI) and include zipx support. Recompiling with Delphi 2009 and without zipx support should roughly halve the size of the 32-bit DLL.
They can be registered for all users (requires admin rights) using:
regsvr32 Abbrevia.dll
And for the current user using:
regsvr32 /i:user /n Abbrevia.dll
To uninstall use:
regsvr32 /u Abbrevia.dll
or
regsvr32 /i:user /n /u Abbrevia.dll

View File

@@ -0,0 +1,262 @@
(* ***** 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 ***** *)
unit _GZipItem;
interface
uses
ComObj, Abbrevia_TLB, AbGzTyp, AbZipKit;
type
TGZipItem = class(TAutoIntfObject, IGZipItem)
private
FOwner : TAbGzipItem;
FParent : TAbZipKit;
public
constructor Create(AOwner : TAbGzipItem; AParent : TAbZipKit);
protected
{IArchiveItem}
function Get_Action: TArchiveAction; safecall;
function Get_CompressedSize: Integer; safecall;
function Get_CRC32: Integer; safecall;
function Get_CRC32St: WideString; safecall;
function Get_DiskFileName: WideString; safecall;
function Get_DiskPath: WideString; safecall;
function Get_ExternalFileAttributes: TFileAttributes; safecall;
procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Get_IsEncrypted: WordBool; safecall;
function Get_LastModFileDateTime: TDateTime; safecall;
function Get_StoredPath: WideString; safecall;
function Get_Tagged: WordBool; safecall;
procedure Set_Tagged(Value: WordBool); safecall;
function Get_UnCompressedSize: Integer; safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
{IGZipItem}
function Get_CompressionMethod: Byte; safecall;
procedure Set_CompressionMethod(Value: Byte); safecall;
function Get_ExtraField: WideString; safecall;
procedure Set_ExtraField(const Value: WideString); safecall;
function Get_ExtraFlags: Byte; safecall;
procedure Set_ExtraFlags(Value: Byte); safecall;
function Get_FileComment: WideString; safecall;
procedure Set_FileComment(const Value: WideString); safecall;
function Get_FileSystem: TFileSystem; safecall;
procedure Set_FileSystem(Value: TFileSystem); safecall;
function Get_Flags: Byte; safecall;
procedure Set_Flags(Value: Byte); safecall;
function Get_HeaderCRC: Integer; safecall;
end;
implementation
uses
ComServ, {StStrL,} SysUtils;
{------------------------------------------------------------------------------}
constructor TGzipItem.Create(AOwner : TAbGzipItem; AParent : TAbZipKit);
begin
inherited Create(ComServer.TypeLib, IGZipItem);
FOwner := AOwner;
FParent := AParent;
end;
{------------------------------------------------------------------------------}
{IArchiveItem}
{------------------------------------------------------------------------------}
function TGzipItem.Get_Action: TArchiveAction;
begin
Result := TArchiveAction(FOwner.Action);
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_CompressedSize: Integer;
begin
result := FOwner.CompressedSize;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_CRC32: Integer;
begin
result := FOwner.CRC32;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_CRC32St: WideString;
begin
result := IntToHex(FOwner.CRC32, 8);
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_DiskFileName: WideString;
begin
result := FOwner.DiskFileName;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_DiskPath: WideString;
begin
result := FOwner.DiskPath;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_ExternalFileAttributes: TFileAttributes;
begin
result := TFileAttributes(FOwner.ExternalFileAttributes);
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_ExternalFileAttributes(Value: TFileAttributes);
begin
FOwner.ExternalFileAttributes := LongInt(Value);
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_FileName: WideString;
begin
result := FOwner.FileName;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_FileName(const Value: WideString);
begin
FOwner.FileName := Value;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_IsEncrypted: WordBool;
begin
result := FOwner.IsEncrypted;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_LastModFileDateTime: TDateTime;
begin
result := FileDateToDateTime((FOwner.LastModFileDate shl 16) + FOwner.LastModFileTime);
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_StoredPath: WideString;
begin
result := FOwner.StoredPath;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_Tagged: WordBool;
begin
result := FOwner.Tagged;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_Tagged(Value: WordBool);
begin
FOwner.Tagged := Value;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_UnCompressedSize: Integer;
begin
result := FOwner.UncompressedSize;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_Password: WideString;
begin
{!!!}
//result := FOwner.Password;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_Password(const Value: WideString);
begin
{!!!}
//FOwner.Password := Value;
//FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
{IGZipItem}
{------------------------------------------------------------------------------}
function TGzipItem.Get_CompressionMethod: Byte;
begin
result := FOwner.CompressionMethod;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_CompressionMethod(Value: Byte);
begin
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_ExtraField: WideString;
begin
result := '';
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_ExtraField(const Value: WideString);
begin
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_ExtraFlags: Byte;
begin
result := FOwner.ExtraFlags;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_ExtraFlags(Value: Byte);
begin
FOwner.ExtraFlags := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_FileComment: WideString;
begin
result := WideString(FOwner.FileComment);
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_FileComment(const Value: WideString);
begin
FOwner.FileComment := AnsiString(Value);
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_FileSystem: TFileSystem;
begin
result := TFileSystem(FOwner.FileSystem);
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_FileSystem(Value: TFileSystem);
begin
FOwner.FileSystem := TAbGzFileSystem(Value);
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_Flags: Byte;
begin
result := FOwner.Flags;
end;
{------------------------------------------------------------------------------}
procedure TGzipItem.Set_Flags(Value: Byte);
begin
end;
{------------------------------------------------------------------------------}
function TGzipItem.Get_HeaderCRC: Integer;
begin
result := 0;
end;
{------------------------------------------------------------------------------}
end.

View File

@@ -0,0 +1,297 @@
(* ***** 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 ***** *)
unit _TarItem;
interface
uses
ComObj, Abbrevia_TLB, AbTarTyp, AbZipKit;
type
TTarItem = class(TAutoIntfObject, ITarItem)
private
FOwner : TAbTarItem;
FParent : TAbZipKit;
public
constructor Create(AOwner : TAbTarItem; AParent : TAbZipKit);
protected
{IArchiveItem}
function Get_Action: TArchiveAction; safecall;
function Get_CompressedSize: Integer; safecall;
function Get_CRC32: Integer; safecall;
function Get_CRC32St: WideString; safecall;
function Get_DiskFileName: WideString; safecall;
function Get_DiskPath: WideString; safecall;
function Get_ExternalFileAttributes: TFileAttributes; safecall;
procedure Set_ExternalFileAttributes(Value: TFileAttributes); safecall;
function Get_FileName: WideString; safecall;
procedure Set_FileName(const Value: WideString); safecall;
function Get_IsEncrypted: WordBool; safecall;
function Get_LastModFileDateTime: TDateTime; safecall;
function Get_StoredPath: WideString; safecall;
function Get_Tagged: WordBool; safecall;
procedure Set_Tagged(Value: WordBool); safecall;
function Get_UnCompressedSize: Integer; safecall;
function Get_Password: WideString; safecall;
procedure Set_Password(const Value: WideString); safecall;
{ITarItem}
function Get_DevMajor: Integer; safecall;
procedure Set_DevMajor(Value: Integer); safecall;
function Get_DevMinor: Integer; safecall;
procedure Set_DevMinor(Value: Integer); safecall;
function Get_GroupID: Integer; safecall;
procedure Set_GroupID(Value: Integer); safecall;
function Get_GroupName: WideString; safecall;
procedure Set_GroupName(const Value: WideString); safecall;
function Get_LinkFlag: Byte; safecall;
procedure Set_LinkFlag(Value: Byte); safecall;
function Get_LinkName: WideString; safecall;
procedure Set_LinkName(const Value: WideString); safecall;
function Get_Mode: Integer; safecall;
procedure Set_Mode(Value: Integer); safecall;
function Get_UserID: Integer; safecall;
procedure Set_UserID(Value: Integer); safecall;
function Get_UserName: WideString; safecall;
procedure Set_UserName(const Value: WideString); safecall;
end;
implementation
uses
ComServ, {StStrL,} SysUtils;
{------------------------------------------------------------------------------}
constructor TTarItem.Create(AOwner : TAbTarItem; AParent : TAbZipKit);
begin
inherited Create(ComServer.TypeLib, ITarItem);
FOwner := AOwner;
FParent := AParent;
end;
{------------------------------------------------------------------------------}
{IArchiveItem}
{------------------------------------------------------------------------------}
function TTarItem.Get_Action: TArchiveAction;
begin
Result := TArchiveAction(FOwner.Action);
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_CompressedSize: Integer;
begin
result := FOwner.CompressedSize;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_CRC32: Integer;
begin
result := FOwner.CRC32;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_CRC32St: WideString;
begin
result := IntToHex(FOwner.CRC32, 8);
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_DiskFileName: WideString;
begin
result := FOwner.DiskFileName;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_DiskPath: WideString;
begin
result := FOwner.DiskPath;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_ExternalFileAttributes: TFileAttributes;
begin
result := TFileAttributes(FOwner.ExternalFileAttributes);
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_ExternalFileAttributes(Value: TFileAttributes);
begin
FOwner.ExternalFileAttributes := LongInt(Value);
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_FileName: WideString;
begin
result := FOwner.FileName;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_FileName(const Value: WideString);
begin
FOwner.FileName := Value;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_IsEncrypted: WordBool;
begin
result := FOwner.IsEncrypted;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_LastModFileDateTime: TDateTime;
begin
result := FileDateToDateTime((FOwner.LastModFileDate shl 16) + FOwner.LastModFileTime);
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_StoredPath: WideString;
begin
result := FOwner.StoredPath;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_Tagged: WordBool;
begin
result := FOwner.Tagged;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_Tagged(Value: WordBool);
begin
FOwner.Tagged := Value;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_UnCompressedSize: Integer;
begin
result := FOwner.UncompressedSize;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_Password: WideString;
begin
{!!!}
//result := FOwner.Password;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_Password(const Value: WideString);
begin
{!!!}
//FOwner.Password := Value;
//FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
{ITarItem}
{------------------------------------------------------------------------------}
function TTarItem.Get_DevMajor: Integer;
begin
result := FOwner.DevMajor;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_DevMajor(Value: Integer);
begin
FOwner.DevMajor := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_DevMinor: Integer;
begin
result := FOwner.DevMinor;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_DevMinor(Value: Integer);
begin
FOwner.DevMinor := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_GroupID: Integer;
begin
result := FOwner.GroupID;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_GroupID(Value: Integer);
begin
FOwner.GroupID := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_GroupName: WideString;
begin
result := FOwner.GroupName;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_GroupName(const Value: WideString);
begin
FOwner.GroupName := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_LinkFlag: Byte;
begin
result := Byte(FOwner.LinkFlag);
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_LinkFlag(Value: Byte);
begin
FOwner.LinkFlag := AnsiChar(Value);
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_LinkName: WideString;
begin
result := FOwner.LinkName;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_LinkName(const Value: WideString);
begin
FOwner.LinkName := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_Mode: Integer;
begin
result := FOwner.Mode;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_Mode(Value: Integer);
begin
FOwner.Mode := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_UserID: Integer;
begin
result := FOwner.UserID;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_UserID(Value: Integer);
begin
FOwner.UserID := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
function TTarItem.Get_UserName: WideString;
begin
result := FOwner.UserName;
end;
{------------------------------------------------------------------------------}
procedure TTarItem.Set_UserName(const Value: WideString);
begin
FOwner.UserName := Value;
FParent.ZipArchive.IsDirty := True;
end;
{------------------------------------------------------------------------------}
end.

Some files were not shown because too many files have changed in this diff Show More