Mercurial > hg > orthanc
diff OrthancServer/DicomInstanceToStore.cpp @ 3841:be7df7fe3d80
avoid one memcpy of the DICOM buffer on "POST /instances"
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 16 Apr 2020 16:58:37 +0200 |
parents | 2a170a8f1faf |
children | 281045a1e6db |
line wrap: on
line diff
--- a/OrthancServer/DicomInstanceToStore.cpp Wed Apr 15 22:17:42 2020 +0200 +++ b/OrthancServer/DicomInstanceToStore.cpp Thu Apr 16 16:58:37 2020 +0200 @@ -150,18 +150,28 @@ { public: DicomInstanceOrigin origin_; - SmartContainer<std::string> buffer_; + bool hasBuffer_; + std::unique_ptr<std::string> ownBuffer_; + const void* bufferData_; + size_t bufferSize_; SmartContainer<ParsedDicomFile> parsed_; SmartContainer<DicomMap> summary_; SmartContainer<Json::Value> json_; MetadataMap metadata_; + PImpl() : + hasBuffer_(false), + bufferData_(NULL), + bufferSize_(0) + { + } + private: std::unique_ptr<DicomInstanceHasher> hasher_; void ComputeMissingInformation() { - if (buffer_.HasContent() && + if (hasBuffer_ && summary_.HasContent() && json_.HasContent()) { @@ -169,7 +179,7 @@ return; } - if (!buffer_.HasContent()) + if (!hasBuffer_) { if (!parsed_.HasContent()) { @@ -186,13 +196,15 @@ } // Serialize the parsed DICOM file - buffer_.Allocate(); - if (!FromDcmtkBridge::SaveToMemoryBuffer(buffer_.GetContent(), + ownBuffer_.reset(new std::string); + if (!FromDcmtkBridge::SaveToMemoryBuffer(*ownBuffer_, *parsed_.GetContent().GetDcmtkObject().getDataset())) { throw OrthancException(ErrorCode_InternalError, "Unable to serialize a DICOM file to a memory buffer"); } + + hasBuffer_ = true; } if (summary_.HasContent() && @@ -205,9 +217,17 @@ // memory buffer, but that its summary or its JSON version is // missing + assert(hasBuffer_); if (!parsed_.HasContent()) { - parsed_.TakeOwnership(new ParsedDicomFile(buffer_.GetConstContent())); + if (ownBuffer_.get() != NULL) + { + parsed_.TakeOwnership(new ParsedDicomFile(*ownBuffer_)); + } + else + { + parsed_.TakeOwnership(new ParsedDicomFile(bufferData_, bufferSize_)); + } } // At this point, we have parsed the DICOM file @@ -232,22 +252,38 @@ public: - const char* GetBufferData() + void SetBuffer(const void* data, + size_t size) + { + ownBuffer_.reset(NULL); + bufferData_ = data; + bufferSize_ = size; + hasBuffer_ = true; + } + + const void* GetBufferData() { ComputeMissingInformation(); - - if (!buffer_.HasContent()) + + if (!hasBuffer_) { throw OrthancException(ErrorCode_InternalError); } - if (buffer_.GetConstContent().size() == 0) + if (ownBuffer_.get() != NULL) { - return NULL; + if (ownBuffer_->empty()) + { + return NULL; + } + else + { + return ownBuffer_->c_str(); + } } else { - return buffer_.GetConstContent().c_str(); + return bufferData_; } } @@ -256,12 +292,19 @@ { ComputeMissingInformation(); - if (!buffer_.HasContent()) + if (!hasBuffer_) { throw OrthancException(ErrorCode_InternalError); } - return buffer_.GetConstContent().size(); + if (ownBuffer_.get() != NULL) + { + return ownBuffer_->size(); + } + else + { + return bufferSize_; + } } @@ -347,9 +390,10 @@ } - void DicomInstanceToStore::SetBuffer(const std::string& dicom) + void DicomInstanceToStore::SetBuffer(const void* dicom, + size_t size) { - pimpl_->buffer_.SetConstReference(dicom); + pimpl_->SetBuffer(dicom, size); } @@ -391,7 +435,7 @@ } - const char* DicomInstanceToStore::GetBufferData() + const void* DicomInstanceToStore::GetBufferData() { return pimpl_->GetBufferData(); }