Mercurial > hg > orthanc
view OrthancServer/Sources/ServerJobs/StoreJob.cpp @ 7129:662d58ce7ddf Orthanc-1.13.0
Orthanc-1.13.0
| author | Sebastien Jodogne <s.jodogne@gmail.com> |
|---|---|
| date | Sat, 15 Aug 2026 13:53:33 +0200 |
| parents | ff10a9364ad7 |
| children | 4ba287b00973 |
line wrap: on
line source
/** * Orthanc - A Lightweight, RESTful DICOM Store * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics * Department, University Hospital of Liege, Belgium * Copyright (C) 2017-2023 Osimis S.A., Belgium * Copyright (C) 2024-2026 Orthanc Team SRL, Belgium * Copyright (C) 2021-2026 Sebastien Jodogne, ICTEAM UCLouvain, Belgium * * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. **/ #include "../PrecompiledHeadersServer.h" #include "StoreJob.h" #include <algorithm> #include "../../../OrthancFramework/Sources/Compatibility.h" #include "../../../OrthancFramework/Sources/Logging.h" #include "../../../OrthancFramework/Sources/SerializationToolbox.h" #include "../ServerContext.h" #include "../OrthancConfiguration.h" namespace Orthanc { class StoreJob::ReaderUserData : public IDynamicObject { private: std::string instanceId_; public: explicit ReaderUserData(const std::string& instanceId) : instanceId_(instanceId) { } const std::string& GetInstanceId() const { return instanceId_; } }; StoreJob::StoreJob(ServerContext& context) : context_(context) { } StoreJob::StoreJob(ServerContext& context, const Json::Value& serialized) : SetOfInstancesJob(serialized), context_(context) { // we need to rebuild the instancesIds_ and filesInfo_ from the SetOfInstancesJob GetInstancesIds(instancesIds_); for (size_t i = 0; i < instancesIds_.size(); ++i) { FileInfo fileInfo; int64_t revisionNotUsed; if (!context.GetIndex().LookupAttachment(fileInfo, revisionNotUsed, ResourceType_Instance, instancesIds_[i], FileContentType_Dicom)) { throw OrthancException(ErrorCode_UnknownResource, std::string("Error while unserializing a job, unable to find DICOM attachment for instance ") + instancesIds_[i]); } filesInfo_.push_back(fileInfo); } } DicomSequentialReader::Item* StoreJob::WaitDicomInstance(const std::string& instanceId) { assert(IsStarted()); if (instancesLoader_.get() == NULL) { instancesLoader_.reset(context_.GetDicomSequentialReaderFactory().CreateForOriginalRawMemoryBuffer()); const size_t position = GetPosition(); // in case we reload a job in progress, we shall not preload the first instances if (instanceId != instancesIds_[position]) { throw OrthancException(ErrorCode_InternalError); } for (size_t i = position; i < instancesIds_.size(); ++i) { instancesLoader_->Submit(filesInfo_[i], new ReaderUserData(instancesIds_[i])); } instancesLoader_->Start(); } if (!instancesLoader_->HasNext()) { throw OrthancException(ErrorCode_BadSequenceOfCalls); } std::unique_ptr<DicomSequentialReader::Item> next(instancesLoader_->Next()); assert(next.get() != NULL && next->HasUserData()); { // This is just a sanity check, the class "MoveReaderUserData" could be removed const ReaderUserData& userData = dynamic_cast<const ReaderUserData&>(next->GetUserData()); if (userData.GetInstanceId() != instanceId) { throw OrthancException(ErrorCode_InternalError); } } return next.release(); } void StoreJob::AddInstances(const std::vector<std::string>& instancesIds, const std::vector<FileInfo>& filesInfo) { assert(instancesIds.size() == filesInfo.size()); instancesIds_.reserve(instancesIds_.size() + instancesIds.size()); filesInfo_.reserve(filesInfo.size() + filesInfo.size()); std::copy(instancesIds.begin(), instancesIds.end(), std::back_inserter(instancesIds_)); std::copy(filesInfo.begin(), filesInfo.end(), std::back_inserter(filesInfo_)); // create the commands (they must be in the same order as the instancesIds_ so that the instancesLoader loads them in the right consume order) for (size_t i = 0; i < instancesIds.size(); ++i) { AddInstance(instancesIds[i]); } } void StoreJob::Stop(JobStopReason reason) { // clear the loader threads (also when simply pausing the job) instancesLoader_.reset(NULL); } }
