ViewVC Help
View File | Revision Log | View Changeset | Root Listing
root/Oni2/oup/current/DataAccess/Access_OniArchive.pas
(Generate patch)

Comparing:
oup/rewrite/DataAccess/Access_OniArchive.pas (file contents), Revision 93 by alloc, Thu Jan 18 17:15:59 2007 UTC vs.
oup/current/DataAccess/Access_OniArchive.pas (file contents), Revision 113 by alloc, Sun Feb 25 17:20:22 2007 UTC

# Line 1 | Line 1
1   unit Access_OniArchive;
2   interface
3  
4 < uses DataAccess, Classes;
4 > uses DataAccess, Classes, TypeDefs;
5  
6   type
7 {
8  THeader = packed record
9    Ident:      array[0..$13] of Byte;
10    Files:      LongWord;
11    NamedFiles: LongWord;
12    Extensions: LongWord;
13    DataAddr:   LongWord;
14    DataSize:   LongWord;
15    NamesAddr:  LongWord;
16    NamesSize:  LongWord;
17    Ident2:     array[0..$F] of Byte;
18  end;
19  TFilesMap = array of packed record
20    Extension: array[0..$3] of Char;
21    DataAddr:  LongWord;
22    NameAddr:  LongWord;
23    FileSize:  LongWord;
24    FileType:  LongWord;
25  end;
26
27  TFileInfo = packed record
28    ID:      Integer;
29    FileName: String;
30    FileNameHex: String;
31    Extension: String[4];
32    Name:    String;
33    Size:    LongWord;
34    FileType: LongWord;
35    DatAddr: LongWord;
36    opened:  Boolean;
37  end;
38  TFiles = array of TFileInfo;
39
40  TNamedFilesMap = array of packed record
41    FileNumber: LongWord;
42    blubb:      LongWord;
43  end;
44  TExtensionsMap = array of packed record
45    Ident:     array[0..$7] of Byte;
46    Extension: array[0..$3] of Char;
47    ExtCount:  LongWord;
48  end;
49 }
50
7    TAccess_OniArchive = class(TDataAccess)
8    private
9 < {    Fdat_file:     TFileStream;
10 <    Fraw_file:     TFileStream;
11 <    Fsep_file:     TFileStream;
12 <    Fdat_header:   THeader;
13 <    Fdat_filesmap: TFilesMap;
14 <    Fdat_files:    TFiles;
15 <    Fdat_namedfilesmap: TNamedFilesMap;
16 <    Fdat_extensionsmap: TExtensionsMap;
17 <    FUnloadWhenUnused: Boolean;
62 <    FDatOpened:    Boolean;
63 <    FRawOpened:    Boolean;
64 <    FSepOpened:    Boolean;
9 >    Fdat_file:           TFileStream;
10 >    Fraw_file:           TFileStream;
11 >    Fsep_file:           TFileStream;
12 >    Fdat_files:          TFiles;
13 >    Fdat_extensionsmap:  TExtensionsMap;
14 >    FUnloadWhenUnused:   Boolean;
15 >    FDatOpened:          Boolean;
16 >    FRawOpened:          Boolean;
17 >    FSepOpened:          Boolean;
18    protected
19    public
20      property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write FUnloadWhenUnused;
21  
22 <    constructor Create(DatFilename: String; var Result: Boolean); override;
22 >    constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
23      procedure Close; override;
24  
25 <    function GetFileInfo(fileid: Integer): TFileInfo; override;
26 <    function GetFilesList(ext: String; pattern: String;
27 <      NoEmptyFiles: Boolean; sort: TSortType): TStringArray; override;
28 <    function GetFilesCount: LongWord; override;
29 <    function GetExtensionsList: TStringArray; override;
30 <    function GetExtendedExtensionsList: TExtensionsMap; override;
31 <
32 <    function LoadDatFile(fileid: LongWord): Tdata; override;
33 <    procedure UpdateDatFile(fileid: LongWord; Data: Tdata); override;
34 <    procedure LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
35 <    procedure UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer); override;
36 <
37 <    procedure LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord; target: Pointer);
38 <    function GetRawList(fileid: LongWord): TRawList; override;
39 <    procedure LoadRawFile(fileid, dat_offset: LongWord; target: Pointer); override;
40 <    procedure UpdateRawFile(fileid, dat_offset: LongWord; size: LongWord;
41 <      target: Pointer); override;
42 <    procedure LoadRawFilePart(fileid, dat_offset: LongWord;
43 <      offset, size: LongWord; target: Pointer); override;
44 <    procedure UpdateRawFilePart(fileid, dat_offset: LongWord;
45 <      offset, size: LongWord; target: Pointer); override;
46 <    function AppendRawFile(loc_sep: Boolean; size: LongWord; target: Pointer): LongWord;
94 <      override;//Returns new Address
25 >    function GetFileInfo(FileID: Integer): TFileInfo; override;
26 >    function GetFilesList(Ext: String; Pattern: String;
27 >      NoEmptyFiles: Boolean; SortType: TSortType): TStrings; override;
28 >    function GetFileCount: Integer; override;
29 >    function GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; override;
30 >
31 >    procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; override;
32 >    procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; override;
33 >    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override;
34 >    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override;
35 >
36 >    function GetDatLinks(FileID: Integer): TDatLinkList; override;
37 >    function GetRawList(FileID: Integer): TRawDataList; override;
38 >    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
39 >
40 >    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
41 >    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override;
42 >    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override;
43 >    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override;
44 >    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override;
45 >
46 >    function AppendRawFile(LocSep: Boolean; Src: TStream): Integer; overload; override;
47    published
48 < }  end;
48 >  end;
49  
50   implementation
51  
52 + uses
53 +  SysUtils, StrUtils, Data, Functions, RawList;
54 +
55  
56   (*
57   ================================================================================
58                        Implementation of  TOniDataDat
59   *)
60  
61 < {
62 < constructor TOniDataDat.Create(DatFilename: String; var Result: Boolean);
108 < const
109 <  header_ident1_pc: array[0..$13] of Byte =
110 <    ($1F, $27, $DC, $33, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
111 <    $14, $00, $10, $00, $08, $00);
112 <  header_ident1_mac: array[0..$13] of Byte =
113 <    ($61, $30, $C1, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
114 <    $14, $00, $10, $00, $08, $00);
115 <  header_ident1_macbeta: array[0..$13] of Byte =
116 <    ($81, $11, $8D, $23, $DF, $BC, $03, $00, $31, $33, $52, $56, $40, $00,
117 <    $14, $00, $10, $00, $08, $00);
118 <  header_ident2: array[0..$F] of Byte =
119 <    ($99, $CF, $40, $00, $90, $4F, $63, $00, $F4, $55, $5F, $00, $90, $4F, $63, $00);
61 >
62 > constructor TAccess_OniArchive.Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
63   var
64 <  i: LongWord;
65 <  header_pc, header_mac: Boolean;
64 >  i: Integer;
65 >  header_pc, header_mac, header_macbeta: Boolean;
66 >  Fdat_header:   THeader;
67 >  Fdat_filesmap: TFilesMap;
68 >  Fdat_namedfilesmap: TNamedFilesMap;
69   begin
70    FUnloadWhenUnused := True;
71    FDatOpened := False;
72    FRawOpened := False;
73 +  Msg := SM_UnknownError;
74    if not FileExists(DatFilename) then
75    begin
76 <    ShowMessage('File doesn''t exist!!!');
130 <    Result := False;
76 >    Msg := SM_FileNotFound;
77      Exit;
78    end;
79    FFileName := DatFilename;
# Line 135 | Line 81 | begin
81    Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
82    header_pc  := True;
83    header_mac := True;
84 <  for i := 0 to High(Fdat_header.Ident) do
84 >  header_macbeta := True;
85 >  for i := 0 to High(Fdat_header.GlobalIdent) do
86 >    if Fdat_header.GlobalIdent[i] <> HeaderGlobalIdent[i] then
87 >    begin
88 >      Msg := SM_IncompatibleFile;
89 >      Exit;
90 >    end;
91 >
92 >  for i := 0 to High(Fdat_header.OSIdent) do
93    begin
94 <    FLevelInfo.Ident[i] := Fdat_header.Ident[i];
141 <    if Fdat_header.Ident[i] <> header_ident1_pc[i] then
94 >    if Fdat_header.OSIdent[i] <> HeaderOSIdentWin[i] then
95        header_pc := False;
96 <    if Fdat_header.Ident[i] <> header_ident1_mac[i] then
96 >    if Fdat_header.OSIdent[i] <> HeaderOSIdentMac[i] then
97        header_mac := False;
98 +    if Fdat_header.OSIdent[i] <> HeaderOSIdentMacBeta[i] then
99 +      header_macbeta := False;
100    end;
101 <  if not (header_pc xor header_mac) then
101 >  if not (header_pc xor header_mac xor header_macbeta) then
102    begin
103 <    Result := False;
103 >    Msg := SM_IncompatibleFile;
104      Exit;
105    end
106    else
107    begin
108 <    if (header_pc and not header_mac) then
109 <      Fos_mac := False
110 <    else
111 <      Fos_mac := True;
108 >    if (header_pc and not header_mac and not header_macbeta) then
109 >      FDataOS := DOS_WIN
110 >    else if (not header_pc and header_mac and not header_macbeta) then
111 >      FDataOS := DOS_MAC
112 >    else if (not header_pc and not header_mac and header_macbeta) then
113 >      FDataOS := DOS_MACBETA;
114    end;
115    SetLength(Fdat_filesmap, Fdat_header.Files);
116    SetLength(Fdat_files, Fdat_header.Files);
# Line 179 | Line 136 | begin
136      begin
137        Fdat_files[i].Name := '';
138      end;
182    Fdat_files[i].FileName    :=
183      FormatNumber(i, 5, '0') + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
184    Fdat_files[i].FileNameHex :=
185      IntToHex(i, 4) + '-' + Fdat_files[i].Name + '.' + Fdat_files[i].Extension;
139    end;
140    Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
141    SetLength(Fdat_namedfilesmap, Fdat_header.NamedFiles);
# Line 195 | Line 148 | begin
148      Fdat_file.Read(Fdat_extensionsmap[i], SizeOf(Fdat_extensionsmap[i]));
149  
150    Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
151 <  Fdat_file.Read(FLevelInfo.LevelNumber, 1);
152 <  FLevelInfo.LevelNumber := FLevelInfo.LevelNumber div 2;
151 >  Fdat_file.Read(FLevelNumber, 1);
152 >  FLevelNumber := FLevelNumber div 2;
153  
154    Fdat_file.Free;
155  
156 <  Result   := True;
157 <  FBackend := ODB_Dat;
156 >  Msg := SM_OK;
157 >  FBackend := DB_ONI;
158 >  FConnectionID := ConnectionID;
159 >  FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
160   end;
161  
162  
163  
164  
165 < procedure TOniDataDat.Close;
165 > procedure TAccess_OniArchive.Close;
166   begin
167 <  if not FUnloadWhenUnused and FDatOpened then
167 >  if FDatOpened then
168      Fdat_file.Free;
169 <  if not FUnloadWhenUnused and FRawOpened then
169 >  if FRawOpened then
170      Fraw_file.Free;
171 <  if not FUnloadWhenUnused and FSepOpened then
171 >  if FSepOpened then
172      Fsep_file.Free;
173    Self.Free;
174   end;
# Line 221 | Line 176 | end;
176  
177  
178  
179 < function TOniDataDat.GetFileInfo(fileid: Integer): TFileInfo;
179 > function TAccess_OniArchive.GetFileInfo(fileid: Integer): TFileInfo;
180   begin
181    if fileid = -1 then
182    begin
183      Result := inherited GetFileInfo(fileid);
184      Exit;
185    end;
186 <  if fileid < Self.GetFilesCount then
186 >  if fileid < Self.GetFileCount then
187      Result    := Fdat_files[fileid]
188    else
189      Result.ID := -1;
# Line 237 | Line 192 | end;
192  
193  
194  
195 < function TOniDataDat.GetFilesList(ext: String; pattern: String;
196 <  NoEmptyFiles: Boolean; sort: TSortType): TStringArray;
195 > function TAccess_OniArchive.GetFilesList(ext: String; pattern: String;
196 >  NoEmptyFiles: Boolean; SortType: TSortType): TStrings;
197   var
198 <  i: LongWord;
199 <  list: TStringList;
198 >  i:      Integer;
199 >  list:   TStringList;
200    id, name, extension: String;
201    fields: TStrings;
202  
203    procedure getfields;
204    begin
205 <     fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
206 <    if sort in [stIDAsc, stIDDesc] then
205 >    fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
206 >    if SortType in [ST_IDAsc, ST_IDDesc] then
207      begin
208        id := fields.Strings[0];
209        name := fields.Strings[1];
210        extension := fields.Strings[2];
211      end;
212 <    if sort in [stNameAsc, stNameDesc] then
212 >    if SortType in [ST_NameAsc, ST_NameDesc] then
213      begin
214        id := fields.Strings[1];
215        name := fields.Strings[0];
216        extension := fields.Strings[2];
217      end;
218 <    if sort in [stExtAsc, stExtDesc] then
218 >    if SortType in [ST_ExtAsc, ST_ExtDesc] then
219      begin
220        id := fields.Strings[1];
221        name := fields.Strings[2];
222        extension := fields.Strings[0];
223      end;
224 +    if SortType in [ST_ExtNameAsc, ST_ExtNameDesc] then
225 +    begin
226 +      id := fields.Strings[2];
227 +      name := fields.Strings[1];
228 +      extension := fields.Strings[0];
229 +    end;
230    end;
231  
232   begin
233    list := TStringList.Create;
234    list.Sorted := True;
235 <  for i := 0 to Fdat_header.Files - 1 do
235 >  for i := 0 to GetFileCount - 1 do
236    begin
237      if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
238        ((Length(pattern) = 0) or
# Line 279 | Line 240 | begin
240      begin
241        if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
242        begin
243 <        if AppSettings.FilenumbersAsHex then
283 <          id := IntToHex(Fdat_files[i].ID, 4)
284 <        else
285 <          id := FormatNumber(Fdat_files[i].ID, 5, '0');
243 >        id := FormatNumber(Fdat_files[i].ID, 5, '0');
244          name := Fdat_files[i].Name;
245          extension := Fdat_files[i].Extension;
246  
247 <        case sort of
248 <          stIDAsc, stIDDesc:     list.Add(id + ';' + name + ';' + extension);
249 <          stNameAsc, stNameDesc: list.Add(name + ';' + id + ';' + extension);
250 <          stExtAsc, stExtDesc:   list.Add(extension + ';' + id + ';' + name);
247 >        case SortType of
248 >          ST_IDAsc, ST_IDDesc:     list.Add(id + ';' + name + ';' + extension);
249 >          ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension);
250 >          ST_ExtAsc, ST_ExtDesc:   list.Add(extension + ';' + id + ';' + name);
251 >          ST_ExtNameAsc, ST_ExtNameDesc: list.Add(name + ';' + extension + ';' + id);
252          end;
253        end;
254      end;
255    end;
256 <  SetLength(Result, list.Count);
257 <  if Length(Result) > 0 then
256 >  if not Assigned(Result) then
257 >    Result := TStringList.Create;
258 >  if list.Count > 0 then
259    begin
260      fields := TStringList.Create;
261 <    if sort in [stIDAsc, stNameAsc, stExtAsc] then
261 >    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc, ST_ExtNameAsc] then
262        for i := 0 to list.Count - 1 do
263        begin
264          getfields;
265 <        Result[i] := id + '-' + name + '.' + extension;
265 >        Result.Add(id + '-' + name + '.' + extension);
266        end
267      else
268        for i := list.Count - 1 downto 0 do
269        begin
270          getfields;
271 <        Result[list.Count - i - 1] := id + '-' + name + '.' + extension;
271 >        Result.Add(id + '-' + name + '.' + extension);
272        end;
273      fields.Free;
274    end;
# Line 318 | Line 278 | end;
278  
279  
280  
281 < function TOniDataDat.GetFilesCount: LongWord;
281 > function TAccess_OniArchive.GetFileCount: Integer;
282   begin
283 <  Result := Fdat_header.Files;
283 >  Result := Length(Fdat_files);
284   end;
285  
286  
287  
288  
289 < function TOniDataDat.GetExtensionsList: TStringArray;
289 > function TAccess_OniArchive.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings;
290   var
291 <  i: LongWord;
291 >  i: Integer;
292   begin
293 <  SetLength(Result, Fdat_header.Extensions);
294 <  for i := 0 to Fdat_header.Extensions - 1 do
293 >  if not Assigned(Result) then
294 >    Result := TStringList.Create;
295 >  if Result is TStringList then
296 >    TStringList(Result).Sorted := True;
297 >  for i := 0 to Length(Fdat_extensionsmap) - 1 do
298    begin
299      with Fdat_extensionsmap[i] do
300      begin
301 <      Result[i] := Extension[3] + Extension[2] + Extension[1] + Extension[0] +
302 <        ' (' + IntToStr(ExtCount) + ')';
301 >      case ExtListFormat of
302 >        EF_ExtOnly:
303 >          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0]);
304 >        EF_ExtCount:
305 >          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0] +
306 >                ' (' + IntToStr(ExtCount) + ')');
307 >      end;
308      end;
309    end;
310   end;
311  
312  
313  
314 <
347 < function TOniDataDat.GetExtendedExtensionsList: TExtensionsMap;
314 > procedure TAccess_OniArchive.LoadDatFile(FileID: Integer; var Target: TStream);
315   var
316 <  i: LongWord;
316 >  streampos: Integer;
317   begin
318 <  SetLength(Result, Fdat_header.Extensions);
352 <  for i := 0 to Fdat_header.Extensions - 1 do
318 >  if fileid < GetFileCount then
319    begin
320 <    Result[i] := Fdat_extensionsmap[i];
321 <  end;
322 < end;
357 <
358 <
359 <
360 <
361 < function TOniDataDat.LoadDatFile(fileid: LongWord): Tdata;
362 < begin
363 <  if fileid < Self.GetFilesCount then
364 <  begin
365 <    if FUnloadWhenUnused or not FDatOpened then
320 >    if not Assigned(Target) then
321 >      Target := TMemoryStream.Create;
322 >    if not FDatOpened then
323        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
324      Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
325 <    SetLength(Result, Fdat_files[fileid].Size);
326 <    Fdat_file.Read(Result[0], Fdat_files[fileid].Size);
325 >    streampos := Target.Position;
326 >    Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
327 >    Target.Seek(streampos, soFromBeginning);
328      if UnloadWhenUnused then
329 <      Fdat_file.Free
329 >    begin
330 >      Fdat_file.Free;
331 >      FDatOpened := False;
332 >    end
333      else
334        FDatOpened := True;
335    end;
336   end;
337  
338 <
378 <
379 <
380 < procedure TOniDataDat.UpdateDatFile(fileid: LongWord; Data: Tdata);
338 > procedure TAccess_OniArchive.UpdateDatFile(FileID: Integer; Src: TStream);
339   begin
340 <  if fileid < Self.GetFilesCount then
340 >  if fileid < GetFileCount then
341    begin
342 <    if FUnloadWhenUnused or not FDatOpened then
342 >    if not FDatOpened then
343        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
344      Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
345 <    Fdat_file.Write(Data[0], Length(Data));
345 >    Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
346      if UnloadWhenUnused then
347 <      Fdat_file.Free
347 >    begin
348 >      Fdat_file.Free;
349 >      FDatOpened := False;
350 >    end
351      else
352        FDatOpened := True;
353    end;
354   end;
355  
356 <
357 <
358 <
398 < procedure TOniDataDat.LoadDatFilePart(fileid, offset, size: LongWord; target: Pointer);
356 > procedure TAccess_OniArchive.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream);
357 > var
358 >  streampos: Integer;
359   begin
360 <  if fileid < Self.GetFilesCount then
360 >  if fileid < GetFileCount then
361    begin
362 <    if FUnloadWhenUnused or not FDatOpened then
362 >    if not Assigned(Target) then
363 >      Target := TMemoryStream.Create;
364 >    if not FDatOpened then
365        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
366      Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
367 <    Fdat_file.Read(target^, size);
367 >    streampos := Target.Position;
368 >    Target.CopyFrom(Fdat_file, size);
369 >    Target.Seek(streampos, soFromBeginning);
370      if UnloadWhenUnused then
371 <      Fdat_file.Free
371 >    begin
372 >      FDatOpened := False;
373 >      Fdat_file.Free;
374 >    end
375      else
376        FDatOpened := True;
377    end;
378   end;
379  
380 <
414 <
415 <
416 < procedure TOniDataDat.UpdateDatFilePart(fileid, offset, size: LongWord; target: Pointer);
380 > procedure TAccess_OniArchive.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream);
381   begin
382 <  if fileid < Self.GetFilesCount then
382 >  if fileid < GetFileCount then
383    begin
384 <    if FUnloadWhenUnused or not FDatOpened then
384 >    if not FDatOpened then
385        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
386      Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
387 <    Fdat_file.Write(target^, size);
387 >    Fdat_file.CopyFrom(Src, Size);
388      if UnloadWhenUnused then
389 <      Fdat_file.Free
389 >    begin
390 >      Fdat_file.Free;
391 >      FDatOpened := False;
392 >    end
393      else
394        FDatOpened := True;
395    end;
# Line 430 | Line 397 | end;
397  
398  
399  
400 + function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
401 + begin
402 +  Result := RawLists.GetRawList(FConnectionID, FileID);
403 + end;
404 +
405  
406 < function TOniDataDat.GetRawList(fileid: LongWord): TRawList;
435 < var
436 <  i: LongWord;
406 > function TAccess_OniArchive.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
407   begin
408 <  SetLength(Result, 0);
439 <  for i := 0 to High(RawListHandlers) do
440 <    if UpperCase(RawListHandlers[i].Ext) = UpperCase(Fdat_files[fileid].extension) then
441 <      if RawListHandlers[i].needed then
442 <      begin
443 <        Result := RawListHandlers[i].Handler(Self, fileid);
444 <        Break;
445 <      end
446 <      else
447 <        Break;
408 >  Result := RawLists.GetRawInfo(FConnectionID, FileID, DatOffset);
409   end;
410  
411  
412  
413  
414 < procedure TOniDataDat.LoadRawOffset(loc_sep: Boolean; raw_addr, size: LongWord;
454 <  target: Pointer);
414 > procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
415   begin
416 <  if not loc_sep then
416 >  if not LocSep then
417    begin
418 <    if FUnloadWhenUnused or not FRawOpened then
418 >    if not FRawOpened then
419        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
420          fmOpenReadWrite);
421 <    if raw_addr <= Fraw_file.Size then
421 >    if RawAddr <= Fraw_file.Size then
422      begin
423 <      Fraw_file.Seek(raw_addr, soFromBeginning);
423 >      Fraw_file.Seek(RawAddr, soFromBeginning);
424        Fraw_file.Read(target^, size);
425      end;
426      if UnloadWhenUnused then
427 <      Fraw_file.Free
427 >    begin
428 >      FRawOpened := False;
429 >      Fraw_file.Free;
430 >    end
431      else
432        FRawOpened := True;
433    end
434    else
435    begin
436 <    if FUnloadWhenUnused or not FSepOpened then
436 >    if not FSepOpened then
437        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
438          fmOpenReadWrite);
439 <    if raw_addr <= Fsep_file.Size then
439 >    if RawAddr <= Fsep_file.Size then
440      begin
441 <      Fsep_file.Seek(raw_addr, soFromBeginning);
441 >      Fsep_file.Seek(RawAddr, soFromBeginning);
442        Fsep_file.Read(target^, size);
443      end;
444      if UnloadWhenUnused then
445 <      Fsep_file.Free
445 >    begin
446 >      FSepOpened := False;
447 >      Fsep_file.Free;
448 >    end
449      else
450        FSepOpened := True;
451    end;
452   end;
453  
454 <
489 <
490 <
491 < procedure TOniDataDat.LoadRawFile(fileid, dat_offset: LongWord; target: Pointer);
454 > procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
455   var
456 <  raw_info: TRawInfo;
456 >  raw_info: TRawDataInfo;
457 >  streampos: Integer;
458   begin
459 <  if fileid < Self.GetFilesCount then
459 >  if not Assigned(Target) then
460 >    Target := TMemoryStream.Create;
461 >  if fileid < GetFileCount then
462    begin
463 <    raw_info := Self.GetRawInfo(fileid, dat_offset);
464 <    if not raw_info.loc_sep then
463 >    raw_info := Self.GetRawInfo(FileID, DatOffset);
464 >    if not raw_info.LocSep then
465      begin
466 <      if FUnloadWhenUnused or not FRawOpened then
466 >      if not FRawOpened then
467          Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
468            fmOpenReadWrite);
469 <      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
470 <      Fraw_file.Read(target^, raw_info.raw_size);
469 >      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
470 >      streampos := Target.Position;
471 >      Target.CopyFrom(Fraw_file, raw_info.RawSize);
472 >      Target.Seek(streampos, soFromBeginning);
473        if UnloadWhenUnused then
474 <        Fraw_file.Free
474 >      begin
475 >        FRawOpened := False;
476 >        Fraw_file.Free;
477 >      end
478        else
479          FRawOpened := True;
480      end
# Line 512 | Line 483 | begin
483        if FUnloadWhenUnused or not FSepOpened then
484          Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
485            fmOpenReadWrite);
486 <      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
487 <      Fsep_file.Read(target^, raw_info.raw_size);
486 >      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
487 >      streampos := Target.Position;
488 >      Target.CopyFrom(Fsep_file, raw_info.RawSize);
489 >      Target.Seek(streampos, soFromBeginning);
490        if UnloadWhenUnused then
491 <        Fsep_file.Free
491 >      begin
492 >        FSepOpened := False;
493 >        Fsep_file.Free;
494 >      end
495        else
496          FSepOpened := True;
497      end;
498    end;
499   end;
500  
501 <
526 <
527 <
528 < procedure TOniDataDat.UpdateRawFile(fileid, dat_offset: LongWord;
529 <  size: LongWord; target: Pointer);
501 > procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
502   var
503 <  raw_info: TRawInfo;
503 >  raw_info: TRawDataInfo;
504   begin
505 <  if fileid < Self.GetFilesCount then
505 >  if fileid < GetFileCount then
506    begin
507 <    raw_info := Self.GetRawInfo(fileid, dat_offset);
508 <    if not raw_info.loc_sep then
507 >    raw_info := GetRawInfo(FileID, DatOffset);
508 >    if not raw_info.LocSep then
509      begin
510 <      if FUnloadWhenUnused or not FRawOpened then
510 >      if not FRawOpened then
511          Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
512            fmOpenReadWrite);
513 <      Fraw_file.Seek(raw_info.raw_addr, soFromBeginning);
514 <      Fraw_file.Write(target^, raw_info.raw_size);
513 >      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
514 >      Fraw_file.CopyFrom(Src, raw_info.RawSize);
515        if UnloadWhenUnused then
516 <        Fraw_file.Free
516 >      begin
517 >        FRawOpened := False;
518 >        Fraw_file.Free;
519 >      end
520        else
521          FRawOpened := True;
522      end
523      else
524      begin
525 <      if FUnloadWhenUnused or not FSepOpened then
525 >      if not FSepOpened then
526          Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
527            fmOpenReadWrite);
528 <      Fsep_file.Seek(raw_info.raw_addr, soFromBeginning);
529 <      Fsep_file.Write(target^, raw_info.raw_size);
528 >      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
529 >      Fsep_file.CopyFrom(Src, raw_info.RawSize);
530        if UnloadWhenUnused then
531 <        Fsep_file.Free
531 >      begin
532 >        FSepOpened := False;
533 >        Fsep_file.Free;
534 >      end
535        else
536          FSepOpened := True;
537      end;
538    end;
539   end;
540  
541 <
564 <
565 <
566 < procedure TOniDataDat.LoadRawFilePart(fileid, dat_offset: LongWord;
567 <  offset, size: LongWord; target: Pointer);
541 > procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
542   var
543 <  raw_info: TRawInfo;
544 <  Data:     Tdata;
571 <  mem:      TMemoryStream;
543 >  Data: TStream;
544 >  streampos: Integer;
545   begin
546 <  if fileid < Self.GetFilesCount then
546 >  if not Assigned(Target) then
547 >    Target := TMemoryStream.Create;
548 >  if fileid < Self.GetFileCount then
549    begin
550 <    raw_info := Self.GetRawInfo(fileid, dat_offset);
551 <    SetLength(Data, raw_info.raw_size);
552 <    Self.LoadRawFile(fileid, dat_offset, @Data[0]);
553 <    mem := TMemoryStream.Create;
554 <    mem.Write(Data[offset], size);
555 <    mem.Read(target^, size);
581 <    mem.Free;
550 >    data := nil;
551 >    LoadRawFile(FileID, DatOffset, Data);
552 >    Data.Seek(Offset, soFromBeginning);
553 >    streampos := Target.Position;
554 >    Target.CopyFrom(Data, Size);
555 >    Target.Seek(streampos, soFromBeginning);
556    end;
557   end;
558  
559 <
586 <
587 <
588 < procedure TOniDataDat.UpdateRawFilePart(fileid, dat_offset: LongWord;
589 <  offset, size: LongWord; target: Pointer);
559 > procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
560   var
561 <  raw_info: TRawInfo;
561 >  raw_info: TRawDataInfo;
562   begin
563 <  if fileid < Self.GetFilesCount then
563 >  if fileid < GetFileCount then
564    begin
565 <    raw_info := Self.GetRawInfo(fileid, dat_offset);
566 <    if not raw_info.loc_sep then
565 >    raw_info := GetRawInfo(FileID, DatOffset);
566 >    if not raw_info.LocSep then
567      begin
568 <      if FUnloadWhenUnused or not FRawOpened then
568 >      if not FRawOpened then
569          Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
570            fmOpenReadWrite);
571 <      Fraw_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
572 <      Fraw_file.Write(target^, raw_info.raw_size);
571 >      Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
572 >      Fraw_file.CopyFrom(Src, Size);
573        if UnloadWhenUnused then
574 <        Fraw_file.Free
574 >      begin
575 >        FRawOpened := False;
576 >        Fraw_file.Free;
577 >      end
578        else
579          FRawOpened := True;
580      end
581      else
582      begin
583 <      if FUnloadWhenUnused or not FSepOpened then
583 >      if not FSepOpened then
584          Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
585            fmOpenReadWrite);
586 <      Fsep_file.Seek(raw_info.raw_addr + offset, soFromBeginning);
587 <      Fsep_file.Write(target^, raw_info.raw_size);
586 >      Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
587 >      Fsep_file.CopyFrom(Src, Size);
588        if UnloadWhenUnused then
589 <        Fsep_file.Free
589 >      begin
590 >        FSepOpened := False;
591 >        Fsep_file.Free;
592 >      end
593        else
594          FSepOpened := True;
595      end;
596    end;
597   end;
598  
599 <
624 <
625 <
626 < function TOniDataDat.AppendRawFile(loc_sep: Boolean; size: LongWord;
627 <  target: Pointer): LongWord; //Returns new Address
599 > function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
600   begin
601 <  if not loc_sep then
601 >  if not LocSep then
602    begin
603 <    if FUnloadWhenUnused or not FRawOpened then
603 >    if not FRawOpened then
604        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
605          fmOpenReadWrite);
606      Result := Fraw_file.Size;
607      Fraw_file.Seek(0, soFromEnd);
608 <    Fraw_file.Write(target^, size);
608 >    Fraw_file.CopyFrom(Src, Src.Size);
609      if UnloadWhenUnused then
610 <      Fraw_file.Free
610 >    begin
611 >      FRawOpened := False;
612 >      Fraw_file.Free;
613 >    end
614      else
615        FRawOpened := True;
616    end
617    else
618    begin
619 <    if FUnloadWhenUnused or not FSepOpened then
619 >    if not FSepOpened then
620        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
621          fmOpenReadWrite);
622      Result := Fsep_file.Size;
623      Fsep_file.Seek(0, soFromEnd);
624 <    Fsep_file.Write(target^, size);
624 >    Fsep_file.CopyFrom(Src, Src.Size);
625      if UnloadWhenUnused then
626 <      Fsep_file.Free
626 >    begin
627 >      FSepOpened := False;
628 >      Fsep_file.Free;
629 >    end
630      else
631        FSepOpened := True;
632    end;
633   end;
634  
657
658 }
659
660
661
662
635   end.

Diff Legend

Removed lines
+ Added lines
< Changed lines (old)
> Changed lines (new)