Index: oup/current/DataAccess/Access_OniArchive.pas
===================================================================
--- oup/current/DataAccess/Access_OniArchive.pas	(revision 255)
+++ oup/current/DataAccess/Access_OniArchive.pas	(revision 256)
@@ -12,6 +12,13 @@
     Fdat_files:          TFiles;
     Fdat_extensionsmap:  TExtensionsMap;
+    FUnloadWhenUnused:   Boolean;
+    FDatOpened:          Boolean;
+    FRawOpened:          Boolean;
+    FSepOpened:          Boolean;
+    procedure SetUnloadWhenUnused(doit: Boolean);
   protected
   public
+    property UnloadWhenUnused: Boolean Read FUnloadWhenUnused Write SetUnloadWhenUnused;
+
     constructor Create(DatFilename: String; ConnectionID: Integer; var Msg: TStatusMessages); override;
     procedure Close; override;
@@ -65,4 +72,7 @@
   Fdat_namedfilesmap: TNamedFilesMap;
 begin
+  FUnloadWhenUnused := True;
+  FDatOpened := False;
+  FRawOpened := False;
   Msg := SM_UnknownError;
   if not FileExists(DatFilename) then
@@ -72,5 +82,5 @@
   end;
   FFileName := DatFilename;
-  Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+  Fdat_file := TFileStream.Create(FFileName, fmOpenRead);
   Fdat_file.Read(Fdat_header, SizeOf(Fdat_header));
   header_pc  := True;
@@ -146,9 +156,5 @@
   FLevelNumber := FLevelNumber div 2;
 
-  Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
-    fmOpenReadWrite);
-  if not (FDataOS = DOS_WIN) then
-    Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
-      fmOpenReadWrite);
+  Fdat_file.Free;
 
   Msg := SM_OK;
@@ -163,11 +169,58 @@
 
 
+procedure TAccess_OniArchive.SetUnloadWhenUnused(doit: Boolean);
+begin
+  FUnloadWhenUnused := doit;
+  if FUnloadWhenUnused then
+  begin
+    if FDatOpened then
+    begin
+      FDatOpened := False;
+      Fdat_file.Free;
+    end;
+    if FRawOpened then
+    begin
+      FRawOpened := False;
+      Fraw_file.Free;
+    end;
+    if FSepOpened then
+    begin
+      FSepOpened := False;
+      Fsep_file.Free;
+    end;
+  end
+  else
+  begin
+    if not FDatOpened then
+    begin
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
+      FDatOpened := True;
+    end;
+    if not FRawOpened then
+    begin
+      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+        fmOpenReadWrite);
+      FRawOpened := True;
+    end;
+    if (not FSepOpened) and (FDataOS <> DOS_WIN) then
+    begin
+      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+        fmOpenReadWrite);
+      FSepOpened := True;
+    end;
+  end;
+end;
+
+
+
+
+
 procedure TAccess_OniArchive.Close;
 begin
-  if Assigned(Fdat_file) then
+  if FDatOpened then
     Fdat_file.Free;
-  if Assigned(Fraw_file) then
+  if FRawOpened then
     Fraw_file.Free;
-  if Assigned(Fsep_file) then
+  if FSepOpened then
     Fsep_file.Free;
   Self.Free;
@@ -324,8 +377,17 @@
     if GetFileInfo(FileID).Size > 0 then
     begin
+      if not FDatOpened then
+        Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
       Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
       streampos := Target.Position;
       Target.CopyFrom(Fdat_file, Fdat_files[fileid].Size);
       Target.Seek(streampos, soFromBeginning);
+      if UnloadWhenUnused then
+      begin
+        Fdat_file.Free;
+        FDatOpened := False;
+      end
+      else
+        FDatOpened := True;
     end;
   end;
@@ -336,6 +398,15 @@
   if fileid < GetFileCount then
   begin
+    if not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr, soFromBeginning);
     Fdat_file.CopyFrom(Src, Fdat_files[fileid].Size);
+    if UnloadWhenUnused then
+    begin
+      Fdat_file.Free;
+      FDatOpened := False;
+    end
+    else
+      FDatOpened := True;
   end;
 end;
@@ -349,8 +420,17 @@
     if not Assigned(Target) then
       Target := TMemoryStream.Create;
+    if not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
     streampos := Target.Position;
     Target.CopyFrom(Fdat_file, size);
     Target.Seek(streampos, soFromBeginning);
+    if UnloadWhenUnused then
+    begin
+      FDatOpened := False;
+      Fdat_file.Free;
+    end
+    else
+      FDatOpened := True;
   end;
 end;
@@ -360,6 +440,15 @@
   if fileid < GetFileCount then
   begin
