From ddff7ab20e32664e09f06668f6e6250ea3b3abf7 Mon Sep 17 00:00:00 2001
From: Justin Clarke Casey
Date: Fri, 23 Jan 2009 17:07:37 +0000
Subject: * Add direct stream loading and saving methods to the archive module.
 * The async stream method does not yet signal completion to interested
 calling code

---
 .../Interfaces/IRegionArchiverModule.cs            | 19 +++++++++++++++
 .../Modules/World/Archiver/ArchiveReadRequest.cs   | 23 ++++++++++--------
 .../World/Archiver/ArchiveWriteRequestExecution.cs | 12 +++++-----
 .../Archiver/ArchiveWriteRequestPreparation.cs     | 26 ++++++++++++++++----
 .../Modules/World/Archiver/ArchiverModule.cs       | 28 +++++++++++++---------
 .../Modules/World/Archiver/Tests/ArchiverTests.cs  | 12 ++++++----
 .../Shared/Api/Implementation/OSSL_Api.cs          |  5 ++--
 7 files changed, 86 insertions(+), 39 deletions(-)

diff --git a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs
index 11eea20..7db784e 100644
--- a/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs
+++ b/OpenSim/Region/Environment/Interfaces/IRegionArchiverModule.cs
@@ -25,6 +25,8 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+using System.IO;
+
 namespace OpenSim.Region.Environment.Interfaces
 {
     /// <summary>
@@ -39,9 +41,26 @@ namespace OpenSim.Region.Environment.Interfaces
         void ArchiveRegion(string savePath);
 
         /// <summary>
+        /// Archive the region to a stream.
+        /// </summary>
+        /// 
+        /// This may be a little problematic to use right now since saves happen asynchronously and there is not yet
+        /// a mechanism to signal completion to the caller (possibly other than continually checking whether the 
+        /// stream has any data in it).  TODO: Address this.
+        /// 
+        /// <param name="saveStream"></param>
+        void ArchiveRegion(Stream saveStream);
+
+        /// <summary>
         /// Dearchive the given region archive into the scene
         /// </summary>
         /// <param name="loadPath"></param>
         void DearchiveRegion(string loadPath);
+        
+        /// <summary>
+        /// Dearchive a region from a stream
+        /// </summary>
+        /// <param name="loadStream"></param>
+        void DearchiveRegion(Stream loadStream);
     }
 }
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs
index 9a0f19a..09776a7 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveReadRequest.cs
@@ -52,7 +52,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         private static System.Text.ASCIIEncoding m_asciiEncoding = new System.Text.ASCIIEncoding();
 
         private Scene m_scene;
-        private string m_loadPath;
+        private Stream m_loadStream;
 
         /// <summary>
         /// Used to cache lookups for valid uuids.
@@ -62,12 +62,19 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         public ArchiveReadRequest(Scene scene, string loadPath)
         {
             m_scene = scene;
-            m_loadPath = loadPath;
-
-            DearchiveRegion();
+            m_loadStream = new GZipStream(GetStream(loadPath), CompressionMode.Decompress);
         }
+        
+        public ArchiveReadRequest(Scene scene, Stream loadStream)
+        {
+            m_scene = scene;
+            m_loadStream = loadStream;
+        }        
 
-        private void DearchiveRegion()
+        /// <summary>
+        /// Dearchive the region embodied in this request.
+        /// </summary>
+        public void DearchiveRegion()
         {
             // The same code can handle dearchiving 0.1 and 0.2 OpenSim Archive versions
             DearchiveRegion0DotStar();
@@ -75,9 +82,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         
         private void DearchiveRegion0DotStar()
         {
-            TarArchiveReader archive
-                = new TarArchiveReader(
-                    new GZipStream(GetStream(m_loadPath), CompressionMode.Decompress));
+            TarArchiveReader archive = new TarArchiveReader(m_loadStream);
 
             //AssetsDearchiver dearchiver = new AssetsDearchiver(m_scene.AssetCache);
 
@@ -368,7 +373,6 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         /// <summary>
         /// Resolve path to a working FileStream
         /// </summary>
-
         private Stream GetStream(string path)
         {
             try
@@ -392,7 +396,6 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
                         // OK, now we know we have an HTTP URI to work with
 
                         return URIFetch(uri);
-
                     }
                 }
             }
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs
index b410e55..36d5eb5 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestExecution.cs
@@ -28,7 +28,6 @@
 using System;
 using System.Collections.Generic;
 using System.IO;
