DEADSOFTWARE

sfs system now works!
authorKetmar Dark <ketmar@ketmar.no-ip.org>
Thu, 7 Apr 2016 23:11:26 +0000 (02:11 +0300)
committerKetmar Dark <ketmar@ketmar.no-ip.org>
Thu, 7 Apr 2016 23:51:51 +0000 (02:51 +0300)
src/sfs/sfs.pas
src/sfs/sfsMemFS.pas
src/sfs/sfsPlainFS.pas
src/sfs/sfsZipFS.pas
src/shared/WADEDITOR.pas

index 3fa92fa728b5537d2d32787e51ceb1e16071d652..9615d4b4db7549457453df0d0933e3bb57725303 100644 (file)
@@ -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;
index f3fcf0b03a269babc3fc5a2b57e8306eef1187bb..2256e7fc48bc28a766359551cb93b6a364d3088c 100644 (file)
@@ -33,6 +33,8 @@ type
     procedure SLHRead ();
 
     procedure ReadDirectory (); override;
+
+  public
     function OpenFileByIndex (const index: Integer): TStream; override;
   end;
 
index 54438f08835a69a935a33fab3f37c1e49870a752..bda12681ff873e4717f4d3a3bc66a1f68d705cc0 100644 (file)
@@ -49,6 +49,8 @@ type
     procedure SINReadDirectory ();
 
     procedure ReadDirectory (); override;
+
+  public
     function OpenFileByIndex (const index: Integer): TStream; override;
   end;
 
index e76aa9adf24e6bd3731fe6e76adee2eedc1c2a08..b3a83245b24a00609629b52bf32537e68d32a251 100644 (file)
@@ -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;
index 903922fccda3b90be88aa5efd675d0f9dacf6650..8da2b385e77822c8b8254564f25dd420f993c973 100644 (file)
@@ -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;