Mercurial > hg > orthanc
changeset 1609:c74495267acf
Implementation of the "GetAllPublicIdsWithLimit" extension
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 02 Sep 2015 15:07:47 +0200 |
parents | adc6a5704cdb |
children | 2dff2bdffdb8 |
files | Plugins/Engine/OrthancPluginDatabase.cpp Plugins/Engine/OrthancPluginDatabase.h Plugins/Engine/OrthancPlugins.cpp Plugins/Include/orthanc/OrthancCDatabasePlugin.h Plugins/Include/orthanc/OrthancCPlugin.h Plugins/Include/orthanc/OrthancCppDatabasePlugin.h |
diffstat | 6 files changed, 195 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/Plugins/Engine/OrthancPluginDatabase.cpp Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.cpp Wed Sep 02 15:07:47 2015 +0200 @@ -187,6 +187,8 @@ OrthancPluginDatabase::OrthancPluginDatabase(const OrthancPluginDatabaseBackend& backend, + const OrthancPluginDatabaseExtensions* extensions, + size_t extensionsSize, void *payload) : type_(_OrthancPluginDatabaseAnswerType_None), backend_(backend), @@ -197,6 +199,15 @@ answerExportedResources_(NULL), answerDone_(NULL) { + memset(&extensions_, 0, sizeof(extensions_)); + + size_t size = sizeof(extensions_); + if (extensionsSize < size) + { + size = extensionsSize; // Not all the extensions are available + } + + memcpy(&extensions_, extensions, size); } @@ -331,32 +342,47 @@ size_t since, size_t limit) { - // TODO add the corresponding primitives to the SDK - - target.clear(); - - if (limit == 0) + if (extensions_.getAllPublicIdsWithLimit != NULL) { - return; - } + // This extension is available since Orthanc 0.9.4 + ResetAnswers(); + + if (extensions_.getAllPublicIdsWithLimit(GetContext(), payload_, Convert(resourceType), since, limit) != 0) + { + throw OrthancException(ErrorCode_Plugin); + } - std::list<std::string> tmp; - GetAllPublicIds(tmp, resourceType); + ForwardAnswers(target); + } + else + { + // The extension is not available in the database plugin, use a + // fallback implementation + target.clear(); + + if (limit == 0) + { + return; + } + + std::list<std::string> tmp; + GetAllPublicIds(tmp, resourceType); - if (tmp.size() <= since) - { - // Not enough results => empty answer - return; - } + if (tmp.size() <= since) + { + // Not enough results => empty answer + return; + } - std::list<std::string>::iterator current = tmp.begin(); - std::advance(current, since); + std::list<std::string>::iterator current = tmp.begin(); + std::advance(current, since); - while (limit > 0 && current != tmp.end()) - { - target.push_back(*current); - --limit; - ++current; + while (limit > 0 && current != tmp.end()) + { + target.push_back(*current); + --limit; + ++current; + } } }
--- a/Plugins/Engine/OrthancPluginDatabase.h Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Engine/OrthancPluginDatabase.h Wed Sep 02 15:07:47 2015 +0200 @@ -46,6 +46,7 @@ _OrthancPluginDatabaseAnswerType type_; OrthancPluginDatabaseBackend backend_; + OrthancPluginDatabaseExtensions extensions_; void* payload_; IDatabaseListener* listener_; @@ -77,6 +78,8 @@ public: OrthancPluginDatabase(const OrthancPluginDatabaseBackend& backend, + const OrthancPluginDatabaseExtensions* extensions, + size_t extensionsSize, void *payload); virtual void AddAttachment(int64_t id,
--- a/Plugins/Engine/OrthancPlugins.cpp Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Engine/OrthancPlugins.cpp Wed Sep 02 15:07:47 2015 +0200 @@ -1409,10 +1409,24 @@ case _OrthancPluginService_RegisterDatabaseBackend: { LOG(INFO) << "Plugin has registered a custom database back-end"; + const _OrthancPluginRegisterDatabaseBackend& p = *reinterpret_cast<const _OrthancPluginRegisterDatabaseBackend*>(parameters); + pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, NULL, 0, p.payload)); - pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, p.payload)); + *(p.result) = reinterpret_cast<OrthancPluginDatabaseContext*>(pimpl_->database_.get()); + + return true; + } + + case _OrthancPluginService_RegisterDatabaseBackendV2: + { + LOG(INFO) << "Plugin has registered a custom database back-end"; + + const _OrthancPluginRegisterDatabaseBackendV2& p = + *reinterpret_cast<const _OrthancPluginRegisterDatabaseBackendV2*>(parameters); + pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, p.extensions, p.extensionsSize, p.payload)); + *(p.result) = reinterpret_cast<OrthancPluginDatabaseContext*>(pimpl_->database_.get()); return true; @@ -1528,8 +1542,15 @@ case _OrthancPluginService_FreeImage: { const _OrthancPluginFreeImage& p = *reinterpret_cast<const _OrthancPluginFreeImage*>(parameters); - delete reinterpret_cast<ImageAccessor*>(p.image); - return true; + if (p.image == NULL) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + else + { + delete reinterpret_cast<ImageAccessor*>(p.image); + return true; + } } case _OrthancPluginService_UncompressImage:
--- a/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Include/orthanc/OrthancCDatabasePlugin.h Wed Sep 02 15:07:47 2015 +0200 @@ -630,6 +630,21 @@ void* payload); } OrthancPluginDatabaseBackend; + + + typedef struct + { + /* Output: Use OrthancPluginDatabaseAnswerString() */ + int32_t (*getAllPublicIdsWithLimit) ( + /* outputs */ + OrthancPluginDatabaseContext* context, + /* inputs */ + void* payload, + OrthancPluginResourceType resourceType, + uint64_t since, + uint64_t limit); + } OrthancPluginDatabaseExtensions; + /*<! @endcond */ @@ -653,6 +668,8 @@ * @param payload Pointer containing private information for the database engine. * @return The context of the database engine (it must not be manually freed). * @ingroup Callbacks + * @deprecated + * @see OrthancPluginRegisterDatabaseBackendV2 **/ ORTHANC_PLUGIN_INLINE OrthancPluginDatabaseContext* OrthancPluginRegisterDatabaseBackend( OrthancPluginContext* context, @@ -685,6 +702,65 @@ } + typedef struct + { + OrthancPluginDatabaseContext** result; + const OrthancPluginDatabaseBackend* backend; + void* payload; + const OrthancPluginDatabaseExtensions* extensions; + uint32_t extensionsSize; + } _OrthancPluginRegisterDatabaseBackendV2; + + + /** + * Register a custom database back-end. + * + * Instead of manually filling the OrthancPluginDatabaseBackendV2 + * structure, you should instead implement a concrete C++ class + * deriving from ::OrthancPlugins::IDatabaseBackend, and register it + * using ::OrthancPlugins::DatabaseBackendAdapter::Register(). + * + * @param context The Orthanc plugin context, as received by OrthancPluginInitialize(). + * @param backend The callbacks of the custom database engine. + * @param payload Pointer containing private information for the database engine. + * @param extensions Extensions to the base database SDK that was shipped until Orthanc 0.9.3. + * @return The context of the database engine (it must not be manually freed). + * @ingroup Callbacks + **/ + ORTHANC_PLUGIN_INLINE OrthancPluginDatabaseContext* OrthancPluginRegisterDatabaseBackendV2( + OrthancPluginContext* context, + const OrthancPluginDatabaseBackend* backend, + const OrthancPluginDatabaseExtensions* extensions, + void* payload) + { + OrthancPluginDatabaseContext* result = NULL; + _OrthancPluginRegisterDatabaseBackendV2 params; + + if (sizeof(int32_t) != sizeof(_OrthancPluginDatabaseAnswerType)) + { + return NULL; + } + + memset(¶ms, 0, sizeof(params)); + params.backend = backend; + params.result = &result; + params.payload = payload; + params.extensions = extensions; + params.extensionsSize = sizeof(OrthancPluginDatabaseExtensions); + + if (context->InvokeService(context, _OrthancPluginService_RegisterDatabaseBackendV2, ¶ms) || + result == NULL) + { + /* Error */ + return NULL; + } + else + { + return result; + } + } + + #ifdef __cplusplus } #endif
--- a/Plugins/Include/orthanc/OrthancCPlugin.h Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Include/orthanc/OrthancCPlugin.h Wed Sep 02 15:07:47 2015 +0200 @@ -17,7 +17,7 @@ * - Possibly register its callback for received DICOM instances using ::OrthancPluginRegisterOnStoredInstanceCallback(). * - 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 OrthancPluginRegisterDatabaseBackend(). + * - Possibly register a custom database back-end area using OrthancPluginRegisterDatabaseBackendV2(). * -# <tt>void OrthancPluginFinalize()</tt>: * This function is invoked by Orthanc during its shutdown. The plugin * must free all its memory. @@ -427,6 +427,7 @@ /* Services for plugins implementing a database back-end */ _OrthancPluginService_RegisterDatabaseBackend = 5000, _OrthancPluginService_DatabaseAnswer = 5001, + _OrthancPluginService_RegisterDatabaseBackendV2 = 5002, /* Primitives for handling images */ _OrthancPluginService_GetImagePixelFormat = 6000,
--- a/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h Wed Sep 02 13:58:08 2015 +0200 +++ b/Plugins/Include/orthanc/OrthancCppDatabasePlugin.h Wed Sep 02 15:07:47 2015 +0200 @@ -314,6 +314,11 @@ virtual void GetAllPublicIds(std::list<std::string>& target, OrthancPluginResourceType resourceType) = 0; + virtual void GetAllPublicIds(std::list<std::string>& target, + OrthancPluginResourceType resourceType, + uint64_t since, + uint64_t limit) = 0; + /* Use GetOutput().AnswerChange() */ virtual void GetChanges(bool& done /*out*/, int64_t since, @@ -639,6 +644,38 @@ } + static int32_t GetAllPublicIdsWithLimit(OrthancPluginDatabaseContext* context, + void* payload, + OrthancPluginResourceType resourceType, + uint64_t since, + uint64_t limit) + { + IDatabaseBackend* backend = reinterpret_cast<IDatabaseBackend*>(payload); + backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None); + + try + { + std::list<std::string> ids; + backend->GetAllPublicIds(ids, resourceType, since, limit); + + for (std::list<std::string>::const_iterator + it = ids.begin(); it != ids.end(); ++it) + { + OrthancPluginDatabaseAnswerString(backend->GetOutput().context_, + backend->GetOutput().database_, + it->c_str()); + } + + return 0; + } + catch (std::runtime_error& e) + { + LogError(backend, e); + return -1; + } + } + + static int32_t GetChanges(OrthancPluginDatabaseContext* context, void* payload, int64_t since, @@ -1496,6 +1533,9 @@ OrthancPluginDatabaseBackend params; memset(¶ms, 0, sizeof(params)); + OrthancPluginDatabaseExtensions extensions; + memset(&extensions, 0, sizeof(extensions)); + params.addAttachment = AddAttachment; params.attachChild = AttachChild; params.clearChanges = ClearChanges; @@ -1543,7 +1583,9 @@ params.open = Open; params.close = Close; - OrthancPluginDatabaseContext* database = OrthancPluginRegisterDatabaseBackend(context, ¶ms, &backend); + extensions.getAllPublicIdsWithLimit = GetAllPublicIdsWithLimit; + + OrthancPluginDatabaseContext* database = OrthancPluginRegisterDatabaseBackendV2(context, ¶ms, &extensions, &backend); if (!context) { throw std::runtime_error("Unable to register the database backend");