# HG changeset patch # User Sebastien Jodogne # Date 1464104756 -7200 # Node ID f0acfa753973f43c417c3153873eab3856755395 # Parent 4d099fee5ecac3b62746cf5ecfc51114c5f42b09 New callback to handle non-worklists C-Find requests: OrthancPluginRegisterCFindCallback() diff -r 4d099fee5eca -r f0acfa753973 NEWS --- a/NEWS Tue May 17 15:45:49 2016 +0200 +++ b/NEWS Tue May 24 17:45:56 2016 +0200 @@ -22,6 +22,7 @@ ------- * New callback to filter incoming HTTP requests: OrthancPluginRegisterIncomingHttpRequestFilter() +* New callback to handle non-worklists C-Find requests: OrthancPluginRegisterCFindCallback() * New function: "OrthancPluginHttpClient()" to do HTTP requests with full control * New function: "OrthancPluginGenerateUuid()" to generate a UUID diff -r 4d099fee5eca -r f0acfa753973 OrthancServer/DicomProtocol/DicomFindAnswers.cpp --- a/OrthancServer/DicomProtocol/DicomFindAnswers.cpp Tue May 17 15:45:49 2016 +0200 +++ b/OrthancServer/DicomProtocol/DicomFindAnswers.cpp Tue May 24 17:45:56 2016 +0200 @@ -67,7 +67,7 @@ CleanupDicom(); } - Answer(const char* dicom, + Answer(const void* dicom, size_t size) : dicom_(new ParsedDicomFile(dicom, size)), map_(NULL) @@ -153,7 +153,7 @@ } - void DicomFindAnswers::Add(const char* dicom, + void DicomFindAnswers::Add(const void* dicom, size_t size) { answers_.push_back(new Answer(dicom, size)); diff -r 4d099fee5eca -r f0acfa753973 OrthancServer/DicomProtocol/DicomFindAnswers.h --- a/OrthancServer/DicomProtocol/DicomFindAnswers.h Tue May 17 15:45:49 2016 +0200 +++ b/OrthancServer/DicomProtocol/DicomFindAnswers.h Tue May 24 17:45:56 2016 +0200 @@ -64,7 +64,7 @@ void Add(ParsedDicomFile& dicom); - void Add(const char* dicom, + void Add(const void* dicom, size_t size); size_t GetSize() const diff -r 4d099fee5eca -r f0acfa753973 OrthancServer/main.cpp --- a/OrthancServer/main.cpp Tue May 17 15:45:49 2016 +0200 +++ b/OrthancServer/main.cpp Tue May 24 17:45:56 2016 +0200 @@ -756,10 +756,17 @@ dicomServer.SetFindRequestHandlerFactory(serverFactory); #if ORTHANC_PLUGINS_ENABLED == 1 - if (plugins && - plugins->HasWorklistHandler()) + if (plugins != NULL) { - dicomServer.SetWorklistRequestHandlerFactory(*plugins); + if (plugins->HasWorklistHandler()) + { + dicomServer.SetWorklistRequestHandlerFactory(*plugins); + } + + if (plugins->HasFindHandler()) + { + dicomServer.SetFindRequestHandlerFactory(*plugins); + } } #endif diff -r 4d099fee5eca -r f0acfa753973 Plugins/Engine/OrthancPlugins.cpp --- a/Plugins/Engine/OrthancPlugins.cpp Tue May 17 15:45:49 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Tue May 24 17:45:56 2016 +0200 @@ -39,6 +39,7 @@ #include "../../Core/ChunkedBuffer.h" +#include "../../Core/DicomFormat/DicomArray.h" #include "../../Core/HttpServer/HttpToolbox.h" #include "../../Core/Logging.h" #include "../../Core/OrthancException.h" @@ -107,6 +108,27 @@ } + static char* CopyString(const std::string& str) + { + char *result = reinterpret_cast(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); + } + + return result; + } + + namespace { class PluginStorageArea : public IStorageArea @@ -291,6 +313,7 @@ RestCallbacks restCallbacks_; OnStoredCallbacks onStoredCallbacks_; OnChangeCallbacks onChangeCallbacks_; + OrthancPluginFindCallback findCallback_; OrthancPluginWorklistCallback worklistCallback_; OrthancPluginDecodeImageCallback decodeImageCallback_; IncomingHttpRequestFilters incomingHttpRequestFilters_; @@ -298,6 +321,7 @@ boost::recursive_mutex restCallbackMutex_; boost::recursive_mutex storedCallbackMutex_; boost::recursive_mutex changeCallbackMutex_; + boost::mutex findCallbackMutex_; boost::mutex worklistCallbackMutex_; boost::mutex decodeImageCallbackMutex_; boost::recursive_mutex invokeServiceMutex_; @@ -309,6 +333,7 @@ PImpl() : context_(NULL), + findCallback_(NULL), worklistCallback_(NULL), decodeImageCallback_(NULL), argc_(1), @@ -345,12 +370,13 @@ const std::string& calledAet) { bool caseSensitivePN = Configuration::GetGlobalBoolParameter("CaseSensitivePN", false); - matcher_.reset(new HierarchicalMatcher(query, caseSensitivePN)); - currentQuery_ = &query; { boost::mutex::scoped_lock lock(that_.pimpl_->worklistCallbackMutex_); + matcher_.reset(new HierarchicalMatcher(query, caseSensitivePN)); + currentQuery_ = &query; + if (that_.pimpl_->worklistCallback_) { OrthancPluginErrorCode error = that_.pimpl_->worklistCallback_ @@ -366,14 +392,18 @@ throw OrthancException(static_cast(error)); } } + + Reset(); } - - Reset(); } void GetDicomQuery(OrthancPluginMemoryBuffer& target) const { - assert(currentQuery_ != NULL); + if (currentQuery_ == NULL) + { + throw OrthancException(ErrorCode_Plugin); + } + std::string dicom; currentQuery_->SaveToMemoryBuffer(dicom); CopyToMemoryBuffer(target, dicom.c_str(), dicom.size()); @@ -382,7 +412,11 @@ bool IsMatch(const void* dicom, size_t size) const { - assert(matcher_.get() != NULL); + if (matcher_.get() == NULL) + { + throw OrthancException(ErrorCode_Plugin); + } + ParsedDicomFile f(dicom, size); return matcher_->Match(f); } @@ -391,7 +425,11 @@ const void* dicom, size_t size) const { - assert(matcher_.get() != NULL); + if (matcher_.get() == NULL) + { + throw OrthancException(ErrorCode_Plugin); + } + ParsedDicomFile f(dicom, size); std::auto_ptr summary(matcher_->Extract(f)); reinterpret_cast(answers)->Add(*summary); @@ -399,25 +437,107 @@ }; - static char* CopyString(const std::string& str) + class OrthancPlugins::FindHandler : public IFindRequestHandler { - char *result = reinterpret_cast(malloc(str.size() + 1)); - if (result == NULL) + private: + OrthancPlugins& that_; + std::auto_ptr currentQuery_; + + void Reset() { - throw OrthancException(ErrorCode_NotEnoughMemory); + currentQuery_.reset(NULL); + } + + public: + FindHandler(OrthancPlugins& that) : that_(that) + { + Reset(); } - if (str.size() == 0) + virtual void Handle(DicomFindAnswers& answers, + const DicomMap& input, + const std::list& sequencesToReturn, + const std::string& remoteIp, + const std::string& remoteAet, + const std::string& calledAet) { - result[0] = '\0'; + DicomMap tmp; + tmp.Assign(input); + + for (std::list::const_iterator it = sequencesToReturn.begin(); + it != sequencesToReturn.end(); ++it) + { + if (!input.HasTag(*it)) + { + tmp.SetValue(*it, ""); + } + } + + { + boost::mutex::scoped_lock lock(that_.pimpl_->findCallbackMutex_); + currentQuery_.reset(new DicomArray(tmp)); + + if (that_.pimpl_->findCallback_) + { + OrthancPluginErrorCode error = that_.pimpl_->findCallback_ + (reinterpret_cast(&answers), + reinterpret_cast(this), + remoteAet.c_str(), + calledAet.c_str()); + + if (error != OrthancPluginErrorCode_Success) + { + Reset(); + that_.GetErrorDictionary().LogError(error, true); + throw OrthancException(static_cast(error)); + } + } + + Reset(); + } } - else + + void Invoke(_OrthancPluginService service, + const _OrthancPluginFindOperation& operation) const { - memcpy(result, &str[0], str.size() + 1); + if (currentQuery_.get() == NULL) + { + throw OrthancException(ErrorCode_Plugin); + } + + switch (service) + { + case _OrthancPluginService_GetFindQuerySize: + *operation.resultUint32 = currentQuery_->GetSize(); + break; + + case _OrthancPluginService_GetFindQueryTag: + { + const DicomTag& tag = currentQuery_->GetElement(operation.index).GetTag(); + *operation.resultGroup = tag.GetGroup(); + *operation.resultElement = tag.GetElement(); + break; + } + + case _OrthancPluginService_GetFindQueryTagName: + { + const DicomTag& tag = currentQuery_->GetElement(operation.index).GetTag(); + *operation.resultString = CopyString(FromDcmtkBridge::GetName(tag)); + break; + } + + case _OrthancPluginService_GetFindQueryValue: + { + *operation.resultString = CopyString(currentQuery_->GetElement(operation.index).GetValue().GetContent()); + break; + } + + default: + throw OrthancException(ErrorCode_InternalError); + } } - - return result; - } + }; + OrthancPlugins::OrthancPlugins() @@ -741,6 +861,26 @@ } + void OrthancPlugins::RegisterFindCallback(const void* parameters) + { + const _OrthancPluginFindCallback& p = + *reinterpret_cast(parameters); + + boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); + + if (pimpl_->findCallback_ != NULL) + { + LOG(ERROR) << "Can only register one plugin to handle C-FIND requests"; + throw OrthancException(ErrorCode_Plugin); + } + else + { + LOG(INFO) << "Plugin has registered a callback to handle C-FIND requests"; + pimpl_->findCallback_ = p.callback; + } + } + + void OrthancPlugins::RegisterDecodeImageCallback(const void* parameters) { const _OrthancPluginDecodeImageCallback& p = @@ -1838,6 +1978,10 @@ RegisterWorklistCallback(parameters); return true; + case _OrthancPluginService_RegisterFindCallback: + RegisterFindCallback(parameters); + return true; + case _OrthancPluginService_RegisterDecodeImageCallback: RegisterDecodeImageCallback(parameters); return true; @@ -2314,6 +2458,33 @@ return true; } + case _OrthancPluginService_FindAddAnswer: + { + const _OrthancPluginFindOperation& p = + *reinterpret_cast(parameters); + reinterpret_cast(p.answers)->Add(p.dicom, p.size); + return true; + } + + case _OrthancPluginService_FindMarkIncomplete: + { + const _OrthancPluginFindOperation& p = + *reinterpret_cast(parameters); + reinterpret_cast(p.answers)->SetComplete(false); + return true; + } + + case _OrthancPluginService_GetFindQuerySize: + case _OrthancPluginService_GetFindQueryTag: + case _OrthancPluginService_GetFindQueryTagName: + case _OrthancPluginService_GetFindQueryValue: + { + const _OrthancPluginFindOperation& p = + *reinterpret_cast(parameters); + reinterpret_cast(p.query)->Invoke(service, p); + return true; + } + case _OrthancPluginService_CreateImage: case _OrthancPluginService_CreateImageAccessor: case _OrthancPluginService_DecodeDicomImage: @@ -2475,6 +2646,26 @@ } + IFindRequestHandler* OrthancPlugins::ConstructFindRequestHandler() + { + if (HasFindHandler()) + { + return new FindHandler(*this); + } + else + { + return NULL; + } + } + + + bool OrthancPlugins::HasFindHandler() + { + boost::mutex::scoped_lock lock(pimpl_->findCallbackMutex_); + return pimpl_->findCallback_ != NULL; + } + + bool OrthancPlugins::HasCustomImageDecoder() { boost::mutex::scoped_lock lock(pimpl_->decodeImageCallbackMutex_); diff -r 4d099fee5eca -r f0acfa753973 Plugins/Engine/OrthancPlugins.h --- a/Plugins/Engine/OrthancPlugins.h Tue May 17 15:45:49 2016 +0200 +++ b/Plugins/Engine/OrthancPlugins.h Tue May 24 17:45:56 2016 +0200 @@ -53,6 +53,7 @@ #include "../../OrthancServer/IServerListener.h" #include "../../OrthancServer/IDicomImageDecoder.h" #include "../../OrthancServer/DicomProtocol/IWorklistRequestHandlerFactory.h" +#include "../../OrthancServer/DicomProtocol/IFindRequestHandlerFactory.h" #include "OrthancPluginDatabase.h" #include "PluginsManager.h" @@ -69,13 +70,15 @@ public IServerListener, public IWorklistRequestHandlerFactory, public IDicomImageDecoder, - public IIncomingHttpRequestFilter + public IIncomingHttpRequestFilter, + public IFindRequestHandlerFactory { private: struct PImpl; boost::shared_ptr pimpl_; class WorklistHandler; + class FindHandler; void CheckContextAvailable(); @@ -88,6 +91,8 @@ void RegisterWorklistCallback(const void* parameters); + void RegisterFindCallback(const void* parameters); + void RegisterDecodeImageCallback(const void* parameters); void RegisterIncomingHttpRequestFilter(const void* parameters); @@ -251,6 +256,10 @@ const char* ip, const char* username, const IHttpHandler::Arguments& httpHeaders) const; + + bool HasFindHandler(); + + virtual IFindRequestHandler* ConstructFindRequestHandler(); }; } diff -r 4d099fee5eca -r f0acfa753973 Plugins/Include/orthanc/OrthancCPlugin.h --- a/Plugins/Include/orthanc/OrthancCPlugin.h Tue May 17 15:45:49 2016 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Tue May 24 17:45:56 2016 +0200 @@ -18,6 +18,7 @@ * - Possibly register its callback for changes to the DICOM store using ::OrthancPluginRegisterOnChangeCallback(). * - Possibly register a custom storage area using ::OrthancPluginRegisterStorageArea(). * - Possibly register a custom database back-end area using OrthancPluginRegisterDatabaseBackendV2(). + * - Possibly register a handler for C-Find SCP using OrthancPluginRegisterFindCallback(). * - Possibly register a handler for C-Find SCP against DICOM worklists using OrthancPluginRegisterWorklistCallback(). * - Possibly register a custom decoder for DICOM images using OrthancPluginRegisterDecodeImageCallback(). * - Possibly register a callback to filter incoming HTTP requests using OrthancPluginRegisterIncomingHttpRequestFilter(). @@ -52,8 +53,8 @@ * @defgroup Callbacks Callbacks * @brief Functions to register and manage callbacks by the plugins. * - * @defgroup Worklists Worklists - * @brief Functions to register and manage worklists. + * @defgroup DicomCallbaks DicomCallbaks + * @brief Functions to register and manage DICOM callbacks (worklists, C-Find, C-MOVE). * * @defgroup Orthanc Orthanc * @brief Functions to access the content of the Orthanc server. @@ -415,6 +416,7 @@ _OrthancPluginService_RegisterWorklistCallback = 1005, _OrthancPluginService_RegisterDecodeImageCallback = 1006, _OrthancPluginService_RegisterIncomingHttpRequestFilter = 1007, + _OrthancPluginService_RegisterFindCallback = 1008, /* Sending answers to REST calls */ _OrthancPluginService_AnswerBuffer = 2000, @@ -484,11 +486,17 @@ _OrthancPluginService_CreateImageAccessor = 6013, _OrthancPluginService_DecodeDicomImage = 6014, - /* Primitives for handling worklists */ + /* Primitives for handling C-Find, C-Move and worklists */ _OrthancPluginService_WorklistAddAnswer = 7000, _OrthancPluginService_WorklistMarkIncomplete = 7001, _OrthancPluginService_WorklistIsMatch = 7002, _OrthancPluginService_WorklistGetDicomQuery = 7003, + _OrthancPluginService_FindAddAnswer = 7004, + _OrthancPluginService_FindMarkIncomplete = 7005, + _OrthancPluginService_GetFindQuerySize = 7006, + _OrthancPluginService_GetFindQueryTag = 7007, + _OrthancPluginService_GetFindQueryTagName = 7008, + _OrthancPluginService_GetFindQueryValue = 7009, _OrthancPluginService_INTERNAL = 0x7fffffff } _OrthancPluginService; @@ -812,22 +820,38 @@ /** - * @brief Opaque structure to an object that represents a C-Find query. - * @ingroup Worklists + * @brief Opaque structure to an object that represents a C-Find query for worklists. + * @ingroup DicomCallbacks **/ typedef struct _OrthancPluginWorklistQuery_t OrthancPluginWorklistQuery; /** - * @brief Opaque structure to an object that represents the answers to a C-Find query. - * @ingroup Worklists + * @brief Opaque structure to an object that represents the answers to a C-Find query for worklists. + * @ingroup DicomCallbacks **/ typedef struct _OrthancPluginWorklistAnswers_t OrthancPluginWorklistAnswers; /** + * @brief Opaque structure to an object that represents a C-Find query. + * @ingroup DicomCallbacks + **/ + typedef struct _OrthancPluginFindQuery_t OrthancPluginFindQuery; + + + + /** + * @brief Opaque structure to an object that represents the answers to a C-Find query for worklists. + * @ingroup DicomCallbacks + **/ + typedef struct _OrthancPluginFindAnswers_t OrthancPluginFindAnswers; + + + + /** * @brief Signature of a callback function that answers to a REST request. * @ingroup Callbacks **/ @@ -935,7 +959,7 @@ /** - * @brief Callback to handle the C-Find SCP requests received by Orthanc. + * @brief Callback to handle the C-Find SCP requests for worklists. * * Signature of a callback function that is triggered when Orthanc * receives a C-Find SCP request against modality worklists. @@ -945,7 +969,7 @@ * @param remoteAet The Application Entity Title (AET) of the modality from which the request originates. * @param calledAet The Application Entity Title (AET) of the modality that is called by the request. * @return 0 if success, other value if error. - * @ingroup Worklists + * @ingroup DicomCallbacks **/ typedef OrthancPluginErrorCode (*OrthancPluginWorklistCallback) ( OrthancPluginWorklistAnswers* answers, @@ -956,6 +980,27 @@ /** + * @brief Callback to handle the C-Find SCP requests. + * + * Signature of a callback function that is triggered when Orthanc + * receives a C-Find SCP request not concerning modality worklists. + * + * @param answers The target structure where answers must be stored. + * @param query The worklist query. + * @param remoteAet The Application Entity Title (AET) of the modality from which the request originates. + * @param calledAet The Application Entity Title (AET) of the modality that is called by the request. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + typedef OrthancPluginErrorCode (*OrthancPluginFindCallback) ( + OrthancPluginFindAnswers* answers, + const OrthancPluginFindQuery* query, + const char* remoteAet, + const char* calledAet); + + + + /** * @brief Callback to filter incoming HTTP requests received by Orthanc. * * Signature of a callback function that is triggered whenever @@ -4194,7 +4239,7 @@ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param callback The callback. * @return 0 if success, other value if error. - * @ingroup Worklists + * @ingroup DicomCallbacks **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterWorklistCallback( OrthancPluginContext* context, @@ -4229,7 +4274,8 @@ * @param dicom The worklist to answer, encoded as a DICOM file. * @param size The size of the DICOM file. * @return 0 if success, other value if error. - * @ingroup Worklists + * @ingroup DicomCallbacks + * @see OrthancPluginCreateDicom() **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginWorklistAddAnswer( OrthancPluginContext* context, @@ -4259,7 +4305,7 @@ * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). * @param answers The set of answers. * @return 0 if success, other value if error. - * @ingroup Worklists + * @ingroup DicomCallbacks **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginWorklistMarkIncomplete( OrthancPluginContext* context, @@ -4297,7 +4343,7 @@ * @param dicom The worklist to answer, encoded as a DICOM file. * @param size The size of the DICOM file. * @return 1 if the worklist matches the query, 0 otherwise. - * @ingroup Worklists + * @ingroup DicomCallbacks **/ ORTHANC_PLUGIN_INLINE int32_t OrthancPluginWorklistIsMatch( OrthancPluginContext* context, @@ -4336,7 +4382,7 @@ * @param target Memory buffer where to store the DICOM file. It must be freed with OrthancPluginFreeMemoryBuffer(). * @param query The worklist query, as received by the callback. * @return 0 if success, other value if error. - * @ingroup Worklists + * @ingroup DicomCallbacks **/ ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginWorklistGetDicomQuery( OrthancPluginContext* context, @@ -4897,6 +4943,246 @@ } + + + typedef struct + { + OrthancPluginFindCallback callback; + } _OrthancPluginFindCallback; + + /** + * @brief Register a callback to handle C-Find requests. + * + * This function registers a callback to handle C-Find SCP requests + * that are not related to modality worklists. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param callback The callback. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginRegisterFindCallback( + OrthancPluginContext* context, + OrthancPluginFindCallback callback) + { + _OrthancPluginFindCallback params; + params.callback = callback; + + return context->InvokeService(context, _OrthancPluginService_RegisterFindCallback, ¶ms); + } + + + typedef struct + { + OrthancPluginFindAnswers *answers; + const OrthancPluginFindQuery *query; + const void *dicom; + uint32_t size; + uint32_t index; + uint32_t *resultUint32; + uint16_t *resultGroup; + uint16_t *resultElement; + char **resultString; + } _OrthancPluginFindOperation; + + /** + * @brief Add one answer to some C-Find request. + * + * This function adds one answer (encoded as a DICOM file) to the + * set of answers corresponding to some C-Find SCP request that is + * not related to modality worklists. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param answers The set of answers. + * @param dicom The answer to be added, encoded as a DICOM file. + * @param size The size of the DICOM file. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + * @see OrthancPluginCreateDicom() + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginFindAddAnswer( + OrthancPluginContext* context, + OrthancPluginFindAnswers* answers, + const void* dicom, + uint32_t size) + { + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.answers = answers; + params.dicom = dicom; + params.size = size; + + return context->InvokeService(context, _OrthancPluginService_FindAddAnswer, ¶ms); + } + + + /** + * @brief Mark the set of C-Find answers as incomplete. + * + * This function marks as incomplete the set of answers + * corresponding to some C-Find SCP request that is not related to + * modality worklists. This must be used if canceling the handling + * of a request when too many answers are to be returned. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param answers The set of answers. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginFindMarkIncomplete( + OrthancPluginContext* context, + OrthancPluginFindAnswers* answers) + { + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.answers = answers; + + return context->InvokeService(context, _OrthancPluginService_FindMarkIncomplete, ¶ms); + } + + + + /** + * @brief Get the number of tags in a C-Find query. + * + * This function returns the number of tags that are contained in + * the given C-Find query. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param query The C-Find query. + * @return The number of tags. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE uint32_t OrthancPluginGetFindQuerySize( + OrthancPluginContext* context, + const OrthancPluginFindQuery* query) + { + uint32_t count = 0; + + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.query = query; + params.resultUint32 = &count; + + if (context->InvokeService(context, _OrthancPluginService_GetFindQuerySize, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return 0; + } + else + { + return count; + } + } + + + /** + * @brief Get one tag in a C-Find query. + * + * This function returns the group and the element of one DICOM tag + * in the given C-Find query. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param group The group of the tag (output). + * @param element The element of the tag (output). + * @param query The C-Find query. + * @param index The index of the tag of interest. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginErrorCode OrthancPluginGetFindQueryTag( + OrthancPluginContext* context, + uint16_t* group, + uint16_t* element, + const OrthancPluginFindQuery* query, + uint32_t index) + { + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.query = query; + params.index = index; + params.resultGroup = group; + params.resultElement = element; + + return context->InvokeService(context, _OrthancPluginService_GetFindQueryTag, ¶ms); + } + + + /** + * @brief Get the symbolic name of one tag in a C-Find query. + * + * This function returns the symbolic name of one DICOM tag in the + * given C-Find query. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param query The C-Find query. + * @param index The index of the tag of interest. + * @return The NULL value in case of error, or a string containing the name of the tag. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE char* OrthancPluginGetFindQueryTagName( + OrthancPluginContext* context, + const OrthancPluginFindQuery* query, + uint32_t index) + { + char* result; + + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.query = query; + params.index = index; + params.resultString = &result; + + if (context->InvokeService(context, _OrthancPluginService_GetFindQueryTagName, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return NULL; + } + else + { + return result; + } + } + + + /** + * @brief Get the value associated with one tag in a C-Find query. + * + * This function returns the value associated with one tag in the + * given C-Find query. + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param query The C-Find query. + * @param index The index of the tag of interest. + * @return The NULL value in case of error, or a string containing the value of the tag. + * @return 0 if success, other value if error. + * @ingroup DicomCallbacks + **/ + ORTHANC_PLUGIN_INLINE char* OrthancPluginGetFindQueryValue( + OrthancPluginContext* context, + const OrthancPluginFindQuery* query, + uint32_t index) + { + char* result; + + _OrthancPluginFindOperation params; + memset(¶ms, 0, sizeof(params)); + params.query = query; + params.index = index; + params.resultString = &result; + + if (context->InvokeService(context, _OrthancPluginService_GetFindQueryValue, ¶ms) != OrthancPluginErrorCode_Success) + { + /* Error */ + return NULL; + } + else + { + return result; + } + } + #ifdef __cplusplus } #endif