# HG changeset patch # User Sebastien Jodogne # Date 1715185716 -7200 # Node ID 4690a0d2b01efadb0f4708e272d51afcb9e9fad0 # Parent 3d0aa94b44b30e44dd0e36f90c1a935d112c3ff9 preliminary support of requestedTags diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/Database/Compatibility/GenericFind.cpp --- a/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/Database/Compatibility/GenericFind.cpp Wed May 08 18:28:36 2024 +0200 @@ -279,48 +279,27 @@ resource->AddChildrenMetadata(*it, values); } - if (!request.GetRetrieveAttachmentOfOneInstance().empty()) + if (request.IsRetrieveOneInstanceIdentifier()) { - std::set todo = request.GetRetrieveAttachmentOfOneInstance(); - std::stack< std::pair > candidates; - candidates.push(std::make_pair(level, internalId)); - - while (!todo.empty() && - !candidates.empty()) - { - std::pair top = candidates.top(); - candidates.pop(); - - if (top.first == ResourceType_Instance) - { - std::set nextTodo; + int64_t currentId = internalId; + ResourceType currentLevel = level; - for (std::set::const_iterator it = todo.begin(); it != todo.end(); ++it) - { - FileInfo attachment; - int64_t revision; - if (transaction_.LookupAttachment(attachment, revision, top.second, *it)) - { - resource->AddAttachmentOfOneInstance(attachment); - } - else - { - nextTodo.insert(*it); - } - } - - todo = nextTodo; + while (currentLevel != ResourceType_Instance) + { + std::list children; + transaction_.GetChildrenInternalId(children, currentId); + if (children.empty()) + { + throw OrthancException(ErrorCode_DatabasePlugin); } else { - std::list children; - transaction_.GetChildrenInternalId(children, top.second); - for (std::list::const_iterator it = children.begin(); it != children.end(); ++it) - { - candidates.push(std::make_pair(GetChildResourceType(top.first), *it)); - } + currentId = children.front(); + currentLevel = GetChildResourceType(currentLevel); } } + + resource->SetOneInstanceIdentifier(transaction_.GetPublicId(currentId)); } response.Add(resource.release()); diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/Database/FindRequest.cpp --- a/OrthancServer/Sources/Database/FindRequest.cpp Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.cpp Wed May 08 18:28:36 2024 +0200 @@ -45,7 +45,8 @@ retrieveLabels_(false), retrieveAttachments_(false), retrieveParentIdentifier_(false), - retrieveChildrenIdentifiers_(false) + retrieveChildrenIdentifiers_(false), + retrieveOneInstanceIdentifier_(false) { } @@ -60,6 +61,82 @@ } } + + void FindRequest::SetOrthancId(ResourceType level, + const std::string& id) + { + switch (level) + { + case ResourceType_Patient: + SetOrthancPatientId(id); + break; + + case ResourceType_Study: + SetOrthancStudyId(id); + break; + + case ResourceType_Series: + SetOrthancSeriesId(id); + break; + + case ResourceType_Instance: + SetOrthancInstanceId(id); + break; + + default: + throw OrthancException(ErrorCode_ParameterOutOfRange); + } + } + + + void FindRequest::SetOrthancPatientId(const std::string& id) + { + orthancIdentifiers_.SetPatientId(id); + } + + + void FindRequest::SetOrthancStudyId(const std::string& id) + { + if (level_ == ResourceType_Patient) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + orthancIdentifiers_.SetStudyId(id); + } + } + + + void FindRequest::SetOrthancSeriesId(const std::string& id) + { + if (level_ == ResourceType_Patient || + level_ == ResourceType_Study) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + orthancIdentifiers_.SetSeriesId(id); + } + } + + + void FindRequest::SetOrthancInstanceId(const std::string& id) + { + if (level_ == ResourceType_Patient || + level_ == ResourceType_Study || + level_ == ResourceType_Series) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + orthancIdentifiers_.SetInstanceId(id); + } + } + + void FindRequest::AddDicomTagConstraint(const DicomTagConstraint& constraint) { dicomTagConstraints_.push_back(constraint); @@ -289,17 +366,4 @@ retrieveChildrenMetadata_.insert(metadata); } } - - - void FindRequest::AddRetrieveAttachmentOfOneInstance(FileContentType type) - { - if (retrieveAttachmentOfOneInstance_.find(type) == retrieveAttachmentOfOneInstance_.end()) - { - retrieveAttachmentOfOneInstance_.insert(type); - } - else - { - throw OrthancException(ErrorCode_BadSequenceOfCalls); - } - } } diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/Database/FindRequest.h --- a/OrthancServer/Sources/Database/FindRequest.h Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/Database/FindRequest.h Wed May 08 18:28:36 2024 +0200 @@ -179,7 +179,7 @@ bool retrieveParentIdentifier_; bool retrieveChildrenIdentifiers_; std::set retrieveChildrenMetadata_; - std::set retrieveAttachmentOfOneInstance_; + bool retrieveOneInstanceIdentifier_; public: explicit FindRequest(ResourceType level); @@ -191,25 +191,16 @@ return level_; } - void SetOrthancPatientId(const std::string& id) - { - orthancIdentifiers_.SetPatientId(id); - } + void SetOrthancId(ResourceType level, + const std::string& id); - void SetOrthancStudyId(const std::string& id) - { - orthancIdentifiers_.SetStudyId(id); - } + void SetOrthancPatientId(const std::string& id); - void SetOrthancSeriesId(const std::string& id) - { - orthancIdentifiers_.SetSeriesId(id); - } + void SetOrthancStudyId(const std::string& id); - void SetOrthancInstanceId(const std::string& id) - { - orthancIdentifiers_.SetInstanceId(id); - } + void SetOrthancSeriesId(const std::string& id); + + void SetOrthancInstanceId(const std::string& id); const OrthancIdentifiers& GetOrthancIdentifiers() const { @@ -322,11 +313,14 @@ return retrieveChildrenMetadata_; } - void AddRetrieveAttachmentOfOneInstance(FileContentType type); + void SetRetrieveOneInstanceIdentifier(bool retrieve) + { + retrieveOneInstanceIdentifier_ = retrieve; + } - const std::set& GetRetrieveAttachmentOfOneInstance() const + bool IsRetrieveOneInstanceIdentifier() const { - return retrieveAttachmentOfOneInstance_; + return retrieveOneInstanceIdentifier_; } }; } diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/Database/FindResponse.cpp --- a/OrthancServer/Sources/Database/FindResponse.cpp Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/Database/FindResponse.cpp Wed May 08 18:28:36 2024 +0200 @@ -245,23 +245,6 @@ } - const std::string& FindResponse::Resource::GetParentIdentifier() const - { - if (level_ == ResourceType_Patient) - { - throw OrthancException(ErrorCode_BadParameterType); - } - else if (HasParentIdentifier()) - { - return *parentIdentifier_; - } - else - { - throw OrthancException(ErrorCode_BadSequenceOfCalls); - } - } - - FindResponse::Resource::~Resource() { for (ChildrenMetadata::iterator it = childrenMetadata_.begin(); it != childrenMetadata_.end(); ++it) @@ -289,6 +272,23 @@ } + const std::string& FindResponse::Resource::GetParentIdentifier() const + { + if (level_ == ResourceType_Patient) + { + throw OrthancException(ErrorCode_BadParameterType); + } + else if (HasParentIdentifier()) + { + return *parentIdentifier_; + } + else + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + } + + bool FindResponse::Resource::HasParentIdentifier() const { if (level_ == ResourceType_Patient) @@ -374,11 +374,24 @@ } - void FindResponse::Resource::AddAttachmentOfOneInstance(const FileInfo& info) + void FindResponse::Resource::SetOneInstanceIdentifier(const std::string& id) { - if (attachmentOfOneInstance_.find(info.GetContentType()) == attachmentOfOneInstance_.end()) + if (HasOneInstanceIdentifier()) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else { - attachmentOfOneInstance_[info.GetContentType()] = info; + oneInstanceIdentifier_.reset(new std::string(id)); + } + } + + + const std::string& FindResponse::Resource::GetOneInstanceIdentifier() const + { + if (HasOneInstanceIdentifier()) + { + return *oneInstanceIdentifier_; } else { @@ -387,20 +400,9 @@ } - bool FindResponse::Resource::LookupAttachmentOfOneInstance(FileInfo& target, - FileContentType type) const + bool FindResponse::Resource::HasOneInstanceIdentifier() const { - std::map::const_iterator found = attachmentOfOneInstance_.find(type); - - if (found == attachmentOfOneInstance_.end()) - { - return false; - } - else - { - target = found->second; - return true; - } + return oneInstanceIdentifier_.get() != NULL; } @@ -579,25 +581,9 @@ } } - for (std::set::const_iterator it = request.GetRetrieveAttachmentOfOneInstance().begin(); - it != request.GetRetrieveAttachmentOfOneInstance().end(); ++it) + if (request.IsRetrieveOneInstanceIdentifier()) { - FileInfo info; - if (LookupAttachmentOfOneInstance(info, *it)) - { - if (info.GetContentType() == *it) - { - DebugAddAttachment(target["AttachmentOfOneInstance"], info); - } - else - { - throw OrthancException(ErrorCode_DatabasePlugin); - } - } - else - { - throw OrthancException(ErrorCode_DatabasePlugin); - } + target["OneInstance"] = GetOneInstanceIdentifier(); } } @@ -642,7 +628,7 @@ } - const FindResponse::Resource& FindResponse::GetResource(size_t index) const + const FindResponse::Resource& FindResponse::GetResourceByIndex(size_t index) const { if (index >= items_.size()) { @@ -656,7 +642,7 @@ } - FindResponse::Resource& FindResponse::GetResource(const std::string& id) + FindResponse::Resource& FindResponse::GetResourceByIdentifier(const std::string& id) { Index::const_iterator found = index_.find(id); diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/Database/FindResponse.h --- a/OrthancServer/Sources/Database/FindResponse.h Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/Database/FindResponse.h Wed May 08 18:28:36 2024 +0200 @@ -88,7 +88,7 @@ std::set labels_; std::map attachments_; ChildrenMetadata childrenMetadata_; - std::map attachmentOfOneInstance_; + std::unique_ptr oneInstanceIdentifier_; MainDicomTagsAtLevel& GetMainDicomTagsAtLevel(ResourceType level); @@ -124,9 +124,9 @@ return identifier_; } - const std::string& GetParentIdentifier() const; + void SetParentIdentifier(const std::string& id); - void SetParentIdentifier(const std::string& id); + const std::string& GetParentIdentifier() const; bool HasParentIdentifier() const; @@ -201,10 +201,11 @@ bool LookupChildrenMetadata(std::list& values, MetadataType metadata) const; - void AddAttachmentOfOneInstance(const FileInfo& info); + const std::string& GetOneInstanceIdentifier() const; - bool LookupAttachmentOfOneInstance(FileInfo& target, - FileContentType type) const; + void SetOneInstanceIdentifier(const std::string& id); + + bool HasOneInstanceIdentifier() const; void DebugExport(Json::Value& target, const FindRequest& request) const; @@ -226,13 +227,13 @@ return items_.size(); } - const Resource& GetResource(size_t index) const; + const Resource& GetResourceByIndex(size_t index) const; - Resource& GetResource(const std::string& id); + Resource& GetResourceByIdentifier(const std::string& id); - const Resource& GetResource(const std::string& id) const + const Resource& GetResourceByIdentifier(const std::string& id) const { - return const_cast(*this).GetResource(id); + return const_cast(*this).GetResourceByIdentifier(id); } bool HasResource(const std::string& id) const diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp --- a/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/OrthancRestApi/OrthancRestResources.cpp Wed May 08 18:28:36 2024 +0200 @@ -241,7 +241,7 @@ OrthancRestApi::GetRequestedTags(requestedTags, call); ResourceFinder finder(resourceType, expand); - finder.SetRequestedTags(requestedTags); + finder.AddRequestedTags(requestedTags); finder.SetFormat(OrthancRestApi::GetDicomFormat(call, DicomToJsonFormat_Human)); if (call.HasArgument("limit") || diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/ResourceFinder.cpp --- a/OrthancServer/Sources/ResourceFinder.cpp Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/ResourceFinder.cpp Wed May 08 18:28:36 2024 +0200 @@ -24,8 +24,10 @@ #include "ResourceFinder.h" #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" +#include "../../OrthancFramework/Sources/Logging.h" #include "../../OrthancFramework/Sources/OrthancException.h" #include "../../OrthancFramework/Sources/SerializationToolbox.h" +#include "OrthancConfiguration.h" #include "ServerContext.h" #include "ServerIndex.h" @@ -92,6 +94,34 @@ } + static void InjectRequestedTags(DicomMap& requestedTags, + std::set& missingTags /* out */, + const FindResponse::Resource& resource, + ResourceType level, + const std::set& tags) + { + if (!tags.empty()) + { + DicomMap m; + resource.GetMainDicomTags(m, level); + + for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) + { + std::string value; + if (m.LookupStringValue(value, *it, false /* not binary */)) + { + requestedTags.SetValue(*it, value, false /* not binary */); + } + else + { + // This is the case where the Housekeeper should be run + missingTags.insert(*it); + } + } + } + } + + void ResourceFinder::Expand(Json::Value& target, const FindResponse::Resource& resource, ServerIndex& index) const @@ -106,11 +136,6 @@ throw OrthancException(ErrorCode_InternalError); } - if (!requestedTags_.empty()) - { - throw OrthancException(ErrorCode_NotImplemented); - } - target = Json::objectValue; target["Type"] = GetResourceTypeText(resource.GetLevel(), false, true); @@ -180,7 +205,7 @@ target["Status"] = EnumerationToString(status); - static const char* EXPECTED_NUMBER_OF_INSTANCES = "ExpectedNumberOfInstances"; + static const char* const EXPECTED_NUMBER_OF_INSTANCES = "ExpectedNumberOfInstances"; if (status == SeriesStatus_Unknown) { @@ -207,7 +232,7 @@ throw OrthancException(ErrorCode_InternalError); } - static const char* INDEX_IN_SERIES = "IndexInSeries"; + static const char* const INDEX_IN_SERIES = "IndexInSeries"; std::string s; uint32_t index; @@ -252,12 +277,40 @@ } { + DicomMap allMainDicomTags; + resource.GetMainDicomTags(allMainDicomTags, resource.GetLevel()); + + /** + * This section was part of "StatelessDatabaseOperations::ExpandResource()" + * in Orthanc <= 1.12.3 + **/ + + // read all main sequences from DB + std::string serializedSequences; + if (resource.LookupMetadata(serializedSequences, resource.GetLevel(), MetadataType_MainDicomSequences)) + { + Json::Value jsonMetadata; + Toolbox::ReadJson(jsonMetadata, serializedSequences); + + if (jsonMetadata["Version"].asInt() == 1) + { + allMainDicomTags.FromDicomAsJson(jsonMetadata["Sequences"], true /* append */, true /* parseSequences */); + } + else + { + throw OrthancException(ErrorCode_NotImplemented); + } + } + + /** + * End of section from StatelessDatabaseOperations + **/ + + static const char* const MAIN_DICOM_TAGS = "MainDicomTags"; static const char* const PATIENT_MAIN_DICOM_TAGS = "PatientMainDicomTags"; - // TODO-FIND : (expandFlags & ExpandResourceFlags_IncludeMainDicomTags) - DicomMap allMainDicomTags; - resource.GetMainDicomTags(allMainDicomTags, resource.GetLevel()); + // TODO-FIND : Ignore "null" values DicomMap levelMainDicomTags; allMainDicomTags.ExtractResourceInformation(levelMainDicomTags, resource.GetLevel()); @@ -273,21 +326,6 @@ target[PATIENT_MAIN_DICOM_TAGS] = Json::objectValue; FromDcmtkBridge::ToJson(target[PATIENT_MAIN_DICOM_TAGS], patientMainDicomTags, format_); } - - /* - TODO-FIND - - if (!requestedTags_.empty()) - { - static const char* const REQUESTED_TAGS = "RequestedTags"; - - DicomMap tags; - resource.GetMainDicomTags().ExtractTags(tags, requestedTags); - - target[REQUESTED_TAGS] = Json::objectValue; - FromDcmtkBridge::ToJson(target[REQUESTED_TAGS], tags, format); - } - */ } { @@ -323,6 +361,7 @@ request_(level), expand_(expand), format_(DicomToJsonFormat_Human), + hasRequestedTags_(false), includeAllMetadata_(false) { if (expand) @@ -353,6 +392,80 @@ } + void ResourceFinder::AddRequestedTags(const DicomTag& tag) + { + if (DicomMap::IsMainDicomTag(tag, ResourceType_Patient)) + { + request_.SetRetrieveMainDicomTags(ResourceType_Patient, true); + request_.SetRetrieveMetadata(ResourceType_Patient, true); + requestedPatientTags_.insert(tag); + } + else if (DicomMap::IsMainDicomTag(tag, ResourceType_Study)) + { + if (request_.GetLevel() == ResourceType_Patient) + { + throw OrthancException(ErrorCode_ParameterOutOfRange, "Requested tag " + tag.Format() + + " is only available at the study/series/instance levels"); + } + else + { + request_.SetRetrieveMainDicomTags(ResourceType_Study, true); + request_.SetRetrieveMetadata(ResourceType_Study, true); + requestedStudyTags_.insert(tag); + } + } + else if (DicomMap::IsMainDicomTag(tag, ResourceType_Series)) + { + if (request_.GetLevel() == ResourceType_Patient || + request_.GetLevel() == ResourceType_Study) + { + throw OrthancException(ErrorCode_ParameterOutOfRange, "Requested tag " + tag.Format() + + " is only available at the series/instance levels"); + } + else + { + request_.SetRetrieveMainDicomTags(ResourceType_Series, true); + request_.SetRetrieveMetadata(ResourceType_Series, true); + requestedSeriesTags_.insert(tag); + } + } + else if (DicomMap::IsMainDicomTag(tag, ResourceType_Instance)) + { + if (request_.GetLevel() == ResourceType_Patient || + request_.GetLevel() == ResourceType_Study || + request_.GetLevel() == ResourceType_Series) + { + throw OrthancException(ErrorCode_ParameterOutOfRange, "Requested tag " + tag.Format() + + " is only available at the instance level"); + } + else + { + // Main DICOM tags from the instance level will be retrieved anyway + assert(request_.IsRetrieveMainDicomTags(ResourceType_Instance)); + assert(request_.IsRetrieveMetadata(ResourceType_Instance)); + requestedInstanceTags_.insert(tag); + } + } + else + { + // This is not a main DICOM tag: We will be forced to access the DICOM file anyway + request_.SetRetrieveOneInstanceIdentifier(true); + requestedTagsFromFileStorage_.insert(tag); + } + + hasRequestedTags_ = true; + } + + + void ResourceFinder::AddRequestedTags(const std::set& tags) + { + for (std::set::const_iterator it = tags.begin(); it != tags.end(); ++it) + { + AddRequestedTags(*it); + } + } + + void ResourceFinder::Execute(Json::Value& target, ServerContext& context) { @@ -361,20 +474,96 @@ target = Json::arrayValue; - if (expand_) + for (size_t i = 0; i < response.GetSize(); i++) { - for (size_t i = 0; i < response.GetSize(); i++) + const FindResponse::Resource& resource = response.GetResourceByIndex(i); + + if (expand_) { Json::Value item; - Expand(item, response.GetResource(i), context.GetIndex()); + Expand(item, resource, context.GetIndex()); + + std::set missingTags = requestedTagsFromFileStorage_; + + DicomMap requestedTags; + InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Patient, requestedPatientTags_); + InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Study, requestedStudyTags_); + InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Series, requestedSeriesTags_); + InjectRequestedTags(requestedTags, missingTags, resource, ResourceType_Instance, requestedInstanceTags_); + + if (!missingTags.empty()) + { + OrthancConfiguration::ReaderLock lock; + if (lock.GetConfiguration().IsWarningEnabled(Warnings_001_TagsBeingReadFromStorage)) + { + std::string missings; + FromDcmtkBridge::FormatListOfTags(missings, missingTags); + + LOG(WARNING) << "W001: Accessing Dicom tags from storage when accessing " + << Orthanc::GetResourceTypeText(resource.GetLevel(), false, false) + << ": " << missings; + } + + std::string instancePublicId; + + if (request_.IsRetrieveOneInstanceIdentifier()) + { + instancePublicId = resource.GetOneInstanceIdentifier(); + } + else + { + FindRequest requestDicomAttachment(request_.GetLevel()); + requestDicomAttachment.SetOrthancId(request_.GetLevel(), resource.GetIdentifier()); + requestDicomAttachment.SetRetrieveOneInstanceIdentifier(true); + + FindResponse responseDicomAttachment; + context.GetIndex().ExecuteFind(responseDicomAttachment, requestDicomAttachment); + + if (responseDicomAttachment.GetSize() != 1 || + !responseDicomAttachment.GetResourceByIndex(0).HasOneInstanceIdentifier()) + { + throw OrthancException(ErrorCode_InexistentFile); + } + else + { + instancePublicId = responseDicomAttachment.GetResourceByIndex(0).GetOneInstanceIdentifier(); + } + } + + LOG(INFO) << "Will retrieve missing DICOM tags from instance: " << instancePublicId; + + Json::Value tmpDicomAsJson; + context.ReadDicomAsJson(tmpDicomAsJson, instancePublicId, missingTags /* ignoreTagLength */); + + DicomMap tmpDicomMap; + tmpDicomMap.FromDicomAsJson(tmpDicomAsJson, false /* append */, true /* parseSequences*/); + + for (std::set::const_iterator it = missingTags.begin(); it != missingTags.end(); ++it) + { + assert(!requestedTags.HasTag(*it)); + if (tmpDicomMap.HasTag(*it)) + { + requestedTags.SetValue(*it, tmpDicomMap.GetValue(*it)); + } + else + { + requestedTags.SetNullValue(*it); // TODO-FIND: Is this compatible with Orthanc <= 1.12.3? + } + } + } + + if (hasRequestedTags_) + { + static const char* const REQUESTED_TAGS = "RequestedTags"; + item[REQUESTED_TAGS] = Json::objectValue; + FromDcmtkBridge::ToJson(item[REQUESTED_TAGS], requestedTags, format_); + } + target.append(item); } - } - else - { - for (size_t i = 0; i < response.GetSize(); i++) + else { - target.append(response.GetResource(i).GetIdentifier()); + target.append(resource.GetIdentifier()); } } } diff -r 3d0aa94b44b3 -r 4690a0d2b01e OrthancServer/Sources/ResourceFinder.h --- a/OrthancServer/Sources/ResourceFinder.h Wed May 08 13:37:23 2024 +0200 +++ b/OrthancServer/Sources/ResourceFinder.h Wed May 08 18:28:36 2024 +0200 @@ -35,8 +35,13 @@ private: FindRequest request_; bool expand_; - std::set requestedTags_; DicomToJsonFormat format_; + bool hasRequestedTags_; + std::set requestedPatientTags_; + std::set requestedStudyTags_; + std::set requestedSeriesTags_; + std::set requestedInstanceTags_; + std::set requestedTagsFromFileStorage_; bool includeAllMetadata_; // Same as: ExpandResourceFlags_IncludeAllMetadata SeriesStatus GetSeriesStatus(uint32_t& expectedNumberOfInstances, @@ -50,11 +55,6 @@ ResourceFinder(ResourceType level, bool expand); - void SetRequestedTags(const std::set& tags) - { - requestedTags_ = tags; - } - void SetFormat(DicomToJsonFormat format) { format_ = format; @@ -71,6 +71,10 @@ includeAllMetadata_ = include; } + void AddRequestedTags(const DicomTag& tag); + + void AddRequestedTags(const std::set& tags); + void Execute(Json::Value& target, ServerContext& context); };