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

Diff Legend

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