1 /*
2 *
3 * Copyright (C) 1994-2018, 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: dcmdata
15 *
16 * Author: Gerd Ehlers, Andrew Hewett
17 *
18 * Purpose: class DcmTag
19 *
20 */
21
22 #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */
23 #include "dcmtk/dcmdata/dctag.h"
24 #include "dcmtk/dcmdata/dcerror.h" /* for dcmdata error constants */
25 #include "dcmtk/dcmdata/dcdict.h"
26 #include "dcmtk/dcmdata/dcdicent.h"
27 #include "dcmtk/ofstd/ofstd.h"
28
29 #define INCLUDE_CSTDIO
30 #define INCLUDE_CSTRING
31 #include "dcmtk/ofstd/ofstdinc.h"
32
33
DcmTag()34 DcmTag::DcmTag()
35 : vr(EVR_UNKNOWN),
36 tagName(NULL),
37 privateCreator(NULL),
38 errorFlag(EC_InvalidTag)
39 {
40 }
41
DcmTag(const DcmTagKey & akey,const char * privCreator)42 DcmTag::DcmTag(const DcmTagKey& akey, const char *privCreator)
43 : DcmTagKey(akey),
44 vr(EVR_UNKNOWN),
45 tagName(NULL),
46 privateCreator(NULL),
47 errorFlag(EC_InvalidTag)
48 {
49 if (privCreator)
50 updatePrivateCreator(privCreator);
51 lookupVRinDictionary();
52 }
53
DcmTag(Uint16 g,Uint16 e,const char * privCreator)54 DcmTag::DcmTag(Uint16 g, Uint16 e, const char *privCreator)
55 : DcmTagKey(g, e),
56 vr(EVR_UNKNOWN),
57 tagName(NULL),
58 privateCreator(NULL),
59 errorFlag(EC_InvalidTag)
60 {
61 if (privCreator)
62 updatePrivateCreator(privCreator);
63 lookupVRinDictionary();
64 }
65
DcmTag(const DcmTagKey & akey,const DcmVR & avr)66 DcmTag::DcmTag(const DcmTagKey& akey, const DcmVR& avr)
67 : DcmTagKey(akey),
68 vr(avr),
69 tagName(NULL),
70 privateCreator(NULL),
71 errorFlag(EC_Normal)
72 {
73 }
74
DcmTag(Uint16 g,Uint16 e,const DcmVR & avr)75 DcmTag::DcmTag(Uint16 g, Uint16 e, const DcmVR& avr)
76 : DcmTagKey(g, e),
77 vr(avr),
78 tagName(NULL),
79 privateCreator(NULL),
80 errorFlag(EC_Normal)
81 {
82 }
83
DcmTag(const DcmTag & tag)84 DcmTag::DcmTag(const DcmTag& tag)
85 : DcmTagKey(tag),
86 vr(tag.vr),
87 tagName(NULL),
88 privateCreator(NULL),
89 errorFlag(tag.errorFlag)
90 {
91 updateTagName(tag.tagName);
92 updatePrivateCreator(tag.privateCreator);
93 }
94
95
96 // ********************************
97
98
~DcmTag()99 DcmTag::~DcmTag()
100 {
101 delete[] tagName;
102 delete[] privateCreator;
103 }
104
105
106 // ********************************
107
108
operator =(const DcmTag & tag)109 DcmTag& DcmTag::operator=(const DcmTag& tag)
110 {
111 if (this != &tag)
112 {
113 updateTagName(tag.tagName);
114 updatePrivateCreator(tag.privateCreator);
115 DcmTagKey::set(tag);
116 vr = tag.vr;
117 errorFlag = tag.errorFlag;
118 }
119 return *this;
120 }
121
122 // ********************************
123
lookupVRinDictionary()124 void DcmTag::lookupVRinDictionary()
125 {
126 const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock();
127 const DcmDictEntry *dictRef = globalDataDict.findEntry(*this, privateCreator);
128 if (dictRef)
129 {
130 vr = dictRef->getVR();
131 errorFlag = EC_Normal;
132 }
133 dcmDataDict.rdunlock();
134 }
135
136 // ********************************
137
138
setVR(const DcmVR & avr)139 DcmVR DcmTag::setVR(const DcmVR& avr) // resolve ambiguous VR
140 {
141 vr = avr;
142
143 if (vr.getEVR() == EVR_UNKNOWN)
144 {
145 errorFlag = EC_InvalidVR;
146 } else {
147 errorFlag = EC_Normal;
148 }
149 return vr;
150 }
151
152
getTagName()153 const char *DcmTag::getTagName()
154 {
155 if (tagName)
156 return tagName;
157
158 const char *newTagName = NULL;
159 const DcmDataDictionary& globalDataDict = dcmDataDict.rdlock();
160 const DcmDictEntry *dictRef = globalDataDict.findEntry(*this, privateCreator);
161 if (dictRef)
162 newTagName=dictRef->getTagName();
163 if (newTagName == NULL)
164 newTagName = DcmTag_ERROR_TagName;
165 updateTagName(newTagName);
166 dcmDataDict.rdunlock();
167
168 if (tagName)
169 return tagName;
170 return DcmTag_ERROR_TagName;
171 }
172
isSignable() const173 OFBool DcmTag::isSignable() const
174 {
175 OFBool result = isSignableTag();
176 if (result)
177 result = !isUnknownVR();
178 return result;
179 }
180
isUnknownVR() const181 OFBool DcmTag::isUnknownVR() const
182 {
183 OFBool result = OFFalse;
184 switch (vr.getValidEVR()) // this is the VR we're going to write in explicit VR
185 {
186 case EVR_UNKNOWN:
187 case EVR_UNKNOWN2B:
188 case EVR_UN:
189 result = OFTrue;
190 break;
191 default:
192 /* nothing */
193 break;
194 }
195 return result;
196 }
197
198
findTagFromName(const char * name,DcmTag & value)199 OFCondition DcmTag::findTagFromName(const char *name, DcmTag &value)
200 {
201 OFCondition result = EC_IllegalParameter;
202 /* check parameters first */
203 if ((name != NULL) && (strlen(name) > 0))
204 {
205 result = EC_Normal;
206 unsigned int grp = 0xffff;
207 unsigned int elm = 0xffff;
208 /* check whether tag name has format 'gggg,eeee' */
209 if (sscanf(name, "%x,%x", &grp, &elm) == 2)
210 {
211 /* store resulting tag value */
212 value.set(OFstatic_cast(Uint16, grp), OFstatic_cast(Uint16, elm));
213 value.lookupVRinDictionary();
214 } else {
215 /* it is a name: look up in the dictionary */
216 const DcmDataDictionary &globalDataDict = dcmDataDict.rdlock();
217 const DcmDictEntry *dicent = globalDataDict.findEntry(name);
218 /* store resulting tag value */
219 if (dicent != NULL)
220 {
221 value.set(dicent->getKey());
222 value.setVR(dicent->getVR());
223 }
224 else
225 result = EC_TagNotFound;
226 dcmDataDict.rdunlock();
227 }
228 }
229 return result;
230 }
231
232
getPrivateCreator() const233 const char* DcmTag::getPrivateCreator() const
234 {
235 return privateCreator;
236 }
237
setPrivateCreator(const char * privCreator)238 void DcmTag::setPrivateCreator(const char *privCreator)
239 {
240 // a new private creator code probably changes the name
241 // of the tag. Enforce new dictionary lookup the next time
242 // getTagName() is called.
243 updateTagName(NULL);
244 updatePrivateCreator(privCreator);
245 }
246
updateTagName(const char * c)247 void DcmTag::updateTagName(const char *c)
248 {
249 delete[] tagName;
250 if (c)
251 {
252 size_t buflen = strlen(c) + 1;
253 tagName = new char[buflen];
254 if (tagName)
255 OFStandard::strlcpy(tagName, c, buflen);
256 } else
257 tagName = NULL;
258 }
259
updatePrivateCreator(const char * c)260 void DcmTag::updatePrivateCreator(const char *c)
261 {
262 delete[] privateCreator;
263 if (c)
264 {
265 size_t buflen = strlen(c) + 1;
266 privateCreator = new char[buflen];
267 if (privateCreator)
268 OFStandard::strlcpy(privateCreator, c, buflen);
269 } else
270 privateCreator = NULL;
271 }
272