From 74b8cc24c941b92453f71fa9c912db10119acf81 Mon Sep 17 00:00:00 2001 From: Ketmar Dark Date: Fri, 8 Apr 2016 02:11:26 +0300 Subject: [PATCH] sfs system now works! --- src/sfs/sfs.pas | 54 +++++++++++++--------- src/sfs/sfsMemFS.pas | 2 + src/sfs/sfsPlainFS.pas | 2 + src/sfs/sfsZipFS.pas | 8 +++- src/shared/WADEDITOR.pas | 97 +++++++++++++++++++++++++++++++--------- 5 files changed, 120 insertions(+), 43 deletions(-) diff --git a/src/sfs/sfs.pas b/src/sfs/sfs.pas index 3fa92fa..9615d4b 100644 --- a/src/sfs/sfs.pas +++ b/src/sfs/sfs.pas @@ -37,6 +37,7 @@ type // òîì ÍÅ ÄÎËÆÅÍ óáèâàòüñÿ íèêàê èíà÷å, ÷åì ïðè ïîìîùè ôàáðèêè! TSFSVolume = class protected + fRC: Integer; // refcounter for other objects fFileName: TSFSString;// îáû÷íî èìÿ îðèãèíàëüíîãî ôàéëà fFileStream: TStream; // îáû÷íî ïîòîê äëÿ ÷òåíèÿ îðèãèíàëüíîãî ôàéëà fFiles: TObjectList; // TSFSFileInfo èëè íàñëåäíèêè @@ -64,9 +65,6 @@ type // åñëè ôàéë íå íàéäåí, âåðíóòü -1. function FindFile (const fPath, fName: TSFSString): Integer; virtual; - // ïðè îøèáêàõ êèäàòüñÿ èñêëþ÷åíèÿìè. - function OpenFileByIndex (const index: Integer): TStream; virtual; abstract; - // âîçâðàùàåò êîëè÷åñòâî ôàéëîâ â fFiles function GetFileCount (): Integer; virtual; @@ -87,6 +85,9 @@ type // òàêæå îíà íîðìàëèçóåò âèä èì¸í. procedure DoDirectoryRead (); + // ïðè îøèáêàõ êèäàòüñÿ èñêëþ÷åíèÿìè. + function OpenFileByIndex (const index: Integer): TStream; virtual; abstract; + // åñëè íå ñìîãëî îòêóïîðèòü ôàéëî (èëè åù¸ ãäå îøèáëîñü), çàøâûðí¸ò èñêëþ÷åíèå. function OpenFileEx (const fName: TSFSString): TStream; virtual; @@ -134,6 +135,7 @@ type constructor Create (const pVolume: TSFSVolume); destructor Destroy (); override; + property Volume: TSFSVolume read fVolume; property Count: Integer read GetCount; // ïðè íåïðàâèëüíîì èíäåêñå ìîë÷à âåðí¸ò NIL. // ïðè ïðàâèëüíîì òîæå ìîæåò âåðíóòü NIL! @@ -588,22 +590,29 @@ var used: Boolean; // ôëàæîê çàþçàíîñòè ïîòîêà êåì-òî åù¸ begin if fFactory <> nil then fFactory.Recycle(fVolume); - fVolume := nil; fFactory := nil; fPackName := ''; - - // òèïà ìóñîðîñáîðíèê: åñëè íàø ïîòîê áîëåå íèêåì íå þçàåòñÿ, - // òî óãðîáèòü åãî íàôèã. - me := volumes.IndexOf(self); - used := false; - f := volumes.Count-1; - while not used and (f >= 0) do + if fVolume <> nil then used := (fVolume.fRC <> 0) else used := false; + fVolume := nil; + fFactory := nil; + fPackName := ''; + + // òèïà ìóñîðîñáîðíèê: åñëè íàø ïîòîê áîëåå íèêåì íå þçàåòñÿ, òî óãðîáèòü åãî íàôèã + if not used then begin - if (f <> me) and (volumes[f] <> nil) then + me := volumes.IndexOf(self); + f := volumes.Count-1; + while not used and (f >= 0) do begin - used := (TVolumeInfo(volumes[f]).fStream = fStream); - if not used then - used := (TVolumeInfo(volumes[f]).fVolume.fFileStream = fStream); + if (f <> me) and (volumes[f] <> nil) then + begin + used := (TVolumeInfo(volumes[f]).fStream = fStream); + if not used then + begin + used := (TVolumeInfo(volumes[f]).fVolume.fFileStream = fStream); + end; + if used then break; + end; + Dec(f); end; - Dec(f); end; if not used then FreeAndNil(fStream); // åñëè áîëüøå íèêåì íå þçàíî, ïðèøèá¸ì inherited Destroy(); @@ -641,8 +650,10 @@ constructor TSFSFileInfo.Create (pOwner: TSFSVolume); begin inherited Create(); fOwner := pOwner; - fPath := ''; fName := ''; - fSize := 0; fOfs := 0; + fPath := ''; + fName := ''; + fSize := 0; + fOfs := 0; if pOwner <> nil then pOwner.fFiles.Add(self); end; @@ -657,6 +668,7 @@ end; constructor TSFSVolume.Create (const pFileName: TSFSString; pSt: TStream); begin inherited Create(); + fRC := 0; fFileStream := pSt; fFileName := pFileName; fFiles := TObjectList.Create(true); @@ -728,6 +740,7 @@ end; procedure TSFSVolume.Clear (); begin + fRC := 0; //FIXME fFiles.Clear(); end; @@ -807,6 +820,7 @@ var begin f := FindVolumeInfoByVolumeInstance(fVolume); ASSERT(f <> -1); + if fVolume <> nil then Dec(fVolume.fRC); Dec(TVolumeInfo(volumes[f]).fOpenedFilesCount); // óáü¸ì çàïèñü, åñëè îíà âðåìåííàÿ, è â íåé íåò áîëüøå íè÷åãî îòêðûòîãî if not TVolumeInfo(volumes[f]).fPermanent and @@ -854,8 +868,7 @@ begin end; -function SFSAddDataFileEx (dataFileName: TSFSString; ds: TStream; - top, permanent: Integer): Integer; +function SFSAddDataFileEx (dataFileName: TSFSString; ds: TStream; top, permanent: Integer): Integer; // dataFileName ìîæåò èìåòü ïðåôèêñ òèïà "zip:" (ñì. âûøå: IsMyPrefix). // ìîæåò âûêèíóòü èñêëþ÷åíèå! // top: @@ -1171,6 +1184,7 @@ begin try result := TSFSFileList.Create(vi.fVolume); + Inc(vi.fVolume.fRC); except if not vi.fPermanent and (vi.fOpenedFilesCount < 1) then volumes[f] := nil; end; diff --git a/src/sfs/sfsMemFS.pas b/src/sfs/sfsMemFS.pas index f3fcf0b..2256e7f 100644 --- a/src/sfs/sfsMemFS.pas +++ b/src/sfs/sfsMemFS.pas @@ -33,6 +33,8 @@ type procedure SLHRead (); procedure ReadDirectory (); override; + + public function OpenFileByIndex (const index: Integer): TStream; override; end; diff --git a/src/sfs/sfsPlainFS.pas b/src/sfs/sfsPlainFS.pas index 54438f0..bda1268 100644 --- a/src/sfs/sfsPlainFS.pas +++ b/src/sfs/sfsPlainFS.pas @@ -49,6 +49,8 @@ type procedure SINReadDirectory (); procedure ReadDirectory (); override; + + public function OpenFileByIndex (const index: Integer): TStream; override; end; diff --git a/src/sfs/sfsZipFS.pas b/src/sfs/sfsZipFS.pas index e76aa9a..b3a8324 100644 --- a/src/sfs/sfsZipFS.pas +++ b/src/sfs/sfsZipFS.pas @@ -33,6 +33,8 @@ type procedure DFWADReadDirectory (); procedure ReadDirectory (); override; + + public function OpenFileByIndex (const index: Integer): TStream; override; end; @@ -408,12 +410,15 @@ begin if (index < 0) or (index >= fFiles.Count) or (fFiles[index] = nil) then exit; kill := false; try + { try fs := TFileStream.Create(fFileName, fmOpenRead or fmShareDenyWrite); kill := true; except fs := fFileStream; end; + } + fs := fFileStream; if TSFSZipFileInfo(fFiles[index]).fMethod = 0 then begin result := TSFSPartialStream.Create(fs, @@ -435,7 +440,7 @@ begin if TSFSZipFileInfo(fFiles[index]).fSize = -1 then begin TSFSZipFileInfo(fFiles[index]).fSize := 0; - //writeln('trying to determine file size...'); + //writeln('trying to determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']'); try while true do begin @@ -450,6 +455,7 @@ begin fs.Seek(TSFSZipFileInfo(fFiles[index]).fOfs, soBeginning); zs := TZDecompressionStream.Create(fs) except + //writeln('*** CAN''T determine file size for [', TSFSZipFileInfo(fFiles[index]).fPath, TSFSZipFileInfo(fFiles[index]).fName, ']'); FreeAndNil(zs); if kill then FreeAndNil(fs); result := nil; diff --git a/src/shared/WADEDITOR.pas b/src/shared/WADEDITOR.pas index 903922f..8da2b38 100644 --- a/src/shared/WADEDITOR.pas +++ b/src/shared/WADEDITOR.pas @@ -1,12 +1,6 @@ unit WADEDITOR; -{ ------------------------------------ -WADEDITOR.PAS ÂÅÐÑÈß ÎÒ 26.08.08 - -Ïîääåðæêà âàäîâ âåðñèè 1 ------------------------------------ -} +{.$DEFINE SFS_DWFAD_DEBUG} interface @@ -139,7 +133,7 @@ end; procedure TWADEditor_1.FreeWAD(); begin if fIter <> nil then FreeAndNil(fIter); - if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY); + //if fFileName <> '' then e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] closed', [fFileName]), MSG_NOTIFY); fFileName := ''; end; @@ -149,7 +143,7 @@ var f: Integer; fi: TSFSFileInfo; fs: TStream; - fn: string; + //fn: string; begin Result := False; if not isOpen or (fIter = nil) then Exit; @@ -162,11 +156,16 @@ begin if (SFSStrComp(fi.path, Section) = 0) and (SFSStrComp(fi.name, Resource) = 0) then begin // i found her! - fn := fFileName+'::'+fi.path+fi.name; - fs := SFSFileOpen(fn); + //fn := fFileName+'::'+fi.path+fi.name; + //fs := SFSFileOpen(fn); + try + fs := fIter.volume.OpenFileByIndex(f); + except + fs := nil; + end; if fs = nil then begin - e_WriteLog(Format('DFWAD: can''t open file [%s]', [fn]), MSG_NOTIFY); + e_WriteLog(Format('DFWAD: can''t open file [%s%s] in [%s]', [Section, Resource, fFileName]), MSG_WARNING); break; end; Len := Integer(fs.size); @@ -174,7 +173,9 @@ begin fs.ReadBuffer(pData^, Len); fs.Free; result := true; - e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY); + {$IFDEF SFS_DWFAD_DEBUG} + e_WriteLog(Format('DFWAD: file [%s%s] FOUND in [%s]; size is %d bytes', [Section, Resource, fFileName, Len]), MSG_NOTIFY); + {$ENDIF} exit; end; end; @@ -204,15 +205,39 @@ end; function TWADEditor_1.ReadFile (FileName: string): Boolean; +var + rfn: string; begin Result := False; - e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY); + //e_WriteLog(Format('TWADEditor_1.ReadFile: [%s]', [FileName]), MSG_NOTIFY); FreeWAD(); - if not FileExists(FileName) then Exit; - fIter := SFSFileList(FileName); + rfn := FileName; + if not FileExists(rfn) then + begin + //if length(rfn) >= 4 then e_WriteLog(Format('XXXX TWADEditor_1.ReadFile: [%s] [%s]', [Copy(rfn, length(rfn)-3, 4), Copy(rfn, 1, length(rfn)-4)]), MSG_NOTIFY); + if (length(rfn) >= 4) and (SFSStrComp(Copy(rfn, length(rfn)-3, 4), '.wad') = 0) then + begin + rfn := Copy(rfn, 1, length(rfn)-4); + if FileExists(rfn+'.pk3') then rfn := rfn+'.pk3' + else if FileExists(rfn+'.zip') then rfn := rfn+'.zip' + else rfn := FileName; + {.$IFDEF SFS_DWFAD_DEBUG} + if FileExists(rfn) then e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY); + {.$ENDIF} + end; + end; + if not FileExists(rfn) then exit; + {$IFDEF SFS_DWFAD_DEBUG} + e_WriteLog(Format('TWADEditor_1.ReadFile: FOUND [%s]', [rfn]), MSG_NOTIFY); + {$ENDIF} + // cache this wad + SFSAddDataFile(rfn); + fIter := SFSFileList(rfn); if fIter = nil then Exit; - fFileName := FileName; - e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY); + fFileName := rfn; + {$IFDEF SFS_DWFAD_DEBUG} + e_WriteLog(Format('TWADEditor_1.ReadFile: [%s] opened', [fFileName]), MSG_NOTIFY); + {$ENDIF} Result := True; end; @@ -223,17 +248,24 @@ var function TWADEditor_1.ReadMemory (Data: Pointer; Len: LongWord): Boolean; var Signature: array[0..4] of Char; - a: Integer; fn: string; st: TStream = nil; + //f: Integer; + //fi: TSFSFileInfo; begin Result := False; FreeWAD(); - if (Data = nil) or (Len = 0) then Exit; + if (Data = nil) or (Len = 0) then + begin + e_WriteLog('TWADEditor_1.ReadMemory: EMPTY SUBWAD!', MSG_WARNING); + Exit; + end; fn := Format(' -- memwad %d -- ', [uniqueCounter]); Inc(uniqueCounter); - e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY); + {$IFDEF SFS_DWFAD_DEBUG} + e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s]', [fn]), MSG_NOTIFY); + {$ENDIF} try st := TSFSMemoryStreamRO.Create(Data, Len); @@ -251,7 +283,28 @@ begin if fIter = nil then Exit; fFileName := fn; - e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY); + {$IFDEF SFS_DWFAD_DEBUG} + e_WriteLog(Format('TWADEditor_1.ReadMemory: [%s] opened', [fFileName]), MSG_NOTIFY); + {$ENDIF} + + { + for f := 0 to fIter.Count-1 do + begin + fi := fIter.Files[f]; + if fi = nil then continue; + st := fIter.volume.OpenFileByIndex(f); + if st = nil then + begin + e_WriteLog(Format('[%s]: [%s : %s] CAN''T OPEN', [fFileName, fi.path, fi.name]), MSG_NOTIFY); + end + else + begin + e_WriteLog(Format('[%s]: [%s : %s] %u', [fFileName, fi.path, fi.name, st.size]), MSG_NOTIFY); + st.Free; + end; + end; + //fIter.volume.OpenFileByIndex(0); + } Result := True; end; -- 2.29.2