Coverage Report

Created: 2026-09-28 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/dcmtk-install/include/dcmtk/dcmdata/dcdicent.h
Line
Count
Source
1
/*
2
 *
3
 *  Copyright (C) 1994-2024, 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:  Andrew Hewett
17
 *
18
 *  Purpose: Interface for a dictionary entry in the loadable DICOM data dictionary
19
 *
20
 */
21
22
#ifndef DCDICENT_H
23
#define DCDICENT_H
24
25
#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
26
#include "dcmtk/dcmdata/dctagkey.h"
27
#include "dcmtk/dcmdata/dcvr.h"
28
#include <cstring>
29
30
/// constant describing an unlimited VM
31
#define DcmVariableVM   -1
32
33
#define DCM_INRANGE(x,a,b) (((x) >= (a)) && ((x) <= (b)))
34
#define DCM_IS_ODD(x) (((x) % 2) == 1)
35
#define DCM_IS_EVEN(x) (((x) % 2) == 0)
36
37
38
/** attribute tag group/element range restrictions
39
 */
40
enum DcmDictRangeRestriction
41
{
42
    /// integer range
43
    DcmDictRange_Unspecified,
44
45
    /// odd range
46
    DcmDictRange_Odd,
47
48
    /// even range
49
    DcmDictRange_Even
50
};
51
52
53
/** each object of this class manages one entry of the
54
 *  global DICOM data dictionary.
55
 */
