changeset 6177:81c7f800856a

using PluginMemoryBuffer32 to simplify OrthancPlugins
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 12 Jun 2025 11:01:53 +0200
parents 705343f27dab
children 8cfe9a74e771
files OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h
diffstat 3 files changed, 115 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Thu Jun 12 09:55:38 2025 +0200
+++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp	Thu Jun 12 11:01:53 2025 +0200
@@ -418,78 +418,45 @@
   };
   
 
-  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
+  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer* target,
                                  const void* data,
                                  size_t size)
   {
-    if (static_cast<uint32_t>(size) != size)
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory, ERROR_MESSAGE_64BIT);
-    }
-
-    target.size = size;
-
-    if (size == 0)
-    {
-      target.data = NULL;
-    }
-    else
-    {
-      target.data = malloc(size);
-      if (target.data != NULL)
-      {
-        memcpy(target.data, data, size);
-      }
-      else
-      {
-        throw OrthancException(ErrorCode_NotEnoughMemory);
-      }
-    }
+    PluginMemoryBuffer32 buffer;
+    buffer.Assign(data, size);
+    buffer.Release(target);
   }
 
 
-  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target,
+  static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer* target,
                                  const std::string& str)
   {
-    if (str.size() == 0)
-    {
-      target.size = 0;
-      target.data = NULL;
-    }
-    else
-    {
-      CopyToMemoryBuffer(target, str.c_str(), str.size());
-    }
+    PluginMemoryBuffer32 buffer;
+    buffer.Assign(str);
+    buffer.Release(target);
   }
 
 
   static char* CopyString(const std::string& str)
   {
-    if (static_cast<uint32_t>(str.size()) != str.size())
-    {
-      throw OrthancException(ErrorCode_NotEnoughMemory, ERROR_MESSAGE_64BIT);
-    }
-
     char *result = reinterpret_cast<char*>(malloc(str.size() + 1));
     if (result == NULL)
     {
       throw OrthancException(ErrorCode_NotEnoughMemory);
     }
 
-    if (str.size() == 0)
-    {
-      result[0] = '\0';
-    }
-    else
-    {
-      memcpy(result, &str[0], str.size() + 1);
-    }
+    if (!str.empty())
+    {
+      memcpy(result, str.c_str(), str.size());
+    }
+
+    result[str.size() - 1] = '\0';  // Add the null terminator of the string
 
     return result;
   }
 
 
-  static void CopyDictionary(OrthancPluginMemoryBuffer& target,
+  static void CopyDictionary(OrthancPluginMemoryBuffer* target,
                              const std::map<std::string, std::string>& dictionary)
   {
     Json::Value json = Json::objectValue;
@@ -500,8 +467,7 @@
       json[it->first] = it->second;
     }
         
-    std::string s = json.toStyledString();
-    CopyToMemoryBuffer(target, s);
+    CopyToMemoryBuffer(target, json.toStyledString());
   }
 
 
@@ -1671,7 +1637,7 @@
       }
     }
 
-    void GetDicomQuery(OrthancPluginMemoryBuffer& target) const
+    void GetDicomQuery(OrthancPluginMemoryBuffer* target) const
     {
       if (currentQuery_ == NULL)
       {
@@ -3180,7 +3146,7 @@
       lock.GetContext().ReadDicom(dicom, p.instanceId);
     }
 
-    CopyToMemoryBuffer(*p.target, dicom);
+    CopyToMemoryBuffer(p.target, dicom);
   }
 
   static void ThrowOnHttpError(HttpStatus httpStatus)
@@ -3230,7 +3196,7 @@
     std::string result;
 
     ThrowOnHttpError(IHttpHandler::SimpleGet(result, NULL, *handler, RequestOrigin_Plugins, p.uri, httpHeaders));
-    CopyToMemoryBuffer(*p.target, result);
+    CopyToMemoryBuffer(p.target, result);
   }
 
 
@@ -3261,7 +3227,7 @@
     std::string result;
 
     ThrowOnHttpError(IHttpHandler::SimpleGet(result, NULL, *handler, RequestOrigin_Plugins, p.uri, headers));
-    CopyToMemoryBuffer(*p.target, result);
+    CopyToMemoryBuffer(p.target, result);
   }
 
 
