1 /*
2 *
3 * Copyright (C) 2000-2019, OFFIS e.V.
4 * All rights reserved. See COPYRIGHT file for details.
5 *
6 * This software and supporting documentation were developed by
7 *
8 * OFFIS e.V.
9 * R&D Division Health
10 * Escherweg 2
11 * D-26121 Oldenburg, Germany
12 *
13 *
14 * Module: dcmsr
15 *
16 * Author: Joerg Riesmeier
17 *
18 * Purpose:
19 * classes: DSRTextTreeNode
20 *
21 */
22
23
24 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
25
26 #include "dcmtk/dcmsr/dsrtypes.h"
27 #include "dcmtk/dcmsr/dsrtextn.h"
28 #include "dcmtk/dcmsr/dsrstrvl.h"
29 #include "dcmtk/dcmsr/dsrxmld.h"
30
31 #include "dcmtk/dcmdata/dcdeftag.h"
32 #include "dcmtk/dcmdata/dcvrut.h"
33
34
DSRTextTreeNode(const E_RelationshipType relationshipType)35 DSRTextTreeNode::DSRTextTreeNode(const E_RelationshipType relationshipType)
36 : DSRDocumentTreeNode(relationshipType, VT_Text),
37 DSRStringValue()
38 {
39 }
40
41
DSRTextTreeNode(const E_RelationshipType relationshipType,const OFString & textValue,const OFBool check)42 DSRTextTreeNode::DSRTextTreeNode(const E_RelationshipType relationshipType,
43 const OFString &textValue,
44 const OFBool check)
45 : DSRDocumentTreeNode(relationshipType, VT_Text),
46 DSRStringValue(textValue, check)
47 {
48 }
49
50
DSRTextTreeNode(const DSRTextTreeNode & node)51 DSRTextTreeNode::DSRTextTreeNode(const DSRTextTreeNode &node)
52 : DSRDocumentTreeNode(node),
53 DSRStringValue(node)
54 {
55 }
56
57
~DSRTextTreeNode()58 DSRTextTreeNode::~DSRTextTreeNode()
59 {
60 }
61
62
operator ==(const DSRDocumentTreeNode & node) const63 OFBool DSRTextTreeNode::operator==(const DSRDocumentTreeNode &node) const
64 {
65 /* call comparison operator of base class (includes check of value type) */
66 OFBool result = DSRDocumentTreeNode::operator==(node);
67 if (result)
68 {
69 /* it's safe to cast the type since the value type has already been checked */
70 result = DSRStringValue::operator==(OFstatic_cast(const DSRTextTreeNode &, node).getValue());
71 }
72 return result;
73 }
74
75
operator !=(const DSRDocumentTreeNode & node) const76 OFBool DSRTextTreeNode::operator!=(const DSRDocumentTreeNode &node) const
77 {
78 /* call comparison operator of base class (includes check of value type) */
79 OFBool result = DSRDocumentTreeNode::operator!=(node);
80 if (!result)
81 {
82 /* it's safe to cast the type since the value type has already been checked */
83 result = DSRStringValue::operator!=(OFstatic_cast(const DSRTextTreeNode &, node).getValue());
84 }
85 return result;
86 }
87
88
clone() const89 DSRTextTreeNode *DSRTextTreeNode::clone() const
90 {
91 return new DSRTextTreeNode(*this);
92 }
93
94
clear()95 void DSRTextTreeNode::clear()
96 {
97 DSRDocumentTreeNode::clear();
98 DSRStringValue::clear();
99 }
100
101
isValid() const102 OFBool DSRTextTreeNode::isValid() const
103 {
104 /* ConceptNameCodeSequence required */
105 return DSRDocumentTreeNode::isValid() && getConceptName().isValid() && hasValidValue();
106 }
107
108
hasValidValue() const109 OFBool DSRTextTreeNode::hasValidValue() const
110 {
111 return checkCurrentValue().good();
112 }
113
114
isShort(const size_t) const115 OFBool DSRTextTreeNode::isShort(const size_t /*flags*/) const
116 {
117 return (getValue().length() <= 40);
118 }
119
120
print(STD_NAMESPACE ostream & stream,const size_t flags) const121 OFCondition DSRTextTreeNode::print(STD_NAMESPACE ostream &stream,
122 const size_t flags) const
123 {
124 OFCondition result = DSRDocumentTreeNode::print(stream, flags);
125 if (result.good())
126 {
127 DCMSR_PRINT_ANSI_ESCAPE_CODE(DCMSR_ANSI_ESCAPE_CODE_DELIMITER)
128 stream << "=";
129 DCMSR_PRINT_ANSI_ESCAPE_CODE(DCMSR_ANSI_ESCAPE_CODE_ITEM_VALUE)
130 if (flags & PF_shortenLongItemValues)
131 DSRStringValue::print(stream, 30); // text output is limited to 30 characters
132 else
133 DSRStringValue::print(stream);
134 }
135 return result;
136 }
137
138
writeXML(STD_NAMESPACE ostream & stream,const size_t flags) const139 OFCondition DSRTextTreeNode::writeXML(STD_NAMESPACE ostream &stream,
140 const size_t flags) const
141 {
142 OFCondition result = EC_Normal;
143 writeXMLItemStart(stream, flags);
144 result = DSRDocumentTreeNode::writeXML(stream, flags);
145 writeStringValueToXML(stream, getValue(), "value", (flags & XF_writeEmptyTags) > 0);
146 writeXMLItemEnd(stream, flags);
147 return result;
148 }
149
150
readContentItem(DcmItem & dataset,const size_t flags)151 OFCondition DSRTextTreeNode::readContentItem(DcmItem &dataset,
152 const size_t flags)
153 {
154 /* read TextValue */
155 return DSRStringValue::read(dataset, DCM_TextValue, flags);
156 }
157
158
writeContentItem(DcmItem & dataset) const159 OFCondition DSRTextTreeNode::writeContentItem(DcmItem &dataset) const
160 {
161 /* write TextValue */
162 return DSRStringValue::write(dataset, DCM_TextValue);
163 }
164
165
readXMLContentItem(const DSRXMLDocument & doc,DSRXMLCursor cursor,const size_t flags)166 OFCondition DSRTextTreeNode::readXMLContentItem(const DSRXMLDocument &doc,
167 DSRXMLCursor cursor,
168 const size_t flags)
169 {
170 /* retrieve value from XML element "value" */
171 return DSRStringValue::readXML(doc, doc.getNamedChildNode(cursor, "value"), flags, OFTrue /*encoding*/);
172 }
173
174
renderHTMLContentItem(STD_NAMESPACE ostream & docStream,STD_NAMESPACE ostream &,const size_t,size_t &,const size_t flags) const175 OFCondition DSRTextTreeNode::renderHTMLContentItem(STD_NAMESPACE ostream &docStream,
176 STD_NAMESPACE ostream & /*annexStream*/,
177 const size_t /*nestingLevel*/,
178 size_t & /*annexNumber*/,
179 const size_t flags) const
180 {
181 OFString htmlString;
182 /* render ConceptName */
183 OFCondition result = renderHTMLConceptName(docStream, flags);
184 /* render TextValue */
185 if (flags & HF_renderItemInline)
186 docStream << "\"" << convertToHTMLString(getValue(), htmlString, flags) << "\"" << OFendl;
187 else
188 docStream << convertToHTMLString(getValue(), htmlString, flags, OFTrue /*newlineAllowed*/) << OFendl;
189 return result;
190 }
191
192
checkValue(const OFString & textValue) const193 OFCondition DSRTextTreeNode::checkValue(const OFString &textValue) const
194 {
195 /* first, make sure that the mandatory value is non-empty */
196 OFCondition result = DSRStringValue::checkValue(textValue);
197 /* then, check whether the passed value is valid with regards to VR and VM.
198 * tbd: unfortunately, we do not know the character set, so "UNKNOWN" is used. */
199 if (result.good())
200 result = DcmUnlimitedText::checkStringValue(textValue, "UNKNOWN");
201 return result;
202 }
203