Mercurial > hg > orthanc
diff OrthancServer/Plugins/Engine/OrthancPlugins.cpp @ 4845:02d77189d8ba received-instance-callback
added ReceivedInstanceCallback + sample C++ plugin
author | Alain Mazy <am@osimis.io> |
---|---|
date | Thu, 09 Dec 2021 17:22:40 +0100 |
parents | b55babf15e4f |
children | 5ec96ada5a53 |
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Tue Dec 07 14:01:17 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Dec 09 17:22:40 2021 +0100 @@ -1168,6 +1168,7 @@ typedef std::list<OrthancPluginIncomingHttpRequestFilter2> IncomingHttpRequestFilters2; typedef std::list<OrthancPluginIncomingDicomInstanceFilter> IncomingDicomInstanceFilters; typedef std::list<OrthancPluginIncomingCStoreInstanceFilter> IncomingCStoreInstanceFilters; + typedef std::list<OrthancPluginReceivedInstanceCallback> ReceivedInstanceCallbacks; typedef std::list<OrthancPluginDecodeImageCallback> DecodeImageCallbacks; typedef std::list<OrthancPluginTranscoderCallback> TranscoderCallbacks; typedef std::list<OrthancPluginJobsUnserializer> JobsUnserializers; @@ -1191,6 +1192,7 @@ IncomingHttpRequestFilters2 incomingHttpRequestFilters2_; IncomingDicomInstanceFilters incomingDicomInstanceFilters_; IncomingCStoreInstanceFilters incomingCStoreInstanceFilters_; // New in Orthanc 1.9.8 + ReceivedInstanceCallbacks receivedInstanceCallbacks_; // New in Orthanc 1.9.8 RefreshMetricsCallbacks refreshMetricsCallbacks_; StorageCommitmentScpCallbacks storageCommitmentScpCallbacks_; std::unique_ptr<StorageAreaFactory> storageArea_; @@ -2295,6 +2297,70 @@ } + bool OrthancPlugins::ApplyReceivedInstanceCallbacks(const void* receivedDicom, + size_t receivedDicomSize, + void** modifiedDicomBufferData, + size_t& modifiedDicomBufferSize) + { + uint64_t modifiedDicomSize64 = 0; + *modifiedDicomBufferData = NULL; + + boost::recursive_mutex::scoped_lock lock(pimpl_->invokeServiceMutex_); + + for (PImpl::ReceivedInstanceCallbacks::const_iterator + callback = pimpl_->receivedInstanceCallbacks_.begin(); + callback != pimpl_->receivedInstanceCallbacks_.end(); ++callback) + { + OrthancPluginReceivedInstanceCallbackResult callbackResult = (*callback) (receivedDicom, + receivedDicomSize, + modifiedDicomBufferData, + &modifiedDicomSize64); + + if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_Discard) + { + if (modifiedDicomSize64 > 0 || *modifiedDicomBufferData != NULL) + { + free(modifiedDicomBufferData); + throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is returning a modified buffer while it has discarded the instance"); + } + return false; + } + else if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_KeepAsIs) + { + if (modifiedDicomSize64 > 0 || *modifiedDicomBufferData != NULL) + { + free(modifiedDicomBufferData); + throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is returning a modified buffer while it has not modified the instance"); + } + return true; + } + else if (callbackResult == OrthancPluginReceivedInstanceCallbackResult_Modified) + { + if (modifiedDicomSize64 > 0 && modifiedDicomBufferData != NULL) + { + if (static_cast<size_t>(modifiedDicomSize64) != modifiedDicomSize64) // Orthanc is running in 32bits and has received a > 4GB buffer + { + free(modifiedDicomBufferData); + throw OrthancException(ErrorCode_Plugin, "The Plugin has returned a > 4GB which is too large for Orthanc running in 32bits"); + } + + modifiedDicomBufferSize = static_cast<size_t>(modifiedDicomSize64); + return true; + } + else + { + throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback plugin is not returning a modified buffer while it has modified the instance"); + } + } + else + { + throw OrthancException(ErrorCode_Plugin, "The ReceivedInstanceCallback has returned an invalid value"); + } + } + + return STATUS_Success; + } + void OrthancPlugins::SignalChangeInternal(OrthancPluginChangeType changeType, OrthancPluginResourceType resourceType, const char* resource) @@ -2521,6 +2587,14 @@ pimpl_->incomingCStoreInstanceFilters_.push_back(p.callback); } + void OrthancPlugins::RegisterReceivedInstanceCallback(const void* parameters) + { + const _OrthancPluginReceivedInstanceCallback& p = + *reinterpret_cast<const _OrthancPluginReceivedInstanceCallback*>(parameters); + + CLOG(INFO, PLUGINS) << "Plugin has registered a received instance callback"; + pimpl_->receivedInstanceCallbacks_.push_back(p.callback); + } void OrthancPlugins::RegisterRefreshMetricsCallback(const void* parameters) { @@ -5004,6 +5078,10 @@ RegisterIncomingCStoreInstanceFilter(parameters); return true; + case _OrthancPluginService_RegisterReceivedInstanceCallback: + RegisterReceivedInstanceCallback(parameters); + return true; + case _OrthancPluginService_RegisterRefreshMetricsCallback: RegisterRefreshMetricsCallback(parameters); return true;