comparison OrthancServer/Search/HierarchicalMatcher.cpp @ 3217:cf8cbeb35f33

preliminary support of Korean character set
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 13 Feb 2019 17:46:12 +0100
parents 1b05fd072c57
children 94f4a18a79cc
comparison
equal deleted inserted replaced
3216:c9a71eb4edcf 3217:cf8cbeb35f33
51 { 51 {
52 OrthancConfiguration::ReaderLock lock; 52 OrthancConfiguration::ReaderLock lock;
53 caseSensitivePN = lock.GetConfiguration().GetBooleanParameter("CaseSensitivePN", false); 53 caseSensitivePN = lock.GetConfiguration().GetBooleanParameter("CaseSensitivePN", false);
54 } 54 }
55 55
56 Setup(*query.GetDcmtkObject().getDataset(), caseSensitivePN, query.GetEncoding()); 56 bool hasCodeExtensions;
57 Encoding encoding = query.DetectEncoding(hasCodeExtensions);
58 Setup(*query.GetDcmtkObject().getDataset(), caseSensitivePN, encoding, hasCodeExtensions);
57 } 59 }
58 60
59 61
60 HierarchicalMatcher::~HierarchicalMatcher() 62 HierarchicalMatcher::~HierarchicalMatcher()
61 { 63 {
70 } 72 }
71 73
72 74
73 void HierarchicalMatcher::Setup(DcmItem& dataset, 75 void HierarchicalMatcher::Setup(DcmItem& dataset,
74 bool caseSensitivePN, 76 bool caseSensitivePN,
75 Encoding encoding) 77 Encoding encoding,
78 bool hasCodeExtensions)
76 { 79 {
77 for (unsigned long i = 0; i < dataset.card(); i++) 80 for (unsigned long i = 0; i < dataset.card(); i++)
78 { 81 {
79 DcmElement* element = dataset.getElement(i); 82 DcmElement* element = dataset.getElement(i);
80 if (element == NULL) 83 if (element == NULL)
106 // Universal matching of a sequence 109 // Universal matching of a sequence
107 sequences_[tag] = NULL; 110 sequences_[tag] = NULL;
108 } 111 }
109 else if (sequence.card() == 1) 112 else if (sequence.card() == 1)
110 { 113 {
111 sequences_[tag] = new HierarchicalMatcher(*sequence.getItem(0), caseSensitivePN, encoding); 114 sequences_[tag] = new HierarchicalMatcher(*sequence.getItem(0), caseSensitivePN, encoding, hasCodeExtensions);
112 } 115 }
113 else 116 else
114 { 117 {
115 throw OrthancException(ErrorCode_BadRequest); 118 throw OrthancException(ErrorCode_BadRequest);
116 } 119 }
120 flatTags_.insert(tag); 123 flatTags_.insert(tag);
121 124
122 std::set<DicomTag> ignoreTagLength; 125 std::set<DicomTag> ignoreTagLength;
123 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement 126 std::auto_ptr<DicomValue> value(FromDcmtkBridge::ConvertLeafElement
124 (*element, DicomToJsonFlags_None, 127 (*element, DicomToJsonFlags_None,
125 0, encoding, ignoreTagLength)); 128 0, encoding, hasCodeExtensions, ignoreTagLength));
126 129
127 // WARNING: Also modify "DatabaseLookup::IsMatch()" if modifying this code 130 // WARNING: Also modify "DatabaseLookup::IsMatch()" if modifying this code
128 if (value.get() == NULL || 131 if (value.get() == NULL ||
129 value->IsNull()) 132 value->IsNull())
130 { 133 {
195 } 198 }
196 199
197 200
198 bool HierarchicalMatcher::Match(ParsedDicomFile& dicom) const 201 bool HierarchicalMatcher::Match(ParsedDicomFile& dicom) const
199 { 202 {
203 bool hasCodeExtensions;
204 Encoding encoding = dicom.DetectEncoding(hasCodeExtensions);
205
200 return MatchInternal(*dicom.GetDcmtkObject().getDataset(), 206 return MatchInternal(*dicom.GetDcmtkObject().getDataset(),
201 dicom.GetEncoding()); 207 encoding, hasCodeExtensions);
202 } 208 }
203 209
204 210
205 bool HierarchicalMatcher::MatchInternal(DcmItem& item, 211 bool HierarchicalMatcher::MatchInternal(DcmItem& item,
206 Encoding encoding) const 212 Encoding encoding,
207 { 213 bool hasCodeExtensions) const
208 if (!flatConstraints_.IsMatch(item, encoding)) 214 {
215 if (!flatConstraints_.IsMatch(item, encoding, hasCodeExtensions))
209 { 216 {
210 return false; 217 return false;
211 } 218 }
212 219
213 for (Sequences::const_iterator it = sequences_.begin(); 220 for (Sequences::const_iterator it = sequences_.begin();
226 233
227 bool match = false; 234 bool match = false;
228 235
229 for (unsigned long i = 0; i < sequence->card(); i++) 236 for (unsigned long i = 0; i < sequence->card(); i++)
230 { 237 {
231 if (it->second->MatchInternal(*sequence->getItem(i), encoding)) 238 if (it->second->MatchInternal(*sequence->getItem(i), encoding, hasCodeExtensions))
232 { 239 {
233 match = true; 240 match = true;
234 break; 241 break;
235 } 242 }
236 } 243 }
245 return true; 252 return true;
246 } 253 }
247 254
248 255
249 DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& source, 256 DcmDataset* HierarchicalMatcher::ExtractInternal(DcmItem& source,
250 Encoding encoding) const 257 Encoding encoding,
258 bool hasCodeExtensions) const
251 { 259 {
252 std::auto_ptr<DcmDataset> target(new DcmDataset); 260 std::auto_ptr<DcmDataset> target(new DcmDataset);
253 261
254 for (std::set<DicomTag>::const_iterator it = flatTags_.begin(); 262 for (std::set<DicomTag>::const_iterator it = flatTags_.begin();
255 it != flatTags_.end(); ++it) 263 it != flatTags_.end(); ++it)
281 { 289 {
282 if (it->second == NULL) 290 if (it->second == NULL)
283 { 291 {
284 cloned->append(new DcmItem(*sequence->getItem(i))); 292 cloned->append(new DcmItem(*sequence->getItem(i)));
285 } 293 }
286 else if (it->second->MatchInternal(*sequence->getItem(i), encoding)) // TODO Might be optimized 294 else if (it->second->MatchInternal(*sequence->getItem(i), encoding, hasCodeExtensions)) // TODO Might be optimized
287 { 295 {
288 // It is necessary to encapsulate the child dataset into a 296 // It is necessary to encapsulate the child dataset into a
289 // "DcmItem" object before it can be included in a 297 // "DcmItem" object before it can be included in a
290 // sequence. Otherwise, "dciodvfy" reports an error "Bad 298 // sequence. Otherwise, "dciodvfy" reports an error "Bad
291 // tag in sequence - Expecting Item or Sequence Delimiter." 299 // tag in sequence - Expecting Item or Sequence Delimiter."
292 std::auto_ptr<DcmDataset> child(it->second->ExtractInternal(*sequence->getItem(i), encoding)); 300 std::auto_ptr<DcmDataset> child(it->second->ExtractInternal(*sequence->getItem(i), encoding, hasCodeExtensions));
293 cloned->append(new DcmItem(*child)); 301 cloned->append(new DcmItem(*child));
294 } 302 }
295 } 303 }
296 304
297 target->insert(cloned.release()); 305 target->insert(cloned.release());
302 } 310 }
303 311
304 312
305 ParsedDicomFile* HierarchicalMatcher::Extract(ParsedDicomFile& dicom) const 313 ParsedDicomFile* HierarchicalMatcher::Extract(ParsedDicomFile& dicom) const
306 { 314 {
315 bool hasCodeExtensions;
316 Encoding encoding = dicom.DetectEncoding(hasCodeExtensions);
317
307 std::auto_ptr<DcmDataset> dataset(ExtractInternal(*dicom.GetDcmtkObject().getDataset(), 318 std::auto_ptr<DcmDataset> dataset(ExtractInternal(*dicom.GetDcmtkObject().getDataset(),
308 dicom.GetEncoding())); 319 encoding, hasCodeExtensions));
309 320
310 std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(*dataset)); 321 std::auto_ptr<ParsedDicomFile> result(new ParsedDicomFile(*dataset));
311 result->SetEncoding(dicom.GetEncoding()); 322 result->SetEncoding(encoding);
312 323
313 return result.release(); 324 return result.release();
314 } 325 }
315 } 326 }