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

Diff Legend

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