56
class DCMTK_DCMDATA_EXPORT DcmDictEntry: public DcmTagKey
57
{
58
public:
59
60
    /** constructor
61
     *  @param g attribute tag group
62
     *  @param e attribute tag element
63
     *  @param vr value representation
64
     *  @param nam attribute name
65
     *  @param vmMin lower limit for value multiplicity
66
     *  @param vmMax upper limit for value multiplicity, DcmVariableVM for unlimited
67
     *  @param vers standard version name, may be NULL
68
     *  @param doCopyStrings true if strings should be copied, false if only referenced
69
     *  @param pcreator private creator identifier, may be NULL (for standard tags)
70
     */
71
    DcmDictEntry(Uint16 g, Uint16 e, DcmVR vr,
72
        const char* nam, int vmMin, int vmMax,
73
        const char* vers, OFBool doCopyStrings,
74
        const char* pcreator);
75
76
    /** constructor for repeating tags
77
     *  @param g attribute tag group lower limit
78
     *  @param e attribute tag element lower limit
79
     *  @param ug attribute tag group upper limit
80
     *  @param ue attribute tag element upper limit
81
     *  @param vr value representation
82
     *  @param nam attribute name
83
     *  @param vmMin lower limit for value multiplicity
84
     *  @param vmMax upper limit for value multiplicity, DcmVariableVM for unlimited
85
     *  @param vers standard version name, may be NULL
86
     *  @param doCopyStrings true if strings should be copied, false if only referenced
87
     *  @param pcreator private creator identifier, may be NULL (for standard tags)
88
     */
89
    DcmDictEntry(Uint16 g, Uint16 e, Uint16 ug, Uint16 ue, DcmVR vr,
90
        const char* nam, int vmMin, int vmMax,
91
        const char* vers, OFBool doCopyStrings,
92
        const char* pcreator);
93
94
    /** copy constructor
95
     * @param e the entry to copy
96
     */
97
    DcmDictEntry(const DcmDictEntry& e);
98
99
    /// destructor
100
    ~DcmDictEntry();
101
102
    /* access methods */
103
104
    /// returns VR object by value
105
    DcmVR getVR() const
106
    {
107
        return valueRepresentation;
108
    }
109
110
    /// returns VR code
111
    DcmEVR getEVR() const
112
0
    {
113
0
        return valueRepresentation.getEVR();
114
0
    }
115
116
    /// returns standard version string, may be NULL
117
    const char* getStandardVersion() const
118
    {
119
        return standardVersion;
120
    }
121
122
    /// returns tag name
123
    const char* getTagName() const
124
    {
125
        return tagName;
126
    }
127
128
    /// returns private creator identifier, may be NULL
129
    const char* getPrivateCreator() const
130
    {
131
        return privateCreator;
132
    }
133
134
    /** checks if the private creator identifier equals the given string
135
     *  @param c string to compare with, may be NULL
136
     *  @return true if equal, false otherwise
137
     */
138
    int privateCreatorMatch(const char *c) const
139
    {
140
      return
141
      (
142
        ((privateCreator == NULL) && (c == NULL)) ||
143
        (privateCreator && c && (0 == strcmp(privateCreator, c)))
144
      );
145
    }
146
147
    /** checks if the private creator identifier of this object matches the one
148
     *  of the given object.
149
     *  @param arg dictionary entry to compare with
150
     *  @return true if private creator identifiers are equal, false otherwise
151
     */
152
    int privateCreatorMatch(const DcmDictEntry& arg) const
153
    {
154
      return privateCreatorMatch(arg.privateCreator);
155
    }
156
157
    /// returns lower limit for VM (value multiplicity)
158
    int getVMMin() const
159
    {
160
        return valueMultiplicityMin;
161
    }
162
163
    /// returns upper limit for VM (value multiplicity), DcmVariableVM for
164
    /// unlimited
165
    int getVMMax() const
166
    {
167
        return valueMultiplicityMax;
168
    }
169
170
    /// returns true if element has a single valid VM value
171
    OFBool isFixedSingleVM() const
172
    {
173
        return ((valueMultiplicityMin != DcmVariableVM) &&
174
                      (valueMultiplicityMin == valueMultiplicityMax));
175
    }
176
177
    /// returns true if element has a fixed VM range
178
    OFBool isFixedRangeVM() const
179
    {
180
        return ((valueMultiplicityMin != DcmVariableVM) &&
181
                      (valueMultiplicityMax != DcmVariableVM));
182
    }
183
184
    /// returns true if element has a variable VM range (no upper limit)
185
    OFBool isVariableRangeVM() const
186
    {
187
        return ((valueMultiplicityMin != DcmVariableVM) &&
188
                      (valueMultiplicityMax == DcmVariableVM));
189
    }
190
191
    /** converts entry into repeating tag entry by defining an upper limit
192
     *  for group and element, taken from the given tag key.
193
     *  @param key tag key containing upper limit for group and element
194
     */
195
    void setUpper(const DcmTagKey& key)
196
0
    {
197
0
        upperKey = key;
198
0
    }
199
200
    /** converts entry into repeating tag entry by defining an upper limit
201
     *  for tag group
202
     *  @param ug upper limit for tag group
203
     */
204
    void setUpperGroup(Uint16 ug)
205
0
    {
206
0
        upperKey.setGroup(ug);
207
0
    }
208
209
    /** converts entry into repeating tag entry by defining an upper limit
210
     *  for tag element
211
     *  @param ue upper limit for tag element
212
     */
213
    void setUpperElement(Uint16 ue)
214
0
    {
215
0
        upperKey.setElement(ue);
216
0
    }
217
218
    /// returns upper limit for tag group
219
    Uint16 getUpperGroup() const
220
    {
221
        return upperKey.getGroup();
222
    }
223
224
    /// returns upper limit for tag element
225
    Uint16 getUpperElement() const
226
    {
227
        return upperKey.getElement();
228
    }
229
230
    /// returns attribute tag as DcmTagKey object by value
231
    DcmTagKey getKey() const
232
    {
233
        return * OFstatic_cast(const DcmTagKey *, this);
234
    }
235
236
    /// returns upper limits for attribute tag as DcmTagKey object by value
237
    DcmTagKey getUpperKey() const
238
0
    {
239
0
        return upperKey;
240
0
    }
241
242
    /// returns true if entry is has a repeating group
243
    int isRepeatingGroup() const
244
    {
245
        return (getGroup() != getUpperGroup());
246
    }
247
248
    /// returns true if entry is has a repeating element
249
    int isRepeatingElement() const
250
    {
251
        return (getElement() != getUpperElement());
252
    }
253
254
    /// returns true if entry is repeating (group or element)
255
    int isRepeating() const
256
    {
257
        return (isRepeatingGroup() || isRepeatingElement());
258
    }
259
260
    /// returns group range restriction
261
    DcmDictRangeRestriction getGroupRangeRestriction() const
262
    {
263
        return groupRangeRestriction;
264
    }
265
266
    /** sets group range restriction
267
     * @param rr the new range restriction
268
     */
269
    void setGroupRangeRestriction(DcmDictRangeRestriction rr)
270
    {
271
        groupRangeRestriction = rr;
272
    }
273
274
    /// returns element range restriction
275
    DcmDictRangeRestriction getElementRangeRestriction() const
276
    {
277
        return elementRangeRestriction;
278
    }
279
280
    /** sets element range restriction
281
    * @param rr the new range restriction
282
    */
283
    void setElementRangeRestriction(DcmDictRangeRestriction rr)
284
    {
285
        elementRangeRestriction = rr;
286
    }
287
288
    /* containment */
289
290
    /** checks if the given tag key and private creator identifier are covered
291
     *  by this object.
292
     *  @param key tag key
293
     *  @param privCreator private creator identifier, may be NULL
294
     *  @return true if this entry contains the given tag for the given private
295
     *    creator identifier
296
     */
297
    int contains(const DcmTagKey& key, const char *privCreator) const /* this contains key */
298
    {
299
        if ((getGroupRangeRestriction() == DcmDictRange_Even) &&
300
            DCM_IS_ODD(key.getGroup()))
301
            return OFFalse;
302
        else if ((getGroupRangeRestriction() == DcmDictRange_Odd) &&
303
            DCM_IS_EVEN(key.getGroup()))
304
            return OFFalse;
305
        else if ((getElementRangeRestriction() == DcmDictRange_Even) &&
306
            DCM_IS_ODD(key.getElement()))
307
            return OFFalse;
308
        else if ((getElementRangeRestriction() == DcmDictRange_Odd) &&
309
            DCM_IS_EVEN(key.getElement()))
310
            return OFFalse;
311
        else if (! privateCreatorMatch(privCreator))
312
            return OFFalse;
313
        else
314
        {
315
            const OFBool groupMatches=DCM_INRANGE(key.getGroup(), getGroup(), getUpperGroup());
316
            OFBool found=groupMatches && DCM_INRANGE(key.getElement(), getElement(), getUpperElement());
317
            if (!found && groupMatches && privCreator)
318
                found=DCM_INRANGE(key.getElement() & 0xFF, getElement(), getUpperElement());
319
            return found;
320
        }
321
    }
322
323
    /** checks if this entry contains the given name
324
     *  @param name attribute name, must not be NULL
325
     *  @return true if tagName matches the given string
326
     */
327
    int contains(const char *name) const /* this contains named key */
328
    {
329
        return !strcmp( tagName, name );
330
    }
331
332
    /* set relations */
333
334
    /** checks if this entry describes a true subset of tag range described by
335
     *  the given entry.
336
     *  @param e entry to compare with
337
     *  @return true if this object is subset of e
338
     */
339
    int subset(const DcmDictEntry& e) const /* this is a subset of key */
340
    {
341
        return ( (getGroup() >= e.getGroup()) &&
342
                 (getUpperGroup() <= e.getUpperGroup()) &&
343
                 (getElement() >= e.getElement()) &&
344
                 (getUpperElement() <= e.getUpperElement()) &&
345
                 privateCreatorMatch(e.privateCreator)
346
            );
347
    }
348
349
    /** checks if this entry describes the same tag range as the given entry.
350
     *  @param e entry to compare with
351
     *  @return true if objects describe the same tag range
352
     */
353
    int setEQ(const DcmDictEntry& e) const /* this is set equal to key */
354
    {
355
        return ( (getGroup() == e.getGroup()) &&
356
                 (getUpperGroup() == e.getUpperGroup()) &&
357
                 (getElement() == e.getElement()) &&
358
                 (getUpperElement() == e.getUpperElement()) &&
359
                 (getGroupRangeRestriction() == e.getGroupRangeRestriction()) &&
360
                 (getElementRangeRestriction() == e.getElementRangeRestriction()) &&
361
                 privateCreatorMatch(e.privateCreator)
362
            );
363
    }
364
365
    /** friend operator<<
366
     * @param s the ostream to append upon
367
     * @param e the dictionary entry
368
     * @return the appended on ostream
369
     */
370
    friend DCMTK_DCMDATA_EXPORT STD_NAMESPACE ostream& operator<<(STD_NAMESPACE ostream& s, const DcmDictEntry& e);
371
372
private:
373
374
    /// private undefined copy assignment operator
375
    DcmDictEntry &operator=(const DcmDictEntry &);
376
377
    /** upper limit of repeating group and element (lower limit is inherited
378
     *   from DcmTagKey)
379
     */
380
    DcmTagKey upperKey;
381
382
    /// value representation
383
    DcmVR valueRepresentation;
384
385
    /// attribute name
386
    const char *tagName;
387
388
    /// lower limit for VM
389
    int valueMultiplicityMin;
390
391
    /// upper limit for VM
392
    int valueMultiplicityMax;
393
394
    /// standard version name, may be NULL
395
    const char *standardVersion;
396
397
    /// true if strings are copies (i.e. should be deleted upon destruction)
398
    OFBool stringsAreCopies;
399
400
    /// restriction (even, odd, unrestricted) for group range
401
    DcmDictRangeRestriction groupRangeRestriction;
402
403
    /// restriction (even, odd, unrestricted) for element range
404
    DcmDictRangeRestriction elementRangeRestriction;
405
406
    /// private creator identifier, may be NULL
407
    const char *privateCreator;
408
};
409
410
#endif /* !DCDICENT_H */