changeset 301:4210556d96ab

fix build against 1.12.9
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 26 Nov 2025 08:39:29 +0100
parents 086904c6a9d6
children 7ffc9e968b3e
files CodeAnalysis/CustomFunctions.json Resources/Orthanc/CMake/Compiler.cmake Resources/Orthanc/CMake/DownloadOrthancFramework.cmake Resources/Orthanc/OrthancPluginCodeModel.json Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h Sources/DicomScpCallbacks.cpp
diffstat 7 files changed, 187 insertions(+), 36 deletions(-) [+]
line wrap: on
line diff
--- a/CodeAnalysis/CustomFunctions.json	Wed Nov 26 06:56:59 2025 +0100
+++ b/CodeAnalysis/CustomFunctions.json	Wed Nov 26 08:39:29 2025 +0100
@@ -206,6 +206,7 @@
       }
     ],
     "return_sdk_type" : "void",
+    "since_sdk" : [ 1, 12, 10 ],
     "sdk_functions" : [ "OrthancPluginRegisterFindCallback" ]
   },
 
@@ -275,7 +276,8 @@
         "callable_protocol_return" : "None"
       }
     ],
-    "return_sdk_type" : "void"
+    "return_sdk_type" : "void",
+    "since_sdk" : [ 1, 12, 10 ]
   },
 
   {
@@ -321,7 +323,8 @@
         "callable_protocol_return" : "None"
       }
     ],
-    "return_sdk_type" : "void"
+    "return_sdk_type" : "void",
+    "since_sdk" : [ 1, 12, 10 ]
   },
 
   {
--- a/Resources/Orthanc/CMake/Compiler.cmake	Wed Nov 26 06:56:59 2025 +0100
+++ b/Resources/Orthanc/CMake/Compiler.cmake	Wed Nov 26 08:39:29 2025 +0100
@@ -246,6 +246,9 @@
   # fix this error that appears with recent compilers on MacOS: boost/mpl/aux_/integral_wrapper.hpp:73:31: error: integer value -1 is outside the valid range of values [0, 3] for this enumeration type [-Wenum-constexpr-conversion]
   SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-enum-constexpr-conversion")
 
+  # it seems that some recent MacOS compilers don't set these flags correctly which prevents zlib from building correctly
+  SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64")
+
   add_definitions(
     -D_XOPEN_SOURCE=1
     )
--- a/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake	Wed Nov 26 06:56:59 2025 +0100
+++ b/Resources/Orthanc/CMake/DownloadOrthancFramework.cmake	Wed Nov 26 08:39:29 2025 +0100
@@ -215,6 +215,10 @@
         # Advanced storage 0.2.2 (framework pre-1.12.10)
         set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
         set(ORTHANC_FRAMEWORK_MD5 "bd5ba2cec329010b912209345acbdeaf")
+      elseif (ORTHANC_FRAMEWORK_VERSION STREQUAL "0ebe8cfd9bf7")
+        # Worklists plugin 0.9.0 (framework pre-1.12.10)
+        set(ORTHANC_FRAMEWORK_PRE_RELEASE ON)
+        set(ORTHANC_FRAMEWORK_MD5 "17a5ca9254e881ab89c93d052d4655cb")
       endif()
     endif()
   endif()
--- a/Resources/Orthanc/OrthancPluginCodeModel.json	Wed Nov 26 06:56:59 2025 +0100
+++ b/Resources/Orthanc/OrthancPluginCodeModel.json	Wed Nov 26 08:39:29 2025 +0100
@@ -47,7 +47,7 @@
                     "documentation": {
                         "args": {},
                         "description": [
-                            "This function returns the Orthanc called AET that a DICOM modality has used in a DICOM connection."
+                            "This function returns the AET that was called by the remote DICOM modality over a DICOM connection. This corresponds to one of the AETs used by Orthanc."
                         ],
                         "return": "The pointer to the called AET, NULL in case of error.",
                         "summary": "Get the called AET of a DICOM connection."
@@ -60,7 +60,12 @@
                     ]
                 }
             ],
-            "name": "OrthancPluginDicomConnection"
+            "name": "OrthancPluginDicomConnection",
+            "since_sdk": [
+                1,
+                12,
+                10
+            ]
         },
         {
             "destructor": "OrthancPluginFreeDicomInstance",
@@ -5591,7 +5596,6 @@
         "OrthancPluginGetImageBuffer",
         "OrthancPluginRestApiGet2",
         "OrthancPluginRegisterWorklistCallback",
-        "OrthancPluginRegisterWorklistCallback2",
         "OrthancPluginRegisterDecodeImageCallback",
         "OrthancPluginCreateImageAccessor",
         "OrthancPluginLookupDictionary",
@@ -5634,6 +5638,7 @@
         "OrthancPluginRegisterHttpAuthentication",
         "OrthancPluginRegisterAuditLogHandler",
         "OrthancPluginReserveQueueValue",
+        "OrthancPluginRegisterWorklistCallback2",
         "OrthancPluginRegisterFindCallback2",
         "OrthancPluginRegisterMoveCallback2",
         "OrthancPluginRegisterStorageCommitmentScpCallback2"
--- a/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp	Wed Nov 26 06:56:59 2025 +0100
+++ b/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.cpp	Wed Nov 26 08:39:29 2025 +0100
@@ -221,6 +221,19 @@
   }
 
 
