# HG changeset patch # User Sebastien Jodogne # Date 1441199267 -7200 # Node ID c74495267acf4b4e4c60c4bc172221a0f224c042 # Parent adc6a5704cdb76fdfce1d5111edce678e0a3b196 Implementation of the "GetAllPublicIdsWithLimit" extension diff -r adc6a5704cdb -r c74495267acf Plugins/Engine/OrthancPluginDatabase.cpp --- 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 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 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::iterator current = tmp.begin(); - std::advance(current, since); + std::list::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; + } } } diff -r adc6a5704cdb -r c74495267acf Plugins/Engine/OrthancPluginDatabase.h --- 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, diff -r adc6a5704cdb -r c74495267acf Plugins/Engine/OrthancPlugins.cpp --- 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(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(pimpl_->database_.get()); + + return true; + } + + case _OrthancPluginService_RegisterDatabaseBackendV2: + { + LOG(INFO) << "Plugin has registered a custom database back-end"; + + const _OrthancPluginRegisterDatabaseBackendV2& p = + *reinterpret_cast(parameters); + pimpl_->database_.reset(new OrthancPluginDatabase(*p.backend, p.extensions, p.extensionsSize, p.payload)); + *(p.result) = reinterpret_cast(pimpl_->database_.get()); return true; @@ -1528,8 +1542,15 @@ case _OrthancPluginService_FreeImage: { const _OrthancPluginFreeImage& p = *reinterpret_cast(parameters); - delete reinterpret_cast(p.image); - return true; + if (p.image == NULL) + { + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + else + { + delete reinterpret_cast(p.image); + return true; + } } case _OrthancPluginService_UncompressImage: diff -r adc6a5704cdb -r c74495267acf Plugins/Include/orthanc/OrthancCDatabasePlugin.h --- 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; + /*InvokeService(context, _OrthancPluginService_RegisterDatabaseBackendV2, ¶ms) || + result == NULL) + { + /* Error */ + return NULL; + } + else + { + return result; + } + } + + #ifdef __cplusplus } #endif diff -r adc6a5704cdb -r c74495267acf Plugins/Include/orthanc/OrthancCPlugin.h --- 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(). * -# void OrthancPluginFinalize(): * 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, diff -r adc6a5704cdb -r c74495267acf Plugins/Include/orthanc/OrthancCppDatabasePlugin.h --- 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& target, OrthancPluginResourceType resourceType) = 0; + virtual void GetAllPublicIds(std::list& 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(payload); + backend->GetOutput().SetAllowedAnswers(DatabaseBackendOutput::AllowedAnswers_None); + + try + { + std::list ids; + backend->GetAllPublicIds(ids, resourceType, since, limit); + + for (std::list::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");