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

Last change on this file since 1089 was 321, checked in by alloc, 16 years ago
File size: 22.1 KB
RevLine 
[93]1unit Access_OniArchive;
2interface
3
[101]4uses DataAccess, Classes, TypeDefs;
[93]5
6type
7 TAccess_OniArchive = class(TDataAccess)
8 private
[101]9 Fdat_file: TFileStream;
10 Fraw_file: TFileStream;
11 Fsep_file: TFileStream;
12 Fdat_files: TFiles;
13 Fdat_extensionsmap: TExtensionsMap;
[256]14 FUnloadWhenUnused: Boolean;
15 FDatOpened: Boolean;
16 FRawOpened: Boolean;
17 FSepOpened: Boolean;
18 procedure SetUnloadWhenUnused(doit: Boolean);
[93]19 protected
20 public
[256]21 property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write SetUnloadWhenUnused;
22
[101]23 constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
[93]24 procedure Close; override;
25
[101]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;
[93]31
[101]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;
[93]36
[113]37 function GetDatLinks(FileID: Integer): TDatLinkList; override;
[116]38 function GetDatLink(FileID, DatOffset: Integer): TDatLink; override;
[101]39 function GetRawList(FileID: Integer): TRawDataList; override;
40 function GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo; override;
[241]41 function GetRawsForType(RawType: String): TRawDataList; override;
[101]42
[148]43 procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream); overload;
44 procedure LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; target: Pointer); overload;
[101]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
[105]50 function AppendRawFile(LocSep: Boolean; Src: TStream): Integer; overload; override;
[93]51 published
[101]52 end;
[93]53
54implementation
55
[101]56uses
[192]57 SysUtils, StrUtils, Data, Functions, RawList, DatLinks, Math;
[93]58
[101]59
[93]60(*
61================================================================================
62 Implementation of TOniDataDat
63*)
64
[101]65
66constructor TAccess_OniArchive.Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages);
[93]67var
[101]68 i: Integer;
69 header_pc, header_mac, header_macbeta: Boolean;
70 Fdat_header: THeader;
71 Fdat_filesmap: TFilesMap;
72 Fdat_namedfilesmap: TNamedFilesMap;
[93]73begin
[256]74 FUnloadWhenUnused := True;
75 FDatOpened := False;
76 FRawOpened := False;
[101]77 Msg := SM_UnknownError;
[93]78 if not FileExists(DatFilename) then
79 begin
[101]80 Msg := SM_FileNotFound;
[93]81 Exit;
82 end;
83 FFileName := DatFilename;
[256]84 Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
[93]85 Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
86 header_pc := True;
87 header_mac := True;
[101]88 header_macbeta := True;
[113]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
[93]97 begin
[113]98 if Fdat_header.OSIdent[i] <> HeaderOSIdentWin[i] then
[93]99 header_pc := False;
[113]100 if Fdat_header.OSIdent[i] <> HeaderOSIdentMac[i] then
[93]101 header_mac := False;
[113]102 if Fdat_header.OSIdent[i] <> HeaderOSIdentMacBeta[i] then
[101]103 header_macbeta := False;
[93]104 end;
[101]105 if not (header_pc xor header_mac xor header_macbeta) then
[93]106 begin
[101]107 Msg := SM_IncompatibleFile;
[93]108 Exit;
109 end
110 else
111 begin
[101]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;
[93]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);
[101]155 Fdat_file.Read(FLevelNumber, 1);
156 FLevelNumber := FLevelNumber div 2;
[93]157
[256]158 Fdat_file.Free;
[93]159
[101]160 Msg := SM_OK;
161 FBackend := DB_ONI;
[105]162 FConnectionID := ConnectionID;
[101]163 FChangeRights := [CR_EditDat, CR_EditRaw, CR_AppendRaw];
[229]164
165 inherited;
[93]166end;
167
168
169
170
[256]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
[101]218procedure TAccess_OniArchive.Close;
[93]219begin
[256]220 if FDatOpened then
[93]221 Fdat_file.Free;
[256]222 if FRawOpened then
[93]223 Fraw_file.Free;
[256]224 if FSepOpened then
[93]225 Fsep_file.Free;
226 Self.Free;
227end;
228
229
230
231
[101]232function TAccess_OniArchive.GetFileInfo(fileid: Integer): TFileInfo;
[93]233begin
234 if fileid = -1 then
235 begin
236 Result := inherited GetFileInfo(fileid);
237 Exit;
238 end;
[101]239 if fileid < Self.GetFileCount then
[93]240 Result := Fdat_files[fileid]
241 else
242 Result.ID := -1;
243end;
244
245
246
247
[101]248function TAccess_OniArchive.GetFilesList(ext: String; pattern: String;
249 NoEmptyFiles: Boolean; SortType: TSortType): TStrings;
[93]250var
[101]251 i: Integer;
252 list: TStringList;
[93]253 id, name, extension: String;
254 fields: TStrings;
255
256 procedure getfields;
257 begin
[101]258 fields.CommaText := StringReplace(AnsiQuotedStr(list.Strings[i], '"'), ';', '","', [rfReplaceAll]);
259 if SortType in [ST_IDAsc, ST_IDDesc] then
[93]260 begin
261 id := fields.Strings[0];
262 name := fields.Strings[1];
263 extension := fields.Strings[2];
264 end;
[101]265 if SortType in [ST_NameAsc, ST_NameDesc] then
[93]266 begin
267 id := fields.Strings[1];
268 name := fields.Strings[0];
269 extension := fields.Strings[2];
270 end;
[101]271 if SortType in [ST_ExtAsc, ST_ExtDesc] then
[93]272 begin
273 id := fields.Strings[1];
274 name := fields.Strings[2];
275 extension := fields.Strings[0];
276 end;
[112]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;
[93]283 end;
284
285begin
286 list := TStringList.Create;
287 list.Sorted := True;
[241]288 if ext = '*' then
289 ext := '';
[101]290 for i := 0 to GetFileCount - 1 do
[93]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
[112]298 id := FormatNumber(Fdat_files[i].ID, 5, '0');
[93]299 name := Fdat_files[i].Name;
300 extension := Fdat_files[i].Extension;
301
[101]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);
[112]306 ST_ExtNameAsc, ST_ExtNameDesc: list.Add(name + ';' + extension + ';' + id);
[93]307 end;
308 end;
309 end;
310 end;
[113]311 if not Assigned(Result) then
312 Result := TStringList.Create;
[101]313 if list.Count > 0 then
[93]314 begin
315 fields := TStringList.Create;
[112]316 if SortType in [ST_IDAsc, ST_NameAsc, ST_ExtAsc, ST_ExtNameAsc] then
[93]317 for i := 0 to list.Count - 1 do
318 begin
319 getfields;
[101]320 Result.Add(id + '-' + name + '.' + extension);
[93]321 end
322 else
323 for i := list.Count - 1 downto 0 do
324 begin
325 getfields;
[101]326 Result.Add(id + '-' + name + '.' + extension);
[93]327 end;
328 fields.Free;
329 end;
330 list.Free;
331end;
332
333
334
335
[101]336function TAccess_OniArchive.GetFileCount: Integer;
[93]337begin
[101]338 Result := Length(Fdat_files);
[93]339end;
340
341
342
343
[101]344function TAccess_OniArchive.GetExtensionsList(ExtListFormat: TExtensionFormat): TStrings;
[93]345var
[101]346 i: Integer;
[93]347begin
[113]348 if not Assigned(Result) then
349 Result := TStringList.Create;
350 if Result is TStringList then
351 TStringList(Result).Sorted := True;
[101]352 for i := 0 to Length(Fdat_extensionsmap) - 1 do
[93]353 begin
354 with Fdat_extensionsmap[i] do
355 begin
[101]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;
[93]363 end;
364 end;
365end;
366
367
368
[101]369procedure TAccess_OniArchive.LoadDatFile(FileID: Integer; var Target: TStream);
[93]370var
[101]371 streampos: Integer;
[93]372begin
[101]373 if fileid < GetFileCount then
[93]374 begin
[248]375 if not Assigned(Target) then
376 Target := TMemoryStream.Create;
[231]377 if GetFileInfo(FileID).Size > 0 then
[101]378 begin
[256]379 if not FDatOpened then
380 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
[231]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);
[256]385 if UnloadWhenUnused then
386 begin
387 Fdat_file.Free;
388 FDatOpened := False;
389 end
390 else
391 FDatOpened := True;
[231]392 end;
[93]393 end;
394end;
395
[101]396procedure TAccess_OniArchive.UpdateDatFile(FileID: Integer; Src: TStream);
[93]397begin
[101]398 if fileid < GetFileCount then
[93]399 begin
[256]400 if not FDatOpened then
401 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
[93]402 Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
[101]403 Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
[256]404 if UnloadWhenUnused then
405 begin
406 Fdat_file.Free;
407 FDatOpened := False;
408 end
409 else
410 FDatOpened := True;
[93]411 end;
412end;
413
[101]414procedure TAccess_OniArchive.LoadDatFilePart(FileID, Offset, Size: Integer; var Target: TStream);
415var
416 streampos: Integer;
[93]417begin
[101]418 if fileid < GetFileCount then
[93]419 begin
[101]420 if not Assigned(Target) then
421 Target := TMemoryStream.Create;
[256]422 if not FDatOpened then
423 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
[93]424 Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
[101]425 streampos := Target.Position;
426 Target.CopyFrom(Fdat_file, size);
427 Target.Seek(streampos, soFromBeginning);
[256]428 if UnloadWhenUnused then
429 begin
430 FDatOpened := False;
431 Fdat_file.Free;
432 end
433 else
434 FDatOpened := True;
[93]435 end;
436end;
437
[101]438procedure TAccess_OniArchive.UpdateDatFilePart(FileID, Offset, Size: Integer; Src: TStream);
[93]439begin
[101]440 if fileid < GetFileCount then
[93]441 begin
[256]442 if not FDatOpened then
443 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
[93]444 Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
[101]445 Fdat_file.CopyFrom(Src, Size);
[256]446 if UnloadWhenUnused then
447 begin
448 Fdat_file.Free;
449 FDatOpened := False;
450 end
451 else
452 FDatOpened := True;
[93]453 end;
454end;
455
456
457
[116]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
[101]491function TAccess_OniArchive.GetRawList(FileID: Integer): TRawDataList;
492begin
493 Result := RawLists.GetRawList(FConnectionID, FileID);
494end;
[93]495
[101]496
[241]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
[243]510 if (list[j].RawType = RawType) and (list[j].RawSize > 0) then
[241]511 begin
512 SetLength(Result, Length(Result)+1);
513 Result[High(Result)] := list[j];
514 end;
515 end;
516 end;
517end;
518
519
[101]520function TAccess_OniArchive.GetRawInfo(FileID, DatOffset: Integer): TRawDataInfo;
[93]521begin
[101]522 Result := RawLists.GetRawInfo(FConnectionID, FileID, DatOffset);
[93]523end;
524
525
526
[148]527procedure TAccess_OniArchive.LoadRawOffset(LocSep: Boolean; RawAddr, Size: Integer; var target: TStream);
[93]528begin
[148]529 if not Assigned(Target) then
530 Target := TMemoryStream.Create;
[101]531 if not LocSep then
[93]532 begin
[256]533 if not FRawOpened then
534 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
535 fmOpenReadWrite);
[101]536 if RawAddr <= Fraw_file.Size then
[93]537 begin
[101]538 Fraw_file.Seek(RawAddr, soFromBeginning);
[148]539 Target.CopyFrom(Fraw_file, size);
540 Target.Seek(0, soFromBeginning);
[93]541 end;
[256]542 if UnloadWhenUnused then
543 begin
544 FRawOpened := False;
545 Fraw_file.Free;
546 end
547 else
548 FRawOpened := True;
[93]549 end
550 else
551 begin
[256]552 if not FSepOpened then
553 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
554 fmOpenReadWrite);
[101]555 if RawAddr <= Fsep_file.Size then
[93]556 begin
[101]557 Fsep_file.Seek(RawAddr, soFromBeginning);
[148]558 Target.CopyFrom(Fsep_file, size);
559 Target.Seek(0, soFromBeginning);
[93]560 end;
[256]561 if UnloadWhenUnused then
562 begin
563 FSepOpened := False;
564 Fsep_file.Free;
565 end
566 else
567 FSepOpened := True;
[93]568 end;
569end;
570
[148]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
[101]581procedure TAccess_OniArchive.LoadRawFile(FileID, DatOffset: Integer; var Target: TStream);
[93]582var
[101]583 raw_info: TRawDataInfo;
584 streampos: Integer;
[93]585begin
[101]586 if not Assigned(Target) then
587 Target := TMemoryStream.Create;
588 if fileid < GetFileCount then
[93]589 begin
[101]590 raw_info := Self.GetRawInfo(FileID, DatOffset);
[321]591 if raw_info.RawSize = 0 then
592 exit;
[101]593 if not raw_info.LocSep then
[93]594 begin
[256]595 if not FRawOpened then
596 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
597 fmOpenReadWrite);
[101]598 Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
599 streampos := Target.Position;
600 Target.CopyFrom(Fraw_file, raw_info.RawSize);
601 Target.Seek(streampos, soFromBeginning);
[256]602 if UnloadWhenUnused then
603 begin
604 FRawOpened := False;
605 Fraw_file.Free;
606 end
607 else
608 FRawOpened := True;
[93]609 end
610 else
611 begin
[256]612 if FUnloadWhenUnused or not FSepOpened then
613 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
614 fmOpenReadWrite);
[101]615 Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
616 streampos := Target.Position;
617 Target.CopyFrom(Fsep_file, raw_info.RawSize);
618 Target.Seek(streampos, soFromBeginning);
[256]619 if UnloadWhenUnused then
620 begin
621 FSepOpened := False;
622 Fsep_file.Free;
623 end
624 else
625 FSepOpened := True;
[93]626 end;
627 end;
628end;
629
[101]630procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
[93]631var
[101]632 raw_info: TRawDataInfo;
[93]633begin
[101]634 if fileid < GetFileCount then
[93]635 begin
[101]636 raw_info := GetRawInfo(FileID, DatOffset);
637 if not raw_info.LocSep then
[93]638 begin
[256]639 if not FRawOpened then
640 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
641 fmOpenReadWrite);
[101]642 Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
[192]643 Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
[256]644 if UnloadWhenUnused then
645 begin
646 FRawOpened := False;
647 Fraw_file.Free;
648 end
649 else
650 FRawOpened := True;
[93]651 end
652 else
653 begin
[256]654 if not FSepOpened then
655 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
656 fmOpenReadWrite);
[101]657 Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
658 Fsep_file.CopyFrom(Src, raw_info.RawSize);
[256]659 if UnloadWhenUnused then
660 begin
661 FSepOpened := False;
662 Fsep_file.Free;
663 end
664 else
665 FSepOpened := True;
[93]666 end;
667 end;
668end;
669
[101]670procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
[93]671var
[101]672 Data: TStream;
673 streampos: Integer;
[93]674begin
[101]675 if not Assigned(Target) then
676 Target := TMemoryStream.Create;
677 if fileid < Self.GetFileCount then
[93]678 begin
[101]679 data := nil;
680 LoadRawFile(FileID, DatOffset, Data);
681 Data.Seek(Offset, soFromBeginning);
682 streampos := Target.Position;
683 Target.CopyFrom(Data, Size);
684 Target.Seek(streampos, soFromBeginning);
[93]685 end;
686end;
687
[148]688
[101]689procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
[93]690var
[101]691 raw_info: TRawDataInfo;
[93]692begin
[101]693 if fileid < GetFileCount then
[93]694 begin
[101]695 raw_info := GetRawInfo(FileID, DatOffset);
696 if not raw_info.LocSep then
[93]697 begin
[256]698 if not FRawOpened then
699 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
700 fmOpenReadWrite);
[101]701 Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
702 Fraw_file.CopyFrom(Src, Size);
[256]703 if UnloadWhenUnused then
704 begin
705 FRawOpened := False;
706 Fraw_file.Free;
707 end
708 else
709 FRawOpened := True;
[93]710 end
711 else
712 begin
[256]713 if not FSepOpened then
714 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
715 fmOpenReadWrite);
[101]716 Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
717 Fsep_file.CopyFrom(Src, Size);
[256]718 if UnloadWhenUnused then
719 begin
720 FSepOpened := False;
721 Fsep_file.Free;
722 end
723 else
724 FSepOpened := True;
[93]725 end;
726 end;
727end;
728
[105]729function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
[173]730const
731 EmptyBytes: Array[0..31] of Byte = (
732 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 );
[93]733begin
[101]734 if not LocSep then
[93]735 begin
[256]736 if not FRawOpened then
737 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
738 fmOpenReadWrite);
[173]739 if (Fraw_file.Size mod 32) > 0 then
740 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
[93]741 Result := Fraw_file.Size;
742 Fraw_file.Seek(0, soFromEnd);
[105]743 Fraw_file.CopyFrom(Src, Src.Size);
[173]744 if (Fraw_file.Size mod 32) > 0 then
745 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
[256]746 if UnloadWhenUnused then
747 begin
748 FRawOpened := False;
749 Fraw_file.Free;
750 end
751 else
752 FRawOpened := True;
[93]753 end
754 else
755 begin
[256]756 if not FSepOpened then
757 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
758 fmOpenReadWrite);
[173]759 if (Fsep_file.Size mod 32) > 0 then
760 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
[93]761 Result := Fsep_file.Size;
762 Fsep_file.Seek(0, soFromEnd);
[105]763 Fsep_file.CopyFrom(Src, Src.Size);
[173]764 if (Fsep_file.Size mod 32) > 0 then
765 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
[256]766 if UnloadWhenUnused then
767 begin
768 FSepOpened := False;
769 Fsep_file.Free;
770 end
771 else
772 FSepOpened := True;
[93]773 end;
774end;
775
776end.
Note: See TracBrowser for help on using the repository browser.