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

Last change on this file since 246 was 243, checked in by alloc, 17 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;
14 FUnloadWhenUnused: Boolean;
15 FDatOpened: Boolean;
16 FRawOpened: Boolean;
17 FSepOpened: Boolean;
[209]18 procedure SetUnloadWhenUnused(doit: Boolean);
[93]19 protected
20 public
[209]21 property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write SetUnloadWhenUnused;
[93]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
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;
84 Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
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
158 Fdat_file.Free;
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
[209]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
[101]220 if FDatOpened then
[93]221 Fdat_file.Free;
[101]222 if FRawOpened then
[93]223 Fraw_file.Free;
[101]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
[231]375 if GetFileInfo(FileID).Size > 0 then
[101]376 begin
[231]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;
[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
[101]400 if not FDatOpened then
[93]401 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
402 Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
[101]403 Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
[93]404 if UnloadWhenUnused then
[101]405 begin
406 Fdat_file.Free;
407 FDatOpened := False;
408 end
[93]409 else
410 FDatOpened := True;
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;
422 if not FDatOpened then
[93]423 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
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);
[93]428 if UnloadWhenUnused then
[101]429 begin
430 FDatOpened := False;
431 Fdat_file.Free;
432 end
[93]433 else
434 FDatOpened := True;
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
[101]442 if not FDatOpened then
[93]443 Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
444 Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
[101]445 Fdat_file.CopyFrom(Src, Size);
[93]446 if UnloadWhenUnused then
[101]447 begin
448 Fdat_file.Free;
449 FDatOpened := False;
450 end
[93]451 else
452 FDatOpened := True;
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
[101]533 if not FRawOpened then
[93]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;
542 if UnloadWhenUnused then
[101]543 begin
544 FRawOpened := False;
545 Fraw_file.Free;
546 end
[93]547 else
548 FRawOpened := True;
549 end
550 else
551 begin
[101]552 if not FSepOpened then
[93]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;
561 if UnloadWhenUnused then
[101]562 begin
563 FSepOpened := False;
564 Fsep_file.Free;
565 end
[93]566 else
567 FSepOpened := True;
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);
591 if not raw_info.LocSep then
[93]592 begin
[101]593 if not FRawOpened then
[93]594 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
595 fmOpenReadWrite);
[101]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);
[93]600 if UnloadWhenUnused then
[101]601 begin
602 FRawOpened := False;
603 Fraw_file.Free;
604 end
[93]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);
[101]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);
[93]617 if UnloadWhenUnused then
[101]618 begin
619 FSepOpened := False;
620 Fsep_file.Free;
621 end
[93]622 else
623 FSepOpened := True;
624 end;
625 end;
626end;
627
[101]628procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
[93]629var
[101]630 raw_info: TRawDataInfo;
[93]631begin
[101]632 if fileid < GetFileCount then
[93]633 begin
[101]634 raw_info := GetRawInfo(FileID, DatOffset);
635 if not raw_info.LocSep then
[93]636 begin
[101]637 if not FRawOpened then
[93]638 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
639 fmOpenReadWrite);
[101]640 Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
[192]641 Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
[93]642 if UnloadWhenUnused then
[101]643 begin
644 FRawOpened := False;
645 Fraw_file.Free;
646 end
[93]647 else
648 FRawOpened := True;
649 end
650 else
651 begin
[101]652 if not FSepOpened then
[93]653 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
654 fmOpenReadWrite);
[101]655 Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
656 Fsep_file.CopyFrom(Src, raw_info.RawSize);
[93]657 if UnloadWhenUnused then
[101]658 begin
659 FSepOpened := False;
660 Fsep_file.Free;
661 end
[93]662 else
663 FSepOpened := True;
664 end;
665 end;
666end;
667
[101]668procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
[93]669var
[101]670 Data: TStream;
671 streampos: Integer;
[93]672begin
[101]673 if not Assigned(Target) then
674 Target := TMemoryStream.Create;
675 if fileid < Self.GetFileCount then
[93]676 begin
[101]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);
[93]683 end;
684end;
685
[148]686
[101]687procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
[93]688var
[101]689 raw_info: TRawDataInfo;
[93]690begin
[101]691 if fileid < GetFileCount then
[93]692 begin
[101]693 raw_info := GetRawInfo(FileID, DatOffset);
694 if not raw_info.LocSep then
[93]695 begin
[101]696 if not FRawOpened then
[93]697 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
698 fmOpenReadWrite);
[101]699 Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
700 Fraw_file.CopyFrom(Src, Size);
[93]701 if UnloadWhenUnused then
[101]702 begin
703 FRawOpened := False;
704 Fraw_file.Free;
705 end
[93]706 else
707 FRawOpened := True;
708 end
709 else
710 begin
[101]711 if not FSepOpened then
[93]712 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
713 fmOpenReadWrite);
[101]714 Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
715 Fsep_file.CopyFrom(Src, Size);
[93]716 if UnloadWhenUnused then
[101]717 begin
718 FSepOpened := False;
719 Fsep_file.Free;
720 end
[93]721 else
722 FSepOpened := True;
723 end;
724 end;
725end;
726
[105]727function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
[173]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 );
[93]731begin
[101]732 if not LocSep then
[93]733 begin
[101]734 if not FRawOpened then
[93]735 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
736 fmOpenReadWrite);
[173]737 if (Fraw_file.Size mod 32) > 0 then
738 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
[93]739 Result := Fraw_file.Size;
740 Fraw_file.Seek(0, soFromEnd);
[105]741 Fraw_file.CopyFrom(Src, Src.Size);
[173]742 if (Fraw_file.Size mod 32) > 0 then
743 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
[93]744 if UnloadWhenUnused then
[101]745 begin
746 FRawOpened := False;
747 Fraw_file.Free;
748 end
[93]749 else
750 FRawOpened := True;
751 end
752 else
753 begin
[101]754 if not FSepOpened then
[93]755 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
756 fmOpenReadWrite);
[173]757 if (Fsep_file.Size mod 32) > 0 then
758 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
[93]759 Result := Fsep_file.Size;
760 Fsep_file.Seek(0, soFromEnd);
[105]761 Fsep_file.CopyFrom(Src, Src.Size);
[173]762 if (Fsep_file.Size mod 32) > 0 then
763 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
[93]764 if UnloadWhenUnused then
[101]765 begin
766 FSepOpened := False;
767 Fsep_file.Free;
768 end
[93]769 else
770 FSepOpened := True;
771 end;
772end;
773
774end.
Note: See TracBrowser for help on using the repository browser.