-using System.IO.Compression;
 using System.Reflection;
 using System.Xml;
 using OpenMetaverse;
@@ -57,20 +56,20 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         protected IRegionSerialiserModule m_serialiser;
         protected List<SceneObjectGroup> m_sceneObjects;
         protected RegionInfo m_regionInfo;
-        protected string m_savePath;
+        protected Stream m_saveStream;
 
         public ArchiveWriteRequestExecution(
              List<SceneObjectGroup> sceneObjects,
              ITerrainModule terrainModule,
              IRegionSerialiserModule serialiser,
              RegionInfo regionInfo,
-             string savePath)
+             Stream saveStream)
         {
             m_sceneObjects = sceneObjects;
             m_terrainModule = terrainModule;
             m_serialiser = serialiser;
             m_regionInfo = regionInfo;
-            m_savePath = savePath;
+            m_saveStream = saveStream;
         }
 
         protected internal void ReceivedAllAssets(IDictionary<UUID, AssetBase> assetsFound, ICollection<UUID> assetsNotFoundUuids)
@@ -124,9 +123,10 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
             AssetsArchiver assetsArchiver = new AssetsArchiver(assetsFound);
             assetsArchiver.Archive(archive);
 
-            archive.WriteTar(new GZipStream(new FileStream(m_savePath, FileMode.Create), CompressionMode.Compress));
+            archive.WriteTar(m_saveStream);
 
-            m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive {0}", m_savePath);
+//            m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_regionInfo.RegionName);
+            m_log.InfoFormat("[ARCHIVER]: Wrote out OpenSimulator archive for {0}", m_saveStream);
         }
 
         /// <summary>
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
index 7c1d015..e9005ae 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiveWriteRequestPreparation.cs
@@ -33,8 +33,9 @@ using OpenSim.Region.Environment.Modules.World.Terrain;
 using OpenSim.Region.Environment.Scenes;
 using System;
 using System.Collections.Generic;
+using System.IO;
+using System.IO.Compression;
 using System.Reflection;
-//using System.Text;
 using System.Text.RegularExpressions;
 using System.Threading;
 using OpenMetaverse;
@@ -51,7 +52,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
         protected Scene m_scene;
-        protected string m_savePath;
+        protected Stream m_saveStream;
 
         /// <summary>
         /// Used as a temporary store of an asset which represents an object.  This can be a null if no appropriate
@@ -70,8 +71,19 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
         public ArchiveWriteRequestPreparation(Scene scene, string savePath)
         {
             m_scene = scene;
-            m_savePath = savePath;
+            m_saveStream = new GZipStream(new FileStream(savePath, FileMode.Create), CompressionMode.Compress);            
         }
+        
+        /// <summary>
+        /// Constructor.
+        /// </summary>
+        /// <param name="scene"></param>
+        /// <param name="saveStream">The stream to which to save data.</param>
+        public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream)
+        {
+            m_scene = scene;
+            m_saveStream = saveStream;            
+        }        
 
         /// <summary>
         /// The callback made when we request the asset for an object from the asset service.
@@ -257,8 +269,12 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
             }
         }
 
+        /// <summary>
+        /// Archive the region requested.
+        /// </summary>
+        /// <exception cref="System.IO.IOException">if there was an io problem with creating the file</exception>
         public void ArchiveRegion()
