AsphyreArchives.pas
上传用户:ctlcnc
上传日期:2021-12-10
资源大小:4933k
文件大小:9k
源码类别:

2D图形编程

开发平台:

Delphi

  1. unit AsphyreArchives;
  2. //---------------------------------------------------------------------------
  3. interface
  4. //---------------------------------------------------------------------------
  5. uses
  6.  Classes, SysUtils, AsphyreAsserts, MediaUtils;
  7. //---------------------------------------------------------------------------
  8. type
  9.  TAsphyreArchiveID = string[8];
  10. //---------------------------------------------------------------------------
  11.  TAsphyreArchiveAttribute = (aaNoExtractToMem);
  12.  TAsphyreArchiveAttributes = set of TAsphyreArchiveAttribute;
  13. //---------------------------------------------------------------------------
  14.  TAsphyreCustomArchive = class
  15.  private
  16.   FArchiveName: string;
  17.  protected
  18.   FAttributes: TAsphyreArchiveAttributes;
  19.   function GetItemCount(): Integer; virtual; abstract;
  20.   function GetItemName(Num: Integer): string; virtual; abstract;
  21.   function OpenArchive(const FileName: string): Boolean; virtual; abstract;
  22.   procedure CloseArchive(); virtual; abstract;
  23.   procedure DoCreate(); virtual; abstract;
  24.  public
  25.   property Attributes: TAsphyreArchiveAttributes read FAttributes;
  26.   property ArchiveName: string read FArchiveName;
  27.   property ItemCount: Integer read GetItemCount;
  28.   property ItemName[Num: Integer]: string read GetItemName;
  29.   function Open(const Name: string): Boolean;
  30.   procedure Close();
  31.   function ExtractToDisk(const ItemName,
  32.    DestPath: string): Boolean; virtual; abstract;
  33.   function ExtractToStream(const ItemName: string;
  34.    Stream: TStream): Boolean; virtual; abstract;
  35.   constructor Create(); 
  36.   destructor Destroy(); override;
  37.  end;
  38. //---------------------------------------------------------------------------
  39.  TAsphyreArchiver = class of TAsphyreCustomArchive;
  40. //---------------------------------------------------------------------------
  41.  TArchiveAssociation = record
  42.   Extension: string;
  43.   Archive  : TAsphyreCustomArchive;
  44.  end;
  45. //---------------------------------------------------------------------------
  46.  TAsphyreArchiveManager = class
  47.  private
  48.   Archives: array of TAsphyreCustomArchive;
  49.   Associations: array of TArchiveAssociation;
  50.   function FindInstance(const Archiver: TAsphyreArchiver): Integer;
  51.   function IncludeArchiver(const Archiver: TAsphyreArchiver): TAsphyreCustomArchive;
  52.   function FindExtension(const Extension: string): Integer;
  53.   procedure RemoveAssociation(AsIndex: Integer);
  54.   procedure ReleaseArchives();
  55.  public
  56.   // Registers a new extension/archiver combination.
  57.   function RegisterExt(const Extension: string;
  58.    Archiver: TAsphyreArchiver): Boolean;
  59.   // Unregisters the specified extension.
  60.   procedure UnregisterExt(const Extension: string);
  61.   // Finds the archive associated with the given extension.
  62.   function AssociatedArchive(const Extension: string): TAsphyreCustomArchive;
  63.   // Checks whether the archiver can only extract to disk.
  64.   function ShouldUseDisk(const Link: string): Boolean;
  65.   function ExtractToDisk(const Link, DestPath: string): Boolean;
  66.   function ExtractToStream(const Link: string; Stream: TStream): Boolean;
  67.   destructor Destroy(); override;
  68.  end;
  69. //---------------------------------------------------------------------------
  70. var
  71.  ArchiveManager: TAsphyreArchiveManager = nil;
  72. //---------------------------------------------------------------------------
  73. implementation
  74. //---------------------------------------------------------------------------
  75. constructor TAsphyreCustomArchive.Create();
  76. begin
  77.  inherited;
  78.  DoCreate();
  79. end;
  80. //---------------------------------------------------------------------------
  81. destructor TAsphyreCustomArchive.Destroy();
  82. begin
  83.  if (FArchiveName <> '') then
  84.   begin
  85.    CloseArchive();
  86.    FArchiveName:= '';
  87.   end;
  88.  
  89.  inherited;
  90. end;
  91. //---------------------------------------------------------------------------
  92. function TAsphyreCustomArchive.Open(const Name: string): Boolean;
  93. begin
  94.  if (LowerCase(FArchiveName) <> LowerCase(Name)) then
  95.   begin
  96.    Result:= OpenArchive(Name);
  97.    if (Result) then FArchiveName:= Name else FArchiveName:= '';
  98.   end else Result:= True;
  99. end;
  100. //---------------------------------------------------------------------------
  101. procedure TAsphyreCustomArchive.Close();
  102. begin
  103.  if (FArchiveName <> '') then CloseArchive();
  104.  FArchiveName:= '';
  105. end;
  106. //---------------------------------------------------------------------------
  107. destructor TAsphyreArchiveManager.Destroy();
  108. begin
  109.  ReleaseArchives();
  110.  inherited;
  111. end;
  112. //---------------------------------------------------------------------------
  113. procedure TAsphyreArchiveManager.ReleaseArchives();
  114. var
  115.  i: Integer;
  116. begin
  117.  for i:= 0 to Length(Archives) - 1 do
  118.   if (Archives[i] <> nil) then
  119.    begin
  120.     Archives[i].Free();
  121.     Archives[i]:= nil;
  122.    end;
  123.  SetLength(Archives, 0);  
  124. end;
  125. //---------------------------------------------------------------------------
  126. function TAsphyreArchiveManager.FindInstance(
  127.  const Archiver: TAsphyreArchiver): Integer;
  128. var
  129.  i: Integer;
  130. begin
  131.  Result:= -1;
  132.  for i:= 0 to Length(Archives) - 1 do
  133.   if (Archives[i] is Archiver) then
  134.    begin
  135.     Result:= i;
  136.     Break;
  137.    end;
  138. end;
  139. //---------------------------------------------------------------------------
  140. function TAsphyreArchiveManager.IncludeArchiver(
  141.  const Archiver: TAsphyreArchiver): TAsphyreCustomArchive;
  142. var
  143.  Index: Integer;
  144. begin
  145.  Index:= FindInstance(Archiver);
  146.  if (Index = -1) then
  147.   begin
  148.    Index:= Length(Archives);
  149.    SetLength(Archives, Index + 1);
  150.    Archives[Index]:= Archiver.Create();
  151.   end;
  152.  Result:= Archives[Index];
  153. end;
  154. //---------------------------------------------------------------------------
  155. function TAsphyreArchiveManager.FindExtension(const Extension: string): Integer;
  156. var
  157.  i: Integer;
  158. begin
  159.  Result:= -1;
  160.  for i:= 0 to Length(Associations) - 1 do
  161.   if (Associations[i].Extension = Extension) then
  162.    begin
  163.     Result:= i;
  164.     Break;
  165.    end;
  166. end;
  167. //---------------------------------------------------------------------------
  168. function TAsphyreArchiveManager.RegisterExt(const Extension: string;
  169.  Archiver: TAsphyreArchiver): Boolean;
  170. var
  171.  AsIndex: Integer;
  172. begin
  173.  AsIndex:= FindExtension(LowerCase(Extension));
  174.  Result:= (AsIndex = -1);
  175.  if (not Result) then Exit;
  176.  AsIndex:= Length(Associations);
  177.  SetLength(Associations, AsIndex + 1);
  178.  Associations[AsIndex].Extension:= LowerCase(Extension);
  179.  Associations[AsIndex].Archive  := IncludeArchiver(Archiver);
  180. end;
  181. //---------------------------------------------------------------------------
  182. procedure TAsphyreArchiveManager.RemoveAssociation(AsIndex: Integer);
  183. var
  184.  i: Integer;
  185. begin
  186.  for i:= AsIndex to Length(Associations) - 2 do
  187.   Associations[i]:= Associations[i + 1];
  188.  SetLength(Associations, Length(Associations) - 1);
  189. end;
  190. //---------------------------------------------------------------------------
  191. procedure TAsphyreArchiveManager.UnregisterExt(const Extension: string);
  192. var
  193.  AsIndex: Integer;
  194. begin
  195.  AsIndex:= FindExtension(LowerCase(Extension));
  196.  if (AsIndex <> -1) then RemoveAssociation(AsIndex);
  197. end;
  198. //---------------------------------------------------------------------------
  199. function TAsphyreArchiveManager.AssociatedArchive(
  200.  const Extension: string): TAsphyreCustomArchive;
  201. var
  202.  Index: Integer;
  203. begin
  204.  Result:= nil;
  205.  Index:= FindExtension(LowerCase(Extension));
  206.  if (Index <> -1) then Result:= Associations[Index].Archive;
  207. end;
  208. //---------------------------------------------------------------------------
  209. function TAsphyreArchiveManager.ShouldUseDisk(const Link: string): Boolean;
  210. var
  211.  Archive: TAsphyreCustomArchive;
  212. begin
  213.  Result:= True;
  214.  Archive:= AssociatedArchive(ExtractFileExt(ExtractArchiveName(Link)));
  215.  Assert(Archive <> nil, msgUnknownArchive);
  216.  if (Archive <> nil) then
  217.   Result:= aaNoExtractToMem in Archive.Attributes;
  218. end;
  219. //---------------------------------------------------------------------------
  220. function TAsphyreArchiveManager.ExtractToDisk(const Link,
  221.  DestPath: string): Boolean;
  222. var
  223.  Archive: TAsphyreCustomArchive;
  224.  ArchiveName: string;
  225. begin
  226.  Result:= False;
  227.  ArchiveName:= ExtractArchiveName(Link);
  228.  Archive:= AssociatedArchive(ExtractFileExt(ArchiveName));
  229.  Assert(Archive <> nil, msgUnknownArchive);
  230.  if (Archive <> nil) then
  231.   begin
  232.    Result:= Archive.OpenArchive(ArchiveName);
  233.    if (Result) then
  234.     Result:= Archive.ExtractToDisk(ExtractArchiveKey(Link), DestPath);
  235.   end;
  236. end;
  237. //---------------------------------------------------------------------------
  238. function TAsphyreArchiveManager.ExtractToStream(const Link: string;
  239.  Stream: TStream): Boolean;
  240. var
  241.  Archive: TAsphyreCustomArchive;
  242.  ArchiveName: string;
  243. begin
  244.  Result:= False;
  245.  ArchiveName:= ExtractArchiveName(Link);
  246.  Archive:= AssociatedArchive(ExtractFileExt(ArchiveName));
  247.  Assert(Archive <> nil, msgUnknownArchive);
  248.  if (Archive <> nil) then
  249.   begin
  250.    Result:= Archive.OpenArchive(ArchiveName);
  251.    if (Result) then
  252.     Result:= Archive.ExtractToStream(ExtractArchiveKey(Link), Stream);
  253.   end;
  254. end;
  255. //---------------------------------------------------------------------------
  256. initialization
  257.  ArchiveManager:= TAsphyreArchiveManager.Create();
  258. //---------------------------------------------------------------------------
  259. finalization
  260.  ArchiveManager.Free();
  261.  ArchiveManager:= nil;
  262. //---------------------------------------------------------------------------
  263. end.