Mercurial > hg > orthanc
diff OrthancServer/Plugins/Engine/OrthancPlugins.cpp @ 4440:eddb212b2df9
New functions in the SDK: OrthancPluginCreateMemoryBuffer64() and OrthancPluginRegisterStorageArea2()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 08 Jan 2021 18:53:33 +0100 |
parents | d9473bd5ed43 |
children | 453cd3a5a0da |
line wrap: on
line diff
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Jan 07 18:18:39 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Fri Jan 08 18:53:33 2021 +0100 @@ -153,35 +153,125 @@ namespace { - class PluginStorageArea : public IStorageArea + class MemoryBufferRaii : public boost::noncopyable + { + private: + OrthancPluginMemoryBuffer buffer_; + + public: + MemoryBufferRaii() + { + buffer_.size = 0; + buffer_.data = NULL; + } + + ~MemoryBufferRaii() + { + if (buffer_.size != 0) + { + free(buffer_.data); + } + } + + OrthancPluginMemoryBuffer* GetObject() + { + return &buffer_; + } + + void ToString(std::string& target) const + { + if ((buffer_.data == NULL && buffer_.size != 0) || + (buffer_.data != NULL && buffer_.size == 0)) + { + throw OrthancException(ErrorCode_Plugin); + } + else + { + target.resize(buffer_.size); + + if (buffer_.size != 0) + { + memcpy(&target[0], buffer_.data, buffer_.size); + } + } + } + }; + + + class MemoryBuffer64Raii : public boost::noncopyable { private: - _OrthancPluginRegisterStorageArea callbacks_; - PluginsErrorDictionary& errorDictionary_; - - void Free(void* buffer) const - { - if (buffer != NULL) - { - callbacks_.free(buffer); - } - } + OrthancPluginMemoryBuffer64 buffer_; public: - PluginStorageArea(const _OrthancPluginRegisterStorageArea& callbacks, - PluginsErrorDictionary& errorDictionary) : - callbacks_(callbacks), + MemoryBuffer64Raii() + { + buffer_.size = 0; + buffer_.data = NULL; + } + + ~MemoryBuffer64Raii() + { + if (buffer_.size != 0) + { + free(buffer_.data); + } + } + + OrthancPluginMemoryBuffer64* GetObject() + { + return &buffer_; + } + + void ToString(std::string& target) const + { + if ((buffer_.data == NULL && buffer_.size != 0) || + (buffer_.data != NULL && buffer_.size == 0)) + { + throw OrthancException(ErrorCode_Plugin); + } + else + { + target.resize(buffer_.size); + + if (buffer_.size != 0) + { + memcpy(&target[0], buffer_.data, buffer_.size); + } + } + } + }; + + + class StorageAreaBase : public IStorageArea + { + private: + OrthancPluginStorageCreate create_; + OrthancPluginStorageRemove remove_; + PluginsErrorDictionary& errorDictionary_; + + protected: + PluginsErrorDictionary& GetErrorDictionary() const + { + return errorDictionary_; + } + + public: + StorageAreaBase(OrthancPluginStorageCreate create, + OrthancPluginStorageRemove remove, + PluginsErrorDictionary& errorDictionary) : + create_(create), + remove_(remove), errorDictionary_(errorDictionary) { } - virtual void Create(const std::string& uuid, const void* content, size_t size, - FileContentType type) - { - OrthancPluginErrorCode error = callbacks_.create + FileContentType type) ORTHANC_OVERRIDE + { + OrthancPluginErrorCode error = create_ (uuid.c_str(), content, size, Plugins::Convert(type)); if (error != OrthancPluginErrorCode_Success) @@ -191,20 +281,57 @@ } } + virtual void Remove(const std::string& uuid, + FileContentType type) ORTHANC_OVERRIDE + { + OrthancPluginErrorCode error = remove_ + (uuid.c_str(), Plugins::Convert(type)); + + if (error != OrthancPluginErrorCode_Success) + { + errorDictionary_.LogError(error, true); + throw OrthancException(static_cast<ErrorCode>(error)); + } + } + }; + + + class PluginStorageArea : public StorageAreaBase + { + private: + OrthancPluginStorageRead read_; + OrthancPluginFree free_; + + void Free(void* buffer) const + { + if (buffer != NULL) + { + free_(buffer); + } + } + + public: + PluginStorageArea(const _OrthancPluginRegisterStorageArea& callbacks, + PluginsErrorDictionary& errorDictionary) : + StorageAreaBase(callbacks.create, callbacks.remove, errorDictionary), + read_(callbacks.read), + free_(callbacks.free) + { + } virtual void Read(std::string& content, const std::string& uuid, - FileContentType type) + FileContentType type) ORTHANC_OVERRIDE { void* buffer = NULL; int64_t size = 0; - OrthancPluginErrorCode error = callbacks_.read + OrthancPluginErrorCode error = read_ (&buffer, &size, uuid.c_str(), Plugins::Convert(type)); if (error != OrthancPluginErrorCode_Success) { - errorDictionary_.LogError(error, true); + GetErrorDictionary().LogError(error, true); throw OrthancException(static_cast<ErrorCode>(error)); } @@ -225,19 +352,45 @@ Free(buffer); } - - - virtual void Remove(const std::string& uuid, - FileContentType type) - { - OrthancPluginErrorCode error = callbacks_.remove - (uuid.c_str(), Plugins::Convert(type)); + }; + + + // New in Orthanc 1.9.0 + class PluginStorageArea2 : public StorageAreaBase + { + private: + OrthancPluginStorageReadWhole readWhole_; + OrthancPluginStorageReadRange readRange_; + + public: + PluginStorageArea2(const _OrthancPluginRegisterStorageArea2& callbacks, + PluginsErrorDictionary& errorDictionary) : + StorageAreaBase(callbacks.create, callbacks.remove, errorDictionary), + readWhole_(callbacks.readWhole), + readRange_(callbacks.readRange) + { + if (readRange_) + { + LOG(WARNING) << "Performance warning: The storage area plugin doesn't implement reading of file ranges"; + } + } + + virtual void Read(std::string& content, + const std::string& uuid, + FileContentType type) ORTHANC_OVERRIDE + { + MemoryBuffer64Raii buffer; + + OrthancPluginErrorCode error = readWhole_ + (buffer.GetObject(), uuid.c_str(), Plugins::Convert(type)); if (error != OrthancPluginErrorCode_Success) { - errorDictionary_.LogError(error, true); + GetErrorDictionary().LogError(error, true); throw OrthancException(static_cast<ErrorCode>(error)); } + + buffer.ToString(content); } }; @@ -245,18 +398,39 @@ class StorageAreaFactory : public boost::noncopyable { private: - SharedLibrary& sharedLibrary_; - _OrthancPluginRegisterStorageArea callbacks_; - PluginsErrorDictionary& errorDictionary_; + enum Version + { + Version1, + Version2 + }; + + SharedLibrary& sharedLibrary_; + Version version_; + _OrthancPluginRegisterStorageArea callbacks_; + _OrthancPluginRegisterStorageArea2 callbacks2_; + PluginsErrorDictionary& errorDictionary_; public: StorageAreaFactory(SharedLibrary& sharedLibrary, const _OrthancPluginRegisterStorageArea& callbacks, PluginsErrorDictionary& errorDictionary) : sharedLibrary_(sharedLibrary), + version_(Version1), callbacks_(callbacks), errorDictionary_(errorDictionary) { + LOG(WARNING) << "Performance warning: The storage area plugin doesn't " + << "use OrthancPluginRegisterStorageArea2()"; + } + + StorageAreaFactory(SharedLibrary& sharedLibrary, + const _OrthancPluginRegisterStorageArea2& callbacks, + PluginsErrorDictionary& errorDictionary) : + sharedLibrary_(sharedLibrary), + version_(Version2), + callbacks2_(callbacks), + errorDictionary_(errorDictionary) + { } SharedLibrary& GetSharedLibrary() @@ -266,7 +440,17 @@ IStorageArea* Create() const { - return new PluginStorageArea(callbacks_, errorDictionary_); + switch (version_) + { + case Version1: + return new PluginStorageArea(callbacks_, errorDictionary_); + + case Version2: + return new PluginStorageArea2(callbacks2_, errorDictionary_); + + default: + throw OrthancException(ErrorCode_InternalError); + } } }; @@ -977,7 +1161,7 @@ const std::string& remoteIp, const std::string& remoteAet, const std::string& calledAet, - ModalityManufacturer manufacturer) + ModalityManufacturer manufacturer) ORTHANC_OVERRIDE { { static const char* LUA_CALLBACK = "IncomingWorklistRequestFilter"; @@ -1098,7 +1282,7 @@ const std::string& remoteIp, const std::string& remoteAet, const std::string& calledAet, - ModalityManufacturer manufacturer) + ModalityManufacturer manufacturer) ORTHANC_OVERRIDE { DicomMap tmp; tmp.Assign(input); @@ -1217,12 +1401,12 @@ } } - virtual unsigned int GetSubOperationCount() const + virtual unsigned int GetSubOperationCount() const ORTHANC_OVERRIDE { return count_; } - virtual Status DoNext() + virtual Status DoNext() ORTHANC_OVERRIDE { if (pos_ >= count_) { @@ -1288,7 +1472,7 @@ const std::string& originatorIp, const std::string& originatorAet, const std::string& calledAet, - uint16_t originatorId) + uint16_t originatorId) ORTHANC_OVERRIDE { std::string levelString = ReadTag(input, DICOM_TAG_QUERY_RETRIEVE_LEVEL); std::string patientId = ReadTag(input, DICOM_TAG_PATIENT_ID); @@ -4411,19 +4595,44 @@ const _OrthancPluginCreateMemoryBuffer& p = *reinterpret_cast<const _OrthancPluginCreateMemoryBuffer*>(parameters); - p.target->size = p.size; + p.target->data = NULL; + p.target->size = 0; - if (p.size == 0) - { - p.target->data = NULL; - } - else + if (p.size != 0) { p.target->data = malloc(p.size); + if (p.target->data == NULL) + { + throw OrthancException(ErrorCode_NotEnoughMemory); + } + + p.target->size = p.size; } return true; } + + case _OrthancPluginService_CreateMemoryBuffer64: + { + const _OrthancPluginCreateMemoryBuffer64& p = + *reinterpret_cast<const _OrthancPluginCreateMemoryBuffer64*>(parameters); + + p.target->data = NULL; + p.target->size = 0; + + if (p.size != 0) + { + p.target->data = malloc(p.size); + if (p.target->data == NULL) + { + throw OrthancException(ErrorCode_NotEnoughMemory); + } + + p.target->size = p.size; + } + + return true; + } case _OrthancPluginService_RegisterIncomingHttpRequestFilter: RegisterIncomingHttpRequestFilter(parameters); @@ -4507,14 +4716,28 @@ return true; case _OrthancPluginService_RegisterStorageArea: + case _OrthancPluginService_RegisterStorageArea2: { CLOG(INFO, PLUGINS) << "Plugin has registered a custom storage area"; - const _OrthancPluginRegisterStorageArea& p = - *reinterpret_cast<const _OrthancPluginRegisterStorageArea*>(parameters); if (pimpl_->storageArea_.get() == NULL) { - pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); + if (service == _OrthancPluginService_RegisterStorageArea) + { + const _OrthancPluginRegisterStorageArea& p = + *reinterpret_cast<const _OrthancPluginRegisterStorageArea*>(parameters); + pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); + } + else if (service == _OrthancPluginService_RegisterStorageArea2) + { + const _OrthancPluginRegisterStorageArea2& p = + *reinterpret_cast<const _OrthancPluginRegisterStorageArea2*>(parameters); + pimpl_->storageArea_.reset(new StorageAreaFactory(plugin, p, GetErrorDictionary())); + } + else + { + throw OrthancException(ErrorCode_InternalError); + } } else { @@ -5197,43 +5420,6 @@ } - class MemoryBufferRaii : public boost::noncopyable - { - private: - OrthancPluginMemoryBuffer buffer_; - - public: - MemoryBufferRaii() - { - buffer_.size = 0; - buffer_.data = NULL; - } - - ~MemoryBufferRaii() - { - if (buffer_.size != 0) - { - free(buffer_.data); - } - } - - OrthancPluginMemoryBuffer* GetObject() - { - return &buffer_; - } - - void ToString(std::string& target) const - { - target.resize(buffer_.size); - - if (buffer_.size != 0) - { - memcpy(&target[0], buffer_.data, buffer_.size); - } - } - }; - - bool OrthancPlugins::TranscodeBuffer(std::string& target, const void* buffer, size_t size,