Mercurial > hg > orthanc
changeset 1801:2c60c357ee3e worklists
sdk primitives to handle worklists
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 20 Nov 2015 14:33:41 +0100 |
parents | 30e97a1f4093 |
children | 138664eb59de |
files | Plugins/Engine/OrthancPlugins.cpp Plugins/Engine/OrthancPlugins.h Plugins/Include/orthanc/OrthancCPlugin.h |
diffstat | 3 files changed, 223 insertions(+), 112 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPlugins.cpp Fri Nov 20 13:53:20 2015 +0100 +++ b/Plugins/Engine/OrthancPlugins.cpp Fri Nov 20 14:33:41 2015 +0100 @@ -47,6 +47,7 @@ #include "../../OrthancServer/OrthancInitialization.h" #include "../../OrthancServer/ServerContext.h" #include "../../OrthancServer/ServerToolbox.h" +#include "../../OrthancServer/Search/HierarchicalMatcher.h" #include "../../Core/Compression/ZlibCompressor.h" #include "../../Core/Compression/GzipCompressor.h" #include "../../Core/Images/Image.h" @@ -61,6 +62,46 @@ namespace Orthanc { + static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target, + const void* data, + size_t size) + { + 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); + } + } + } + + + 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()); + } + } + + namespace { class PluginStorageArea : public IStorageArea @@ -268,6 +309,78 @@ + class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler + { + private: + OrthancPlugins& that_; + std::auto_ptr<HierarchicalMatcher> matcher_; + ParsedDicomFile* currentQuery_; + + void Reset() + { + matcher_.reset(NULL); + currentQuery_ = NULL; + } + + public: + WorklistHandler(OrthancPlugins& that) : that_(that) + { + Reset(); + } + + virtual void Handle(DicomFindAnswers& answers, + ParsedDicomFile& query, + const std::string& remoteIp, + const std::string& remoteAet, + const std::string& calledAet) + { + bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false); + matcher_.reset(new HierarchicalMatcher(query, caseSensitivePN)); + currentQuery_ = &query; + + { + boost::recursive_mutex::scoped_lock lock(that_.pimpl_->worklistCallbackMutex_); + + for (PImpl::WorklistCallbacks::const_iterator + callback = that_.pimpl_->worklistCallbacks_.begin(); + callback != that_.pimpl_->worklistCallbacks_.end(); ++callback) + { + OrthancPluginErrorCode error = (*callback) + (reinterpret_cast<OrthancPluginWorklistAnswers*>(&answers), + reinterpret_cast<const OrthancPluginWorklistQuery*>(this), + remoteAet.c_str(), + calledAet.c_str()); + + if (error != OrthancPluginErrorCode_Success) + { + Reset(); + that_.GetErrorDictionary().LogError(error, true); + throw OrthancException(static_cast<ErrorCode>(error)); + } + } + } + + Reset(); + } + + bool IsMatch(const void* dicom, + size_t size) const + { + assert(matcher_.get() != NULL); + ParsedDicomFile f(dicom, size); + return matcher_->Match(f); + } + + void GetQueryDicom(OrthancPluginMemoryBuffer& target) const + { + assert(currentQuery_ != NULL); + std::string dicom; + currentQuery_->SaveToMemoryBuffer(dicom); + CopyToMemoryBuffer(target, dicom.c_str(), dicom.size()); + } + }; + + static char* CopyString(const std::string& str) { char *result = reinterpret_cast<char*>(malloc(str.size() + 1)); @@ -549,46 +662,6 @@ - static void CopyToMemoryBuffer(OrthancPluginMemoryBuffer& target, - const void* data, - size_t size) - { - 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); - } - } - } - - - 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()); - } - } - - void OrthancPlugins::RegisterRestCallback(const void* parameters, bool lock) { @@ -1851,11 +1924,36 @@ case _OrthancPluginService_AddWorklistAnswer: { - const _OrthancPluginAddWorklistAnswer& p = - *reinterpret_cast<const _OrthancPluginAddWorklistAnswer*>(parameters); + const _OrthancPluginWorklistAnswersOperation& p = + *reinterpret_cast<const _OrthancPluginWorklistAnswersOperation*>(parameters); - ParsedDicomFile answer(p.answerDicom, p.answerSize); - reinterpret_cast<DicomFindAnswers*>(p.target)->Add(answer); + ParsedDicomFile answer(p.dicom, p.size); + reinterpret_cast<DicomFindAnswers*>(p.answers)->Add(answer); + return true; + } + + case _OrthancPluginService_MarkWorklistAnswersIncomplete: + { + const _OrthancPluginWorklistAnswersOperation& p = + *reinterpret_cast<const _OrthancPluginWorklistAnswersOperation*>(parameters); + + reinterpret_cast<DicomFindAnswers*>(p.answers)->SetComplete(false); + return true; + } + + case _OrthancPluginService_IsWorklistMatch: + { + const _OrthancPluginWorklistQueryOperation& p = + *reinterpret_cast<const _OrthancPluginWorklistQueryOperation*>(parameters); + *p.isMatch = reinterpret_cast<const WorklistHandler*>(p.query)->IsMatch(p.dicom, p.size); + return true; + } + + case _OrthancPluginService_GetWorklistQueryDicom: + { + const _OrthancPluginWorklistQueryOperation& p = + *reinterpret_cast<const _OrthancPluginWorklistQueryOperation*>(parameters); + reinterpret_cast<const WorklistHandler*>(p.query)->GetQueryDicom(*p.target); return true; } @@ -1978,54 +2076,6 @@ } - void OrthancPlugins::HandleWorklist(DicomFindAnswers& answers, - ParsedDicomFile& query, - const std::string& remoteIp, - const std::string& remoteAet, - const std::string& calledAet) - { - boost::recursive_mutex::scoped_lock lock(pimpl_->worklistCallbackMutex_); - - for (PImpl::WorklistCallbacks::const_iterator - callback = pimpl_->worklistCallbacks_.begin(); - callback != pimpl_->worklistCallbacks_.end(); ++callback) - { - OrthancPluginErrorCode error = (*callback) - (reinterpret_cast<OrthancPluginWorklistAnswers*>(&answers), - reinterpret_cast<OrthancPluginWorklistQuery*>(&query), - remoteAet.c_str(), - calledAet.c_str()); - - if (error != OrthancPluginErrorCode_Success) - { - GetErrorDictionary().LogError(error, true); - throw OrthancException(static_cast<ErrorCode>(error)); - } - } - } - - - class OrthancPlugins::WorklistHandler : public IWorklistRequestHandler - { - private: - OrthancPlugins& plugins_; - - public: - WorklistHandler(OrthancPlugins& plugins) : plugins_(plugins) - { - } - - virtual void Handle(DicomFindAnswers& answers, - ParsedDicomFile& query, - const std::string& remoteIp, - const std::string& remoteAet, - const std::string& calledAet) - { - plugins_.HandleWorklist(answers, query, remoteIp, remoteAet, calledAet); - } - }; - - IWorklistRequestHandler* OrthancPlugins::ConstructWorklistRequestHandler() { bool hasHandler;
--- a/Plugins/Engine/OrthancPlugins.h Fri Nov 20 13:53:20 2015 +0100 +++ b/Plugins/Engine/OrthancPlugins.h Fri Nov 20 14:33:41 2015 +0100 @@ -144,12 +144,6 @@ OrthancPluginResourceType resourceType, const char* resource); - void HandleWorklist(DicomFindAnswers& answers, - ParsedDicomFile& query, - const std::string& remoteIp, - const std::string& remoteAet, - const std::string& calledAet); - public: OrthancPlugins();
--- a/Plugins/Include/orthanc/OrthancCPlugin.h Fri Nov 20 13:53:20 2015 +0100 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Fri Nov 20 14:33:41 2015 +0100 @@ -469,6 +469,9 @@ /* Primitives for handling worklists */ _OrthancPluginService_AddWorklistAnswer = 7000, + _OrthancPluginService_MarkWorklistAnswersIncomplete = 7001, + _OrthancPluginService_IsWorklistMatch = 7002, + _OrthancPluginService_GetWorklistQueryDicom = 7003, _OrthancPluginService_INTERNAL = 0x7fffffff } _OrthancPluginService; @@ -4100,27 +4103,91 @@ typedef struct { - OrthancPluginWorklistAnswers* target; - const void* answerDicom; - uint32_t answerSize; - } _OrthancPluginAddWorklistAnswer; - - - ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginAddWorklistAnswer( + OrthancPluginWorklistAnswers* answers; + const void* dicom; + uint32_t size; + } _OrthancPluginWorklistAnswersOperation; + + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginWorklistAnswersOperation( OrthancPluginContext* context, - OrthancPluginWorklistAnswers* target, - const void* answerDicom, - uint32_t answerSize) + OrthancPluginWorklistAnswers* answers, + const void* dicom, + uint32_t size) { - _OrthancPluginAddWorklistAnswer params; - params.target = target; - params.answerDicom = answerDicom; - params.answerSize = answerSize; + _OrthancPluginWorklistAnswersOperation params; + params.answers = answers; + params.dicom = dicom; + params.size = size; return context->InvokeService(context, _OrthancPluginService_AddWorklistAnswer, ¶ms); } + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginMarkWorklistAnswersIncomplete( + OrthancPluginContext* context, + OrthancPluginWorklistAnswers* answers) + { + _OrthancPluginWorklistAnswersOperation params; + params.answers = answers; + params.dicom = NULL; + params.size = 0; + + return context->InvokeService(context, _OrthancPluginService_MarkWorklistAnswersIncomplete, ¶ms); + } + + + typedef struct + { + const OrthancPluginWorklistQuery* query; + const void* dicom; + uint32_t size; + int32_t* isMatch; + OrthancPluginMemoryBuffer* target; + } _OrthancPluginWorklistQueryOperation; + + ORTHANC_PLUGIN_INLINE int32_t OrthancPluginIsWorklistMatch( + OrthancPluginContext* context, + const OrthancPluginWorklistQuery* query, + const void* dicom, + uint32_t size) + { + int32_t isMatch = 0; + + _OrthancPluginWorklistQueryOperation params; + params.query = query; + params.dicom = dicom; + params.size = size; + params.isMatch = &isMatch; + params.target = NULL; + + if (context->InvokeService(context, _OrthancPluginService_IsWorklistMatch, ¶ms) == OrthancPluginErrorCode_Success) + { + return isMatch; + } + else + { + /* Error: Assume non-match */ + return 0; + } + } + + + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginGetWorklistQueryDicom( + OrthancPluginContext* context, + OrthancPluginMemoryBuffer* target, + const OrthancPluginWorklistQuery* query) + { + _OrthancPluginWorklistQueryOperation params; + params.query = query; + params.dicom = NULL; + params.size = 0; + params.isMatch = NULL; + params.target = target; + + return context->InvokeService(context, _OrthancPluginService_GetWorklistQueryDicom, ¶ms); + } + + #ifdef __cplusplus } #endif