+    if not FDatOpened then
+      Fdat_file := TFileStream.Create(FFileName, fmOpenReadWrite);
     Fdat_file.Seek(Fdat_files[fileid].DatAddr + offset, soFromBeginning);
     Fdat_file.CopyFrom(Src, Size);
+    if UnloadWhenUnused then
+    begin
+      Fdat_file.Free;
+      FDatOpened := False;
+    end
+    else
+      FDatOpened := True;
   end;
 end;
@@ -442,4 +531,7 @@
   if not LocSep then
   begin
+    if not FRawOpened then
+      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+        fmOpenReadWrite);
     if RawAddr <= Fraw_file.Size then
     begin
@@ -448,7 +540,17 @@
       Target.Seek(0, soFromBeginning);
     end;
+    if UnloadWhenUnused then
+    begin
+      FRawOpened := False;
+      Fraw_file.Free;
+    end
+    else
+      FRawOpened := True;
   end
   else
   begin
+    if not FSepOpened then
+      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+        fmOpenReadWrite);
     if RawAddr <= Fsep_file.Size then
     begin
@@ -457,4 +559,11 @@
       Target.Seek(0, soFromBeginning);
     end;
+    if UnloadWhenUnused then
+    begin
+      FSepOpened := False;
+      Fsep_file.Free;
+    end
+    else
+      FSepOpened := True;
   end;
 end;
@@ -482,15 +591,35 @@
     if not raw_info.LocSep then
     begin
+      if not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
       Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
       streampos := Target.Position;
       Target.CopyFrom(Fraw_file, raw_info.RawSize);
       Target.Seek(streampos, soFromBeginning);
-    end
-    else
-    begin
+      if UnloadWhenUnused then
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if FUnloadWhenUnused or not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
       Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
       streampos := Target.Position;
       Target.CopyFrom(Fsep_file, raw_info.RawSize);
       Target.Seek(streampos, soFromBeginning);
+      if UnloadWhenUnused then
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
+      else
+        FSepOpened := True;
     end;
   end;
@@ -506,11 +635,31 @@
     if not raw_info.LocSep then
     begin
+      if not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
       Fraw_file.Seek(raw_info.RawAddr, soFromBeginning);
       Fraw_file.CopyFrom(Src, Min(raw_info.RawSize, Src.Size));
-    end
-    else
-    begin
+      if UnloadWhenUnused then
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
       Fsep_file.Seek(raw_info.RawAddr, soFromBeginning);
       Fsep_file.CopyFrom(Src, raw_info.RawSize);
+      if UnloadWhenUnused then
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
+      else
+        FSepOpened := True;
     end;
   end;
@@ -545,11 +694,31 @@
     if not raw_info.LocSep then
     begin
+      if not FRawOpened then
+        Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+          fmOpenReadWrite);
       Fraw_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
       Fraw_file.CopyFrom(Src, Size);
-    end
-    else
-    begin
+      if UnloadWhenUnused then
+      begin
+        FRawOpened := False;
+        Fraw_file.Free;
+      end
+      else
+        FRawOpened := True;
+    end
+    else
+    begin
+      if not FSepOpened then
+        Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+          fmOpenReadWrite);
       Fsep_file.Seek(raw_info.RawAddr + Offset, soFromBeginning);
       Fsep_file.CopyFrom(Src, Size);
+      if UnloadWhenUnused then
+      begin
+        FSepOpened := False;
+        Fsep_file.Free;
+      end
+      else
+        FSepOpened := True;
     end;
   end;
@@ -563,4 +732,7 @@
   if not LocSep then
   begin
+    if not FRawOpened then
+      Fraw_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.raw'),
+        fmOpenReadWrite);
     if (Fraw_file.Size mod 32) > 0 then
       Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
@@ -570,7 +742,17 @@
     if (Fraw_file.Size mod 32) > 0 then
       Fraw_file.Write(EmptyBytes[0], 32 - (Fraw_file.Size mod 32));
+    if UnloadWhenUnused then
+    begin
+      FRawOpened := False;
+      Fraw_file.Free;
+    end
+    else
+      FRawOpened := True;
   end
   else
   begin
+    if not FSepOpened then
+      Fsep_file := TFileStream.Create(AnsiReplaceStr(FFileName, '.dat', '.sep'),
+        fmOpenReadWrite);
     if (Fsep_file.Size mod 32) > 0 then
       Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
@@ -580,4 +762,11 @@
     if (Fsep_file.Size mod 32) > 0 then
       Fsep_file.Write(EmptyBytes[0], 32 - (Fsep_file.Size mod 32));
+    if UnloadWhenUnused then
+    begin
+      FSepOpened := False;
+      Fsep_file.Free;
+    end
+    else
+      FSepOpened := True;
   end;
 end;