@@ -3291,7 +3257,7 @@
                                  p.body, p.bodySize, httpHeaders) :
         IHttpHandler::SimplePut(result, NULL, *handler, RequestOrigin_Plugins, p.uri,
                                 p.body, p.bodySize, httpHeaders)));
-    CopyToMemoryBuffer(*p.target, result);
+    CopyToMemoryBuffer(p.target, result);
   }
 
 
@@ -3585,7 +3551,7 @@
       }
     }
 
-    CopyToMemoryBuffer(*p.target, result);
+    CopyToMemoryBuffer(p.target, result);
   }
 
 
@@ -3646,7 +3612,7 @@
         MimeType mime;
         std::string frame;
         instance.GetParsedDicomFile().GetRawFrame(frame, mime, p.frameIndex);
-        CopyToMemoryBuffer(*p.targetBuffer, frame);
+        CopyToMemoryBuffer(p.targetBuffer, frame);
         return;
       }
         
@@ -3676,7 +3642,7 @@
 
         p.targetBuffer->data = NULL;
         p.targetBuffer->size = 0;
-        CopyToMemoryBuffer(*p.targetBuffer, instance.GetBufferData(), instance.GetBufferSize());
+        CopyToMemoryBuffer(p.targetBuffer, instance.GetBufferData(), instance.GetBufferSize());
         return;
       }
 
@@ -3785,7 +3751,7 @@
         throw OrthancException(ErrorCode_ParameterOutOfRange);
     }
 
-    CopyToMemoryBuffer(*p.target, compressed.size() > 0 ? compressed.c_str() : NULL, compressed.size());
+    CopyToMemoryBuffer(p.target, compressed);
   }
 
 
@@ -3884,7 +3850,7 @@
     // Copy the HTTP headers of the answer, if the plugin requested them
     if (answerHeaders != NULL)
     {
-      CopyDictionary(*answerHeaders, headers);
+      CopyDictionary(answerHeaders, headers);
     }
 
     // Copy the body of the answer if it makes sense
@@ -3894,7 +3860,7 @@
       {
         if (answerBody != NULL)
         {
-          CopyToMemoryBuffer(*answerBody, body);
+          CopyToMemoryBuffer(answerBody, body);
         }
       }
       catch (OrthancException&)
@@ -4105,14 +4071,14 @@
 
     if (p.answerHeaders != NULL)
     {
-      CopyDictionary(*p.answerHeaders, answerHeaders);
+      CopyDictionary(p.answerHeaders, answerHeaders);
     }
 
     try
     {
       if (p.answerBody != NULL)
       {
-        CopyToMemoryBuffer(*p.answerBody, answerBody);
+        CopyToMemoryBuffer(p.answerBody, answerBody);
       }
     }
     catch (OrthancException&)
@@ -4190,7 +4156,7 @@
     // Copy the HTTP headers of the answer, if the plugin requested them
     if (p.answerHeaders != NULL)
     {
-      CopyDictionary(*p.answerHeaders, headers);
+      CopyDictionary(p.answerHeaders, headers);
     }
 
     // Copy the body of the answer if it makes sense
@@ -4200,7 +4166,7 @@
       {
         if (p.answerBody != NULL)
         {
-          CopyToMemoryBuffer(*p.answerBody, body);
+          CopyToMemoryBuffer(p.answerBody, body);
         }
       }
       catch (OrthancException&)
@@ -4351,7 +4317,7 @@
       file->SaveToMemoryBuffer(dicom);
     }
 
-    CopyToMemoryBuffer(*parameters.target, dicom);
+    CopyToMemoryBuffer(parameters.target, dicom);
   }
 
 
@@ -4908,7 +4874,7 @@
 
         std::string content;
         SystemToolbox::ReadFile(content, p.path);
-        CopyToMemoryBuffer(*p.target, content.size() > 0 ? content.c_str() : NULL, content.size());
+        CopyToMemoryBuffer(p.target, content);
 
         return true;
       }
@@ -5040,7 +5006,7 @@
           *reinterpret_cast<const _OrthancPluginStorageAreaRead*>(parameters);
         IStorageArea& storage = *reinterpret_cast<IStorageArea*>(p.storageArea);
         std::unique_ptr<IMemoryBuffer> content(storage.Read(p.uuid, Plugins::Convert(p.type)));
