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

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