changeset 6060:4a8c4559dc95 attach-custom-data

refactoring by introducing PluginStorageAreaAdapter
author Sebastien Jodogne <s.jodogne@gmail.com>
date Tue, 25 Mar 2025 21:35:08 +0100
parents ea2f3d9323e6
children c8df30b3e748
files OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake OrthancFramework/Sources/FileStorage/FilesystemStorage.h OrthancFramework/Sources/FileStorage/IStorageArea.h OrthancFramework/Sources/FileStorage/MemoryStorageArea.h OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.cpp OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h OrthancFramework/Sources/FileStorage/StorageAccessor.cpp OrthancFramework/Sources/FileStorage/StorageAccessor.h OrthancFramework/UnitTestsSources/FileStorageTests.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabase.h OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/OrthancPlugins.h OrthancServer/Sources/Database/IDatabaseWrapper.h OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h OrthancServer/Sources/OrthancInitialization.cpp OrthancServer/Sources/OrthancInitialization.h OrthancServer/Sources/ServerContext.cpp OrthancServer/Sources/ServerContext.h OrthancServer/Sources/ServerToolbox.cpp OrthancServer/Sources/ServerToolbox.h OrthancServer/Sources/main.cpp OrthancServer/UnitTestsSources/ServerConfigTests.cpp OrthancServer/UnitTestsSources/ServerIndexTests.cpp OrthancServer/UnitTestsSources/ServerJobsTests.cpp
diffstat 30 files changed, 216 insertions(+), 112 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Resources/CMake/OrthancFrameworkConfiguration.cmake	Tue Mar 25 21:35:08 2025 +0100
@@ -162,6 +162,7 @@
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/Enumerations.cpp
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/FileStorage/FileInfo.cpp
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/FileStorage/MemoryStorageArea.cpp
+  ${CMAKE_CURRENT_LIST_DIR}/../../Sources/FileStorage/PluginStorageAreaAdapter.cpp
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/HttpServer/CStringMatcher.cpp
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/HttpServer/HttpContentNegociation.cpp
   ${CMAKE_CURRENT_LIST_DIR}/../../Sources/HttpServer/HttpToolbox.cpp
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h	Tue Mar 25 21:35:08 2025 +0100
@@ -43,7 +43,7 @@
 
 namespace Orthanc
 {
-  class ORTHANC_PUBLIC FilesystemStorage : public ICoreStorageArea
+  class ORTHANC_PUBLIC FilesystemStorage : public IStorageArea
   {
     // TODO REMOVE THIS
     friend class FilesystemHttpSender;
--- a/OrthancFramework/Sources/FileStorage/IStorageArea.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Sources/FileStorage/IStorageArea.h	Tue Mar 25 21:35:08 2025 +0100
@@ -43,6 +43,31 @@
     {
     }
 
+    virtual void Create(const std::string& uuid,
+                        const void* content,
+                        size_t size,
+                        FileContentType type) = 0;
+
+    virtual IMemoryBuffer* ReadRange(const std::string& uuid,
+                                     FileContentType type,
+                                     uint64_t start /* inclusive */,
+                                     uint64_t end /* exclusive */) = 0;
+
+    virtual bool HasEfficientReadRange() const = 0;
+
+    virtual void Remove(const std::string& uuid,
+                        FileContentType type) = 0;
+  };
+
+
+  // storage area with customData (customData are used only in plugins)
+  class IPluginStorageArea : public boost::noncopyable
+  {
+  public:
+    virtual ~IPluginStorageArea()
+    {
+    }
+
     virtual void Create(std::string& customData /* out */,
                         const std::string& uuid,
                         const void* content,
@@ -63,50 +88,4 @@
                         FileContentType type,
                         const std::string& customData) = 0;
   };
-
-  // storage area without customData (customData are used only in plugins)
-  class ICoreStorageArea : public IStorageArea
-  {
-  public:
-    virtual void Create(std::string& customData,
-                        const std::string& uuid,
-                        const void* content,
-                        size_t size,
-                        FileContentType type,
-                        CompressionType compression,
-                        const DicomInstanceToStore* dicomInstance) ORTHANC_OVERRIDE
-    {
-      customData.clear();
-      Create(uuid, content, size, type);
-    }
-
-    virtual IMemoryBuffer* ReadRange(const std::string& uuid,
-                                     FileContentType type,
-                                     uint64_t start /* inclusive */,
-                                     uint64_t end /* exclusive */,
-                                     const std::string& customData) ORTHANC_OVERRIDE
-    {
-      return ReadRange(uuid, type, start, end);
-    }
-
-    virtual void Remove(const std::string& uuid,
-                        FileContentType type,
-                        const std::string& customData) ORTHANC_OVERRIDE
-    {
-      Remove(uuid, type);
-    }
-
-    virtual void Create(const std::string& uuid,
-                        const void* content,
-                        size_t size,
-                        FileContentType type) = 0;
-
-    virtual IMemoryBuffer* ReadRange(const std::string& uuid,
-                                     FileContentType type,
-                                     uint64_t start /* inclusive */,
-                                     uint64_t end /* exclusive */) = 0;
-
-    virtual void Remove(const std::string& uuid,
-                        FileContentType type) = 0;
-  };
 }
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h	Tue Mar 25 21:35:08 2025 +0100
@@ -33,7 +33,7 @@
 
 namespace Orthanc
 {
-  class MemoryStorageArea : public ICoreStorageArea
+  class MemoryStorageArea : public IStorageArea
   {
   private:
     typedef std::map<std::string, std::string*>  Content;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -0,0 +1,53 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "../PrecompiledHeaders.h"
+#include "PluginStorageAreaAdapter.h"
+
+#include "../OrthancException.h"
+
+namespace Orthanc
+{
+  PluginStorageAreaAdapter::PluginStorageAreaAdapter(IStorageArea* storage) :
+    storage_(storage)
+  {
+    if (storage == NULL)
+    {
+      throw OrthancException(Orthanc::ErrorCode_NullPointer);
+    }
+  }
+
+
+  void PluginStorageAreaAdapter::Create(std::string& customData,
+                                        const std::string& uuid,
+                                        const void* content,
+                                        size_t size,
+                                        FileContentType type,
+                                        CompressionType compression,
+                                        const DicomInstanceToStore* dicomInstance)
+  {
+    customData.clear();
+    storage_->Create(uuid, content, size, type);
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h	Tue Mar 25 21:35:08 2025 +0100
@@ -0,0 +1,69 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
+ * Department, University Hospital of Liege, Belgium
+ * Copyright (C) 2017-2023 Osimis S.A., Belgium
+ * Copyright (C) 2024-2025 Orthanc Team SRL, Belgium
+ * Copyright (C) 2021-2025 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
+ *
+ * This program is free software: you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation, either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program. If not, see
+ * <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "IStorageArea.h"
+
+
+namespace Orthanc
+{
+  class PluginStorageAreaAdapter : public IPluginStorageArea
+  {
+  private:
+    std::unique_ptr<IStorageArea> storage_;
+
+  public:
+    explicit PluginStorageAreaAdapter(IStorageArea* storage /* takes ownership */);
+
+    virtual void Create(std::string& customData,
+                        const std::string& uuid,
+                        const void* content,
+                        size_t size,
+                        FileContentType type,
+                        CompressionType compression,
+                        const DicomInstanceToStore* dicomInstance) ORTHANC_OVERRIDE;
+
+    virtual IMemoryBuffer* ReadRange(const std::string& uuid,
+                                     FileContentType type,
+                                     uint64_t start /* inclusive */,
+                                     uint64_t end /* exclusive */,
+                                     const std::string& customData) ORTHANC_OVERRIDE
+    {
+      return storage_->ReadRange(uuid, type, start, end);
+    }
+
+    virtual void Remove(const std::string& uuid,
+                        FileContentType type,
+                        const std::string& customData) ORTHANC_OVERRIDE
+    {
+      storage_->Remove(uuid, type);
+    }
+
+    virtual bool HasEfficientReadRange() const ORTHANC_OVERRIDE
+    {
+      return storage_->HasEfficientReadRange();
+    }
+  };
+}
--- a/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -275,7 +275,7 @@
   };
 
 
-  StorageAccessor::StorageAccessor(IStorageArea& area) :
+  StorageAccessor::StorageAccessor(IPluginStorageArea& area) :
     area_(area),
     cache_(NULL),
     metrics_(NULL)
@@ -283,7 +283,7 @@
   }
   
 
-  StorageAccessor::StorageAccessor(IStorageArea& area, 
+  StorageAccessor::StorageAccessor(IPluginStorageArea& area,
                                    StorageCache& cache) :
     area_(area),
     cache_(&cache),
@@ -292,7 +292,7 @@
   }
 
 
-  StorageAccessor::StorageAccessor(IStorageArea& area,
+  StorageAccessor::StorageAccessor(IPluginStorageArea& area,
                                    MetricsRegistry& metrics) :
     area_(area),
     cache_(NULL),
@@ -300,7 +300,7 @@
   {
   }
 
-  StorageAccessor::StorageAccessor(IStorageArea& area, 
+  StorageAccessor::StorageAccessor(IPluginStorageArea& area,
                                    StorageCache& cache,
                                    MetricsRegistry& metrics) :
     area_(area),
--- a/OrthancFramework/Sources/FileStorage/StorageAccessor.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/Sources/FileStorage/StorageAccessor.h	Tue Mar 25 21:35:08 2025 +0100
@@ -110,7 +110,7 @@
   private:
     class MetricsTimer;
 
-    IStorageArea&     area_;
+    IPluginStorageArea&     area_;
     StorageCache*     cache_;
     MetricsRegistry*  metrics_;
 
@@ -121,15 +121,15 @@
 #endif
 
   public:
-    explicit StorageAccessor(IStorageArea& area);
+    explicit StorageAccessor(IPluginStorageArea& area);
 
-    StorageAccessor(IStorageArea& area,
+    StorageAccessor(IPluginStorageArea& area,
                     StorageCache& cache);
 
-    StorageAccessor(IStorageArea& area,
+    StorageAccessor(IPluginStorageArea& area,
                     MetricsRegistry& metrics);
 
-    StorageAccessor(IStorageArea& area,
+    StorageAccessor(IPluginStorageArea& area,
                     StorageCache& cache,
                     MetricsRegistry& metrics);
 
--- a/OrthancFramework/UnitTestsSources/FileStorageTests.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancFramework/UnitTestsSources/FileStorageTests.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -30,10 +30,9 @@
 #include <gtest/gtest.h>
 
 #include "../Sources/FileStorage/FilesystemStorage.h"
+#include "../Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../Sources/FileStorage/StorageAccessor.h"
 #include "../Sources/FileStorage/StorageCache.h"
-#include "../Sources/HttpServer/BufferHttpSender.h"
-#include "../Sources/HttpServer/FilesystemHttpSender.h"
 #include "../Sources/Logging.h"
 #include "../Sources/OrthancException.h"
 #include "../Sources/Toolbox.h"
@@ -181,7 +180,7 @@
 
 TEST(StorageAccessor, NoCompression)
 {
-  FilesystemStorage s("UnitTestsStorage");
+  PluginStorageAreaAdapter s(new FilesystemStorage("UnitTestsStorage"));
   StorageCache cache;
   StorageAccessor accessor(s, cache);
 
@@ -203,7 +202,7 @@
 
 TEST(StorageAccessor, Compression)
 {
-  FilesystemStorage s("UnitTestsStorage");
+  PluginStorageAreaAdapter s(new FilesystemStorage("UnitTestsStorage"));
   StorageCache cache;
   StorageAccessor accessor(s, cache);
 
@@ -224,7 +223,7 @@
 
 TEST(StorageAccessor, Mix)
 {
-  FilesystemStorage s("UnitTestsStorage");
+  PluginStorageAreaAdapter s(new FilesystemStorage("UnitTestsStorage"));
   StorageCache cache;
   StorageAccessor accessor(s, cache);
 
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -1622,7 +1622,7 @@
 
 
   void OrthancPluginDatabase::Upgrade(unsigned int targetVersion,
-                                      IStorageArea& storageArea)
+                                      IPluginStorageArea& storageArea)
   {
     VoidDatabaseListener listener;
     
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabase.h	Tue Mar 25 21:35:08 2025 +0100
@@ -103,7 +103,7 @@
     virtual unsigned int GetDatabaseVersion() ORTHANC_OVERRIDE;
 
     virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea) ORTHANC_OVERRIDE;    
+                         IPluginStorageArea& storageArea) ORTHANC_OVERRIDE;
 
     virtual const Capabilities GetDatabaseCapabilities() const ORTHANC_OVERRIDE
     {
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -1233,7 +1233,7 @@
 
   
   void OrthancPluginDatabaseV3::Upgrade(unsigned int targetVersion,
-                                        IStorageArea& storageArea)
+                                        IPluginStorageArea& storageArea)
   {
     VoidDatabaseListener listener;
     
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV3.h	Tue Mar 25 21:35:08 2025 +0100
@@ -76,7 +76,7 @@
     virtual unsigned int GetDatabaseVersion() ORTHANC_OVERRIDE;
 
     virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea) ORTHANC_OVERRIDE;    
+                         IPluginStorageArea& storageArea) ORTHANC_OVERRIDE;
 
     virtual const Capabilities GetDatabaseCapabilities() const ORTHANC_OVERRIDE
     {
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -1963,7 +1963,7 @@
 
   
   void OrthancPluginDatabaseV4::Upgrade(unsigned int targetVersion,
-                                        IStorageArea& storageArea)
+                                        IPluginStorageArea& storageArea)
   {
     if (!open_)
     {
--- a/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPluginDatabaseV4.h	Tue Mar 25 21:35:08 2025 +0100
@@ -88,7 +88,7 @@
     virtual unsigned int GetDatabaseVersion() ORTHANC_OVERRIDE;
 
     virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea) ORTHANC_OVERRIDE;    
+                         IPluginStorageArea& storageArea) ORTHANC_OVERRIDE;
 
     virtual uint64_t MeasureLatency() ORTHANC_OVERRIDE;
 
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -39,7 +39,7 @@
 #include "../../../OrthancFramework/Sources/DicomParsing/DicomWebJsonVisitor.h"
 #include "../../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../../OrthancFramework/Sources/DicomParsing/Internals/DicomImageDecoder.h"
-#include "../../../OrthancFramework/Sources/DicomParsing/ToDcmtkBridge.h"
+#include "../../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../../OrthancFramework/Sources/HttpServer/HttpServer.h"
 #include "../../../OrthancFramework/Sources/HttpServer/HttpToolbox.h"
 #include "../../../OrthancFramework/Sources/Images/Image.h"
@@ -59,7 +59,6 @@
 #include "../../Sources/Database/VoidDatabaseListener.h"
 #include "../../Sources/OrthancConfiguration.h"
 #include "../../Sources/OrthancFindRequestHandler.h"
-#include "../../Sources/Search/IDatabaseConstraint.h"
 #include "../../Sources/Search/HierarchicalMatcher.h"
 #include "../../Sources/ServerContext.h"
 #include "../../Sources/ServerToolbox.h"
@@ -710,7 +709,7 @@
 
 
     // "legacy" storage plugins don't store customData -> derive from ICoreStorageArea
-    class PluginStorageAreaBase : public ICoreStorageArea
+    class PluginStorageAreaBase : public IStorageArea
     {
     private:
       OrthancPluginStorageCreate create_;
@@ -906,7 +905,7 @@
 
 
     // New in Orthanc 1.12.7
-    class PluginStorageArea3 : public IStorageArea
+    class PluginStorageArea3 : public IPluginStorageArea
     {
     private:
       OrthancPluginStorageCreate2     create_;
@@ -1098,15 +1097,15 @@
         return sharedLibrary_;
       }
 
-      IStorageArea* Create() const
+      IPluginStorageArea* Create() const
       {
         switch (version_)
         {
           case Version1:
-            return new PluginStorageArea(callbacks_, errorDictionary_);
+            return new PluginStorageAreaAdapter(new PluginStorageArea(callbacks_, errorDictionary_));
 
           case Version2:
-            return new PluginStorageArea2(callbacks2_, errorDictionary_);
+            return new PluginStorageAreaAdapter(new PluginStorageArea2(callbacks2_, errorDictionary_));
 
           case Version3:
             return new PluginStorageArea3(callbacks3_, errorDictionary_);
@@ -5262,7 +5261,7 @@
       {
         const _OrthancPluginStorageAreaRemove& p =
           *reinterpret_cast<const _OrthancPluginStorageAreaRemove*>(parameters);
-        IStorageArea& storage = *reinterpret_cast<IStorageArea*>(p.storageArea);
+        IPluginStorageArea& storage = *reinterpret_cast<IPluginStorageArea*>(p.storageArea);
         std::string customDataNotUsed;
         storage.Remove(p.uuid, Plugins::Convert(p.type), customDataNotUsed);
         return true;
@@ -6068,7 +6067,7 @@
         VoidDatabaseListener listener;
         
         {
-          IStorageArea& storage = *reinterpret_cast<IStorageArea*>(p.storageArea);
+          IPluginStorageArea& storage = *reinterpret_cast<IPluginStorageArea*>(p.storageArea);
 
           std::unique_ptr<IDatabaseWrapper::ITransaction> transaction(
             pimpl_->database_->StartTransaction(TransactionType_ReadWrite, listener));
@@ -6167,7 +6166,7 @@
   }
 
 
-  IStorageArea* OrthancPlugins::CreateStorageArea()
+  IPluginStorageArea* OrthancPlugins::CreateStorageArea()
   {
     if (!HasStorageArea())
     {
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.h	Tue Mar 25 21:35:08 2025 +0100
@@ -296,7 +296,7 @@
 
     bool HasStorageArea() const;
 
-    IStorageArea* CreateStorageArea();  // To be freed after use
+    IPluginStorageArea* CreateStorageArea();  // To be freed after use
 
     const SharedLibrary& GetStorageAreaLibrary() const;
 
--- a/OrthancServer/Sources/Database/IDatabaseWrapper.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/Database/IDatabaseWrapper.h	Tue Mar 25 21:35:08 2025 +0100
@@ -468,7 +468,7 @@
     virtual unsigned int GetDatabaseVersion() = 0;
 
     virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea) = 0;
+                         IPluginStorageArea& storageArea) = 0;
 
     virtual const Capabilities GetDatabaseCapabilities() const = 0;
 
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -2453,7 +2453,7 @@
 
 
   void SQLiteDatabaseWrapper::Upgrade(unsigned int targetVersion,
-                                      IStorageArea& storageArea)
+                                      IPluginStorageArea& storageArea)
   {
     boost::mutex::scoped_lock lock(mutex_);
 
--- a/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/Database/SQLiteDatabaseWrapper.h	Tue Mar 25 21:35:08 2025 +0100
@@ -88,7 +88,7 @@
     }
 
     virtual void Upgrade(unsigned int targetVersion,
-                         IStorageArea& storageArea) ORTHANC_OVERRIDE;
+                         IPluginStorageArea& storageArea) ORTHANC_OVERRIDE;
 
     virtual const Capabilities GetDatabaseCapabilities() const ORTHANC_OVERRIDE
     {
--- a/OrthancServer/Sources/OrthancInitialization.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/OrthancInitialization.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -40,6 +40,7 @@
 
 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h"
+#include "../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../OrthancFramework/Sources/HttpClient.h"
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "../../OrthancFramework/Sources/OrthancException.h"
@@ -453,7 +454,7 @@
   {
     // Anonymous namespace to avoid clashes between compilation modules
 
-    class FilesystemStorageWithoutDicom : public ICoreStorageArea
+    class FilesystemStorageWithoutDicom : public IStorageArea
     {
     private:
       FilesystemStorage storage_;
@@ -508,7 +509,7 @@
   }
 
 
-  static IStorageArea* CreateFilesystemStorage()
+  static IPluginStorageArea* CreateFilesystemStorage()
   {
     static const char* const SYNC_STORAGE_AREA = "SyncStorageArea";
     static const char* const STORE_DICOM = "StoreDicom";
@@ -528,12 +529,12 @@
 
     if (lock.GetConfiguration().GetBooleanParameter(STORE_DICOM, true))
     {
-      return new FilesystemStorage(storageDirectory.string(), fsyncOnWrite);
+      return new PluginStorageAreaAdapter(new FilesystemStorage(storageDirectory.string(), fsyncOnWrite));
     }
     else
     {
       LOG(WARNING) << "The DICOM files will not be stored, Orthanc running in index-only mode";
-      return new FilesystemStorageWithoutDicom(storageDirectory.string(), fsyncOnWrite);
+      return new PluginStorageAreaAdapter(new FilesystemStorageWithoutDicom(storageDirectory.string(), fsyncOnWrite));
     }
   }
 
@@ -544,7 +545,7 @@
   }
 
 
-  IStorageArea* CreateStorageArea()
+  IPluginStorageArea* CreateStorageArea()
   {
     return CreateFilesystemStorage();
   }
--- a/OrthancServer/Sources/OrthancInitialization.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/OrthancInitialization.h	Tue Mar 25 21:35:08 2025 +0100
@@ -35,7 +35,7 @@
 
   IDatabaseWrapper* CreateDatabaseWrapper();
 
-  IStorageArea* CreateStorageArea();
+  IPluginStorageArea* CreateStorageArea();
 
   void SetGlobalVerbosity(Verbosity verbosity);
 
--- a/OrthancServer/Sources/ServerContext.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/ServerContext.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -356,7 +356,7 @@
 
 
   ServerContext::ServerContext(IDatabaseWrapper& database,
-                               IStorageArea& area,
+                               IPluginStorageArea& area,
                                bool unitTesting,
                                size_t maxCompletedJobs,
                                bool readOnly,
--- a/OrthancServer/Sources/ServerContext.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/ServerContext.h	Tue Mar 25 21:35:08 2025 +0100
@@ -43,7 +43,7 @@
 namespace Orthanc
 {
   class DicomInstanceToStore;
-  class IStorageArea;
+  class IPluginStorageArea;
   class JobsEngine;
   class MetricsRegistry;
   class OrthancPlugins;
@@ -193,7 +193,7 @@
     virtual void SignalJobFailure(const std::string& jobId) ORTHANC_OVERRIDE;
 
     ServerIndex index_;
-    IStorageArea& area_;
+    IPluginStorageArea& area_;
     StorageCache storageCache_;
 
     bool compressionEnabled_;
@@ -313,7 +313,7 @@
     };
 
     ServerContext(IDatabaseWrapper& database,
-                  IStorageArea& area,
+                  IPluginStorageArea& area,
                   bool unitTesting,
                   size_t maxCompletedJobs,
                   bool readOnly,
--- a/OrthancServer/Sources/ServerToolbox.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/ServerToolbox.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -96,7 +96,7 @@
 
 
     void ReconstructMainDicomTags(IDatabaseWrapper::ITransaction& transaction,
-                                  IStorageArea& storageArea,
+                                  IPluginStorageArea& storageArea,
                                   ResourceType level)
     {
       // WARNING: The database should be locked with a transaction!
--- a/OrthancServer/Sources/ServerToolbox.h	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/ServerToolbox.h	Tue Mar 25 21:35:08 2025 +0100
@@ -32,7 +32,7 @@
 namespace Orthanc
 {
   class ServerContext;
-  class IStorageArea;
+  class IPluginStorageArea;
 
   namespace ServerToolbox
   {
@@ -42,7 +42,7 @@
                               ResourceType type);
 
     void ReconstructMainDicomTags(IDatabaseWrapper::ITransaction& transaction,
-                                  IStorageArea& storageArea,
+                                  IPluginStorageArea& storageArea,
                                   ResourceType level);
 
     void LoadIdentifiers(const DicomTag*& tags,
--- a/OrthancServer/Sources/main.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/Sources/main.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -30,6 +30,7 @@
 #include "../../OrthancFramework/Sources/DicomNetworking/DicomServer.h"
 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
+#include "../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../OrthancFramework/Sources/HttpServer/FilesystemHttpHandler.h"
 #include "../../OrthancFramework/Sources/HttpServer/HttpServer.h"
 #include "../../OrthancFramework/Sources/Logging.h"
@@ -1426,7 +1427,7 @@
 
 
 static void UpgradeDatabase(IDatabaseWrapper& database,
-                            IStorageArea& storageArea)
+                            IPluginStorageArea& storageArea)
 {
   // Upgrade the schema of the database, if needed
   unsigned int currentVersion = database.GetDatabaseVersion();
@@ -1529,7 +1530,7 @@
 
 
 static bool ConfigureServerContext(IDatabaseWrapper& database,
-                                   IStorageArea& storageArea,
+                                   IPluginStorageArea& storageArea,
                                    OrthancPlugins *plugins,
                                    bool loadJobsFromDatabase)
 {
@@ -1667,7 +1668,7 @@
 
 
 static bool ConfigureDatabase(IDatabaseWrapper& database,
-                              IStorageArea& storageArea,
+                              IPluginStorageArea& storageArea,
                               OrthancPlugins *plugins,
                               bool upgradeDatabase,
                               bool loadJobsFromDatabase)
@@ -1746,7 +1747,7 @@
                              bool loadJobsFromDatabase)
 {
   std::unique_ptr<IDatabaseWrapper>  databasePtr;
-  std::unique_ptr<IStorageArea>  storage;
+  std::unique_ptr<IPluginStorageArea>  storage;
 
 #if ORTHANC_ENABLE_PLUGINS == 1
   std::string databaseServerIdentifier;
@@ -1997,7 +1998,7 @@
         {
           SQLiteDatabaseWrapper inMemoryDatabase;
           inMemoryDatabase.Open();
-          MemoryStorageArea inMemoryStorage;
+          PluginStorageAreaAdapter inMemoryStorage(new MemoryStorageArea);
           ServerContext context(inMemoryDatabase, inMemoryStorage, true /* unit testing */, 0 /* max completed jobs */, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
           OrthancRestApi restApi(context, false /* no Orthanc Explorer */);
           restApi.GenerateOpenApiDocumentation(openapi);
@@ -2048,7 +2049,7 @@
         {
           SQLiteDatabaseWrapper inMemoryDatabase;
           inMemoryDatabase.Open();
-          MemoryStorageArea inMemoryStorage;
+          PluginStorageAreaAdapter inMemoryStorage(new MemoryStorageArea);
           ServerContext context(inMemoryDatabase, inMemoryStorage, true /* unit testing */, 0 /* max completed jobs */, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
           OrthancRestApi restApi(context, false /* no Orthanc Explorer */);
           restApi.GenerateReStructuredTextCheatSheet(cheatsheet, "https://orthanc.uclouvain.be/api/index.html");
--- a/OrthancServer/UnitTestsSources/ServerConfigTests.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/UnitTestsSources/ServerConfigTests.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -26,9 +26,8 @@
 
 #include "../../OrthancFramework/Sources/Compatibility.h"
 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
-#include "../../OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.h"
+#include "../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../OrthancFramework/Sources/Logging.h"
-#include "../../OrthancFramework/Sources/SerializationToolbox.h"
 
 #include "../Sources/Database/SQLiteDatabaseWrapper.h"
 #include "../Sources/ServerContext.h"
@@ -39,7 +38,7 @@
 {
   const std::string path = "UnitTestsStorage";
 
-  MemoryStorageArea storage;
+  PluginStorageAreaAdapter storage(new MemoryStorageArea);
   SQLiteDatabaseWrapper db;   // The SQLite DB is in memory
   db.Open();
   ServerContext context(db, storage, true /* running unit tests */, 10, false, 1);
--- a/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/UnitTestsSources/ServerIndexTests.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -27,6 +27,7 @@
 #include "../../OrthancFramework/Sources/Compatibility.h"
 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h"
 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
+#include "../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../OrthancFramework/Sources/Images/Image.h"
 #include "../../OrthancFramework/Sources/Logging.h"
 
@@ -617,7 +618,7 @@
   const std::string path = "UnitTestsStorage";
 
   SystemToolbox::RemoveFile(path + "/index");
-  FilesystemStorage storage(path);
+  PluginStorageAreaAdapter storage(new FilesystemStorage(path));
   SQLiteDatabaseWrapper db;   // The SQLite DB is in memory
   db.Open();
   ServerContext context(db, storage, true /* running unit tests */, 10, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
@@ -699,7 +700,7 @@
   const std::string path = "UnitTestsStorage";
 
   SystemToolbox::RemoveFile(path + "/index");
-  FilesystemStorage storage(path);
+  PluginStorageAreaAdapter storage(new FilesystemStorage(path));
   SQLiteDatabaseWrapper db;   // The SQLite DB is in memory
   db.Open();
   ServerContext context(db, storage, true /* running unit tests */, 10, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
@@ -816,7 +817,7 @@
   {
     bool overwrite = (i == 0);
 
-    MemoryStorageArea storage;
+    PluginStorageAreaAdapter storage(new MemoryStorageArea);
     SQLiteDatabaseWrapper db;   // The SQLite DB is in memory
     db.Open();
     ServerContext context(db, storage, true /* running unit tests */, 10, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
@@ -981,7 +982,7 @@
   {
     const bool compression = (i == 0);
     
-    MemoryStorageArea storage;
+    PluginStorageAreaAdapter storage(new MemoryStorageArea);
     SQLiteDatabaseWrapper db;   // The SQLite DB is in memory
     db.Open();
     ServerContext context(db, storage, true /* running unit tests */, 10, false /* readonly */, 1 /* DCMTK concurrent transcoders */);
--- a/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Tue Mar 25 20:42:19 2025 +0100
+++ b/OrthancServer/UnitTestsSources/ServerJobsTests.cpp	Tue Mar 25 21:35:08 2025 +0100
@@ -26,6 +26,7 @@
 
 #include "../../OrthancFramework/Sources/Compatibility.h"
 #include "../../OrthancFramework/Sources/FileStorage/MemoryStorageArea.h"
+#include "../../OrthancFramework/Sources/FileStorage/PluginStorageAreaAdapter.h"
 #include "../../OrthancFramework/Sources/JobsEngine/Operations/LogJobOperation.h"
 #include "../../OrthancFramework/Sources/Logging.h"
 #include "../../OrthancFramework/Sources/SerializationToolbox.h"
@@ -528,12 +529,13 @@
   class OrthancJobsSerialization : public testing::Test
   {
   private:
-    MemoryStorageArea              storage_;
-    SQLiteDatabaseWrapper          db_;   // The SQLite DB is in memory
-    std::unique_ptr<ServerContext>   context_;
+    PluginStorageAreaAdapter        storage_;
+    SQLiteDatabaseWrapper           db_;   // The SQLite DB is in memory
+    std::unique_ptr<ServerContext>  context_;
 
   public:
-    OrthancJobsSerialization()
+    OrthancJobsSerialization() :
+      storage_(new MemoryStorageArea)
     {
       db_.Open();
       context_.reset(new ServerContext(db_, storage_, true /* running unit tests */, 10, false /* readonly */, 1 /* DCMTK concurrent transcoders */));