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

Last change on this file since 1106 was 321, checked in by alloc, 16 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 not Assigned(Target) then
376 Target := TMemoryStream.Create;
377 if GetFileInfo(FileID).Size > 0 then
378 begin
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 raw_info.RawSize = 0 then
592 exit;
593 if not raw_info.LocSep then
594 begin
595 if not FRawOpened then
596 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
597 fmOpenReadWrite);
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);
602 if UnloadWhenUnused then
603 begin
604 FRawOpened := False;
605 Fraw_file.Free;
606 end
607 else
608 FRawOpened := True;
609 end
610 else
611 begin
612 if FUnloadWhenUnused or not FSepOpened then
613 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
614 fmOpenReadWrite);
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);
619 if UnloadWhenUnused then
620 begin
621 FSepOpened := False;
622 Fsep_file.Free;
623 end
624 else
625 FSepOpened := True;
626 end;
627 end;
628end;
629
630procedure TAccess_OniArchive.UpdateRawFile(FileID, DatOffset: Integer; Src: TStream);
631var
632 raw_info: TRawDataInfo;
633begin
634 if fileid < GetFileCount then
635 begin
636 raw_info := GetRawInfo(FileID, DatOffset);
637 if not raw_info.LocSep then
638 begin
639 if not FRawOpened then
640 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
641 fmOpenReadWrite);
642 Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
643 Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
644 if UnloadWhenUnused then
645 begin
646 FRawOpened := False;
647 Fraw_file.Free;
648 end
649 else
650 FRawOpened := True;
651 end
652 else
653 begin
654 if not FSepOpened then
655 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
656 fmOpenReadWrite);
657 Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
658 Fsep_file.CopyFrom(Src, raw_info.RawSize);
659 if UnloadWhenUnused then
660 begin
661 FSepOpened := False;
662 Fsep_file.Free;
663 end
664 else
665 FSepOpened := True;
666 end;
667 end;
668end;
669
670procedure TAccess_OniArchive.LoadRawFilePart(FileID, DatOffset, Offset, Size: Integer; var Target: TStream);
671var
672 Data: TStream;
673 streampos: Integer;
674begin
675 if not Assigned(Target) then
676 Target := TMemoryStream.Create;
677 if fileid < Self.GetFileCount then
678 begin
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);
685 end;
686end;
687
688
689procedure TAccess_OniArchive.UpdateRawFilePart(FileID, DatOffset, Offset, Size: Integer; Src: TStream);
690var
691 raw_info: TRawDataInfo;
692begin
693 if fileid < GetFileCount then
694 begin
695 raw_info := GetRawInfo(FileID, DatOffset);
696 if not raw_info.LocSep then
697 begin
698 if not FRawOpened then
699 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
700 fmOpenReadWrite);
701 Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
702 Fraw_file.CopyFrom(Src, Size);
703 if UnloadWhenUnused then
704 begin
705 FRawOpened := False;
706 Fraw_file.Free;
707 end
708 else
709 FRawOpened := True;
710 end
711 else
712 begin
713 if not FSepOpened then
714 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
715 fmOpenReadWrite);
716 Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
717 Fsep_file.CopyFrom(Src, Size);
718 if UnloadWhenUnused then
719 begin
720 FSepOpened := False;
721 Fsep_file.Free;
722 end
723 else
724 FSepOpened := True;
725 end;
726 end;
727end;
728
729function TAccess_OniArchive.AppendRawFile(LocSep: Boolean; Src: TStream): Integer;
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 );
733begin
734 if not LocSep then
735 begin
736 if not FRawOpened then
737 Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
738 fmOpenReadWrite);
739 if (Fraw_file.Size mod 32) > 0 then
740 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
741 Result := Fraw_file.Size;
742 Fraw_file.Seek(0, soFromEnd);
743 Fraw_file.CopyFrom(Src, Src.Size);
744 if (Fraw_file.Size mod 32) > 0 then
745 Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
746 if UnloadWhenUnused then
747 begin
748 FRawOpened := False;
749 Fraw_file.Free;
750 end
751 else
752 FRawOpened := True;
753 end
754 else
755 begin
756 if not FSepOpened then
757 Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
758 fmOpenReadWrite);
759 if (Fsep_file.Size mod 32) > 0 then
760 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
761 Result := Fsep_file.Size;
762 Fsep_file.Seek(0, soFromEnd);
763 Fsep_file.CopyFrom(Src, Src.Size);
764 if (Fsep_file.Size mod 32) > 0 then
765 Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
766 if UnloadWhenUnused then
767 begin
768 FSepOpened := False;
769 Fsep_file.Free;
770 end
771 else
772 FSepOpened := True;
773 end;
774end;
775
776end.
Note: See TracBrowser for help on using the repository browser.