+  MemoryBuffer::~MemoryBuffer()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void MemoryBuffer::Clear()
   {
     if (buffer_.data != NULL)
@@ -351,6 +364,8 @@
     }
   }
 
+
+#if (HAS_ORTHANC_PLUGIN_PEERS == 1) || (HAS_ORTHANC_PLUGIN_HTTP_CLIENT == 1) || (HAS_ORTHANC_PLUGIN_GENERIC_CALL_REST_API == 1)
   static void DecodeHttpHeaders(HttpHeaders& target,
                                 const MemoryBuffer& source)
   {
@@ -378,6 +393,8 @@
       }
     }
   }
+#endif
+
 
   // helper class to convert std::map of headers to the plugin SDK C structure
   class PluginHttpHeaders
@@ -652,6 +669,19 @@
   }
 
 
+  OrthancString::~OrthancString()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void OrthancString::Assign(char* str)
   {
     Clear();
@@ -1301,6 +1331,20 @@
     }
   }
 
+
+  OrthancImage::~OrthancImage()
+  {
+    try
+    {
+      Clear();
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS&)
+    {
+      // Don't throw exceptions in destructors
+    }
+  }
+
+
   void OrthancImage::UncompressPngImage(const void* data,
                                         size_t size)
   {
@@ -2676,32 +2720,42 @@
 
         return;
       }
-      else if (state == "Running")
+      else if (state == "Running" ||
+               state == "Pending" ||
+               state == "Paused" ||
+               state == "Retry")
       {
         continue;
       }
-      else if (!status.isMember("ErrorCode") ||
-               status["ErrorCode"].type() != Json::intValue)
+      else if (state == "Failure")
       {
-        ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
+        if (!status.isMember("ErrorCode") ||
+            status["ErrorCode"].type() != Json::intValue)
+        {
+          ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
+        }
+        else
+        {
+          if (!status.isMember("ErrorDescription") ||
+              status["ErrorDescription"].type() != Json::stringValue)
+          {
+            ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());
+          }
+          else
+          {
+  #if HAS_ORTHANC_EXCEPTION == 1
+            throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(status["ErrorCode"].asInt()),
+                                            status["ErrorDescription"].asString());
+  #else
+            ORTHANC_PLUGINS_LOG_ERROR("Exception while executing the job: " + status["ErrorDescription"].asString());
+            ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());          
+  #endif
+          }
+        }
       }
       else
       {
-        if (!status.isMember("ErrorDescription") ||
-            status["ErrorDescription"].type() != Json::stringValue)
-        {
-          ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());
-        }
-        else
-        {
-#if HAS_ORTHANC_EXCEPTION == 1
-          throw Orthanc::OrthancException(static_cast<Orthanc::ErrorCode>(status["ErrorCode"].asInt()),
-                                          status["ErrorDescription"].asString());
-#else
-          ORTHANC_PLUGINS_LOG_ERROR("Exception while executing the job: " + status["ErrorDescription"].asString());
-          ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(status["ErrorCode"].asInt());          
-#endif
-        }
+        ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(OrthancPluginErrorCode_InternalError);
       }
     }
   }
@@ -4607,8 +4661,11 @@
     uint8_t found = false;
     OrthancPlugins::MemoryBuffer valueBuffer;
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
     OrthancPluginErrorCode code = OrthancPluginDequeueValue(OrthancPlugins::GetGlobalContext(), &found,
                                                             *valueBuffer, queueId_.c_str(), origin);
+#pragma GCC diagnostic pop
 
     if (code != OrthancPluginErrorCode_Success)
     {
@@ -4643,4 +4700,54 @@
     }
   }
 #endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveInternal(std::string& value, uint64_t& valueId, OrthancPluginQueueOrigin origin, uint32_t releaseTimeout)
