source: oup/current/DataAccess/Access_OniArchive.pas @ 243

Last change on this file since 243 was 243, checked in by alloc, 15 years ago
File size: 22.1 KB
Line 
1unit Access_OniArchive;
2interface
3
4uses DataAccess, Classes, TypeDefs;
5
6type
7  TAccess_OniArchive = class(TDataAccess)
8  private
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    procedure SetUnloadWhenUnused(doit: Boolean);
19  protected
20  public
21    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write SetUnloadWhenUnused;
22
23    constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
24    procedure Close; override;
25
26    function GetFileInfo(FileID: Integer): TFileInfo; override;
27    function GetFilesList(Ext: String; Pattern: String;
28      NoEmptyFiles: Boolean; SortType: TSortType): TStrings; override;
29    function GetFileCount: Integer; override;
30    function GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings; override;
31
32    procedure LoadDatFile(FileID: Integer; var Target: TStream); overload; override;
33    procedure UpdateDatFile(FileID: Integer; Src: TStream); overload; override;
34    procedure LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream); overload; override;
35    procedure UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream); overload; override;
36
37    function GetDatLinks(FileID: Integer): TDatLinkList; override;
38    function GetDatLink(FileID, DatOffset: Integer): TDatLink; override;
39    function GetRawList(FileID: Integer): TRawDataList; override;
40    function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
41    function GetRawsForType(RawType: String): TRawDataList; override;
42
43    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream); overload;
44    procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer); overload;
45    procedure LoadRawFile(FileID, DatOffset: Integer; var Target: TStream); overload; override;
46    procedure UpdateRawFile(FileID, DatOffset: Integer; Src: TStream); overload; override;
47    procedure LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream); overload; override;
48    procedure UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream); overload; override;
49
50    function AppendRawFile(LocSep: Boolean; Src: TStream): Integer; overload; override;
51  published
52  end;
53
54implementation
55
56uses
57  SysUtils, StrUtils, Data, Functions, RawList, DatLinks, Math;
58
59
60(*
61================================================================================
62                      Implementation of  TOniDataDat
63*)
64
65
66constructor TAccess_OniArchive.Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
67var
68  i: Integer;
69  header_pc, header_mac, header_macbeta: Boolean;
70  Fdat_header:   THeader;
71  Fdat_filesmap: TFilesMap;
72  Fdat_namedfilesmap: TNamedFilesMap;
73begin
74  FUnloadWhenUnused := True;
75  FDatOpened := False;
76  FRawOpened := False;
77  Msg := SM_UnknownError;
78  if not FileExists(DatFilename) then
79  begin
80    Msg := SM_FileNotFound;
81    Exit;
82  end;
83  FFileName := DatFilename;
84  Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
85  Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
86  header_pc  := True;
87  header_mac := True;
88  header_macbeta := True;
89  for i := 0 to High(Fdat_header.GlobalIdent) do
90    if Fdat_header.GlobalIdent[i] <> HeaderGlobalIdent[i] then
91    begin
92      Msg := SM_IncompatibleFile;
93      Exit;
94    end;
95
96  for i := 0 to High(Fdat_header.OSIdent) do
97  begin
98    if Fdat_header.OSIdent[i] <> HeaderOSIdentWin[i] then
99      header_pc := False;
100    if Fdat_header.OSIdent[i] <> HeaderOSIdentMac[i] then
101      header_mac := False;
102    if Fdat_header.OSIdent[i] <> HeaderOSIdentMacBeta[i] then
103      header_macbeta := False;
104  end;
105  if not (header_pc xor header_mac xor header_macbeta) then
106  begin
107    Msg := SM_IncompatibleFile;
108    Exit;
109  end
110  else
111  begin
112    if (header_pc and not header_mac and not header_macbeta) then
113      FDataOS := DOS_WIN
114    else if (not header_pc and header_mac and not header_macbeta) then
115      FDataOS := DOS_MAC
116    else if (not header_pc and not header_mac and header_macbeta) then
117      FDataOS := DOS_MACBETA;
118  end;
119  SetLength(Fdat_filesmap, Fdat_header.Files);
120  SetLength(Fdat_files, Fdat_header.Files);
121  for i := 0 to Fdat_header.Files - 1 do
122    Fdat_file.Read(Fdat_filesmap[i], SizeOf(Fdat_filesmap[i]));
123  for i := 0 to Fdat_header.Files - 1 do
124  begin
125    Fdat_files[i].ID := i;
126    Fdat_files[i].Extension := Fdat_filesmap[i].Extension;
127    Fdat_files[i].Extension := ReverseString(Fdat_files[i].Extension);
128    Fdat_files[i].Size      := Fdat_filesmap[i].FileSize;
129    Fdat_files[i].FileType  := Fdat_filesmap[i].FileType;
130    Fdat_files[i].DatAddr   := Fdat_filesmap[i].DataAddr - 8 + Fdat_header.DataAddr;
131    if (Fdat_filesmap[i].FileType and $01) = 0 then
132    begin
133      Fdat_file.Seek(Fdat_filesmap[i].NameAddr + Fdat_header.NamesAddr, soFromBeginning);
134      SetLength(Fdat_files[i].Name, 100);
135      Fdat_file.Read(Fdat_files[i].Name[1], 100);
136      Fdat_files[i].Name := MidStr(Fdat_files[i].Name, 1 + 4, Pos(
137        #0, Fdat_files[i].Name) - 1 - 4);
138    end
139    else
140    begin
141      Fdat_files[i].Name := '';
142    end;
143  end;
144  Fdat_file.Seek($40 + Fdat_header.Files * $14, soFromBeginning);
145  SetLength(Fdat_namedfilesmap, Fdat_header.NamedFiles);
146  for i := 0 to Fdat_header.NamedFiles - 1 do
147    Fdat_file.Read(Fdat_namedfilesmap[i], SizeOf(Fdat_namedfilesmap[i]));
148
149  Fdat_file.Seek($40 + Fdat_header.Files * $14 + Fdat_header.NamedFiles * $8, soFromBeginning);
150  SetLength(Fdat_extensionsmap, Fdat_header.Extensions);
151  for i := 0 to Fdat_header.Extensions - 1 do
152    Fdat_file.Read(Fdat_extensionsmap[i], SizeOf(Fdat_extensionsmap[i]));
153
154  Fdat_file.Seek(Fdat_files[0].DatAddr + 7, soFromBeginning);
155  Fdat_file.Read(FLevelNumber, 1);
156  FLevelNumber := FLevelNumber div 2;
157
158  Fdat_file.Free;
159
160  Msg := SM_OK;
161  FBackend := DB_ONI;
162  FConnectionID := ConnectionID;
163  FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
164
165  inherited;
166end;
167
168
169
170
171procedure TAccess_OniArchive.SetUnloadWhenUnused(doit: Boolean);
172begin
173  FUnloadWhenUnused := doit;
174  if FUnloadWhenUnused then
175  begin
176    if FDatOpened then
177    begin
178      FDatOpened := False;
179      Fdat_file.Free;
180    end;
181    if FRawOpened then
182    begin
183      FRawOpened := False;
184      Fraw_file.Free;
185    end;
186    if FSepOpened then
187    begin
188      FSepOpened := False;
189      Fsep_file.Free;
190    end;
191  end
192  else
193  begin
194    if not FDatOpened then
195    begin
196      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
197      FDatOpened := True;
198    end;
199    if not FRawOpened then
200    begin
201      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
202        fmOpenReadWrite);
203      FRawOpened := True;
204    end;
205    if (not FSepOpened) and (FDataOS <> DOS_WIN) then
206    begin
207      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
208        fmOpenReadWrite);
209      FSepOpened := True;
210    end;
211  end;
212end;
213
214
215
216
217
218procedure TAccess_OniArchive.Close;
219begin
220  if FDatOpened then
221    Fdat_file.Free;
222  if FRawOpened then
223    Fraw_file.Free;
224  if FSepOpened then
225    Fsep_file.Free;
226  Self.Free;
227end;
228
229
230
231
232function TAccess_OniArchive.GetFileInfo(fileid: Integer): TFileInfo;
233begin
234  if fileid = -1 then
235  begin
236    Result := inherited GetFileInfo(fileid);
237    Exit;
238  end;
239  if fileid < Self.GetFileCount then
240    Result    := Fdat_files[fileid]
241  else
242    Result.ID := -1;
243end;
244
245
246
247
248function TAccess_OniArchive.GetFilesList(ext: String; pattern: String;
249  NoEmptyFiles: Boolean; SortType: TSortType): TStrings;
250var
251  i:      Integer;
252  list:   TStringList;
253  id, name, extension: String;
254  fields: TStrings;
255
256  procedure getfields;
257  begin
258    fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
259    if SortType in [ST_IDAsc, ST_IDDesc] then
260    begin
261      id := fields.Strings[0];
262      name := fields.Strings[1];
263      extension := fields.Strings[2];
264    end;
265    if SortType in [ST_NameAsc, ST_NameDesc] then
266    begin
267      id := fields.Strings[1];
268      name := fields.Strings[0];
269      extension := fields.Strings[2];
270    end;
271    if SortType in [ST_ExtAsc, ST_ExtDesc] then
272    begin
273      id := fields.Strings[1];
274      name := fields.Strings[2];
275      extension := fields.Strings[0];
276    end;
277    if SortType in [ST_ExtNameAsc, ST_ExtNameDesc] then
278    begin
279      id := fields.Strings[2];
280      name := fields.Strings[1];
281      extension := fields.Strings[0];
282    end;
283  end;
284
285begin
286  list := TStringList.Create;
287  list.Sorted := True;
288  if ext = '*' then
289    ext := '';
290  for i := 0 to GetFileCount - 1 do
291  begin
292    if ((Length(ext) = 0) or (Pos(Fdat_files[i].Extension, ext) > 0)) and
293      ((Length(pattern) = 0) or
294      (Pos(UpperCase(pattern), UpperCase(Fdat_files[i].Name)) > 0)) then
295    begin
296      if (NoEmptyFiles = False) or ((Fdat_files[i].FileType and $02) = 0) then
297      begin
298        id := FormatNumber(Fdat_files[i].ID, 5, '0');
299        name := Fdat_files[i].Name;
300        extension := Fdat_files[i].Extension;
301
302        case SortType of
303          ST_IDAsc, ST_IDDesc:     list.Add(id + ';' + name + ';' + extension);
304          ST_NameAsc, ST_NameDesc: list.Add(name + ';' + id + ';' + extension);
305          ST_ExtAsc, ST_ExtDesc:   list.Add(extension + ';' + id + ';' + name);
306          ST_ExtNameAsc, ST_ExtNameDesc: list.Add(name + ';' + extension + ';' + id);
307        end;
308      end;
309    end;
310  end;
311  if not Assigned(Result) then
312    Result := TStringList.Create;
313  if list.Count > 0 then
314  begin
315    fields := TStringList.Create;
316    if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc, ST_ExtNameAsc] then
317      for i := 0 to list.Count - 1 do
318      begin
319        getfields;
320        Result.Add(id + '-' + name + '.' + extension);
321      end
322    else
323      for i := list.Count - 1 downto 0 do
324      begin
325        getfields;
326        Result.Add(id + '-' + name + '.' + extension);
327      end;
328    fields.Free;
329  end;
330  list.Free;
331end;
332
333
334
335
336function TAccess_OniArchive.GetFileCount: Integer;
337begin
338  Result := Length(Fdat_files);
339end;
340
341
342
343
344function TAccess_OniArchive.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings;
345var
346  i: Integer;
347begin
348  if not Assigned(Result) then
349    Result := TStringList.Create;
350  if Result is TStringList then
351    TStringList(Result).Sorted := True;
352  for i := 0 to Length(Fdat_extensionsmap) - 1 do
353  begin
354    with Fdat_extensionsmap[i] do
355    begin
356      case ExtListFormat of
357        EF_ExtOnly:
358          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0]);
359        EF_ExtCount:
360          Result.Add(Extension[3] + Extension[2] + Extension[1] + Extension[0] +
361                ' (' + IntToStr(ExtCount) + ')');
362      end;
363    end;
364  end;
365end;
366
367
368
369procedure TAccess_OniArchive.LoadDatFile(FileID: Integer; var Target: TStream);
370var
371  streampos: Integer;
372begin
373  if fileid < GetFileCount then
374  begin
375    if GetFileInfo(FileID).Size > 0 then
376    begin
377      if not Assigned(Target) then
378        Target := TMemoryStream.Create;
379      if not FDatOpened then
380        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
381      Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
382      streampos := Target.Position;
383      Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
384      Target.Seek(streampos, soFromBeginning);
385      if UnloadWhenUnused then
386      begin
387        Fdat_file.Free;
388        FDatOpened := False;
389      end
390      else
391        FDatOpened := True;
392    end;
393  end;
394end;
395
396procedure TAccess_OniArchive.UpdateDatFile(FileID: Integer; Src: TStream);
397begin
398  if fileid < GetFileCount then
399  begin
400    if not FDatOpened then
401      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
402    Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
403    Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
404    if UnloadWhenUnused then
405    begin
406      Fdat_file.Free;
407      FDatOpened := False;
408    end
409    else
410      FDatOpened := True;
411  end;
412end;
413
414procedure TAccess_OniArchive.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream);
415var
416  streampos: Integer;
417begin
418  if fileid < GetFileCount then
419  begin
420    if not Assigned(Target) then
421      Target := TMemoryStream.Create;
422    if not FDatOpened then
423      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
424    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
425    streampos := Target.Position;
426    Target.CopyFrom(Fdat_file, size);
427    Target.Seek(streampos, soFromBeginning);
428    if UnloadWhenUnused then
429    begin
430      FDatOpened := False;
431      Fdat_file.Free;
432    end
433    else
434      FDatOpened := True;
435  end;
436end;
437
438procedure TAccess_OniArchive.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream);
439begin
440  if fileid < GetFileCount then
441  begin
442    if not FDatOpened then
443      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
444    Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
445    Fdat_file.CopyFrom(Src, Size);
446    if UnloadWhenUnused then
447    begin
448      Fdat_file.Free;
449      FDatOpened := False;
450    end
451    else
452      FDatOpened := True;
453  end;
454end;
455
456
457
458function TAccess_OniArchive.GetDatLink(FileID, DatOffset: Integer): TDatLink;
459var
460  link: Integer;
461begin
462  Result := DatLinksManager.GetDatLink(FConnectionID, FileID, DatOffset);
463  LoadDatFilePart(fileid, Result.SrcOffset, 4, @link);
464  if link > 0 then
465    Result.DestID := link div 256
466  else
467    Result.DestID := -1;
468end;
469
470
471function TAccess_OniArchive.GetDatLinks(FileID: Integer): TDatLinkList;
472var
473  i: Integer;
474  link: Integer;
475begin
476  Result := DatLinksManager.GetDatLinks(FConnectionID, FileID);
477  if Length(Result) > 0 then
478  begin
479    for i := 0 to High(Result) do
480    begin
481      LoadDatFilePart(fileid, Result[i].SrcOffset, 4, @link);
482      if link > 0 then
483        Result[i].DestID := link div 256
484      else
485        Result[i].DestID := -1;
486    end;
487  end;
488end;
489
490
491function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
492begin
493  Result := RawLists.GetRawList(FConnectionID, FileID);
494end;
495
496
497function TAccess_OniArchive.GetRawsForType(RawType: String): TRawDataList;
498var
499  i, j: Integer;
500  dats: TStrings;
501  list: TRawDataList;
502begin
503  dats := nil;
504  dats := GetFilesList(MidStr(RawType, 1, 4), '', True, ST_IDAsc);
505  for i := 0 to dats.Count - 1 do
506  begin
507    list := GetRawList(StrToInt(MidStr(dats.Strings[i], 1, 5)));
508    for j := 0 to Length(list) - 1 do
509    begin
510      if (list[j].RawType = RawType) and (list[j].RawSize > 0) then
511      begin
512        SetLength(Result, Length(Result)+1);
513        Result[High(Result)] := list[j];
514      end;
515    end;
516  end;
517end;
518
519
520function TAccess_OniArchive.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
521begin
522  Result := RawLists.GetRawInfo(FConnectionID, FileID, DatOffset);
523end;
524
525
526
527procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream);
528begin
529  if not Assigned(Target) then
530    Target := TMemoryStream.Create;
531  if not LocSep then
532  begin
533    if not FRawOpened then
534      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
535        fmOpenReadWrite);
536    if RawAddr <= Fraw_file.Size then
537    begin
538      Fraw_file.Seek(RawAddr, soFromBeginning);
539      Target.CopyFrom(Fraw_file, size);
540      Target.Seek(0, soFromBeginning);
541    end;
542    if UnloadWhenUnused then
543    begin
544      FRawOpened := False;
545      Fraw_file.Free;
546    end
547    else
548      FRawOpened := True;
549  end
550  else
551  begin
552    if not FSepOpened then
553      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
554        fmOpenReadWrite);
555    if RawAddr <= Fsep_file.Size then
556    begin
557      Fsep_file.Seek(RawAddr, soFromBeginning);
558      Target.CopyFrom(Fsep_file, size);
559      Target.Seek(0, soFromBeginning);
560    end;
561    if UnloadWhenUnused then
562    begin
563      FSepOpened := False;
564      Fsep_file.Free;
565    end
566    else
567      FSepOpened := True;
568  end;
569end;
570
571procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer);
572var
573  data: TStream;
574begin
575  data := nil;
576  LoadRawOffset(LocSep, RawAddr, Size, data);
577  data.Read(Target^, Size);
578  data.Free;
579end;
580
581procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
582var
583  raw_info: TRawDataInfo;
584  streampos: Integer;
585begin
586  if not Assigned(Target) then
587    Target := TMemoryStream.Create;
588  if fileid < GetFileCount then
589  begin
590    raw_info := Self.GetRawInfo(FileID, DatOffset);
591    if not raw_info.LocSep then
592    begin
593      if not FRawOpened then
594        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
595          fmOpenReadWrite);
596      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
597      streampos := Target.Position;
598      Target.CopyFrom(Fraw_file, raw_info.RawSize);
599      Target.Seek(streampos, soFromBeginning);
600      if UnloadWhenUnused then
601      begin
602        FRawOpened := False;
603        Fraw_file.Free;
604      end
605      else
606        FRawOpened := True;
607    end
608    else
609    begin
610      if FUnloadWhenUnused or not FSepOpened then
611        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
612          fmOpenReadWrite);
613      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
614      streampos := Target.Position;
615      Target.CopyFrom(Fsep_file, raw_info.RawSize);
616      Target.Seek(streampos, soFromBeginning);
617      if UnloadWhenUnused then
618      begin
619        FSepOpened := False;
620        Fsep_file.Free;
621      end
622      else
623        FSepOpened := True;
624    end;
625  end;
626end;
627
628procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
629var
630  raw_info: TRawDataInfo;
631begin
632  if fileid < GetFileCount then
633  begin
634    raw_info := GetRawInfo(FileID, DatOffset);
635    if not raw_info.LocSep then
636    begin
637      if not FRawOpened then
638        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
639          fmOpenReadWrite);
640      Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
641      Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
642      if UnloadWhenUnused then
643      begin
644        FRawOpened := False;
645        Fraw_file.Free;
646      end
647      else
648        FRawOpened := True;
649    end
650    else
651    begin
652      if not FSepOpened then
653        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
654          fmOpenReadWrite);
655      Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
656      Fsep_file.CopyFrom(Src, raw_info.RawSize);
657      if UnloadWhenUnused then
658      begin
659        FSepOpened := False;
660        Fsep_file.Free;
661      end
662      else
663        FSepOpened := True;
664    end;
665  end;
666end;
667
668procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
669var
670  Data: TStream;
671  streampos: Integer;
672begin
673  if not Assigned(Target) then
674    Target := TMemoryStream.Create;
675  if fileid < Self.GetFileCount then
676  begin
677    data := nil;
678    LoadRawFile(FileID, DatOffset, Data);
679    Data.Seek(Offset, soFromBeginning);
680    streampos := Target.Position;
681    Target.CopyFrom(Data, Size);
682    Target.Seek(streampos, soFromBeginning);
683  end;
684end;
685
686
687procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
688var
689  raw_info: TRawDataInfo;
690begin
691  if fileid < GetFileCount then
692  begin
693    raw_info := GetRawInfo(FileID, DatOffset);
694    if not raw_info.LocSep then
695    begin
696      if not FRawOpened then
697        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
698          fmOpenReadWrite);
699      Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
700      Fraw_file.CopyFrom(Src, Size);
701      if UnloadWhenUnused then
702      begin
703        FRawOpened := False;
704        Fraw_file.Free;
705      end
706      else
707        FRawOpened := True;
708    end
709    else
710    begin
711      if not FSepOpened then
712        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
713          fmOpenReadWrite);
714      Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
715      Fsep_file.CopyFrom(Src, Size);
716      if UnloadWhenUnused then
717      begin
718        FSepOpened := False;
719        Fsep_file.Free;
720      end
721      else
722        FSepOpened := True;
723    end;
724  end;
725end;
726
727function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
728const
729  EmptyBytes: Array[0..31] of Byte = (
730      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 );
731begin
732  if not LocSep then
733  begin
734    if not FRawOpened then
735      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
736        fmOpenReadWrite);
737    if (Fraw_file.Size mod 32) > 0 then
738      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
739    Result := Fraw_file.Size;
740    Fraw_file.Seek(0, soFromEnd);
741    Fraw_file.CopyFrom(Src, Src.Size);
742    if (Fraw_file.Size mod 32) > 0 then
743      Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
744    if UnloadWhenUnused then
745    begin
746      FRawOpened := False;
747      Fraw_file.Free;
748    end
749    else
750      FRawOpened := True;
751  end
752  else
753  begin
754    if not FSepOpened then
755      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
756        fmOpenReadWrite);
757    if (Fsep_file.Size mod 32) > 0 then
758      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
759    Result := Fsep_file.Size;
760    Fsep_file.Seek(0, soFromEnd);
761    Fsep_file.CopyFrom(Src, Src.Size);
762    if (Fsep_file.Size mod 32) > 0 then
763      Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
764    if UnloadWhenUnused then
765    begin
766      FSepOpened := False;
767      Fsep_file.Free;
768    end
769    else
770      FSepOpened := True;
771  end;
772end;
773
774end.
Note: See TracBrowser for help on using the repository browser.