1 /*
2 *
3 * Copyright (C) 2015-2020, Open Connections GmbH
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation are maintained by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmiod
15 *
16 * Author: Michael Onken
17 *
18 * Purpose: Collection of classes representing DICOM IOD macros
19 *
20 */
21
22 #include "dcmtk/dcmiod/iodmacro.h"
23 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
24 #include "dcmtk/dcmiod/iodutil.h" // for static IOD helpers
25 #include "dcmtk/ofstd/ofstream.h"
26
27 // --------------------------- Code Sequence Macro ---------------------------
28
29 // -- Code Sequence Macro
30
CodeSequenceMacro(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent)31 CodeSequenceMacro::CodeSequenceMacro(OFshared_ptr<DcmItem> item, OFshared_ptr<IODRules> rules, IODComponent* parent)
32 : IODComponent(item, rules, parent)
33 {
34 // reset element rules
35 resetRules();
36 }
37
CodeSequenceMacro(IODComponent * parent)38 CodeSequenceMacro::CodeSequenceMacro(IODComponent* parent)
39 : IODComponent(parent)
40 {
41 // reset element rules
42 resetRules();
43 }
44
CodeSequenceMacro(const CodeSequenceMacro & rhs)45 CodeSequenceMacro::CodeSequenceMacro(const CodeSequenceMacro& rhs)
46 : IODComponent(rhs)
47 {
48 }
49
~CodeSequenceMacro()50 CodeSequenceMacro::~CodeSequenceMacro()
51 {
52 // nothing to do
53 }
54
CodeSequenceMacro(const OFString & codeValue,const OFString & codingSchemeDesignator,const OFString & codeMeaning,const OFString & codingSchemeVersion,IODComponent * parent)55 CodeSequenceMacro::CodeSequenceMacro(const OFString& codeValue,
56 const OFString& codingSchemeDesignator,
57 const OFString& codeMeaning,
58 const OFString& codingSchemeVersion,
59 IODComponent* parent)
60 : IODComponent(parent)
61 {
62 // reset element rules
63 resetRules();
64 set(codeValue, codingSchemeDesignator, codeMeaning, codingSchemeVersion);
65 }
66
check(const bool quiet)67 OFCondition CodeSequenceMacro::check(const bool quiet)
68 {
69 OFString val;
70 getCodeValue(val);
71 if (!val.empty())
72 getCodingSchemeDesignator(val);
73 if (!val.empty())
74 getCodeMeaning(val);
75 if (!val.empty())
76 return EC_Normal;
77
78 return EC_IllegalParameter;
79 }
80
CodeSequenceMacro(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent,const OFString & codeValue,const OFString & codingSchemeDesignator,const OFString & codeMeaning,const OFString & codingSchemeVersion)81 CodeSequenceMacro::CodeSequenceMacro(OFshared_ptr<DcmItem> item,
82 OFshared_ptr<IODRules> rules,
83 IODComponent* parent,
84 const OFString& codeValue,
85 const OFString& codingSchemeDesignator,
86 const OFString& codeMeaning,
87 const OFString& codingSchemeVersion)
88 : IODComponent(item, rules, parent)
89 {
90 // reset element rules
91 resetRules();
92 set(codeValue, codingSchemeDesignator, codeMeaning, codingSchemeVersion);
93 }
94
getName() const95 OFString CodeSequenceMacro::getName() const
96 {
97 return "CodeSequenceMacro";
98 }
99
resetRules()100 void CodeSequenceMacro::resetRules()
101 {
102 m_Rules->addRule(new IODRule(DCM_CodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED),
103 OFTrue /*overwrite old rule*/);
104 m_Rules->addRule(new IODRule(DCM_URNCodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED),
105 OFTrue /*overwrite old rule*/);
106 m_Rules->addRule(new IODRule(DCM_LongCodeValue, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED),
107 OFTrue /*overwrite old rule*/);
108 m_Rules->addRule(new IODRule(DCM_CodingSchemeDesignator, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED),
109 OFTrue /*overwrite old rule*/);
110 m_Rules->addRule(new IODRule(DCM_CodingSchemeVersion, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED),
111 OFTrue /*overwrite old rule*/);
112 m_Rules->addRule(new IODRule(DCM_CodeMeaning, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED),
113 OFTrue /*overwrite old rule*/);
114 }
115
116 // -- get dicom attributes --
117
getCodeValue(OFString & value,const signed long pos,const OFBool autoTag)118 OFCondition CodeSequenceMacro::getCodeValue(OFString& value, const signed long pos, const OFBool autoTag)
119 {
120 OFString c;
121 OFCondition cond = DcmIODUtil::getStringValueFromItem(DCM_CodeValue, *m_Item, value, pos);
122 if (cond.good() || ((cond == EC_TagNotFound) && !autoTag))
123 return cond;
124
125 cond = DcmIODUtil::getStringValueFromItem(DCM_URNCodeValue, *m_Item, value, pos);
126 if (cond != EC_TagNotFound)
127 return cond;
128
129 cond = DcmIODUtil::getStringValueFromItem(DCM_LongCodeValue, *m_Item, value, pos);
130 return cond;
131 }
132
getURNCodeValue(OFString & value,const signed long pos)133 OFCondition CodeSequenceMacro::getURNCodeValue(OFString& value, const signed long pos)
134 {
135 return DcmIODUtil::getStringValueFromItem(DCM_URNCodeValue, *m_Item, value, pos);
136 }
137
getLongCodeValue(OFString & value,const signed long pos)138 OFCondition CodeSequenceMacro::getLongCodeValue(OFString& value, const signed long pos)
139 {
140 return DcmIODUtil::getStringValueFromItem(DCM_LongCodeValue, *m_Item, value, pos);
141 }
142
getCodingSchemeDesignator(OFString & value,const signed long pos)143 OFCondition CodeSequenceMacro::getCodingSchemeDesignator(OFString& value, const signed long pos)
144 {
145 return DcmIODUtil::getStringValueFromItem(DCM_CodingSchemeDesignator, *m_Item, value, pos);
146 }
147
getCodingSchemeVersion(OFString & value,const signed long pos)148 OFCondition CodeSequenceMacro::getCodingSchemeVersion(OFString& value, const signed long pos)
149 {
150 return DcmIODUtil::getStringValueFromItem(DCM_CodingSchemeVersion, *m_Item, value, pos);
151 }
152
getCodeMeaning(OFString & value,const signed long pos)153 OFCondition CodeSequenceMacro::getCodeMeaning(OFString& value, const signed long pos)
154 {
155 return DcmIODUtil::getStringValueFromItem(DCM_CodeMeaning, *m_Item, value, pos);
156 }
157
empty()158 OFBool CodeSequenceMacro::empty()
159 {
160 OFString val;
161 getCodeValue(val);
162 if (val.empty())
163 {
164 getCodingSchemeDesignator(val);
165 if (val.empty())
166 {
167 getCodingSchemeVersion(val);
168 if (val.empty())
169 {
170 getCodingSchemeDesignator(val);
171 if (val.empty())
172 {
173 return OFTrue;
174 }
175 }
176 }
177 }
178 return OFFalse;
179 }
180
181 // -- set dicom attributes --
182
setCodeValue(const OFString & value,const OFBool checkValue,const OFBool autoTag)183 OFCondition CodeSequenceMacro::setCodeValue(const OFString& value, const OFBool checkValue, const OFBool autoTag)
184 {
185 OFCondition result;
186
187 // Identify the code value tag to be used
188 if (autoTag)
189 {
190 if ((value.find("://") != OFString_npos) || (value.compare(0, 4, "urn:") == 0))
191 {
192 return setURNCodeValue(value, checkValue);
193 }
194 else if (value.length() > 16) // Long Code Value
195 {
196 return setLongCodeValue(value, checkValue);
197 }
198 }
199 // Classic Code Value
200 result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal;
201 if (result.bad())
202 return result;
203 // TODO: Should check length in characters (not bytes), since SH permits usage of
204 // non-ASCII characters (i.e. as defined in 0008,0015).
205 if (value.length() > 16)
206 return EC_MaximumLengthViolated;
207 result = m_Item->putAndInsertOFStringArray(DCM_CodeValue, value);
208 if (result.good())
209 {
210 deleteUnusedCodeValues(DCM_CodeValue);
211 }
212 return result;
213 }
214
setURNCodeValue(const OFString & value,const bool checkValue)215 OFCondition CodeSequenceMacro::setURNCodeValue(const OFString& value, const bool checkValue)
216 {
217 OFCondition result = (checkValue) ? DcmUniversalResourceIdentifierOrLocator::checkStringValue(value) : EC_Normal;
218 if (result.good())
219 result = m_Item->putAndInsertOFStringArray(DCM_URNCodeValue, value);
220 if (result.good())
221 {
222 deleteUnusedCodeValues(DCM_URNCodeValue);
223 }
224 return result;
225 }
226
setLongCodeValue(const OFString & value,const bool checkValue)227 OFCondition CodeSequenceMacro::setLongCodeValue(const OFString& value, const bool checkValue)
228 {
229 OFCondition result = (checkValue) ? DcmUnlimitedCharacters::checkStringValue(value, "1") : EC_Normal;
230 if (result.good())
231 result = m_Item->putAndInsertOFStringArray(DCM_LongCodeValue, value);
232 if (result.good())
233 {
234 deleteUnusedCodeValues(DCM_LongCodeValue);
235 }
236 return result;
237 }
238
setCodingSchemeDesignator(const OFString & value,const OFBool checkValue)239 OFCondition CodeSequenceMacro::setCodingSchemeDesignator(const OFString& value, const OFBool checkValue)
240 {
241 OFCondition result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal;
242 if (result.good())
243 result = m_Item->putAndInsertOFStringArray(DCM_CodingSchemeDesignator, value);
244 return result;
245 }
246
setCodingSchemeVersion(const OFString & value,const OFBool checkValue)247 OFCondition CodeSequenceMacro::setCodingSchemeVersion(const OFString& value, const OFBool checkValue)
248 {
249 OFCondition result = (checkValue) ? DcmShortString::checkStringValue(value, "1") : EC_Normal;
250 if (result.good())
251 result = m_Item->putAndInsertOFStringArray(DCM_CodingSchemeVersion, value);
252 return result;
253 }
254
setCodeMeaning(const OFString & value,const OFBool checkValue)255 OFCondition CodeSequenceMacro::setCodeMeaning(const OFString& value, const OFBool checkValue)
256 {
257 OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal;
258 if (result.good())
259 result = m_Item->putAndInsertOFStringArray(DCM_CodeMeaning, value);
260 return result;
261 }
262
set(const OFString & value,const OFString & scheme,const OFString & meaning,const OFString & schemeVersion,const OFBool checkValue,const OFBool autoTag)263 OFCondition CodeSequenceMacro::set(const OFString& value,
264 const OFString& scheme,
265 const OFString& meaning,
266 const OFString& schemeVersion,
267 const OFBool checkValue,
268 const OFBool autoTag)
269 {
270 OFCondition result;
271 result = setCodeValue(value, checkValue, autoTag);
272 if (result.good())
273 result = setCodingSchemeDesignator(scheme, checkValue);
274 if (result.good())
275 result = setCodeMeaning(meaning, checkValue);
276 if (result.good() && !schemeVersion.empty())
277 result = setCodingSchemeVersion(schemeVersion, checkValue);
278 return result;
279 }
280
deleteUnusedCodeValues(const DcmTagKey & keepTag)281 void CodeSequenceMacro::deleteUnusedCodeValues(const DcmTagKey& keepTag)
282 {
283 if (keepTag != DCM_CodeValue)
284 m_Item->findAndDeleteElement(DCM_CodeValue);
285 if (keepTag != DCM_URNCodeValue)
286 m_Item->findAndDeleteElement(DCM_URNCodeValue);
287 if (keepTag != DCM_LongCodeValue)
288 m_Item->findAndDeleteElement(DCM_LongCodeValue);
289 }
290
291 // ---------------------- CodeWithModifiers----------------------
292
CodeWithModifiers(const OFString & modifierType,const OFString & modifierVM,const DcmTagKey & modifierSeq)293 CodeWithModifiers::CodeWithModifiers(const OFString& modifierType,
294 const OFString& modifierVM,
295 const DcmTagKey& modifierSeq)
296 : CodeSequenceMacro()
297 , m_Modifiers()
298 , m_ModifierType(modifierType)
299 , m_ModifierVM(modifierVM)
300 , m_CodeModifierSeq(modifierSeq)
301 {
302 resetRules();
303 }
304
CodeWithModifiers(const CodeWithModifiers & rhs)305 CodeWithModifiers::CodeWithModifiers(const CodeWithModifiers& rhs)
306 : CodeSequenceMacro(rhs)
307 , m_Modifiers()
308 , m_ModifierType()
309 , m_ModifierVM()
310 , m_CodeModifierSeq()
311 {
312 if (&rhs == this)
313 return;
314
315 *this = rhs;
316 }
317
operator =(const CodeWithModifiers & rhs)318 CodeWithModifiers& CodeWithModifiers::operator=(const CodeWithModifiers& rhs)
319 {
320 if (&rhs == this)
321 return *this;
322
323 CodeSequenceMacro::operator=(rhs);
324
325 const CodeWithModifiers* r = OFstatic_cast(const CodeWithModifiers*, &rhs);
326 if (r)
327 {
328 OFVector<CodeSequenceMacro*>::const_iterator it = r->m_Modifiers.begin();
329 while ((it != r->m_Modifiers.end()))
330 {
331 m_Modifiers.push_back(new CodeSequenceMacro(*it));
332 it++;
333 }
334 }
335
336 return *this;
337 }
338
check(const OFBool quiet)339 OFCondition CodeWithModifiers::check(const OFBool quiet)
340 {
341 OFCondition result = CodeSequenceMacro::check(quiet);
342 if (result.good())
343 {
344 OFVector<CodeSequenceMacro*>::iterator it = m_Modifiers.begin();
345 while (result.good() && (it != m_Modifiers.end()))
346 {
347 result = (*it)->check(quiet);
348 it++;
349 }
350 }
351 if (result.bad())
352 {
353 if (!quiet)
354 {
355 DCMIOD_ERROR("Invalid code in Code Sequence Macro or its modifiers");
356 }
357 }
358 return result;
359 }
360
clearData()361 void CodeWithModifiers::clearData()
362 {
363 CodeSequenceMacro::clearData();
364 DcmIODUtil::freeContainer(m_Modifiers);
365 }
366
compare(const IODComponent & rhs) const367 int CodeWithModifiers::compare(const IODComponent& rhs) const
368 {
369 const CodeWithModifiers* r = OFstatic_cast(const CodeWithModifiers*, &rhs);
370 if (!r)
371 return -1;
372
373 if (m_Modifiers.size() < r->m_Modifiers.size())
374 return -1;
375 else if (m_Modifiers.size() > r->m_Modifiers.size())
376 return 1;
377
378 int result = IODComponent::compare(*r);
379 if (result == 0)
380 {
381 for (size_t n = 0; (n < m_Modifiers.size()) && (result == 0); n++)
382 {
383 result = m_Modifiers[n]->compare(*r->m_Modifiers[n]);
384 }
385 }
386 return result;
387 }
388
getName() const389 OFString CodeWithModifiers::getName() const
390 {
391 return "CodeWithModifiers";
392 }
393
addModifier(const CodeSequenceMacro & modifier)394 OFCondition CodeWithModifiers::addModifier(const CodeSequenceMacro& modifier)
395 {
396 OFCondition result = OFconst_cast(CodeSequenceMacro*, &modifier)->check();
397 if (result.good())
398 {
399 m_Modifiers.push_back(new CodeSequenceMacro(modifier));
400 }
401 return result;
402 }
403
getModifier(const size_t index)404 CodeSequenceMacro* CodeWithModifiers::getModifier(const size_t index)
405 {
406 if (index + 1 > m_Modifiers.size())
407 return NULL;
408 else
409 return m_Modifiers[index];
410 }
411
read(DcmItem & source,const OFBool clearOldData)412 OFCondition CodeWithModifiers::read(DcmItem& source, const OFBool clearOldData)
413 {
414 OFCondition result = CodeSequenceMacro::read(source, clearOldData);
415 if (result.good() && clearOldData)
416 {
417 DcmIODUtil::freeContainer(m_Modifiers);
418 }
419 if (result.good())
420 {
421 result = DcmIODUtil::readSubSequence(
422 source, m_CodeModifierSeq, m_Modifiers, getRules()->getByTag(m_CodeModifierSeq));
423 }
424 return result;
425 }
426
resetRules()427 void CodeWithModifiers::resetRules()
428 {
429 CodeSequenceMacro::resetRules();
430 m_Rules->addRule(
431 new IODRule(m_CodeModifierSeq, m_ModifierVM, m_ModifierType, getName(), DcmIODTypes::IE_UNDEFINED));
432 }
433
write(DcmItem & destination)434 OFCondition CodeWithModifiers::write(DcmItem& destination)
435 {
436 OFCondition result;
437 DcmIODUtil::writeSubSequence(
438 result, m_CodeModifierSeq, m_Modifiers, getData(), getRules()->getByTag(m_CodeModifierSeq));
439 if (result.good())
440 {
441 result = CodeSequenceMacro::write(destination);
442 }
443 return result;
444 }
445
~CodeWithModifiers()446 CodeWithModifiers::~CodeWithModifiers()
447 {
448 DcmIODUtil::freeContainer(m_Modifiers);
449 }
450
toString()451 OFString CodeSequenceMacro::toString()
452 {
453 OFString d, m, v;
454 getCodeValue(v);
455 getCodeMeaning(m);
456 getCodingSchemeDesignator(d);
457 OFStringStream oss;
458 oss << "(" << d << "," << v << "," << m << ")";
459 OFSTRINGSTREAM_GETOFSTRING(oss, msg);
460 return msg;
461 }
462
463 // ---------------------- SeriesAndInstanceReferenceMacro----------------------
464
465 const OFString IODSeriesAndInstanceReferenceMacro::m_ComponentName = "SeriesAndInstanceReferenceMacro";
466 const OFString IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::m_ComponentName
467 = "SeriesAndInstanceReferenceMacro";
468
IODSeriesAndInstanceReferenceMacro(OFshared_ptr<DcmItem> data,OFshared_ptr<IODRules> rules,IODComponent * parent)469 IODSeriesAndInstanceReferenceMacro::IODSeriesAndInstanceReferenceMacro(OFshared_ptr<DcmItem> data,
470 OFshared_ptr<IODRules> rules,
471 IODComponent* parent)
472 : IODComponent(data, rules, parent)
473 , m_ReferencedSeriesItems()
474 {
475 // reset element rules
476 resetRules();
477 }
478
IODSeriesAndInstanceReferenceMacro(IODComponent * parent)479 IODSeriesAndInstanceReferenceMacro::IODSeriesAndInstanceReferenceMacro(IODComponent* parent)
480 : IODComponent(parent)
481 , m_ReferencedSeriesItems()
482 {
483 // reset element rules
484 resetRules();
485 }
486
getName() const487 OFString IODSeriesAndInstanceReferenceMacro::getName() const
488 {
489 return m_ComponentName;
490 }
491
read(DcmItem & source,const OFBool clearOldData)492 OFCondition IODSeriesAndInstanceReferenceMacro::read(DcmItem& source, const OFBool clearOldData)
493 {
494 if (clearOldData)
495 clearData();
496
497 DcmIODUtil::readSubSequence<OFVector<ReferencedSeriesItem*> >(
498 source, DCM_ReferencedSeriesSequence, m_ReferencedSeriesItems, m_Rules->getByTag(DCM_ReferencedSeriesSequence));
499 return EC_Normal;
500 }
501
write(DcmItem & destination)502 OFCondition IODSeriesAndInstanceReferenceMacro::write(DcmItem& destination)
503 {
504 OFCondition result = EC_Normal;
505
506 DcmIODUtil::writeSubSequence<OFVector<ReferencedSeriesItem*> >(result,
507 DCM_ReferencedSeriesSequence,
508 m_ReferencedSeriesItems,
509 destination,
510 m_Rules->getByTag(DCM_ReferencedSeriesSequence));
511
512 return result;
513 }
514
clearData()515 void IODSeriesAndInstanceReferenceMacro::clearData()
516 {
517 DcmIODUtil::freeContainer(m_ReferencedSeriesItems);
518 }
519
resetRules()520 void IODSeriesAndInstanceReferenceMacro::resetRules()
521 {
522 m_Rules->addRule(new IODRule(DCM_ReferencedSeriesSequence, "1-n", "1", getName(), DcmIODTypes::IE_INSTANCE),
523 OFTrue);
524 }
525
526 OFVector<IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem*>&
getReferencedSeriesItems()527 IODSeriesAndInstanceReferenceMacro::getReferencedSeriesItems()
528 {
529 return m_ReferencedSeriesItems;
530 }
531
~IODSeriesAndInstanceReferenceMacro()532 IODSeriesAndInstanceReferenceMacro::~IODSeriesAndInstanceReferenceMacro()
533 {
534 DcmIODUtil::freeContainer(m_ReferencedSeriesItems);
535 }
536
ReferencedSeriesItem(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent)537 IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::ReferencedSeriesItem(OFshared_ptr<DcmItem> item,
538 OFshared_ptr<IODRules> rules,
539 IODComponent* parent)
540 : IODComponent(item, rules, parent)
541 , m_ReferencedInstanceSequence()
542 {
543 // reset element rules
544 resetRules();
545 }
546
ReferencedSeriesItem(IODComponent * parent)547 IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::ReferencedSeriesItem(IODComponent* parent)
548 : IODComponent(parent)
549 , m_ReferencedInstanceSequence()
550 {
551 // reset element rules
552 resetRules();
553 }
554
~ReferencedSeriesItem()555 IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::~ReferencedSeriesItem()
556 {
557 clearData();
558 }
559
getName() const560 OFString IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getName() const
561 {
562 return m_ComponentName;
563 }
564
clearData()565 void IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::clearData()
566 {
567 DcmIODUtil::freeContainer(m_ReferencedInstanceSequence);
568 IODComponent::clearData();
569 }
570
read(DcmItem & source,const OFBool clearOldData)571 OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::read(DcmItem& source, const OFBool clearOldData)
572 {
573 if (clearOldData)
574 clearData();
575
576 IODComponent::read(source, clearOldData);
577 DcmIODUtil::readSubSequence(source,
578 DCM_ReferencedInstanceSequence,
579 m_ReferencedInstanceSequence,
580 m_Rules->getByTag(DCM_ReferencedInstanceSequence));
581 return EC_Normal;
582 }
583
write(DcmItem & destination)584 OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::write(DcmItem& destination)
585 {
586 OFCondition result = EC_Normal;
587
588 DcmIODUtil::writeSubSequence<OFVector<SOPInstanceReferenceMacro*> >(
589 result,
590 DCM_ReferencedInstanceSequence,
591 m_ReferencedInstanceSequence,
592 *m_Item,
593 m_Rules->getByTag(DCM_ReferencedInstanceSequence));
594 result = IODComponent::write(destination);
595
596 return result;
597 }
598
resetRules()599 void IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::resetRules()
600 {
601 // Parameters for Rule are tag, VM, type (1,1C,2,2C,3), module name and logical IOD level
602 m_Rules->addRule(new IODRule(DCM_SeriesInstanceUID, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
603 m_Rules->addRule(new IODRule(DCM_ReferencedInstanceSequence, "1-n", "1", getName(), DcmIODTypes::IE_INSTANCE),
604 OFTrue);
605 }
606
607 OFVector<SOPInstanceReferenceMacro*>&
getReferencedInstanceItems()608 IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getReferencedInstanceItems()
609 {
610 return m_ReferencedInstanceSequence;
611 }
612
613 OFCondition
getSeriesInstanceUID(OFString & value,const long signed int pos) const614 IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::getSeriesInstanceUID(OFString& value,
615 const long signed int pos) const
616 {
617 return DcmIODUtil::getStringValueFromItem(DCM_SeriesInstanceUID, *m_Item, value, pos);
618 }
619
setSeriesInstanceUID(const OFString & value,const OFBool checkValue)620 OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::setSeriesInstanceUID(const OFString& value,
621 const OFBool checkValue)
622 {
623 OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal;
624 if (result.good())
625 result = m_Item->putAndInsertOFStringArray(DCM_SeriesInstanceUID, value);
626 return result;
627 }
628
addReference(const OFString & sopClassUID,const OFString & sopInstanceUID)629 OFCondition IODSeriesAndInstanceReferenceMacro::ReferencedSeriesItem::addReference(const OFString& sopClassUID,
630 const OFString& sopInstanceUID)
631 {
632 OFVector<SOPInstanceReferenceMacro*>::iterator instance = m_ReferencedInstanceSequence.begin();
633 while (instance != m_ReferencedInstanceSequence.end())
634 {
635 OFString c, i;
636 (*instance)->getReferencedSOPClassUID(c);
637 (*instance)->getReferencedSOPInstanceUID(i);
638 if (i == sopInstanceUID)
639 {
640 DCMIOD_DEBUG("Skipping doubled instance reference when adding to Series and Instance Reference Macro");
641 return EC_Normal;
642 }
643 else
644 {
645 instance++;
646 }
647 }
648 // We get here in case that we do not have this reference, add new one
649 SOPInstanceReferenceMacro* macro = new SOPInstanceReferenceMacro();
650 if (!macro)
651 {
652 return EC_MemoryExhausted;
653 }
654 OFCondition result = macro->setReferencedSOPClassUID(sopClassUID);
655 if (result.good())
656 result = macro->setReferencedSOPInstanceUID(sopInstanceUID);
657 if (result.good())
658 {
659 m_ReferencedInstanceSequence.push_back(macro);
660 }
661 else
662 {
663 delete macro;
664 result = IOD_EC_InvalidElementValue;
665 }
666 return result;
667 }
668
669 // ---------------------- SOPInstanceReferenceMacro ----------------------
670
SOPInstanceReferenceMacro(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent)671 SOPInstanceReferenceMacro::SOPInstanceReferenceMacro(OFshared_ptr<DcmItem> item,
672 OFshared_ptr<IODRules> rules,
673 IODComponent* parent)
674 : IODComponent(item, rules, parent)
675 {
676 // reset element rules
677 resetRules();
678 }
679
SOPInstanceReferenceMacro(IODComponent * parent)680 SOPInstanceReferenceMacro::SOPInstanceReferenceMacro(IODComponent* parent)
681 : IODComponent(parent)
682 {
683 // reset element rules
684 resetRules();
685 }
686
~SOPInstanceReferenceMacro()687 SOPInstanceReferenceMacro::~SOPInstanceReferenceMacro()
688 {
689 // nothing to do
690 }
691
getName() const692 OFString SOPInstanceReferenceMacro::getName() const
693 {
694 return "SOPInstanceReferenceMacro";
695 }
696
resetRules()697 void SOPInstanceReferenceMacro::resetRules()
698 {
699 // Parameters for Rule are tag, VM, type (1,1C,2,2C,3), module name and logical IOD level
700 m_Rules->addRule(new IODRule(DCM_ReferencedSOPClassUID, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue);
701 m_Rules->addRule(new IODRule(DCM_ReferencedSOPInstanceUID, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue);
702 }
703
704 // -- get dicom attributes --
705
getReferencedSOPClassUID(OFString & value,const signed long pos)706 OFCondition SOPInstanceReferenceMacro::getReferencedSOPClassUID(OFString& value, const signed long pos)
707 {
708 return DcmIODUtil::getStringValueFromItem(DCM_ReferencedSOPClassUID, *m_Item, value, pos);
709 }
710
getReferencedSOPInstanceUID(OFString & value,const signed long pos)711 OFCondition SOPInstanceReferenceMacro::getReferencedSOPInstanceUID(OFString& value, const signed long pos)
712 {
713 return DcmIODUtil::getStringValueFromItem(DCM_ReferencedSOPInstanceUID, *m_Item, value, pos);
714 }
715
716 // -- set dicom attributes --
717
setReferencedSOPClassUID(const OFString & value,const OFBool checkValue)718 OFCondition SOPInstanceReferenceMacro::setReferencedSOPClassUID(const OFString& value, const OFBool checkValue)
719 {
720 OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal;
721 if (result.good())
722 result = m_Item->putAndInsertOFStringArray(DCM_ReferencedSOPClassUID, value);
723 return result;
724 }
725
setReferencedSOPInstanceUID(const OFString & value,const OFBool checkValue)726 OFCondition SOPInstanceReferenceMacro::setReferencedSOPInstanceUID(const OFString& value, const OFBool checkValue)
727 {
728 OFCondition result = (checkValue) ? DcmUniqueIdentifier::checkStringValue(value, "1") : EC_Normal;
729 if (result.good())
730 result = m_Item->putAndInsertOFStringArray(DCM_ReferencedSOPInstanceUID, value);
731 return result;
732 }
733
734 // ---------------------- ImageSOPInstanceReferenceMacro ----------------------
735
ImageSOPInstanceReferenceMacro()736 ImageSOPInstanceReferenceMacro::ImageSOPInstanceReferenceMacro()
737 : ReferencedFrameNumber(DCM_ReferencedFrameNumber)
738 , ReferencedSegmentNumber(DCM_ReferencedSegmentNumber)
739 {
740 }
741
create(const OFString & sopClassUID,const OFString & sopInstanceUID,ImageSOPInstanceReferenceMacro * & result)742 OFCondition ImageSOPInstanceReferenceMacro::create(const OFString& sopClassUID,
743 const OFString& sopInstanceUID,
744 ImageSOPInstanceReferenceMacro*& result)
745 {
746 result = new ImageSOPInstanceReferenceMacro();
747 if (!result)
748 return EC_MemoryExhausted;
749
750 OFCondition cond = result->setReferencedSOPClassUID(sopClassUID);
751 if (cond.good())
752 {
753 cond = result->setReferencedSOPInstanceUID(sopInstanceUID);
754 }
755 if (cond.bad())
756 {
757 delete result;
758 result = NULL;
759 }
760 return cond;
761 }
762
create(const OFString & sopClassUID,const OFString & sopInstanceUID,const OFVector<Uint16> & refFramesOrSegments,ImageSOPInstanceReferenceMacro * & result)763 OFCondition ImageSOPInstanceReferenceMacro::create(const OFString& sopClassUID,
764 const OFString& sopInstanceUID,
765 const OFVector<Uint16>& refFramesOrSegments,
766 ImageSOPInstanceReferenceMacro*& result)
767 {
768 OFCondition cond = create(sopClassUID, sopInstanceUID, result);
769 if (cond.good())
770 {
771 if (!refFramesOrSegments.empty())
772 {
773 if (sopClassUID == UID_SegmentationStorage)
774 {
775 cond = result->setReferencedSegmentNumber(refFramesOrSegments);
776 }
777 else
778 {
779 cond = result->setReferencedFrameNumber(refFramesOrSegments);
780 }
781 }
782 if (cond.bad())
783 {
784 delete result;
785 result = NULL;
786 }
787 }
788 return cond;
789 }
790
~ImageSOPInstanceReferenceMacro()791 ImageSOPInstanceReferenceMacro::~ImageSOPInstanceReferenceMacro()
792 {
793 }
794
compare(const IODComponent & rhs) const795 int ImageSOPInstanceReferenceMacro::compare(const IODComponent& rhs) const
796 {
797 const ImageSOPInstanceReferenceMacro* macro = OFstatic_cast(const ImageSOPInstanceReferenceMacro*, &rhs);
798 if (macro == NULL)
799 return -1;
800 int result = ReferencedFrameNumber.compare(macro->ReferencedFrameNumber);
801 if (result == 0)
802 ReferencedSegmentNumber.compare(macro->ReferencedSegmentNumber);
803 if (result == 0)
804 return SOPInstanceReferenceMacro::compare(rhs);
805 return result;
806 }
807
clear()808 void ImageSOPInstanceReferenceMacro::clear()
809 {
810 SOPInstanceReferenceMacro::clearData();
811 ReferencedFrameNumber.clear();
812 ReferencedSegmentNumber.clear();
813 }
814
read(DcmItem & source,const OFBool clearOldData)815 OFCondition ImageSOPInstanceReferenceMacro::read(DcmItem& source, const OFBool clearOldData)
816 {
817 /* re-initialize object */
818 if (clearOldData)
819 clear();
820
821 OFCondition result = SOPInstanceReferenceMacro::read(source, clearOldData);
822
823 DcmIODUtil::getAndCheckElementFromDataset(
824 source, ReferencedFrameNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro");
825 DcmIODUtil::getAndCheckElementFromDataset(
826 source, ReferencedSegmentNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro");
827
828 return result;
829 }
830
write(DcmItem & item)831 OFCondition ImageSOPInstanceReferenceMacro::write(DcmItem& item)
832 {
833 OFCondition result = EC_Normal;
834 /* copy all elements to dataset */
835 DcmIODUtil::copyElementToDataset(
836 result, item, ReferencedFrameNumber, "1-n" /* VM */, "1C" /* Type */, "ImageSOPInstanceReferenceMacro");
837 DcmIODUtil::copyElementToDataset(
838 result, item, ReferencedSegmentNumber, "1-n", "1C", "ImageSOPInstanceReferenceMacro");
839
840 if (result.good())
841 result = SOPInstanceReferenceMacro::write(item);
842
843 return result;
844 }
845
846 // -- get dicom attributes --
847
getReferencedFrameNumber(OFVector<Uint16> & values)848 OFCondition ImageSOPInstanceReferenceMacro::getReferencedFrameNumber(OFVector<Uint16>& values)
849 {
850 // cast away const since underlying dcmdata routine is not const...
851 DcmIntegerString* is = OFconst_cast(DcmIntegerString*, &ReferencedFrameNumber);
852 for (size_t n = 0; n < is->getNumberOfValues(); n++)
853 {
854 Sint32 sint = 0;
855 is->getSint32(sint, OFstatic_cast(unsigned long, n));
856 if (sint < 0)
857 {
858 DCMIOD_WARN("Invalid Referenced Frame Number in Image SOP Instance Reference Macro: " << sint);
859 return EC_CorruptedData;
860 }
861 values.push_back(OFstatic_cast(Uint16, sint));
862 }
863 return EC_Normal;
864 }
865
getReferencedSegmentNumber(OFVector<Uint16> & values)866 OFCondition ImageSOPInstanceReferenceMacro::getReferencedSegmentNumber(OFVector<Uint16>& values)
867 {
868 // cast away const since underlying dcmdata routine is not const...
869 DcmUnsignedShort* us = OFconst_cast(DcmUnsignedShort*, &ReferencedSegmentNumber);
870 return DcmIODUtil::getUint16ValuesFromElement(*us, values);
871 }
872
873 // -- set dicom attributes --
874
setReferencedFrameNumber(const OFVector<Uint16> & values,const OFBool checkValue)875 OFCondition ImageSOPInstanceReferenceMacro::setReferencedFrameNumber(const OFVector<Uint16>& values,
876 const OFBool checkValue)
877 {
878 return DcmIODUtil::setUint16ValuesOnElement(ReferencedFrameNumber, values, "1-n", checkValue);
879 }
880
addReferencedFrameNumber(const Uint16 & value,const OFBool checkValue)881 OFCondition ImageSOPInstanceReferenceMacro::addReferencedFrameNumber(const Uint16& value, const OFBool checkValue)
882 {
883 (void)checkValue;
884 OFString val;
885 ReferencedFrameNumber.getOFStringArray(val);
886 if (ReferencedFrameNumber.getNumberOfValues() > 0)
887 {
888 val += "\\";
889 }
890 char buf[10];
891 sprintf(buf, "%u", value);
892 val += buf;
893 return ReferencedFrameNumber.putOFStringArray(val);
894 }
895
setReferencedSegmentNumber(const OFVector<Uint16> & values,const OFBool checkValue)896 OFCondition ImageSOPInstanceReferenceMacro::setReferencedSegmentNumber(const OFVector<Uint16>& values,
897 const OFBool checkValue)
898 {
899 return DcmIODUtil::setUint16ValuesOnElement(ReferencedSegmentNumber, values, "1-n", checkValue);
900 }
901
addReferencedSegmentNumber(const Uint16 & value,const OFBool checkValue)902 OFCondition ImageSOPInstanceReferenceMacro::addReferencedSegmentNumber(const Uint16& value, const OFBool checkValue)
903 {
904 (void)checkValue;
905 const unsigned long count = ReferencedSegmentNumber.getNumberOfValues();
906 return ReferencedSegmentNumber.putUint16(value, count /* starts with 0, so add new value at the end */);
907 }
908
909 // ---------------------- GeneralAnatomyMacro ----------------------
910
GeneralAnatomyMacro(const OFString & type)911 GeneralAnatomyMacro::GeneralAnatomyMacro(const OFString& type)
912 : m_Type(type)
913 , m_AnatomicRegion()
914 , m_AnatomicRegionModifier()
915 , m_PrimaryAnatomicStructure("3" /* Modifier in Primary Anatomic Structure is always optional */,
916 "1",
917 DCM_PrimaryAnatomicStructureModifierSequence)
918 {
919 m_Type = type;
920 }
921
GeneralAnatomyMacro(const GeneralAnatomyMacro & rhs)922 GeneralAnatomyMacro::GeneralAnatomyMacro(const GeneralAnatomyMacro& rhs)
923 : m_Type(rhs.m_Type)
924 , m_AnatomicRegion()
925 , m_AnatomicRegionModifier()
926 , m_PrimaryAnatomicStructure("3" /* Modifier in Primary Anatomic Structure is always optional */,
927 "1",
928 DCM_PrimaryAnatomicStructureModifierSequence)
929 {
930 *this = rhs;
931 }
932
operator =(const GeneralAnatomyMacro & rhs)933 GeneralAnatomyMacro& GeneralAnatomyMacro::operator=(const GeneralAnatomyMacro& rhs)
934 {
935 if (this != &rhs)
936 {
937 clearData();
938 m_Type = rhs.m_Type;
939 m_AnatomicRegion = rhs.m_AnatomicRegion;
940 m_PrimaryAnatomicStructure = rhs.m_PrimaryAnatomicStructure;
941
942 OFVector<CodeSequenceMacro*>::const_iterator it = rhs.m_AnatomicRegionModifier.begin();
943 while (it != rhs.m_AnatomicRegionModifier.end())
944 {
945 m_AnatomicRegionModifier.push_back(new CodeSequenceMacro(**it));
946 it++;
947 }
948 }
949 return *this;
950 }
951
~GeneralAnatomyMacro()952 GeneralAnatomyMacro::~GeneralAnatomyMacro()
953 {
954 clearData();
955 }
956
clearData()957 void GeneralAnatomyMacro::clearData()
958 {
959 // m_Type stays the same
960 m_AnatomicRegion.clearData();
961 DcmIODUtil::freeContainer(m_AnatomicRegionModifier);
962 m_PrimaryAnatomicStructure.clearData();
963 }
964
check(const OFBool quiet)965 OFCondition GeneralAnatomyMacro::check(const OFBool quiet)
966 {
967 OFCondition result = m_AnatomicRegion.check(quiet);
968 if (result.bad())
969 return result;
970
971 OFVector<CodeSequenceMacro*>::iterator it = m_AnatomicRegionModifier.begin();
972 while (it != m_AnatomicRegionModifier.begin())
973 {
974 result = (*it)->check(quiet);
975 if (result.bad())
976 return result;
977 it++;
978 }
979 // Primary Anatomic Structure is optional (type 3), so only check if
980 // user intended to fill in something.
981 if (!m_PrimaryAnatomicStructure.empty())
982 {
983 result = m_PrimaryAnatomicStructure.check(quiet);
984 }
985 return result;
986 }
987
getAnatomicRegion()988 CodeSequenceMacro& GeneralAnatomyMacro::getAnatomicRegion()
989 {
990 return m_AnatomicRegion;
991 }
992
getAnatomicRegionModifier()993 OFVector<CodeSequenceMacro*>& GeneralAnatomyMacro::getAnatomicRegionModifier()
994 {
995 return m_AnatomicRegionModifier;
996 }
997
getPrimaryAnatomicStructure()998 PrimaryAnatomicStructureMacro& GeneralAnatomyMacro::getPrimaryAnatomicStructure()
999 {
1000 return m_PrimaryAnatomicStructure;
1001 }
1002
1003 // Reads Anatomic Region Sequence and Primary Anatomic Structure Macro from given item
read(DcmItem & source,const OFBool clearOldData)1004 OFCondition GeneralAnatomyMacro::read(DcmItem& source, const OFBool clearOldData)
1005 {
1006 OFCondition result = EC_Normal;
1007
1008 /* re-initialize object */
1009 if (clearOldData)
1010 clearData();
1011
1012 /* read Anatomic Region Sequence item into Code Sequence Macro */
1013 DcmIODUtil::readSingleItem<CodeSequenceMacro>(
1014 source, DCM_AnatomicRegionSequence, m_AnatomicRegion, m_Type, "GeneralAnatomyMacro");
1015
1016 /* read Primary Anatomic Structure Macro (main level, i.e.\ original item) */
1017 DcmIODUtil::readSingleItem(
1018 source, DCM_PrimaryAnatomicStructureSequence, m_PrimaryAnatomicStructure, "3", "GeneralAnatomyMacro");
1019
1020 /* Get the single item from Anatomic Region Sequence and read modifier if found */
1021 DcmItem* localItem = NULL;
1022 if (source.findAndGetSequenceItem(DCM_AnatomicRegionSequence, localItem).bad())
1023 {
1024 return result;
1025 }
1026
1027 /* read Anatomic Region Modifier Sequence from */
1028 DcmIODUtil::readSubSequence<OFVector<CodeSequenceMacro*> >(*localItem, /* item of Anatomic Region Sequence */
1029 DCM_AnatomicRegionModifierSequence,
1030 m_AnatomicRegionModifier,
1031 "1-n",
1032 "3",
1033 "GeneralAnatomyMacro");
1034
1035 return result;
1036 }
1037
1038 /// Write Anatomic Region Sequence from given item
write(DcmItem & item)1039 OFCondition GeneralAnatomyMacro::write(DcmItem& item)
1040 {
1041 OFCondition result = EC_Normal;
1042
1043 /* delete old data */
1044 item.findAndDeleteElement(DCM_AnatomicRegionSequence);
1045 item.findAndDeleteElement(DCM_PrimaryAnatomicStructureSequence);
1046
1047 /* Write sub structures */
1048 DcmIODUtil::writeSingleItem<CodeSequenceMacro>(
1049 result, DCM_AnatomicRegionSequence, m_AnatomicRegion, item, m_Type, "GeneralAnatomyMacro");
1050 if (result.good())
1051 {
1052 DcmItem* seqItem = NULL;
1053 result = item.findAndGetSequenceItem(DCM_AnatomicRegionSequence, seqItem, 0);
1054 if (result.good())
1055 {
1056 DcmIODUtil::writeSubSequence<OFVector<CodeSequenceMacro*> >(result,
1057 DCM_AnatomicRegionModifierSequence,
1058 m_AnatomicRegionModifier,
1059 *seqItem,
1060 "1-n",
1061 "3",
1062 "GeneralAnatomyMacro");
1063 }
1064 }
1065 DcmIODUtil::writeSingleItem(
1066 result, DCM_PrimaryAnatomicStructureSequence, m_PrimaryAnatomicStructure, item, "3", "GeneralAnatomyMacro");
1067 return result;
1068 }
1069
compare(const GeneralAnatomyMacro & rhs) const1070 int GeneralAnatomyMacro::compare(const GeneralAnatomyMacro& rhs) const
1071 {
1072 int result = m_AnatomicRegion.compare(rhs.m_AnatomicRegion);
1073 if (result == 0)
1074 {
1075 if (m_AnatomicRegionModifier.size() > rhs.m_AnatomicRegionModifier.size())
1076 {
1077 return 1;
1078 }
1079 else if (m_AnatomicRegionModifier.size() < rhs.m_AnatomicRegionModifier.size())
1080 {
1081 return -1;
1082 }
1083
1084 for (size_t m = 0; m < m_AnatomicRegionModifier.size(); m++)
1085 {
1086 result = m_AnatomicRegionModifier[m]->compare(*(rhs.m_AnatomicRegionModifier[m]));
1087 if (result != 0)
1088 {
1089 return result;
1090 }
1091 }
1092 result = m_PrimaryAnatomicStructure.compare(rhs.m_PrimaryAnatomicStructure);
1093 }
1094 return result;
1095 }
1096
1097 // ---------------------- AlgorithmIdentificationMacro ----------------------
1098
AlgorithmIdentificationMacro()1099 AlgorithmIdentificationMacro::AlgorithmIdentificationMacro()
1100 : m_AlgorithmFamilyCode()
1101 , m_AlgorithmNameCode()
1102 , m_AlgorithmName(DCM_AlgorithmName)
1103 , m_AlgorithmVersion(DCM_AlgorithmVersion)
1104 , m_AlgorithmParameters(DCM_AlgorithmParameters)
1105 , m_AlgorithmSource(DCM_AlgorithmSource)
1106 {
1107 }
1108 //
~AlgorithmIdentificationMacro()1109 AlgorithmIdentificationMacro::~AlgorithmIdentificationMacro()
1110 {
1111 clearData();
1112 }
1113
clearData()1114 void AlgorithmIdentificationMacro::clearData()
1115 {
1116 m_AlgorithmFamilyCode.clearData();
1117 m_AlgorithmNameCode.clearData();
1118 m_AlgorithmName.clear();
1119 m_AlgorithmVersion.clear();
1120 m_AlgorithmParameters.clear();
1121 m_AlgorithmSource.clear();
1122 }
1123
check(const OFBool quiet)1124 OFCondition AlgorithmIdentificationMacro::check(const OFBool quiet)
1125 {
1126 OFCondition result;
1127 result = m_AlgorithmFamilyCode.check(quiet);
1128 if (result.good())
1129 {
1130 if (m_AlgorithmName.isEmpty() || m_AlgorithmVersion.isEmpty())
1131 {
1132 result = EC_MissingValue;
1133 }
1134 }
1135 return result;
1136 }
1137
getAlgorithmFamilyCode()1138 CodeSequenceMacro& AlgorithmIdentificationMacro::getAlgorithmFamilyCode()
1139 {
1140 return m_AlgorithmFamilyCode;
1141 }
1142
getAlgorithmNameCode()1143 CodeSequenceMacro& AlgorithmIdentificationMacro::getAlgorithmNameCode()
1144 {
1145 return m_AlgorithmNameCode;
1146 }
1147
getAlgorithmName(OFString & value,const signed long pos)1148 OFCondition AlgorithmIdentificationMacro::getAlgorithmName(OFString& value, const signed long pos)
1149 {
1150 return DcmIODUtil::getStringValueFromElement(m_AlgorithmName, value, pos);
1151 }
1152
getAlgorithmVersion(OFString & value,const signed long pos)1153 OFCondition AlgorithmIdentificationMacro::getAlgorithmVersion(OFString& value, const signed long pos)
1154 {
1155 return DcmIODUtil::getStringValueFromElement(m_AlgorithmVersion, value, pos);
1156 }
1157
getAlgorithmParameters(OFString & value,const signed long pos)1158 OFCondition AlgorithmIdentificationMacro::getAlgorithmParameters(OFString& value, const signed long pos)
1159 {
1160 return DcmIODUtil::getStringValueFromElement(m_AlgorithmParameters, value, pos);
1161 }
1162
getAlgorithmSource(OFString & value,const signed long pos)1163 OFCondition AlgorithmIdentificationMacro::getAlgorithmSource(OFString& value, const signed long pos)
1164 {
1165 return DcmIODUtil::getStringValueFromElement(m_AlgorithmSource, value, pos);
1166 }
1167
setAlgorithmName(const OFString & value,const OFBool checkValue)1168 OFCondition AlgorithmIdentificationMacro::setAlgorithmName(const OFString& value, const OFBool checkValue)
1169 {
1170 OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal;
1171 if (result.good())
1172 result = m_AlgorithmName.putOFStringArray(value);
1173 return result;
1174 }
1175
setAlgorithmVersion(const OFString & value,const OFBool checkValue)1176 OFCondition AlgorithmIdentificationMacro::setAlgorithmVersion(const OFString& value, const OFBool checkValue)
1177
1178 {
1179 OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal;
1180 if (result.good())
1181 result = m_AlgorithmVersion.putOFStringArray(value);
1182 return result;
1183 }
1184
setAlgorithmParameters(const OFString & value,const OFBool checkValue)1185 OFCondition AlgorithmIdentificationMacro::setAlgorithmParameters(const OFString& value, const OFBool checkValue)
1186 {
1187 (void)checkValue;
1188 return m_AlgorithmParameters.putOFStringArray(value);
1189 }
1190
setAlgorithmSource(const OFString & value,const OFBool checkValue)1191 OFCondition AlgorithmIdentificationMacro::setAlgorithmSource(const OFString& value, const OFBool checkValue)
1192 {
1193 OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal;
1194 if (result.good())
1195 result = m_AlgorithmSource.putOFStringArray(value);
1196 return result;
1197 }
1198
1199 /// Reads Anatomic Region Sequence and Primary Anatomic Structure Macro from given item
read(DcmItem & source,const OFBool clearOldData)1200 OFCondition AlgorithmIdentificationMacro::read(DcmItem& source, const OFBool clearOldData)
1201 {
1202 OFCondition result;
1203
1204 if (clearOldData)
1205 clearData();
1206
1207 DcmIODUtil::readSingleItem<CodeSequenceMacro>(
1208 source, DCM_AlgorithmFamilyCodeSequence, m_AlgorithmFamilyCode, "1", "AlgorithmIdentificationMacro");
1209
1210 DcmIODUtil::readSingleItem<CodeSequenceMacro>(
1211 source, DCM_AlgorithmNameCodeSequence, m_AlgorithmNameCode, "3", "AlgorithmIdentificationMacro");
1212
1213 DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmName, "1", "1", "AlgorithmIdentificationMacro");
1214 DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmVersion, "1", "1", "AlgorithmIdentificationMacro");
1215 DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmParameters, "1", "3", "AlgorithmIdentificationMacro");
1216 DcmIODUtil::getAndCheckElementFromDataset(source, m_AlgorithmSource, "1", "3", "AlgorithmIdentificationMacro");
1217
1218 return result;
1219 }
1220
write(DcmItem & item)1221 OFCondition AlgorithmIdentificationMacro::write(DcmItem& item)
1222 {
1223 OFCondition result = EC_Normal;
1224
1225 // write to item
1226 DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmName, "1", "1", "AlgorithmIdentificationMacro");
1227 DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmVersion, "1", "1", "AlgorithmIdentificationMacro");
1228 DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmParameters, "1", "3", "AlgorithmIdentificationMacro");
1229 DcmIODUtil::copyElementToDataset(result, item, m_AlgorithmSource, "1", "3", "AlgorithmIdentificationMacro");
1230
1231 DcmIODUtil::writeSingleItem<CodeSequenceMacro>(
1232 result, DCM_AlgorithmFamilyCodeSequence, m_AlgorithmFamilyCode, item, "1", "AlgorithmIdentificationMacro");
1233
1234 DcmIODUtil::writeSingleItem<CodeSequenceMacro>(
1235 result, DCM_AlgorithmNameCodeSequence, m_AlgorithmNameCode, item, "3", "AlgorithmIdentificationMacro");
1236
1237 return result;
1238 }
1239
1240 // ---------------------- ContentIdentificationMacro ----------------------
1241
ContentIdentificationMacro()1242 ContentIdentificationMacro::ContentIdentificationMacro()
1243 : m_InstanceNumber(DCM_InstanceNumber)
1244 , m_ContentLabel(DCM_ContentLabel)
1245 , m_ContentDescription(DCM_ContentDescription)
1246 , m_AlternateContentDescription()
1247 , m_ContentCreatorName(DCM_ContentCreatorName)
1248 , m_ContentCreatorIdentificationCode()
1249 , m_IODRules()
1250 {
1251 resetRules();
1252 }
1253
ContentIdentificationMacro(const OFString & instanceNumber,const OFString & contentLabel,const OFString & contentDescription,const OFString & contentCreatorName)1254 ContentIdentificationMacro::ContentIdentificationMacro(const OFString& instanceNumber,
1255 const OFString& contentLabel,
1256 const OFString& contentDescription,
1257 const OFString& contentCreatorName)
1258 : m_InstanceNumber(DCM_InstanceNumber)
1259 , m_ContentLabel(DCM_ContentLabel)
1260 , m_ContentDescription(DCM_ContentDescription)
1261 , m_AlternateContentDescription()
1262 , m_ContentCreatorName(DCM_ContentCreatorName)
1263 , m_ContentCreatorIdentificationCode()
1264 , m_IODRules()
1265 {
1266 resetRules();
1267 setInstanceNumber(instanceNumber);
1268 setContentLabel(contentLabel);
1269 setContentDescription(contentDescription);
1270 setContentCreatorName(contentCreatorName);
1271 }
1272
resetRules()1273 void ContentIdentificationMacro::resetRules()
1274 {
1275 m_IODRules.addRule(new IODRule(DCM_InstanceNumber, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
1276 m_IODRules.addRule(new IODRule(DCM_ContentLabel, "1", "1", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
1277 m_IODRules.addRule(new IODRule(DCM_ContentDescription, "1", "2", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
1278 m_IODRules.addRule(new IODRule(DCM_ContentCreatorName, "1", "2", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
1279 m_IODRules.addRule(
1280 new IODRule(DCM_AlternateContentDescriptionSequence, "1-n", "3", getName(), DcmIODTypes::IE_INSTANCE), OFTrue);
1281 m_IODRules.addRule(
1282 new IODRule(DCM_ContentCreatorIdentificationCodeSequence, "1", "3", getName(), DcmIODTypes::IE_INSTANCE),
1283 OFTrue);
1284 }
1285
getName() const1286 OFString ContentIdentificationMacro::getName() const
1287 {
1288 return "ContentIdentificationMacro";
1289 }
1290
getIODRules()1291 IODRules& ContentIdentificationMacro::getIODRules()
1292 {
1293 return m_IODRules;
1294 }
1295
ContentIdentificationMacro(const ContentIdentificationMacro & rhs)1296 ContentIdentificationMacro::ContentIdentificationMacro(const ContentIdentificationMacro& rhs)
1297 : m_InstanceNumber(DCM_InstanceNumber)
1298 , m_ContentLabel(DCM_ContentLabel)
1299 , m_ContentDescription(DCM_ContentDescription)
1300 , m_AlternateContentDescription()
1301 , m_ContentCreatorName(DCM_ContentCreatorName)
1302 , m_ContentCreatorIdentificationCode()
1303 , m_IODRules()
1304 {
1305 if (&rhs != this)
1306 {
1307 resetRules();
1308 m_InstanceNumber = rhs.m_InstanceNumber;
1309 m_ContentLabel = rhs.m_ContentLabel;
1310 m_ContentDescription = rhs.m_ContentDescription;
1311 m_ContentCreatorName = rhs.m_ContentCreatorName;
1312 m_ContentCreatorIdentificationCode = rhs.m_ContentCreatorIdentificationCode;
1313 /* perform deep vector copy */
1314 OFVector<AlternateContentDescriptionItem*>::const_iterator it = rhs.m_AlternateContentDescription.begin();
1315 while (it != rhs.m_AlternateContentDescription.end())
1316 {
1317 m_AlternateContentDescription.push_back(new AlternateContentDescriptionItem(**it));
1318 it++;
1319 }
1320 }
1321 }
1322
create(const OFString & instanceNumber,const OFString & contentLabel,const OFString & contentDescription,const OFString & contentCreatorName,ContentIdentificationMacro * & result)1323 OFCondition ContentIdentificationMacro::create(const OFString& instanceNumber,
1324 const OFString& contentLabel,
1325 const OFString& contentDescription,
1326 const OFString& contentCreatorName,
1327 ContentIdentificationMacro*& result)
1328 {
1329 result = new ContentIdentificationMacro();
1330 if (!result)
1331 return EC_MemoryExhausted;
1332 OFCondition cond = result->setInstanceNumber(instanceNumber);
1333 if (cond.good())
1334 {
1335 cond = result->setContentLabel(contentLabel);
1336 }
1337 if (cond.good())
1338 {
1339 cond = result->setContentDescription(contentDescription);
1340 }
1341 if (cond.good())
1342 {
1343 cond = result->setContentCreatorName(contentCreatorName);
1344 }
1345 if (cond.good())
1346 {
1347 cond = result->check();
1348 }
1349 if (cond.bad())
1350 {
1351 delete result;
1352 result = NULL;
1353 }
1354 return cond;
1355 }
1356
operator =(const ContentIdentificationMacro & rhs)1357 ContentIdentificationMacro& ContentIdentificationMacro::operator=(const ContentIdentificationMacro& rhs)
1358 {
1359 if (&rhs != this)
1360 {
1361 this->clearData();
1362 m_InstanceNumber = rhs.m_InstanceNumber;
1363 m_ContentLabel = rhs.m_ContentLabel;
1364 m_ContentDescription = rhs.m_ContentDescription;
1365 m_ContentCreatorName = rhs.m_ContentCreatorName;
1366 m_ContentCreatorIdentificationCode = rhs.m_ContentCreatorIdentificationCode;
1367 /* perform deep vector copy */
1368 OFVector<AlternateContentDescriptionItem*>::const_iterator it = rhs.m_AlternateContentDescription.begin();
1369 while (it != rhs.m_AlternateContentDescription.end())
1370 {
1371 AlternateContentDescriptionItem* newItem = new AlternateContentDescriptionItem();
1372 *newItem = **it;
1373 m_AlternateContentDescription.push_back(newItem);
1374 it++;
1375 }
1376 }
1377 return *this;
1378 }
1379
~ContentIdentificationMacro()1380 ContentIdentificationMacro::~ContentIdentificationMacro()
1381 {
1382 clearData();
1383 }
1384
clearData()1385 void ContentIdentificationMacro::clearData()
1386 {
1387 m_InstanceNumber.clear();
1388 m_ContentLabel.clear();
1389 m_ContentDescription.clear();
1390 DcmIODUtil::freeContainer(m_AlternateContentDescription);
1391 m_ContentCreatorName.clear();
1392 m_ContentCreatorIdentificationCode.clearData();
1393 }
1394
check(const OFBool quiet)1395 OFCondition ContentIdentificationMacro::check(const OFBool quiet)
1396 {
1397 (void)quiet;
1398 OFCondition result;
1399 OFBool failure = m_ContentLabel.isEmpty() || m_InstanceNumber.isEmpty();
1400 if (!failure)
1401 {
1402 if (!m_AlternateContentDescription.empty()) // type 3
1403 {
1404 OFVector<AlternateContentDescriptionItem*>::iterator it = m_AlternateContentDescription.begin();
1405 while (it != m_AlternateContentDescription.end() && !failure)
1406 {
1407 OFString str;
1408 (*it)->getContentDescription(str).good(); // type 1
1409 failure = str.empty();
1410 if (!failure)
1411 {
1412 OFString meaning, value, designator;
1413 (*it)->getLanguageCode().getCodeMeaning(meaning);
1414 (*it)->getLanguageCode().getCodeValue(value);
1415 (*it)->getLanguageCode().getCodeValue(designator);
1416 failure = meaning.empty() || value.empty() || designator.empty();
1417 }
1418 it++;
1419 }
1420 }
1421 }
1422 if (failure)
1423 result = EC_IllegalParameter;
1424 return result;
1425 }
1426
getInstanceNumber(OFString & value,const signed long pos) const1427 OFCondition ContentIdentificationMacro::getInstanceNumber(OFString& value, const signed long pos) const
1428 {
1429 return DcmIODUtil::getStringValueFromElement(m_InstanceNumber, value, pos);
1430 }
1431
getContentLabel(OFString & value,const signed long pos) const1432 OFCondition ContentIdentificationMacro::getContentLabel(OFString& value, const signed long pos) const
1433 {
1434 return DcmIODUtil::getStringValueFromElement(m_ContentLabel, value, pos);
1435 }
1436
getContentDescription(OFString & value,const signed long pos) const1437 OFCondition ContentIdentificationMacro::getContentDescription(OFString& value, const signed long pos) const
1438 {
1439 return DcmIODUtil::getStringValueFromElement(m_ContentDescription, value, pos);
1440 }
1441
getContentCreatorName(OFString & value,const signed long pos) const1442 OFCondition ContentIdentificationMacro::getContentCreatorName(OFString& value, const signed long pos) const
1443 {
1444 return DcmIODUtil::getStringValueFromElement(m_ContentCreatorName, value, pos);
1445 }
1446
getContentCreatorIdentificationCode()1447 CodeSequenceMacro& ContentIdentificationMacro::getContentCreatorIdentificationCode()
1448 {
1449 return m_ContentCreatorIdentificationCode;
1450 }
1451
1452 OFVector<ContentIdentificationMacro::AlternateContentDescriptionItem*>&
getAlternateContentDescription()1453 ContentIdentificationMacro::getAlternateContentDescription()
1454 {
1455 return m_AlternateContentDescription;
1456 }
1457
setInstanceNumber(const OFString & value,const OFBool checkValue)1458 OFCondition ContentIdentificationMacro::setInstanceNumber(const OFString& value, const OFBool checkValue)
1459 {
1460 OFCondition result;
1461 if (checkValue)
1462 {
1463 result = (checkValue) ? DcmIntegerString::checkStringValue(value, "1") : EC_Normal;
1464 }
1465 if (result.good())
1466 {
1467 result = m_InstanceNumber.putOFStringArray(value);
1468 }
1469 return result;
1470 }
1471
setContentLabel(const OFString & value,const OFBool checkValue)1472 OFCondition ContentIdentificationMacro::setContentLabel(const OFString& value, const OFBool checkValue)
1473 {
1474 OFCondition result = (checkValue)
1475 ? DcmCodeString::checkStringValue(value, m_IODRules.getByTag(DCM_ContentLabel)->getVM())
1476 : EC_Normal;
1477 if (result.good())
1478 result = m_ContentLabel.putOFStringArray(value);
1479 return result;
1480 }
1481
setContentDescription(const OFString & value,const OFBool checkValue)1482 OFCondition ContentIdentificationMacro::setContentDescription(const OFString& value, const OFBool checkValue)
1483 {
1484 OFCondition result = (checkValue)
1485 ? DcmLongString::checkStringValue(value, m_IODRules.getByTag(DCM_ContentDescription)->getVM())
1486 : EC_Normal;
1487 if (result.good())
1488 result = m_ContentDescription.putOFStringArray(value);
1489 return result;
1490 }
1491
setContentCreatorName(const OFString & value,const OFBool checkValue)1492 OFCondition ContentIdentificationMacro::setContentCreatorName(const OFString& value, const OFBool checkValue)
1493 {
1494 OFCondition result = (checkValue)
1495 ? DcmPersonName::checkStringValue(value, m_IODRules.getByTag(DCM_ContentCreatorName)->getVM())
1496 : EC_Normal;
1497 if (result.good())
1498 result = m_ContentCreatorName.putOFStringArray(value);
1499 return result;
1500 }
1501
read(DcmItem & source,const OFBool clearOldData)1502 OFCondition ContentIdentificationMacro::read(DcmItem& source, const OFBool clearOldData)
1503 {
1504 OFCondition result;
1505
1506 if (clearOldData)
1507 clearData();
1508
1509 /* flat elements */
1510
1511 DcmIODUtil::getAndCheckElementFromDataset(source, m_InstanceNumber, m_IODRules.getByTag(DCM_InstanceNumber));
1512 DcmIODUtil::getAndCheckElementFromDataset(source, m_ContentLabel, m_IODRules.getByTag(DCM_ContentLabel));
1513 DcmIODUtil::getAndCheckElementFromDataset(
1514 source, m_ContentDescription, m_IODRules.getByTag(DCM_ContentDescription));
1515 DcmIODUtil::getAndCheckElementFromDataset(
1516 source, m_ContentCreatorName, m_IODRules.getByTag(DCM_ContentCreatorName));
1517
1518 /* sub sequences */
1519 IODRule* rule = m_IODRules.getByTag(DCM_AlternateContentDescriptionSequence);
1520 DcmIODUtil::readSubSequence<OFVector<AlternateContentDescriptionItem*> >(source,
1521 DCM_AlternateContentDescriptionSequence,
1522 m_AlternateContentDescription,
1523 rule->getVM(),
1524 rule->getType(),
1525 "ContentIdentificationMacro");
1526
1527 rule = m_IODRules.getByTag(DCM_ContentCreatorIdentificationCodeSequence);
1528 DcmIODUtil::readSingleItem<CodeSequenceMacro>(source,
1529 DCM_ContentCreatorIdentificationCodeSequence,
1530 m_ContentCreatorIdentificationCode,
1531 rule->getType(),
1532 "ContentIdentificationMacro");
1533
1534 return result;
1535 }
1536
write(DcmItem & item)1537 OFCondition ContentIdentificationMacro::write(DcmItem& item)
1538 {
1539 OFCondition result = EC_Normal;
1540
1541 /* flat elements */
1542 DcmIODUtil::copyElementToDataset(result, item, m_InstanceNumber, m_IODRules.getByTag(DCM_InstanceNumber));
1543 DcmIODUtil::copyElementToDataset(result, item, m_ContentLabel, m_IODRules.getByTag(DCM_ContentLabel));
1544 DcmIODUtil::copyElementToDataset(result, item, m_ContentDescription, m_IODRules.getByTag(DCM_ContentDescription));
1545 DcmIODUtil::copyElementToDataset(result, item, m_ContentCreatorName, m_IODRules.getByTag(DCM_ContentCreatorName));
1546
1547 IODRule* rule = m_IODRules.getByTag(DCM_ContentCreatorIdentificationCodeSequence);
1548 DcmIODUtil::writeSingleItem<CodeSequenceMacro>(result,
1549 DCM_ContentCreatorIdentificationCodeSequence,
1550 m_ContentCreatorIdentificationCode,
1551 item,
1552 rule->getType(),
1553 "ContentIdentificationMacro");
1554
1555 rule = m_IODRules.getByTag(DCM_AlternateContentDescriptionSequence);
1556 DcmIODUtil::writeSubSequence<OFVector<ContentIdentificationMacro::AlternateContentDescriptionItem*> >(
1557 result,
1558 DCM_AlternateContentDescriptionSequence,
1559 m_AlternateContentDescription,
1560 item,
1561 rule->getVM(),
1562 rule->getType(),
1563 "ContentIdentificationMacro");
1564
1565 return result;
1566 }
1567
1568 // ---------------- ContentIdentificationMacro::AlternateContentDescriptionItem -----------------
1569
AlternateContentDescriptionItem()1570 ContentIdentificationMacro::AlternateContentDescriptionItem::AlternateContentDescriptionItem()
1571 : m_ContentDescription(DCM_ContentDescription)
1572 , m_LanguageCode()
1573 {
1574 // nothing to do
1575 }
1576
~AlternateContentDescriptionItem()1577 ContentIdentificationMacro::AlternateContentDescriptionItem::~AlternateContentDescriptionItem()
1578 {
1579 m_LanguageCode.clearData();
1580 }
1581
clearData()1582 void ContentIdentificationMacro::AlternateContentDescriptionItem::clearData()
1583 {
1584 m_ContentDescription.clear();
1585 m_LanguageCode.clearData();
1586 }
1587
read(DcmItem & source,const OFBool clearOldData)1588 OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::read(DcmItem& source,
1589 const OFBool clearOldData)
1590 {
1591 OFCondition result;
1592 if (clearOldData)
1593 clearData();
1594
1595 DcmIODUtil::getAndCheckElementFromDataset(source, m_ContentDescription, "1", "1", "ContentIdentificationMacro");
1596 DcmIODUtil::readSingleItem<CodeSequenceMacro>(
1597 source, DCM_LanguageCodeSequence, m_LanguageCode, "1", "ContentIdentificationMacro");
1598
1599 return result;
1600 }
1601
1602 OFCondition
getContentDescription(OFString & value,const long signed int pos)1603 ContentIdentificationMacro::AlternateContentDescriptionItem::getContentDescription(OFString& value,
1604 const long signed int pos)
1605 {
1606 return DcmIODUtil::getStringValueFromElement(m_ContentDescription, value, pos);
1607 }
1608
getLanguageCode()1609 CodeSequenceMacro& ContentIdentificationMacro::AlternateContentDescriptionItem::getLanguageCode()
1610 {
1611 return m_LanguageCode;
1612 }
1613
write(DcmItem & item)1614 OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::write(DcmItem& item)
1615 {
1616 OFCondition result = EC_Normal;
1617 // write to item
1618 DcmIODUtil::copyElementToDataset(result, item, m_ContentDescription, "1", "1", "ContentIdentificationMacro");
1619 DcmIODUtil::writeSingleItem<CodeSequenceMacro>(
1620 result, DCM_LanguageCodeSequence, m_LanguageCode, item, "1", "ContentIdentificationMacro");
1621 return result;
1622 }
1623
setContentDescription(const OFString & value,const OFBool checkValue)1624 OFCondition ContentIdentificationMacro::AlternateContentDescriptionItem::setContentDescription(const OFString& value,
1625 const OFBool checkValue)
1626 {
1627 OFCondition result = (checkValue) ? DcmLongString::checkStringValue(value, "1") : EC_Normal;
1628 if (result.good())
1629 result = m_ContentDescription.putOFStringArray(value);
1630 return result;
1631 }
1632
1633 // -------------------- HL7HierarchicDesignatorMacro --------------------
1634
HL7HierarchicDesignatorMacro(IODComponent * parent)1635 HL7HierarchicDesignatorMacro::HL7HierarchicDesignatorMacro(IODComponent* parent)
1636 : IODComponent(parent)
1637 {
1638 // reset element rules
1639 resetRules();
1640 }
1641
HL7HierarchicDesignatorMacro(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent)1642 HL7HierarchicDesignatorMacro::HL7HierarchicDesignatorMacro(OFshared_ptr<DcmItem> item,
1643 OFshared_ptr<IODRules> rules,
1644 IODComponent* parent)
1645 : IODComponent(item, rules, parent)
1646 {
1647 // reset element rules
1648 resetRules();
1649 }
1650
getUniversalEntityID(OFString & value,const long signed int pos) const1651 OFCondition HL7HierarchicDesignatorMacro::getUniversalEntityID(OFString& value, const long signed int pos) const
1652 {
1653 return DcmIODUtil::getStringValueFromItem(DCM_UniversalEntityID, *m_Item, value, pos);
1654 }
1655
getLocalNamespaceEntityID(OFString & value,const long signed int pos) const1656 OFCondition HL7HierarchicDesignatorMacro::getLocalNamespaceEntityID(OFString& value, const long signed int pos) const
1657 {
1658 return DcmIODUtil::getStringValueFromItem(DCM_LocalNamespaceEntityID, *m_Item, value, pos);
1659 }
1660
getUniversalEntityIDType(OFString & value,const long signed int pos) const1661 OFCondition HL7HierarchicDesignatorMacro::getUniversalEntityIDType(OFString& value, const long signed int pos) const
1662 {
1663 return DcmIODUtil::getStringValueFromItem(DCM_UniversalEntityIDType, *m_Item, value, pos);
1664 }
1665
getName() const1666 OFString HL7HierarchicDesignatorMacro::getName() const
1667 {
1668 return "HL7HierarchicDesignatorMacro";
1669 }
1670
resetRules()1671 void HL7HierarchicDesignatorMacro::resetRules()
1672 {
1673 // parameters are tag, VM, type. Overwrite old rules if any.
1674 m_Rules->addRule(new IODRule(DCM_UniversalEntityID, "1", "1C", "getName()", DcmIODTypes::IE_UNDEFINED), OFTrue);
1675 m_Rules->addRule(new IODRule(DCM_LocalNamespaceEntityID, "1", "1C", "getName()", DcmIODTypes::IE_UNDEFINED),
1676 OFTrue);
1677 m_Rules->addRule(new IODRule(DCM_UniversalEntityIDType, "1", "1C", "getName()", DcmIODTypes::IE_UNDEFINED), OFTrue);
1678 }
1679
setLocalNamespaceEntityID(const OFString & value,const OFBool checkValue)1680 OFCondition HL7HierarchicDesignatorMacro::setLocalNamespaceEntityID(const OFString& value, const OFBool checkValue)
1681 {
1682 (void)checkValue;
1683 return m_Item->putAndInsertOFStringArray(DCM_LocalNamespaceEntityID, value);
1684 }
1685
setUniversalEntityID(const OFString & value,const OFBool checkValue)1686 OFCondition HL7HierarchicDesignatorMacro::setUniversalEntityID(const OFString& value, const OFBool checkValue)
1687 {
1688 (void)checkValue;
1689 return m_Item->putAndInsertOFStringArray(DCM_UniversalEntityID, value);
1690 }
1691
setUniversalEntityIDType(const OFString & value,const OFBool checkValue)1692 OFCondition HL7HierarchicDesignatorMacro::setUniversalEntityIDType(const OFString& value, const OFBool checkValue)
1693 {
1694 OFCondition result = (checkValue) ? DcmCodeString::checkStringValue(value, "1") : EC_Normal;
1695 if (result.good())
1696 result = m_Item->putAndInsertOFStringArray(DCM_UniversalEntityID, value);
1697 return result;
1698 }
1699
1700 // -------------------- Mandatory View and Slice Progression Direction Macro --------------------
1701
MandatoryViewAndSliceProgressionDirectionMacro(OFshared_ptr<DcmItem> item,OFshared_ptr<IODRules> rules,IODComponent * parent)1702 MandatoryViewAndSliceProgressionDirectionMacro::MandatoryViewAndSliceProgressionDirectionMacro(
1703 OFshared_ptr<DcmItem> item, OFshared_ptr<IODRules> rules, IODComponent* parent)
1704 : IODComponent(item, rules, parent)
1705 , m_ViewCodeSequence()
1706 , m_ViewModifierCode()
1707 {
1708 resetRules();
1709 }
1710
MandatoryViewAndSliceProgressionDirectionMacro(IODComponent * parent)1711 MandatoryViewAndSliceProgressionDirectionMacro::MandatoryViewAndSliceProgressionDirectionMacro(IODComponent* parent)
1712 : IODComponent(parent)
1713 , m_ViewCodeSequence()
1714 , m_ViewModifierCode()
1715 {
1716 resetRules();
1717 }
1718
getName() const1719 OFString MandatoryViewAndSliceProgressionDirectionMacro::getName() const
1720 {
1721 return "MandatoryViewAndSliceProgressionDirectionMacro";
1722 }
1723
resetRules()1724 void MandatoryViewAndSliceProgressionDirectionMacro::resetRules()
1725 {
1726 m_Rules->addRule(new IODRule(DCM_ViewCodeSequence, "1", "1", getName(), DcmIODTypes::IE_UNDEFINED), OFTrue);
1727 m_Rules->addRule(new IODRule(DCM_ViewModifierCodeSequence, "1-n", "2C", getName(), DcmIODTypes::IE_UNDEFINED),
1728 OFTrue);
1729 m_Rules->addRule(new IODRule(DCM_SliceProgressionDirection, "1", "1C", getName(), DcmIODTypes::IE_UNDEFINED),
1730 OFTrue);
1731 }
1732
clearData()1733 void MandatoryViewAndSliceProgressionDirectionMacro::clearData()
1734 {
1735 DcmIODUtil::freeContainer(m_ViewModifierCode);
1736 m_ViewCodeSequence.clearData();
1737 IODComponent::clearData();
1738 }
1739
read(DcmItem & source,const OFBool clearOldData)1740 OFCondition MandatoryViewAndSliceProgressionDirectionMacro::read(DcmItem& source, const OFBool clearOldData)
1741 {
1742 if (clearOldData)
1743 {
1744 m_ViewCodeSequence.clearData();
1745 DcmIODUtil::freeContainer(m_ViewModifierCode);
1746 }
1747 OFCondition result = EC_Normal;
1748 DcmIODUtil::readSingleItem(
1749 source, DCM_ViewCodeSequence, m_ViewCodeSequence, m_Rules->getByTag(DCM_ViewCodeSequence));
1750 DcmIODUtil::readSubSequence(
1751 source, DCM_ViewCodeSequence, m_ViewModifierCode, m_Rules->getByTag(DCM_ViewCodeSequence));
1752 IODComponent::read(source, clearOldData);
1753 return EC_Normal;
1754 }
1755
write(DcmItem & item)1756 OFCondition MandatoryViewAndSliceProgressionDirectionMacro::write(DcmItem& item)
1757 {
1758 OFCondition result = EC_Normal;
1759 DcmIODUtil::writeSingleItem(
1760 result, DCM_ViewCodeSequence, m_ViewCodeSequence, *m_Item, m_Rules->getByTag(DCM_ViewCodeSequence));
1761 DcmIODUtil::writeSubSequence(
1762 result, DCM_ViewCodeSequence, m_ViewModifierCode, *m_Item, m_Rules->getByTag(DCM_ViewModifierCodeSequence));
1763 if (result.good())
1764 result = IODComponent::write(item);
1765 return result;
1766 }
1767
getViewCode()1768 CodeSequenceMacro& MandatoryViewAndSliceProgressionDirectionMacro::getViewCode()
1769 {
1770 return m_ViewCodeSequence;
1771 }
1772
getViewModifierCode()1773 OFVector<CodeSequenceMacro*>& MandatoryViewAndSliceProgressionDirectionMacro::getViewModifierCode()
1774 {
1775 return m_ViewModifierCode;
1776 }
1777