-        CopyToMemoryBuffer(*p.target, content->GetData(), content->GetSize());
+        CopyToMemoryBuffer(p.target, content->GetData(), content->GetSize());
         return true;
       }
 
@@ -5103,7 +5069,7 @@
       {
         const _OrthancPluginWorklistQueryOperation& p =
           *reinterpret_cast<const _OrthancPluginWorklistQueryOperation*>(parameters);
-        reinterpret_cast<const WorklistHandler*>(p.query)->GetDicomQuery(*p.target);
+        reinterpret_cast<const WorklistHandler*>(p.query)->GetDicomQuery(p.target);
         return true;
       }
 
@@ -5486,20 +5452,10 @@
         const _OrthancPluginCreateMemoryBuffer& p =
           *reinterpret_cast<const _OrthancPluginCreateMemoryBuffer*>(parameters);
 
-        p.target->data = NULL;
-        p.target->size = 0;
-        
-        if (p.size != 0)
-        {
-          p.target->data = malloc(p.size);
-          if (p.target->data == NULL)
-          {
-            throw OrthancException(ErrorCode_NotEnoughMemory);
-          }
-
-          p.target->size = p.size;
-        }          
-        
+        PluginMemoryBuffer32 buffer;
+        buffer.Resize(p.size);
+        buffer.Release(p.target);
+
         return true;
       }
 
--- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp	Thu Jun 12 09:55:38 2025 +0200
+++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.cpp	Thu Jun 12 11:01:53 2025 +0200
@@ -27,6 +27,8 @@
 #include "../../../OrthancFramework/Sources/OrthancException.h"
 #include "../../../OrthancFramework/Sources/Toolbox.h"
 
+#define ERROR_MESSAGE_64BIT "A 64bit version of the Orthanc SDK is necessary to use buffers > 4GB, but is currently not available"
+
 
 namespace Orthanc
 {
@@ -36,6 +38,9 @@
     {
       ::free(buffer_.data);
     }
+
+    buffer_.data = NULL;
+    buffer_.size = 0;
   }
 
 
@@ -93,6 +98,68 @@
   }
 
 
+  void PluginMemoryBuffer32::Release(OrthancPluginMemoryBuffer* target)
+  {
+    SanityCheck();
+
+    if (target == NULL)
+    {
+      throw OrthancException(ErrorCode_NullPointer);
+    }
+
+    *target = buffer_;
+    buffer_.data = NULL;
+    buffer_.size = 0;
+  }
+
+
+  void PluginMemoryBuffer32::Resize(size_t size)
+  {
+    if (static_cast<size_t>(static_cast<uint32_t>(size)) != size)
+    {
+      throw OrthancException(ErrorCode_NotEnoughMemory, ERROR_MESSAGE_64BIT);
+    }
+
+    Clear();
+
+    if (size == 0)
+    {
+      buffer_.data = NULL;
+    }
+    else
+    {
+      buffer_.data = ::malloc(size);
+    }
+
+    buffer_.size = size;
+  }
+
+
+  void PluginMemoryBuffer32::Assign(const void* data,
+                                    size_t size)
+  {
+    Resize(size);
+
+    if (size != 0)
+    {
+      memcpy(buffer_.data, data, size);
+    }
+  }
+
+
+  void PluginMemoryBuffer32::Assign(const std::string& data)
+  {
+    if (data.empty())
+    {
+      Assign(NULL, 0);
+    }
+    else
+    {
+      Assign(data.c_str(), data.size());
+    }
+  }
+
+
   void PluginMemoryBuffer32::ToJsonObject(Json::Value& target) const
   {
     SanityCheck();
--- a/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h	Thu Jun 12 09:55:38 2025 +0200
+++ b/OrthancServer/Plugins/Engine/PluginMemoryBuffer32.h	Thu Jun 12 11:01:53 2025 +0200
@@ -62,6 +62,15 @@
       return &buffer_;
     }
 
+    void Release(OrthancPluginMemoryBuffer* target);
+
+    void Resize(size_t size);
+
+    void Assign(const void* data,
+                size_t size);
+
+    void Assign(const std::string& data);
+
     void ToJsonObject(Json::Value& target) const;
   };
 }