343c92f684fe81ba28ece6a79e502db30675e3da
3 {$DEFINE SFS_DWFAD_DEBUG}
12 SArray
= array of ShortString;
14 TWADFile
= class(TObject
)
16 fFileName
: AnsiString; // empty: not opened
19 function getIsOpen (): Boolean;
23 destructor Destroy(); override;
27 function ReadFile (FileName
: AnsiString): Boolean;
28 function ReadMemory (Data
: Pointer; Len
: LongWord): Boolean;
29 function GetResource (Section
, Resource
: AnsiString; var pData
: Pointer; var Len
: Integer): Boolean;
30 function GetResourcesList (Section
: AnsiString): SArray
;
32 property isOpen
: Boolean read getIsOpen
;
36 procedure g_ProcessResourceStr (ResourceStr
: AnsiString; var FileName
, SectionName
, ResourceName
: AnsiString); overload
;
37 procedure g_ProcessResourceStr (ResourceStr
: AnsiString; FileName
, SectionName
, ResourceName
: PString); overload
;
39 // return fixed AnsiString or empty AnsiString
40 function findDiskWad (fname
: AnsiString): AnsiString;
46 SysUtils
, Classes
, BinEditor
, e_log
, g_options
, utils
;
49 function findDiskWad (fname
: AnsiString): AnsiString;
52 if not findFileCI(fname
) then
54 //e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s] [%s]', [path, ExtractFileName(fname)]), MSG_NOTIFY);
55 if StrEquCI1251(ExtractFileExt(fname
), '.wad') then
57 fname
:= ChangeFileExt(ExtractFileName(fname
), '.pk3');
58 //e_WriteLog(Format(' looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
59 if not findFileCI(fname
) then
61 //e_WriteLog(Format(' looking for [%s] [%s]', [path, rfn]), MSG_NOTIFY);
62 fname
:= ChangeFileExt(ExtractFileName(fname
), '.zip');
63 if not findFileCI(fname
) then exit
;
70 //e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
74 //if rfn <> ExtractFileName(FileName) then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY);
80 procedure g_ProcessResourceStr (ResourceStr
: AnsiString; var FileName
, SectionName
, ResourceName
: AnsiString);
84 //e_WriteLog(Format('g_ProcessResourceStr0: [%s]', [ResourceStr]), MSG_NOTIFY);
85 for i
:= Length(ResourceStr
) downto 1 do if ResourceStr
[i
] = ':' then break
;
86 FileName
:= Copy(ResourceStr
, 1, i
-1);
87 for a
:= i
+1 to Length(ResourceStr
) do if (ResourceStr
[a
] = '\') or (ResourceStr
[a
] = '/') then Break
;
88 ResourceName
:= Copy(ResourceStr
, a
+1, Length(ResourceStr
)-Abs(a
));
89 SectionName
:= Copy(ResourceStr
, i
+1, Length(ResourceStr
)-Length(ResourceName
)-Length(FileName
)-2);
93 procedure g_ProcessResourceStr (ResourceStr
: AnsiString; FileName
, SectionName
, ResourceName
: PAnsiString);
95 a
, i
, l1
, l2
: Integer;
97 //e_WriteLog(Format('g_ProcessResourceStr1: [%s]', [ResourceStr]), MSG_NOTIFY);
98 for i
:= Length(ResourceStr
) downto 1 do if ResourceStr
[i
] = ':' then break
;
99 if FileName
<> nil then
101 FileName
^ := Copy(ResourceStr
, 1, i
-1);
102 l1
:= Length(FileName
^);
108 for a
:= i
+1 to Length(ResourceStr
) do if (ResourceStr
[a
] = '\') or (ResourceStr
[a
] = '/') then break
;
109 if ResourceName
<> nil then
111 ResourceName
^ := Copy(ResourceStr
, a
+1, Length(ResourceStr
)-Abs(a
));
112 l2
:= Length(ResourceName
^);
118 if SectionName
<> nil then SectionName
^ := Copy(ResourceStr
, i
+1, Length(ResourceStr
)-l2
-l1
-2);
123 constructor TWADFile
.Create();
129 destructor TWADFile
.Destroy();
136 function TWADFile
.getIsOpen (): Boolean;
138 result
:= (fFileName
<> '');
142 procedure TWADFile
.FreeWAD();
144 if fIter
<> nil then FreeAndNil(fIter
);
145 //if fFileName <> '' then e_WriteLog(Format('TWADFile.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY);
150 function removeExt (s
: AnsiString): AnsiString;
155 while (i
> 1) and (s
[i
-1] <> '.') and (s
[i
-1] <> '/') do Dec(i
);
156 if (i
> 1) and (s
[i
-1] = '.') then
158 //writeln('[', s, '] -> [', Copy(s, 1, i-2), ']');
159 s
:= Copy(s
, 1, i
-2);
164 function TWADFile
.GetResource (Section
, Resource
: AnsiString; var pData
: Pointer; var Len
: Integer): Boolean;
173 if not isOpen
or (fIter
= nil) then Exit
;
174 if length(Resource
) = 0 then Exit
; // just in case
175 if (length(Section
) <> 0) and (Section
[length(Section
)] <> '/') then Section
:= Section
+'/';
176 // backwards, due to possible similar names and such
177 for f
:= fIter
.Count
-1 downto 0 do
179 fi
:= fIter
.Files
[f
];
180 if fi
= nil then continue
;
181 //e_WriteLog(Format('DFWAD: searching for [%s : %s] in [%s]; current is [%s : %s]', [Section, Resource, fFileName, fi.path, fi.name]), MSG_NOTIFY);
182 if StrEquCI1251(fi
.path
, Section
) and StrEquCI1251(removeExt(fi
.name
), Resource
) then
185 //fn := fFileName+'::'+fi.path+fi.name;
186 //fs := SFSFileOpen(fn);
188 fs
:= fIter
.volume
.OpenFileByIndex(f
);
194 e_WriteLog(Format('DFWAD: can''t open file [%s%s] in [%s]', [Section
, Resource
, fFileName
]), MSG_WARNING
);
197 Len
:= Integer(fs
.size
);
201 fs
.ReadBuffer(pData
^, Len
);
213 {$IFDEF SFS_DWFAD_DEBUG}
215 e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section
, Resource
, fFileName
, Len
]), MSG_NOTIFY
);
220 e_WriteLog(Format('DFWAD: file [%s%s] not found in [%s]', [Section
, Resource
, fFileName
]), MSG_WARNING
);
224 function TWADFile
.GetResourcesList (Section
: AnsiString): SArray
;
230 if not isOpen
or (fIter
= nil) then Exit
;
231 if (length(Section
) <> 0) and (Section
[length(Section
)] <> '/') then Section
:= Section
+'/';
232 for f
:= 0 to fIter
.Count
-1 do
234 fi
:= fIter
.Files
[f
];
235 if fi
= nil then continue
;
236 if length(fi
.name
) = 0 then continue
;
237 if StrEquCI1251(fi
.path
, Section
) then
239 SetLength(result
, Length(result
)+1);
240 result
[high(result
)] := removeExt(fi
.name
);
246 function TWADFile
.ReadFile (FileName
: AnsiString): Boolean;
253 //e_WriteLog(Format('TWADFile.ReadFile: [%s]', [FileName]), MSG_NOTIFY);
255 rfn
:= findDiskWad(FileName
);
256 if length(rfn
) = 0 then
258 e_WriteLog(Format('TWADFile.ReadFile: error looking for [%s]', [FileName
]), MSG_NOTIFY
);
261 {$IFDEF SFS_DWFAD_DEBUG}
262 if gSFSDebug
then e_WriteLog(Format('TWADFile.ReadFile: FOUND [%s]', [rfn
]), MSG_NOTIFY
);
268 if not SFSAddDataFile(rfn
, true) then exit
;
272 if not SFSAddDataFileTemp(rfn
, true) then exit
;
277 fIter
:= SFSFileList(rfn
);
278 if fIter
= nil then Exit
;
280 {$IFDEF SFS_DWFAD_DEBUG}
281 if gSFSDebug
then e_WriteLog(Format('TWADFile.ReadFile: [%s] opened', [fFileName
]), MSG_NOTIFY
);
288 uniqueCounter
: Integer = 0;
290 function TWADFile
.ReadMemory (Data
: Pointer; Len
: LongWord): Boolean;
299 if (Data
= nil) or (Len
= 0) then
301 e_WriteLog('TWADFile.ReadMemory: EMPTY SUBWAD!', MSG_WARNING
);
305 fn
:= Format(' -- memwad %d -- ', [uniqueCounter
]);
307 {$IFDEF SFS_DWFAD_DEBUG}
308 e_WriteLog(Format('TWADFile.ReadMemory: [%s]', [fn
]), MSG_NOTIFY
);
312 st
:= TSFSMemoryStreamRO
.Create(Data
, Len
);
313 if not SFSAddSubDataFile(fn
, st
, true) then
323 fIter
:= SFSFileList(fn
);
324 if fIter
= nil then Exit
;
327 {$IFDEF SFS_DWFAD_DEBUG}
328 e_WriteLog(Format('TWADFile.ReadMemory: [%s] opened', [fFileName
]), MSG_NOTIFY
);
332 for f := 0 to fIter.Count-1 do
334 fi := fIter.Files[f];
335 if fi = nil then continue;
336 st := fIter.volume.OpenFileByIndex(f);
339 e_WriteLog(Format('[%s]: [%s : %s] CAN''T OPEN', [fFileName, fi.path, fi.name]), MSG_NOTIFY);
343 e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, st.size]), MSG_NOTIFY);
347 //fIter.volume.OpenFileByIndex(0);
355 sfsDiskDirs
:= '<exedir>/data'; //FIXME