changeset 3397:9019279dbfd7

new plugin c++ wrapper: MultipartRestCallback
author Sebastien Jodogne <s.jodogne@gmail.com>
date Fri, 07 Jun 2019 11:26:34 +0200
parents 4981405e6c5c
children 4acd1431e603
files Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Samples/Common/OrthancPluginCppWrapper.cpp Plugins/Samples/Common/OrthancPluginCppWrapper.h
diffstat 4 files changed, 239 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp	Thu Jun 06 21:35:05 2019 +0200
+++ b/Plugins/Engine/OrthancPlugins.cpp	Fri Jun 07 11:26:34 2019 +0200
@@ -4142,6 +4142,16 @@
       assert(handler_ != NULL);
 
       // TODO => multipart parsing
+
+      OrthancPluginErrorCode error = 
+        parameters_.addPart(handler_, "content-type", 0 /* headers */, NULL, NULL,
+                            data, size);
+
+      if (error != OrthancPluginErrorCode_Success)
+      {
+        errorDictionary_.LogError(error, true);
+        throw OrthancException(static_cast<ErrorCode>(error));
+      }
     }
 
     virtual void Execute(HttpOutput& output)
@@ -4195,7 +4205,8 @@
 
         std::string contentType = "TODO";   // TODO
 
-        OrthancPluginMultipartRestHandler* handler = (*it)->GetParameters().factory(
+        OrthancPluginMultipartRestHandler* handler = (*it)->GetParameters().createHandler(
+          (*it)->GetParameters().factory,
           convertedMethod, matcher.GetFlatUri().c_str(), contentType.c_str(),
           matcher.GetGroupsCount(), matcher.GetGroups(), headers.size(),
           headers.empty() ? NULL : &headersKeys[0],
--- a/Plugins/Include/orthanc/OrthancCPlugin.h	Thu Jun 06 21:35:05 2019 +0200
+++ b/Plugins/Include/orthanc/OrthancCPlugin.h	Fri Jun 07 11:26:34 2019 +0200
@@ -6911,22 +6911,27 @@
 
   typedef struct _OrthancPluginMultipartRestHandler_t OrthancPluginMultipartRestHandler;
 
-  typedef OrthancPluginMultipartRestHandler* (*OrthancPluginMultipartRestFactory) (
-    OrthancPluginHttpMethod method,
-    const char*             url,
-    const char*             contentType,
-    uint32_t                groupsCount,
-    const char* const*      groups,
-    uint32_t                headersCount,
-    const char* const*      headersKeys,
-    const char* const*      headersValues);
+  typedef struct _OrthancPluginMultipartRestFactory_t OrthancPluginMultipartRestFactory;
+
+  typedef OrthancPluginMultipartRestHandler* (*OrthancPluginMultipartRestCreateHandler) (
+    OrthancPluginMultipartRestFactory* factory,
+    OrthancPluginHttpMethod            method,
+    const char*                        url,
+    const char*                        contentType,
+    uint32_t                           groupsCount,
+    const char* const*                 groups,
+    uint32_t                           headersCount,
+    const char* const*                 headersKeys,
+    const char* const*                 headersValues);
 
   typedef OrthancPluginErrorCode (*OrthancPluginMultipartHandlerAddPart) (
     OrthancPluginMultipartRestHandler* handler,
+    const char*                        contentType,
     uint32_t                           headersCount,
     const char* const*                 headersKeys,
     const char* const*                 headersValues,
-    const char*                        contentType);
+    const void*                        data,
+    uint32_t                           size);
     
   typedef OrthancPluginErrorCode (*OrthancPluginMultipartHandlerExecute) (
     OrthancPluginMultipartRestHandler* handler,
@@ -6937,24 +6942,27 @@
   
   typedef struct
   {
-    const char*                           pathRegularExpression;
-    OrthancPluginMultipartRestFactory     factory;
-    OrthancPluginMultipartHandlerAddPart  addPart;
-    OrthancPluginMultipartHandlerExecute  execute;
-   OrthancPluginMultipartHandlerFinalize  finalize;
+    const char*                              pathRegularExpression;
+    OrthancPluginMultipartRestFactory*       factory;
+    OrthancPluginMultipartRestCreateHandler  createHandler;
+    OrthancPluginMultipartHandlerAddPart     addPart;
+    OrthancPluginMultipartHandlerExecute     execute;
+   OrthancPluginMultipartHandlerFinalize     finalize;
   } _OrthancPluginMultipartRestCallback;
 
   ORTHANC_PLUGIN_INLINE void OrthancPluginRegisterMultipartRestCallback(
-    OrthancPluginContext*                  context,
-    const char*                            pathRegularExpression,
-    OrthancPluginMultipartRestFactory      factory,
-    OrthancPluginMultipartHandlerAddPart   addPart,
-    OrthancPluginMultipartHandlerExecute   execute,
-    OrthancPluginMultipartHandlerFinalize  finalize)
+    OrthancPluginContext*                    context,
+    const char*                              pathRegularExpression,
+    OrthancPluginMultipartRestFactory*       factory,
+    OrthancPluginMultipartRestCreateHandler  createHandler,
+    OrthancPluginMultipartHandlerAddPart     addPart,
+    OrthancPluginMultipartHandlerExecute     execute,
+    OrthancPluginMultipartHandlerFinalize    finalize)
   {
     _OrthancPluginMultipartRestCallback params;
     params.pathRegularExpression = pathRegularExpression;
     params.factory = factory;
+    params.createHandler = createHandler;
     params.addPart = addPart;
     params.execute = execute;
     params.finalize = finalize;
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Thu Jun 06 21:35:05 2019 +0200
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp	Fri Jun 07 11:26:34 2019 +0200
@@ -1805,6 +1805,12 @@
 
 
 
+
+
+  /******************************************************************
+   ** JOBS
+   ******************************************************************/
+
 #if HAS_ORTHANC_PLUGIN_JOB == 1
   void OrthancJob::CallbackFinalize(void* job)
   {
@@ -2041,6 +2047,12 @@
 #endif
 
 
+
+
+  /******************************************************************
+   ** METRICS
+   ******************************************************************/
+
 #if HAS_ORTHANC_PLUGIN_METRICS == 1
   MetricsTimer::MetricsTimer(const char* name) :
     name_(name)
@@ -2059,6 +2071,11 @@
 
 
 
+
+  /******************************************************************
+   ** HTTP CLIENT
+   ******************************************************************/
+
 #if HAS_ORTHANC_PLUGIN_HTTP_CLIENT == 1
   class HttpClient::RequestBodyWrapper : public boost::noncopyable
   {
@@ -2581,4 +2598,139 @@
   }
 
 #endif  /* HAS_ORTHANC_PLUGIN_HTTP_CLIENT == 1 */
+
+
+
+
+
+  /******************************************************************
+   ** MULTIPART REST SERVER
+   ******************************************************************/
+
+#if HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER == 1
+  static OrthancPluginMultipartRestHandler* MultipartRestFactory(
+    OrthancPluginMultipartRestFactory* factory,
+    OrthancPluginHttpMethod            method,
+    const char*                        url,
+    const char*                        contentType,
+    uint32_t                           groupsCount,
+    const char* const*                 groups,
+    uint32_t                           headersCount,
+    const char* const*                 headersKeys,
+    const char* const*                 headersValues)
+  {
+    try
+    {
+      assert(factory != NULL);
+      MultipartRestCallback& that = *reinterpret_cast<MultipartRestCallback*>(factory);
+
+      std::vector<std::string> g;
+      g.resize(groupsCount);
+
+      for (uint32_t i = 0; i < groupsCount; i++)
+      {
+        g[i] = groups[i];
+      }
+
+      std::map<std::string, std::string> headers;
+      for (uint32_t i = 0; i < headersCount; i++)
+      {
+        headers[headersKeys[i]] = headersValues[i];
+      }
+
+      return reinterpret_cast<OrthancPluginMultipartRestHandler*>(
+        that.CreateHandler(method, url, contentType, g, headers));
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
+    {
+      LogError("Exception while creating a multipart handler");
+      return NULL;
+    }
+    catch (...)
+    {
+      LogError("Native exception while creating a multipart handler");
+      return NULL;
+    }
+  }
+
+  static OrthancPluginErrorCode MultipartRestAddPart(
+    OrthancPluginMultipartRestHandler* handler,
+    const char*                        contentType,
+    uint32_t                           headersCount,
+    const char* const*                 headersKeys,
+    const char* const*                 headersValues,
+    const void*                        data,
+    uint32_t                           size)
+  {
+    try
+    {
+      assert(handler != NULL);
+      std::map<std::string, std::string> headers;
+      for (uint32_t i = 0; i < headersCount; i++)
+      {
+        headers[headersKeys[i]] = headersValues[i];
+      }
+
+      return reinterpret_cast<MultipartRestCallback::IHandler*>(handler)->
+        AddPart(contentType, headers, data, size);
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
+    {
+      LogError("Exception while add a part to a multipart handler");
+      return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
+    }
+    catch (...)
+    {
+      LogError("Native exception while add a part to a multipart handler");
+      return OrthancPluginErrorCode_Plugin;
+    }
+  }
+    
+  static OrthancPluginErrorCode MultipartRestExecute(
+    OrthancPluginMultipartRestHandler* handler,
+    OrthancPluginRestOutput*           output)
+  {
+    try
+    {
+      assert(handler != NULL);
+      return reinterpret_cast<MultipartRestCallback::IHandler*>(handler)->Execute(output);
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
+    {
+      LogError("Exception while executing a multipart handler");
+      return static_cast<OrthancPluginErrorCode>(e.GetErrorCode());
+    }
+    catch (...)
+    {
+      LogError("Native exception while executing a multipart handler");
+      return OrthancPluginErrorCode_Plugin;
+    }
+  }
+  
+  static void MultipartRestFinalize(OrthancPluginMultipartRestHandler* handler)
+  {
+    try
+    {
+      assert(handler != NULL);
+      delete reinterpret_cast<MultipartRestCallback::IHandler*>(handler);
+    }
+    catch (ORTHANC_PLUGINS_EXCEPTION_CLASS& e)
+    {
+      LogError("Exception while finalizing a multipart handler");
+    }
+    catch (...)
+    {
+      LogError("Native exception while finalizing a multipart handler");
+    }
+  }  
+
+  void MultipartRestCallback::Register(const std::string& regularExpression)
+  {
+    OrthancPluginRegisterMultipartRestCallback(
+      GetGlobalContext(), regularExpression.c_str(), 
+      reinterpret_cast<OrthancPluginMultipartRestFactory*>(this), 
+      MultipartRestFactory, MultipartRestAddPart, MultipartRestExecute, MultipartRestFinalize);
+  }
+#endif
+
 }
--- a/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Thu Jun 06 21:35:05 2019 +0200
+++ b/Plugins/Samples/Common/OrthancPluginCppWrapper.h	Fri Jun 07 11:26:34 2019 +0200
@@ -97,6 +97,12 @@
 #  define HAS_ORTHANC_PLUGIN_STREAMING_HTTP_CLIENT  0
 #endif
 
+#if ORTHANC_PLUGINS_VERSION_IS_ABOVE(1, 5, 7)
+#  define HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER  1
+#else
+#  define HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER  0
+#endif
+
 
 
 namespace OrthancPlugins
@@ -365,7 +371,7 @@
                  uint32_t                  height,
                  uint32_t                  pitch,
                  void*                     buffer
-                 );
+      );
 
     ~OrthancImage()
     {
@@ -568,7 +574,7 @@
           // error message. This is to avoid duplicating the details,
           // because "OrthancException" already does it on construction.
           OrthancPluginSetHttpErrorDetails
-              (GetGlobalContext(), output, e.GetDetails(), false);
+            (GetGlobalContext(), output, e.GetDetails(), false);
         }
 #endif
 
@@ -593,12 +599,12 @@
     if (isThreadSafe)
     {
       OrthancPluginRegisterRestCallbackNoLock
-          (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>);
+        (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>);
     }
     else
     {
       OrthancPluginRegisterRestCallback
-          (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>);
+        (GetGlobalContext(), uri.c_str(), Internals::Protect<Callback>);
     }
   }
 
@@ -912,4 +918,40 @@
                  std::string& answerBody /* out */);
   };
 #endif
+
+
+
+#if HAS_ORTHANC_PLUGIN_HTTP_MULTIPART_SERVER == 1
+  class MultipartRestCallback : public boost::noncopyable
+  {
+  public:
+    class IHandler : public boost::noncopyable
+    {
+    public:
+      virtual ~IHandler()
+      {
+      }
+
+      virtual OrthancPluginErrorCode AddPart(const std::string& contentType,
+                                             const std::map<std::string, std::string>& headers,
+                                             const void* data,
+                                             size_t size) = 0;
+
+      virtual OrthancPluginErrorCode Execute(OrthancPluginRestOutput* output) = 0;
+    };
+
+
+    virtual ~MultipartRestCallback()
+    {
+    }
+
+    virtual IHandler* CreateHandler(OrthancPluginHttpMethod method,
+                                    const std::string& url,
+                                    const std::string& contentType,
+                                    const std::vector<std::string>& groups,
+                                    const std::map<std::string, std::string>& headers) = 0;
+
+    void Register(const std::string& regularExpression);
+  };
+#endif
 }