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

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