318 lines
9.7 KiB
Plaintext
318 lines
9.7 KiB
Plaintext
unit ResourceCompUnit;
|
|
{reSource Component Unit
|
|
Component Front End for reSource Compression Engine
|
|
|
|
reSource v2.6
|
|
Copyright (C) 1998-2001 Victor Kasenda / gruv
|
|
http://go.to/gruv
|
|
email: vickas@singnet.com.sg
|
|
|
|
|
|
USAGE:
|
|
Drop the component onto the form to use it.
|
|
Default name will be Resource1.
|
|
To perform any action on the archive, use Resource1.ArchiveMan (Archive Manager)
|
|
|
|
There are 2 ways to perform actions on archives:
|
|
Type 1: To deal directly with ArchiveMan.
|
|
This is the most efficient type and allows the fastest way to add/extract
|
|
multiple files from archive.
|
|
Type 2: Call CompressToFile, DecompressFromFile.
|
|
This wraps ArchiveMan and is simple to use if only dealing with one file.
|
|
|
|
ACTIONS: (Type 1)
|
|
Before doing any action, set the parameters for ArchiveMan
|
|
Resource1.ArchiveMan.TempDir := 'c:\temp'; // Set the Temporary Directory
|
|
|
|
To Open an Archive:
|
|
Resource1.ArchiveMan.OpenArchive(<ArchiveName>);
|
|
|
|
To Close the Archive:
|
|
Resource1.ArchiveMan.CloseArchive;
|
|
|
|
To Add files:
|
|
Resource1.ArchiveMan.AddFiles(FileList: TStrings; const infile_dir: string)
|
|
There are 2 ways to send the FileList
|
|
- If each entry in FileList has the full Path+Name, then infile_dir can be ''.
|
|
- If each entry in FileList is only the name, then infile_dir must contain
|
|
the path the files are in.
|
|
|
|
To Extract the file:
|
|
Before calling ExtractList, set the parameters for file extract:
|
|
Resource1.ArchiveMan.dest_dir := 'c:\mydir'; // destination dir for extract
|
|
|
|
Resource1.ArchiveMan.ExtractList(List: TList; var files_extracted, extracted_size: integer);
|
|
|
|
List is a TList of TCentralFileHeader.
|
|
The CentralFileHeader is gotten from Resource1.ArchiveMan.ArchiveFile.CentralDir[i],
|
|
where i is the index of the file.
|
|
So to add file index 2 to the extract list, call
|
|
List.Add(Resource1.ArchiveMan.ArchiveFile.CentralDir[2]);
|
|
Then call ExtractList(List, a, b)
|
|
The files_extracted and extracted_size are returned values.
|
|
|
|
To Delete files:
|
|
Resource1.ArchiveMan.DeleteFiles
|
|
All files that are flagged for deletion are removed.
|
|
To flag a file for delete, set the Delete property in its CentralFileHeader entry.
|
|
e.g. to delete file of index 2 and 5,
|
|
Resource1.ArchiveMan.ArchiveFile.CentralDir[2].Deleted := true; // flag
|
|
Resource1.ArchiveMan.ArchiveFile.CentralDir[5].Deleted := true; // flag
|
|
Resource1.ArchiveMan.DeleteFiles; // actual process
|
|
|
|
|
|
|
|
EVENTS:
|
|
OnCentralDirChange
|
|
- called when Resource1.ArchiveMan.ArchiveFile.CentralDir changes.
|
|
use it to update the list of files in the archive.
|
|
OnAddLog (for debugging)
|
|
- called when ArchiveMan outputs verbose information on what it is doing.
|
|
mainly used for debugging.
|
|
}
|
|
|
|
interface
|
|
|
|
uses
|
|
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
|
|
{CG}
|
|
ArchiveManagerUnit, ArchiveHeadersUnit, StructsUnit;
|
|
|
|
type
|
|
TResource = class(TComponent)
|
|
private
|
|
{function GetOnShowStatusMsg: TStrEvent;
|
|
procedure SetOnShowStatusMsg(const Value: TStrEvent);}
|
|
function GetOnCentralDirChange: TNotifyEvent;
|
|
procedure SetOnCentralDirChange(const Value: TNotifyEvent);
|
|
function GetOnAddLog: TStrEvent;
|
|
procedure SetOnAddLog(const Value: TStrEvent);
|
|
protected
|
|
FArchiveMan: TArchiveManager;
|
|
public
|
|
property ArchiveMan: TArchiveManager read FArchiveMan;
|
|
constructor Create(AOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
|
|
{Wrapper for ArchiveMan.
|
|
To work on one file in one archive
|
|
NOTE:
|
|
- These do not require an archive to be opened. They can be called
|
|
'immediately'.
|
|
- Do not call ArchiveMan.OpenArchive when you use these procedures.
|
|
|
|
See Help above for description.
|
|
|
|
CompressToArchive:
|
|
SourceFileNamePath - File to compress
|
|
ArchiveNamePath - Archive to add to.
|
|
If it exists, the file will be Added to the existing archive.
|
|
|
|
DecompressFromArchive:
|
|
ArchiveNamePath - Full path to archive file
|
|
DestPath - Destination dir to extract files to
|
|
FileName - the name of the file to extract. Leave blank to extract all files (Default)
|
|
}
|
|
procedure CompressToArchive(SourceFileNamePath, ArchiveNamePath: string);
|
|
procedure DecompressFromArchive(ArchiveNamePath, DestPath: string; ExtractFileName: string = '');
|
|
|
|
published
|
|
property OnCentralDirChange: TNotifyEvent read GetOnCentralDirChange write SetOnCentralDirChange;
|
|
//property OnShowStatusMsg: TStrEvent read GetOnShowStatusMsg write SetOnShowStatusMsg;
|
|
property OnAddLog: TStrEvent read GetOnAddLog write SetOnAddLog;
|
|
end;
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
procedure Register;
|
|
begin
|
|
RegisterComponents('Compression', [TResource]);
|
|
end;
|
|
|
|
|
|
{ TResource }
|
|
|
|
|
|
constructor TResource.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
{if not (csDesigning in ComponentState) then
|
|
begin}
|
|
FArchiveMan := TArchiveManager.Create;
|
|
{end;}
|
|
end;
|
|
|
|
|
|
|
|
destructor TResource.Destroy;
|
|
begin
|
|
if Assigned(FArchiveMan) then FArchiveMan.Free;
|
|
inherited;
|
|
end;
|
|
|
|
function TResource.GetOnAddLog: TStrEvent;
|
|
begin
|
|
result := FArchiveMan.OnAddLog;
|
|
end;
|
|
|
|
function TResource.GetOnCentralDirChange: TNotifyEvent;
|
|
begin
|
|
result := FArchiveMan.OnCentralDirChange;
|
|
end;
|
|
|
|
{function TResource.GetOnShowStatusMsg: TStrEvent;
|
|
begin
|
|
result := FArchiveMan.OnShowStatusMsg;
|
|
end;}
|
|
|
|
procedure TResource.SetOnAddLog(const Value: TStrEvent);
|
|
begin
|
|
FArchiveMan.OnAddLog := Value;
|
|
end;
|
|
|
|
procedure TResource.SetOnCentralDirChange(const Value: TNotifyEvent);
|
|
begin
|
|
FArchiveMan.OnCentralDirChange := Value;
|
|
end;
|
|
|
|
{procedure TResource.SetOnShowStatusMsg(const Value: TStrEvent);
|
|
begin
|
|
FArchiveMan.OnShowStatusMsg := Value;
|
|
end;}
|
|
|
|
{-------------------------------------------------------------------------------
|
|
CompressToArchive
|
|
-------------------------------------------------------------------------------}
|
|
procedure TResource.CompressToArchive(SourceFileNamePath,
|
|
ArchiveNamePath: string);
|
|
var
|
|
FilesAdded: integer;
|
|
list: TStringList;
|
|
begin
|
|
{Algorithm:
|
|
Open Archive
|
|
Add the file
|
|
Close Archive}
|
|
if ArchiveMan.IsArchiveOpen then
|
|
begin
|
|
{Error Check: Cannot use when Archive is opened.
|
|
We will open and close the Archive ourselves}
|
|
Application.MessageBox('reSource: ArchiveMan cannot be opened to use CompressToArchive',
|
|
'Error', MB_OK);
|
|
exit;
|
|
end;
|
|
|
|
{ Step 1: Open Archive }
|
|
ArchiveMan.OpenArchive(ArchiveNamePath, false);
|
|
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
{ Step 2: Add the file }
|
|
// Construct a TStringList of files to add
|
|
// We pass a nil in the folder because the full path is in list
|
|
list := TStringList.Create;
|
|
list.Add(SourceFileNamePath);
|
|
FilesAdded := ArchiveMan.AddFiles(list, '');
|
|
if (FilesAdded = 0) then
|
|
begin
|
|
Application.MessageBox('reSource.CompressToArchive: Error No Files Added',
|
|
'Error', MB_OK);
|
|
exit;
|
|
end
|
|
else
|
|
begin
|
|
Application.MessageBox('reSource.CompressToArchive: One file added to archive.',
|
|
'Error', MB_OK);
|
|
exit;
|
|
end;
|
|
|
|
finally
|
|
{ Step 3: Close the archive }
|
|
if ArchiveMan.IsArchiveOpen then
|
|
ArchiveMan.CloseArchive;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
{-------------------------------------------------------------------------------
|
|
DecompressFromArchive
|
|
-------------------------------------------------------------------------------}
|
|
procedure TResource.DecompressFromArchive(ArchiveNamePath, DestPath: string;
|
|
ExtractFileName: string='');
|
|
var
|
|
CFH: TCentralFileHeader;
|
|
i, FilesExtracted, ExtractedSize: integer;
|
|
CFHList: TList;
|
|
begin
|
|
{Algorithm
|
|
Check that the Archive exists before calling this.
|
|
Open Archive
|
|
if FileName <> '' then
|
|
search for FileName and extract one file
|
|
else
|
|
extract all files in archive
|
|
Close Archive
|
|
}
|
|
|
|
FilesExtracted := 0;
|
|
ExtractedSize := 0;
|
|
|
|
if not FileExists(ArchiveNamePath) then
|
|
begin
|
|
Application.MessageBox('reSource.DecompressFromArchive: Archive file does not exist.',
|
|
'Error', MB_OK);
|
|
exit;
|
|
end;
|
|
|
|
ArchiveMan.OpenArchive(ArchiveNamePath, true);
|
|
Screen.Cursor := crHourGlass;
|
|
try
|
|
with ArchiveMan.ArchiveFile do
|
|
begin
|
|
ArchiveMan.dest_dir := IncludeTrailingBackslash(DestPath);
|
|
{Search for file name in CentralFileHeader}
|
|
if ExtractFileName <> '' then
|
|
begin
|
|
for i := 0 to CentralDir.Count-1 do
|
|
begin
|
|
CFH := TCentralFileHeader(CentralDir[i]);
|
|
if CompareText(CFH.filename, ExtractFileName) = 0 then
|
|
begin
|
|
{Construct a CFHList with one CentralFileHeader (CFH) }
|
|
CFHList := TList.Create;
|
|
CFHList.Add(CFH);
|
|
ArchiveMan.ExtractList(CFHList, FilesExtracted, ExtractedSize);
|
|
CFHList.Free;
|
|
break;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
{extract all files in archive.
|
|
Add all the CentralDir CFH into CFHList}
|
|
CFHList := TList.Create;
|
|
for i := 0 to CentralDir.Count-1 do
|
|
CFHList.Add(TCentralFileHeader(CentralDir[i]));
|
|
ArchiveMan.ExtractList(CFHList, FilesExtracted, ExtractedSize);
|
|
CFHList.Free;
|
|
end;
|
|
end;
|
|
|
|
if FilesExtracted = 0 then
|
|
ShowMessage('Error: No files extracted')
|
|
else
|
|
ShowMessage(IntToStr(FilesExtracted)+' file(s) extracted');
|
|
|
|
finally
|
|
if ArchiveMan.IsArchiveOpen then
|
|
ArchiveMan.CloseArchive;
|
|
Screen.Cursor := crDefault;
|
|
end;
|
|
end;
|
|
|
|
|
|
end.
|