unit _FileTypes; interface uses TypeDefs, _TreeElement, Classes, Forms, _DataTypes; type TRawCache = record DatOffset: Integer; RawStream: TMemoryStream; end; TResource = class(TTreeElement) protected FFileInfo: TFileInfo; FFileStream: TMemoryStream; FRawCaches: array of TRawCache; FCached: Boolean; FChanged: Boolean; FReplaced: Boolean; FDataFields: TBlock; FEditor: TFrame; FOpened: Boolean; function GetChildCount: Integer; override; function GetChild(ID: Integer): TTreeElement; override; function GetCaption: String; override; function GetType: String; override; function GetEditor: TFrame; function GetFieldByOffset(Offset: Integer): TDataField; function GetRawCacheID(Offset: Integer): Integer; procedure SetOpened(Opened: Boolean); virtual; published public constructor Create(ConnectionID, FileID: Integer); virtual; procedure Free; procedure InitDataFields; virtual; procedure InitEditor; virtual; procedure ReCreateFile(fs: TStream); procedure CacheFile; procedure CacheRawFile(Offset: Integer); procedure CacheAllRawFiles; procedure DiscardFileCache; procedure DiscardRawCache(Offset: Integer); procedure DiscardAllRawCaches; procedure StoreFileCache; procedure StoreRawCache(Offset: Integer); procedure StoreAllRawCaches; property FileStream: TMemoryStream read FFileStream; property FileInfo: TFileInfo read FFileInfo; property Cached: Boolean read FCached; property Changed: Boolean read FChanged write FChanged; property Editor: TFrame read GetEditor; property Opened: Boolean read FOpened write SetOpened; property FieldByOffset[Offset: Integer]: TDataField read GetFieldByOffset; end; type TFileType = class of TResource; implementation uses DatLinks, RawList, ConnectionManager, Dialogs, _MetaTypes, _MetaManager, SysUtils; { TFileType } procedure TResource.CacheFile; begin if not Assigned(FFileStream) then begin FFileStream := TMemoryStream.Create; ConManager.Connection[FConnectionID].LoadDatFile(FFileInfo.ID, TStream(FFileStream)); end; end; procedure TResource.CacheRawFile(Offset: Integer); var i: Integer; begin for i := 0 to High(FRawCaches) do begin if FRawCaches[i].DatOffset = Offset then begin if not Assigned(FRawCaches[i].RawStream) then begin FRawCaches[i].RawStream := TMemoryStream.Create; ConManager.Connection[ConnectionID].LoadRawFile(FFileInfo.ID, Offset, TStream(FRawCaches[i].RawStream)); end; end; end; end; procedure TResource.CacheAllRawFiles; var i: Integer; begin for i := 0 to High(FRawCaches) do CacheRawFile(FRawCaches[i].DatOffset); end; procedure TResource.DiscardFileCache; begin if Assigned(FFileStream) then FFileStream.Free; FFileStream := nil; end; procedure TResource.DiscardRawCache(Offset: Integer); var i: Integer; begin for i := 0 to High(FRawCaches) do begin if FRawCaches[i].DatOffset = Offset then begin if Assigned(FRawCaches[i].RawStream) then FRawCaches[i].RawStream.Free; FRawCaches[i].RawStream := nil; end; end; end; procedure TResource.DiscardAllRawCaches; var i: Integer; begin for i := 0 to High(FRawCaches) do DiscardRawCache(FRawCaches[i].DatOffset); end; procedure TResource.StoreFileCache; begin Exit; end; procedure TResource.StoreRawCache(Offset: Integer); begin Exit; end; procedure TResource.StoreAllRawCaches; var i: Integer; begin for i := 0 to High(FRawCaches) do StoreRawCache(FRawCaches[i].DatOffset); end; procedure TResource.SetOpened(Opened: Boolean); begin FOpened := Opened; end; constructor TResource.Create(ConnectionID, FileID: Integer); var rawlist: TRawDataList; i: Integer; begin FConnectionID := ConnectionID; FFileInfo := ConManager.Connection[ConnectionID].GetFileInfo(FileID); rawlist := ConManager.Connection[ConnectionID].GetRawList(FileID); SetLength(FRawCaches, Length(rawlist)); for i := 0 to High(rawlist) do FRawCaches[i].DatOffset := rawlist[i].SrcOffset; FCached := False; FChanged := False; FDataFields := nil; FEditor := nil; if not (Self is TFile_Empty) then InitDataFields; end; procedure TResource.Free; begin FDataFields.Free; end; function TResource.GetFieldByOffset(Offset: Integer): TDataField; begin Result := FDataFields.FieldByOffset[Offset]; end; function TResource.GetRawCacheID(Offset: Integer): Integer; var i: Integer; begin Result := -1; for i := 0 to High(FRawCaches) do if FRawCaches[i].DatOffset = Offset then Result := i; end; function TResource.GetType: String; begin Result := FFileInfo.Extension; end; function TResource.GetCaption: String; begin Result := FFileInfo.Name; if Result = '' then Result := 'Unnamed'; Result := Result + ' (' + IntToStr(FFileInfo.ID) + ')'; end; function TResource.GetChild(ID: Integer): TTreeElement; begin Result := FDataFields.Child[ID]; end; function TResource.GetChildCount: Integer; begin if FDataFields <> nil then Result := FDataFields.ChildCount else Result := 0; end; function TResource.GetEditor: TFrame; begin if not Assigned(FEditor) then InitEditor; Result := FEditor; end; procedure TResource.InitDataFields; begin if Assigned(FDataFields) then Exit; FFileStream := TMemoryStream.Create; ConManager.Connection[FConnectionID].LoadDatFile(FFileInfo.ID, TStream(FFileStream)); end; procedure TResource.InitEditor; begin Exit; end; //********************************************************* //********************************************************* //********************************************************* procedure TResource.ReCreateFile(fs: TStream); const temp0: array[0..31] of Byte = ($AD,$DE,$AD,$DE,$AD,$DE,$AD,$DE, $AD,$DE,$AD,$DE,$AD,$DE,$AD,$DE, $AD,$DE,$AD,$DE,$AD,$DE,$AD,$DE, $AD,$DE,$AD,$DE,$AD,$DE,$AD,$DE); var count: Integer; begin FDataFields.WriteData(fs); count := fs.Size mod 32; if count > 0 then fs.Write(temp0[count], 32 - count); end; //********************************************************* //********************************************************* //********************************************************* end.