+  {
+    uint8_t found = false;
+    OrthancPlugins::MemoryBuffer valueBuffer;
+
+    OrthancPluginErrorCode code = OrthancPluginReserveQueueValue(OrthancPlugins::GetGlobalContext(), &found,
+                                                                 *valueBuffer, &valueId, queueId_.c_str(), origin, releaseTimeout);
+
+    if (code != OrthancPluginErrorCode_Success)
+    {
+      ORTHANC_PLUGINS_THROW_PLUGIN_ERROR_CODE(code);
+    }
+    else if (found)
+    {
+      valueBuffer.ToString(value);
+      return true;
+    }
+    else
+    {
+      return false;
+    }
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveBack(std::string& value, uint64_t& valueId, uint32_t releaseTimeout)
+  {
+    return ReserveInternal(value, valueId, OrthancPluginQueueOrigin_Back, releaseTimeout);
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  bool Queue::ReserveFront(std::string& value, uint64_t& valueId, uint32_t releaseTimeout)
+  {
+    return ReserveInternal(value, valueId, OrthancPluginQueueOrigin_Front, releaseTimeout);
+  }
+#endif
+
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+  void Queue::Acknowledge(uint64_t valueId)
+  {
+    OrthancPluginAcknowledgeQueueValue(OrthancPlugins::GetGlobalContext(), queueId_.c_str(), valueId);
+  }
+#endif
 }
--- a/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h	Wed Nov 26 06:56:59 2025 +0100
+++ b/Resources/Orthanc/Plugins/OrthancPluginCppWrapper.h	Wed Nov 26 08:39:29 2025 +0100
@@ -142,6 +142,12 @@
 #  define HAS_ORTHANC_PLUGIN_QUEUES            0
 #endif
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
+#  define HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE   1
+#else
+#  define HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE   0
+#endif
+
 
 // Macro to tag a function as having been deprecated
 #if (__cplusplus >= 201402L)  // C++14
@@ -213,10 +219,7 @@
   public:
     MemoryBuffer();
 
-    ~MemoryBuffer()
-    {
-      Clear();
-    }
+    ~MemoryBuffer();
 
     OrthancPluginMemoryBuffer* operator*()
     {
@@ -371,10 +374,7 @@
     {
     }
 
-    ~OrthancString()
-    {
-      Clear();
-    }
+    ~OrthancString();
 
     // This transfers ownership, warning: The string must have been
     // allocated by the Orthanc core
@@ -491,10 +491,7 @@
                  uint32_t                  pitch,
                  void*                     buffer);
 
-    ~OrthancImage()
-    {
-      Clear();
-    }
+    ~OrthancImage();
 
     void UncompressPngImage(const void* data,
                             size_t size);
@@ -1726,6 +1723,10 @@
 
     bool DequeueInternal(std::string& value, OrthancPluginQueueOrigin origin);
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveInternal(std::string& value, uint64_t& valueId, OrthancPluginQueueOrigin origin, uint32_t releaseTimeout);
+#endif
+
   public:
     explicit Queue(const std::string& queueId) :
       queueId_(queueId)
@@ -1745,17 +1746,37 @@
       Enqueue(value.empty() ? NULL : value.c_str(), value.size());
     }
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    // Use ReserveBack() instead
+    ORTHANC_PLUGIN_DEPRECATED
+#endif
     bool DequeueBack(std::string& value)
     {
       return DequeueInternal(value, OrthancPluginQueueOrigin_Back);
     }
 
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    // Use ReserveFront() instead
+    ORTHANC_PLUGIN_DEPRECATED
+#endif
     bool DequeueFront(std::string& value)
     {
       return DequeueInternal(value, OrthancPluginQueueOrigin_Front);
     }
 
     uint64_t GetSize();
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveBack(std::string& value, uint64_t& valueId, uint32_t releaseTimeout);
+#endif
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    bool ReserveFront(std::string& value, uint64_t& valueId, uint32_t releaseTimeout);
+#endif
+
+#if HAS_ORTHANC_PLUGIN_RESERVE_QUEUE_VALUE == 1
+    void Acknowledge(uint64_t valueId);
+#endif
   };
 #endif
 }
--- a/Sources/DicomScpCallbacks.cpp	Wed Nov 26 06:56:59 2025 +0100
+++ b/Sources/DicomScpCallbacks.cpp	Wed Nov 26 08:39:29 2025 +0100
@@ -147,6 +147,7 @@
 }
 
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
 static OrthancPluginErrorCode FindCallback2(OrthancPluginFindAnswers *answers,
                                             const OrthancPluginFindQuery *query,
                                             const OrthancPluginDicomConnection* connection)
@@ -195,6 +196,7 @@
     return e.GetErrorCode();
   }
 }
+#endif
 
 
 class IMoveDriver : public boost::noncopyable
@@ -580,6 +582,7 @@
 }
 
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
 static void* CreateMoveCallback3(OrthancPluginResourceType resourceType,
                                  const char *patientId,
                                  const char *accessionNumber,
@@ -728,6 +731,7 @@
     return NULL;
   }
 }
+#endif
 
 
 static uint32_t GetMoveSize2(void *moveDriver)
@@ -862,6 +866,7 @@
 }
 
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
 PyObject* RegisterFindCallback2(PyObject* module, PyObject* args)
 {
   // The GIL is locked at this point (no need to create "PythonLock")
@@ -879,6 +884,7 @@
   return ICallbackRegistration::Apply(
     registration, args, findScpCallback2_, "Python C-FIND SCP callback (v2)");
 }
+#endif
 
 
 PyObject* RegisterMoveCallback(PyObject* module, PyObject* args)
@@ -921,6 +927,7 @@
 }
 
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 12, 10)
 PyObject* RegisterMoveCallback3(PyObject* module, PyObject* args)
 {
   // The GIL is locked at this point (no need to create "PythonLock")
@@ -939,6 +946,7 @@
   return ICallbackRegistration::Apply4(
     registration, args, createMoveScpDriverCallback2_, getMoveSizeCallback_, applyMoveCallback_, freeMoveCallback_, "Python C-MOVE SCP callback (v3)");
 }
+#endif
 
 
 PyObject* RegisterWorklistCallback(PyObject* module, PyObject* args)