comparison OrthancServer/Sources/Database/FindResponse.cpp @ 5554:12d8a1a266e9 find-refactoring

introduction of FindRequest and FindResponse
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 15 Apr 2024 16:13:24 +0200
parents
children def06a42e5ef
comparison
equal deleted inserted replaced
5549:dcbf0c776945 5554:12d8a1a266e9
1 /**
2 * Orthanc - A Lightweight, RESTful DICOM Store
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics
4 * Department, University Hospital of Liege, Belgium
5 * Copyright (C) 2017-2024 Osimis S.A., Belgium
6 * Copyright (C) 2021-2024 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
7 *
8 * This program is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 **/
21
22
23 #include "FindResponse.h"
24
25 #include "../../../OrthancFramework/Sources/DicomFormat/DicomInstanceHasher.h"
26 #include "../../../OrthancFramework/Sources/OrthancException.h"
27
28 #include <cassert>
29
30
31 namespace Orthanc
32 {
33 static void ExtractOrthancIdentifiers(OrthancIdentifiers& identifiers,
34 ResourceType level,
35 const DicomMap& dicom)
36 {
37 switch (level)
38 {
39 case ResourceType_Patient:
40 {
41 std::string patientId;
42 if (!dicom.LookupStringValue(patientId, Orthanc::DICOM_TAG_PATIENT_ID, false))
43 {
44 throw OrthancException(ErrorCode_ParameterOutOfRange);
45 }
46 else
47 {
48 DicomInstanceHasher hasher(patientId, "", "", "");
49 identifiers.SetPatientId(hasher.HashPatient());
50 }
51 break;
52 }
53
54 case ResourceType_Study:
55 {
56 std::string patientId, studyInstanceUid;
57 if (!dicom.LookupStringValue(patientId, Orthanc::DICOM_TAG_PATIENT_ID, false) ||
58 !dicom.LookupStringValue(studyInstanceUid, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false))
59 {
60 throw OrthancException(ErrorCode_ParameterOutOfRange);
61 }
62 else
63 {
64 DicomInstanceHasher hasher(patientId, studyInstanceUid, "", "");
65 identifiers.SetPatientId(hasher.HashPatient());
66 identifiers.SetStudyId(hasher.HashStudy());
67 }
68 break;
69 }
70
71 case ResourceType_Series:
72 {
73 std::string patientId, studyInstanceUid, seriesInstanceUid;
74 if (!dicom.LookupStringValue(patientId, Orthanc::DICOM_TAG_PATIENT_ID, false) ||
75 !dicom.LookupStringValue(studyInstanceUid, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false) ||
76 !dicom.LookupStringValue(seriesInstanceUid, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false))
77 {
78 throw OrthancException(ErrorCode_ParameterOutOfRange);
79 }
80 else
81 {
82 DicomInstanceHasher hasher(patientId, studyInstanceUid, seriesInstanceUid, "");
83 identifiers.SetPatientId(hasher.HashPatient());
84 identifiers.SetStudyId(hasher.HashStudy());
85 identifiers.SetSeriesId(hasher.HashSeries());
86 }
87 break;
88 }
89
90 case ResourceType_Instance:
91 {
92 std::string patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid;
93 if (!dicom.LookupStringValue(patientId, Orthanc::DICOM_TAG_PATIENT_ID, false) ||
94 !dicom.LookupStringValue(studyInstanceUid, Orthanc::DICOM_TAG_STUDY_INSTANCE_UID, false) ||
95 !dicom.LookupStringValue(seriesInstanceUid, Orthanc::DICOM_TAG_SERIES_INSTANCE_UID, false) ||
96 !dicom.LookupStringValue(sopInstanceUid, Orthanc::DICOM_TAG_SOP_INSTANCE_UID, false))
97 {
98 throw OrthancException(ErrorCode_ParameterOutOfRange);
99 }
100 else
101 {
102 DicomInstanceHasher hasher(patientId, studyInstanceUid, seriesInstanceUid, sopInstanceUid);
103 identifiers.SetPatientId(hasher.HashPatient());
104 identifiers.SetStudyId(hasher.HashStudy());
105 identifiers.SetSeriesId(hasher.HashSeries());
106 identifiers.SetInstanceId(hasher.HashInstance());
107 }
108 break;
109 }
110
111 default:
112 throw OrthancException(ErrorCode_NotImplemented);
113 }
114 }
115
116
117 FindResponse::Item::Item(ResourceType level,
118 DicomMap* dicomMap /* takes ownership */) :
119 level_(level),
120 dicomMap_(dicomMap)
121 {
122 if (dicomMap == NULL)
123 {
124 throw OrthancException(ErrorCode_NullPointer);
125 }
126 else
127 {
128 ExtractOrthancIdentifiers(identifiers_, level, *dicomMap);
129 }
130 }
131
132
133 void FindResponse::Item::AddMetadata(MetadataType metadata,
134 const std::string& value)
135 {
136 if (metadata_.find(metadata) != metadata_.end())
137 {
138 throw OrthancException(ErrorCode_BadSequenceOfCalls); // Metadata already present
139 }
140 else
141 {
142 metadata_[metadata] = value;
143 }
144 }
145
146
147 bool FindResponse::Item::LookupMetadata(std::string& value,
148 MetadataType metadata) const
149 {
150 std::map<MetadataType, std::string>::const_iterator found = metadata_.find(metadata);
151
152 if (found == metadata_.end())
153 {
154 return false;
155 }
156 else
157 {
158 value = found->second;
159 return true;
160 }
161 }
162
163
164 void FindResponse::Item::ListMetadata(std::set<MetadataType> target) const
165 {
166 target.clear();
167
168 for (std::map<MetadataType, std::string>::const_iterator it = metadata_.begin(); it != metadata_.end(); ++it)
169 {
170 target.insert(it->first);
171 }
172 }
173
174
175 const DicomMap& FindResponse::Item::GetDicomMap() const
176 {
177 if (dicomMap_.get() == NULL)
178 {
179 throw OrthancException(ErrorCode_BadSequenceOfCalls);
180 }
181 else
182 {
183 return *dicomMap_;
184 }
185 }
186
187
188 FindResponse::~FindResponse()
189 {
190 for (size_t i = 0; i < items_.size(); i++)
191 {
192 assert(items_[i] != NULL);
193 delete items_[i];
194 }
195 }
196
197
198 void FindResponse::Add(Item* item /* takes ownership */)
199 {
200 if (item == NULL)
201 {
202 throw OrthancException(ErrorCode_NullPointer);
203 }
204 else
205 {
206 items_.push_back(item);
207 }
208 }
209
210
211 const FindResponse::Item& FindResponse::GetItem(size_t index) const
212 {
213 if (index >= items_.size())
214 {
215 throw OrthancException(ErrorCode_ParameterOutOfRange);
216 }
217 else
218 {
219 assert(items_[index] != NULL);
220 return *items_[index];
221 }
222 }
223 }