-        {
+        {                            
             Dictionary<UUID, int> assetUuids = new Dictionary<UUID, int>();
 
             List<EntityBase> entities = m_scene.GetEntities();
@@ -309,7 +325,7 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
                     m_scene.RequestModuleInterface<ITerrainModule>(),
                     m_scene.RequestModuleInterface<IRegionSerialiserModule>(),
                     m_scene.RegionInfo,
-                    m_savePath);
+                    m_saveStream);
             
             new AssetsRequest(assetUuids.Keys, m_scene.AssetCache, awre.ReceivedAllAssets).Execute();
         }
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs
index de60472..f07185c 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/ArchiverModule.cs
@@ -25,15 +25,16 @@
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-using OpenSim.Framework.Communications.Cache;
-using OpenSim.Region.Environment.Interfaces;
-using OpenSim.Region.Environment.Modules.World.Serialiser;
-using OpenSim.Region.Environment.Scenes;
 using System.Collections.Generic;
+using System.IO;
 using System.Reflection;
 using OpenMetaverse;
 using log4net;
 using Nini.Config;
+using OpenSim.Framework.Communications.Cache;
+using OpenSim.Region.Environment.Interfaces;
+using OpenSim.Region.Environment.Modules.World.Serialiser;
+using OpenSim.Region.Environment.Scenes;
 
 namespace OpenSim.Region.Environment.Modules.World.Archiver
 {
@@ -44,14 +45,9 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
     {
         private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
-        /// <summary>
-        /// Scene to which this module belongs
-        /// </summary>
-        /// <param name="scene"></param>
-        /// <param name="source"></param>
         private Scene m_scene;
 
-        public string Name { get { return "ArchiverModule"; } }
+        public string Name { get { return "Archiver Module"; } }
 
         public bool IsSharedModule { get { return false; } }
 
@@ -75,12 +71,22 @@ namespace OpenSim.Region.Environment.Modules.World.Archiver
             
             new ArchiveWriteRequestPreparation(m_scene, savePath).ArchiveRegion();
         }
+        
+        public void ArchiveRegion(Stream saveStream)
+        {
+            new ArchiveWriteRequestPreparation(m_scene, saveStream).ArchiveRegion();
+        }
 
         public void DearchiveRegion(string loadPath)
         {
             m_log.InfoFormat("[SCENE]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath);
             
-            new ArchiveReadRequest(m_scene, loadPath);
+            new ArchiveReadRequest(m_scene, loadPath).DearchiveRegion();
+        }
+        
+        public void DearchiveRegion(Stream loadStream)
+        {
+            new ArchiveReadRequest(m_scene, loadStream).DearchiveRegion();
         }
     }
 }
diff --git a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs
index c2f0d63..149293d 100644
--- a/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs
+++ b/OpenSim/Region/Environment/Modules/World/Archiver/Tests/ArchiverTests.cs
@@ -26,18 +26,22 @@
  */
 
 using NUnit.Framework;
+using OpenSim.Region.Environment.Modules.World.Archiver;
 
-namespace OpenSim.Region.Environment.Modules.World.Archiver
+namespace OpenSim.Region.Environment.Modules.World.Archiver.Tests
 {
     [TestFixture]
     public class ArchiverTests
     {
         /// <summary>
-        /// Test loading a V0.2 OpenSim Region Archive.  Does not yet do what it says on the tin
+        /// Test saving a V0.2 OpenSim Region Archive.  Does not yet do what it says on the tin
         /// </summary>
         [Test]        
-        public void TestLoadOarV0p2()
-        {
+        public void TestSaveOarV0p2()
+        {            
+            // Create an archive containing only a terrain
+            //TarArchiveWriter taw = new TarArchiveWriter();
+            
             //System.Console.WriteLine("wibble");
         }
     }
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
index a9ee88a..2b6d08d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs
@@ -24,6 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -116,9 +117,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
             m_host = host;
             m_localID = localID;
             m_itemID = itemID;
-            
-            
-
+                        
             if (m_ScriptEngine.Config.GetBoolean("AllowOSFunctions", false))
                 m_OSFunctionsEnabled = true;
 
-- 
cgit v1.1