Mercurial > hg > orthanc
changeset 4495:fa2311f94d9f
IStorageArea::ReadRange()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 04 Feb 2021 18:01:07 +0100 |
parents | 39192eb9b43d |
children | 9ea70ccf0c21 |
files | OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp OrthancFramework/Sources/FileStorage/FilesystemStorage.h OrthancFramework/Sources/FileStorage/IStorageArea.h OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp OrthancFramework/Sources/FileStorage/MemoryStorageArea.h OrthancServer/Plugins/Engine/OrthancPlugins.cpp OrthancServer/Sources/OrthancInitialization.cpp |
diffstat | 9 files changed, 196 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.cpp Thu Feb 04 18:01:07 2021 +0100 @@ -186,6 +186,12 @@ } + bool ParsedDicomCache::Accessor::IsValid() const + { + return file_ != NULL; + } + + ParsedDicomFile& ParsedDicomCache::Accessor::GetDicom() const { if (IsValid())
--- a/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/DicomParsing/ParsedDicomCache.h Thu Feb 04 18:01:07 2021 +0100 @@ -72,10 +72,7 @@ Accessor(ParsedDicomCache& that, const std::string& id); - bool IsValid() const - { - return file_ != NULL; - } + bool IsValid() const; ParsedDicomFile& GetDicom() const;
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.cpp Thu Feb 04 18:01:07 2021 +0100 @@ -164,6 +164,22 @@ } + IMemoryBuffer* FilesystemStorage::ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) + { + LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" << GetDescriptionInternal(type) + << "\" content type (range from " << start << " to " << end << ")"; + + std::string content; + SystemToolbox::ReadFileRange( + content, GetPath(uuid).string(), start, end, true /* throw if overflow */); + + return StringMemoryBuffer::CreateFromSwap(content); + } + + uintmax_t FilesystemStorage::GetSize(const std::string& uuid) const { boost::filesystem::path path = GetPath(uuid);
--- a/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/FileStorage/FilesystemStorage.h Thu Feb 04 18:01:07 2021 +0100 @@ -81,6 +81,11 @@ virtual IMemoryBuffer* Read(const std::string& uuid, FileContentType type) ORTHANC_OVERRIDE; + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) ORTHANC_OVERRIDE; + virtual void Remove(const std::string& uuid, FileContentType type) ORTHANC_OVERRIDE;
--- a/OrthancFramework/Sources/FileStorage/IStorageArea.h Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/FileStorage/IStorageArea.h Thu Feb 04 18:01:07 2021 +0100 @@ -44,6 +44,11 @@ virtual IMemoryBuffer* Read(const std::string& uuid, FileContentType type) = 0; + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) = 0; + virtual void Remove(const std::string& uuid, FileContentType type) = 0; };
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.cpp Thu Feb 04 18:01:07 2021 +0100 @@ -91,6 +91,55 @@ } + IMemoryBuffer* MemoryStorageArea::ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) + { + LOG(INFO) << "Reading attachment \"" << uuid << "\" of \"" + << static_cast<int>(type) << "\" content type " + << "(range from " << start << " to " << end << ")"; + + if (start > end) + { + throw OrthancException(ErrorCode_BadRange); + } + else if (start == end) + { + return new StringMemoryBuffer; + } + else + { + boost::mutex::scoped_lock lock(mutex_); + + Content::const_iterator found = content_.find(uuid); + + if (found == content_.end()) + { + throw OrthancException(ErrorCode_InexistentFile); + } + else if (found->second == NULL) + { + throw OrthancException(ErrorCode_InternalError); + } + else if (end > found->second->size()) + { + throw OrthancException(ErrorCode_BadRange); + } + else + { + std::string range; + range.resize(end - start); + assert(!range.empty()); + + memcpy(&range[0], &found->second[start], range.size()); + + return StringMemoryBuffer::CreateFromSwap(range); + } + } + } + + void MemoryStorageArea::Remove(const std::string& uuid, FileContentType type) {
--- a/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancFramework/Sources/FileStorage/MemoryStorageArea.h Thu Feb 04 18:01:07 2021 +0100 @@ -50,6 +50,11 @@ virtual IMemoryBuffer* Read(const std::string& uuid, FileContentType type) ORTHANC_OVERRIDE; + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) ORTHANC_OVERRIDE; + virtual void Remove(const std::string& uuid, FileContentType type) ORTHANC_OVERRIDE; };
--- a/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancServer/Plugins/Engine/OrthancPlugins.cpp Thu Feb 04 18:01:07 2021 +0100 @@ -63,6 +63,7 @@ #include "../../../OrthancFramework/Sources/MetricsRegistry.h" #include "../../../OrthancFramework/Sources/OrthancException.h" #include "../../../OrthancFramework/Sources/SerializationToolbox.h" +#include "../../../OrthancFramework/Sources/StringMemoryBuffer.h" #include "../../../OrthancFramework/Sources/Toolbox.h" #include "../../Sources/OrthancConfiguration.h" #include "../../Sources/OrthancFindRequestHandler.h" @@ -211,6 +212,46 @@ { return errorDictionary_; } + + IMemoryBuffer* RangeFromWhole(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) + { + if (start > end) + { + throw OrthancException(ErrorCode_BadRange); + } + else if (start == end) + { + return new StringMemoryBuffer; // Empty + } + else + { + std::unique_ptr<IMemoryBuffer> whole(Read(uuid, type)); + + if (start == 0 && + end == whole->GetSize()) + { + return whole.release(); + } + else if (end > whole->GetSize()) + { + throw OrthancException(ErrorCode_BadRange); + } + else + { + std::string range; + range.resize(end - start); + assert(!range.empty()); + + memcpy(&range[0], reinterpret_cast<const char*>(whole->GetData()) + start, range.size()); + + whole.reset(NULL); + return StringMemoryBuffer::CreateFromSwap(range); + } + } + } public: StorageAreaBase(OrthancPluginStorageCreate create, @@ -306,6 +347,14 @@ throw OrthancException(static_cast<ErrorCode>(error)); } } + + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) ORTHANC_OVERRIDE + { + return RangeFromWhole(uuid, type, start, end); + } }; @@ -349,6 +398,51 @@ throw OrthancException(static_cast<ErrorCode>(error)); } } + + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) ORTHANC_OVERRIDE + { + if (readRange_ == NULL) + { + return RangeFromWhole(uuid, type, start, end); + } + else + { + if (start > end) + { + throw OrthancException(ErrorCode_BadRange); + } + else if (start == end) + { + return new StringMemoryBuffer; + } + else + { + std::string range; + range.resize(end - start); + assert(!range.empty()); + + OrthancPluginMemoryBuffer64 buffer; + buffer.data = &range[0]; + buffer.size = static_cast<uint64_t>(range.size()); + + OrthancPluginErrorCode error = + readRange_(&buffer, uuid.c_str(), Plugins::Convert(type), start); + + if (error == OrthancPluginErrorCode_Success) + { + return StringMemoryBuffer::CreateFromSwap(range); + } + else + { + GetErrorDictionary().LogError(error, true); + throw OrthancException(static_cast<ErrorCode>(error)); + } + } + } + } };
--- a/OrthancServer/Sources/OrthancInitialization.cpp Thu Feb 04 15:31:00 2021 +0100 +++ b/OrthancServer/Sources/OrthancInitialization.cpp Thu Feb 04 18:01:07 2021 +0100 @@ -380,6 +380,21 @@ } } + virtual IMemoryBuffer* ReadRange(const std::string& uuid, + FileContentType type, + uint64_t start /* inclusive */, + uint64_t end /* exclusive */) ORTHANC_OVERRIDE + { + if (type != FileContentType_Dicom) + { + return storage_.ReadRange(uuid, type, start, end); + } + else + { + throw OrthancException(ErrorCode_UnknownResource); + } + } + virtual void Remove(const std::string& uuid, FileContentType type) ORTHANC_OVERRIDE {