Coverage Report

Created: 2026-06-30 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/work/dcmtk-install/include/dcmtk/dcmdata/dcobject.h
Line
Count
Source
1
/*
2
 *
3
 *  Copyright (C) 1994-2026, 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
17
 *
18
 *  Purpose:
19
 *  This file contains the interface to routines which provide
20
 *  DICOM object encoding/decoding, search and lookup facilities.
21
 *
22
 */
23
24
25
#ifndef DCOBJECT_H
26
#define DCOBJECT_H
27
28
#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */
29
30
#include "dcmtk/ofstd/ofglobal.h"
31
#include "dcmtk/dcmdata/dcerror.h"
32
#include "dcmtk/dcmdata/dcxfer.h"
33
#include "dcmtk/dcmdata/dctag.h"
34
#include "dcmtk/dcmdata/dcstack.h"
35
36
37
// forward declarations
38
class DcmItem;
39
class DcmJsonFormat;
40
class DcmOutputStream;
41
class DcmInputStream;
42
class DcmWriteCache;
43
class DcmSpecificCharacterSet;
44
45
// include this file in doxygen documentation
46
47
/** @file dcobject.h
48
 *  @brief interface to DICOM object/dataset handling
49
 */
50
51
// Undefined Length Identifier now defined in dctypes.h
52
53
// Default maximum sequence nesting depth (can be overridden at compile time).
54
// Must be in the range [1, 2147483647].
55
#ifndef DCMTK_MAX_SEQUENCE_NESTING
56
#define DCMTK_MAX_SEQUENCE_NESTING 64
57
#endif
58
#if DCMTK_MAX_SEQUENCE_NESTING < 1
59
#error "DCMTK_MAX_SEQUENCE_NESTING must be >= 1"
60
#endif
61
#if DCMTK_MAX_SEQUENCE_NESTING > 2147483647
62
#error "DCMTK_MAX_SEQUENCE_NESTING must be <= 2147483647"
63
#endif
64
65
// Maximum number of read bytes for a Value Element
66
const Uint32 DCM_MaxReadLength = 4096;
67
68
// Maximum length of tag and length in a DICOM element
69
const Uint32 DCM_TagInfoLength = 12;
70
71
// Optimum line length if not all data printed
72
const Uint32 DCM_OptPrintLineLength = 70;
73
74
// Optimum value length if not all data printed
75
const Uint32 DCM_OptPrintValueLength = 40;
76
77
// Optimum attribute name length (for tree output)
78
const Uint32 DCM_OptPrintAttributeNameLength = 35;
79
80
/** This flags defines whether automatic correction should be applied to input
81
 *  data (e.g.\ stripping of padding blanks, removal of blanks in UIDs, etc).
82
 *  Default is enabled.
83
 */
84
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableAutomaticInputDataCorrection; /* default OFTrue */
85
86
/** This flag defines the handling of illegal odd-length attributes: If flag is
87
 *  true, odd lengths are respected (i.e.\ an odd number of bytes is read from
88
 *  the input stream.) After successful reading, padding to even number of bytes
89
 *  is enforced by adding a zero pad byte if dcmEnableAutomaticInputDataCorrection
90
 *  is true. Otherwise the odd number of bytes remains as read.
91
 *
92
 *  If flag is false, old (pre DCMTK 3.5.2) behaviour applies: The length field
93
 *  implicitly incremented and an even number of bytes is read from the stream.
94
 */
95
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAcceptOddAttributeLength; /* default OFTrue */
96
97
/** This flag defines how UN attributes with undefined length are treated
98
 *  by the parser when reading. The default is to expect the content of the
99
 *  UN element (up to and including the sequence delimitation item)
100
 *  to be encoded in Implicit VR Little Endian, as described in CP 246.
101
 *  DCMTK expects the attribute to be encoded like a DICOM sequence, i.e.
102
 *  the content of each item is parsed as a DICOM dataset.
103
 *  If the flag is disabled old (pre DCMTK 3.5.4) behaviour applies: The
104
 *  attribute is treated as if it was an Explicit VR SQ element.
105
 *
106
 *  Note that the flag only affects the read behaviour but not the write
107
 *  behaviour - DCMTK will never write UN elements with undefined length.
108
 */
109
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableCP246Support; /* default OFTrue */
110
111
/** DCMTK releases up to 3.5.3 created a non-conforming byte stream
112
 *  as input to the MAC algorithm when creating or verifying digital signatures
113
 *  including compressed pixel data (i.e.\ signatures including attribute
114
 *  (7FE0,0010) in an encapsulated transfer syntax). This has been fixed
115
 *  in DCMTK 3.5.4, but this flag allows to revert to the old behavior
116
 *  in order to create or verify signatures that are compatible with older
117
 *  releases. Default is "off" (OFFalse).
118
 */
119
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmEnableOldSignatureFormat; /* default OFFalse */
120
121
/** This flag defines whether the transfer syntax for uncompressed datasets
122
 *  is detected automatically.  The automatic detection has been introduced
123
 *  since there are (incorrectly encoded) DICOM dataset stored with a
124
 *  different transfer syntax than specified in the meta header.
125
 */
126
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAutoDetectDatasetXfer; /* default OFFalse */
127
128
/** This flag defines how non-standard VRs are treated by the parser when
129
 *  reading. The default is to treat data element with non-standard VR as
130
 *  unknown. If this flag is enabled, the parser will try to read the data
131
 *  element with Implicit VR Little Endian transfer syntax.
132
 */
133
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmAcceptUnexpectedImplicitEncoding; /* default OFFalse */
134
135
/** This flag defines how the element's VR is treated by the parser when
136
 *  reading from a dataset with explicit VR encoding. By default, the
137
 *  VR from the dataset is used. If this flag is enabled and the VR of the
138
 *  tag is defined in the data dictionary, the parser will use the VR from
139
 *  the data dictionary (and ignore the one from the dataset). This flag is,
140
 *  therefore, useful for reading incorrectly encoded DICOM datasets.
141
 */
142
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferVRFromDataDictionary; /* default OFFalse */
143
144
/** This flag defines how the element's length field is interpreted when reading
145
 *  from a dataset with explicit VR encoding and the data dictionary doesn't
146
 *  agree with the VR from the dataset. By default, the length field is assumed
147
 *  to match the size of the VR in the dataset. If this flag is enabled and the
148
 *  tag is defined in the data dictionary, the parser will use the size for the
149
 *  VR from the data dictionary (and ignore the one from the dataset). This flag
150
 *  is, therefore, useful for reading incorrectly encoded DICOM datasets.
151
 */
152
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmPreferLengthFieldSizeFromDataDictionary; /* default OFFalse */
153
154
/** This flag indicates, whether private attributes with implicit transfer
155
 *  syntax having a maximum length should be handled as sequences (ignoring
156
 *  any dictionary entries for that tag). This can happen, if for example
157
 *  a private creator element is illegally inserted with VR SQ
158
 *  (undefined length and implicit coding). The parser usually would then
159
 *  try to parse the element with VR=LO (private creator) with maximum
160
 *  length, which would lead to an error. The default behaviour is to
161
 *  rely on the dictionary.
162
 */
163
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmReadImplPrivAttribMaxLengthAsSQ; /* default OFFalse */
164
165
/** This flag indicates, whether parsing errors during reading
166
 *  should be ignored, i.e.\ whether the parser should try to recover and
167
 *  parse the rest of the stream.
168
 *  This flag does not work for all parsing errors (at this time)
169
 *  making sense but was introduced afterwards.
170
 */
171
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmIgnoreParsingErrors; /* default OFFalse */
172
173
/** This flag indicates, whether parsing should stop after a certain
174
 *  element in the stream was parsed. This is especially useful for
175
 *  datasets containing garbage at the end, usually after the Pixel
176
 *  Data attribute. To prevent the parser for "stumbling" over that
177
 *  garbage, it is possible to tell the parser to stop after a
178
 *  specific element. The flag is only sensitive to elements on
179
 *  dataset level, i.e. inside sequence any occurrence of the specified
180
 *  tag is ignored. Caution: Note that if Pixel Data is chosen
181
 *  as stop element, any attributes behind will not be parsed, e. g.
182
 *  any digital signature attributes coming after.
183
 *  Default is (0xffff,0xffff), which means that the feature is
184
 *  disabled.
185
 */
186
extern DCMTK_DCMDATA_EXPORT OFGlobal<DcmTagKey> dcmStopParsingAfterElement; /* default OFTrue */
187
188
/** This flag influences behaviour when writing a dataset with items
189
 *  and sequences set to be encoded with explicit length. It is possible
190
 *  that the content of a sequence (or item) has an encoded length greater
191
 *  than the maximum 32-bit value that can be written to the sequence (item)
192
 *  length field. If this flag is enabled (OFTrue) then the encoding of the
193
 *  very sequence (item) is switched to undefined length encoding. Any
194
 *  contained items (sequences) will be encoded explicitly if possible.
195
 *  Default is OFTrue, i.e. encoding is switched to implicit if maximum
196
 *  size of length field is exceeded.
197
 */
198
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmWriteOversizedSeqsAndItemsUndefined; /* default OFTrue */
199
200
/** This flag allows for ignoring the value of (0002,0000) File Meta Information
201
 *  Group Length which is useful in cases where this value is incorrect.  If the
202
 *  header length is ignored, the behavior is identical to the case when no value
203
 *  is available (i.e. all elements are read as long as the group number is 0x0002).
204
 */
205
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmIgnoreFileMetaInformationGroupLength; /* default OFFalse */
206
207
/** This flag enables the replacement of a wrong delimitation item at the end of
208
 *  a sequence or item.  This is because there are incorrect systems that write
209
 *  a Sequence Delimitation Item (fffe,e0dd) at the end of an item or an Item
210
 *  Delimitation Item (fffe,e00d) at the end of a sequence.  By default, no
211
 *  delimitation items are replaced.
212
 */
213
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmReplaceWrongDelimitationItem; /* default OFFalse */
214
215
/** This flag enables the "silent" conversion of illegal OB/OW elements
216
 *  with undefined length (other than PixelData) to SQ elements while reading.
217
 *  The default behaviour is to reject such elements with an error message.
218
 */
219
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmConvertUndefinedLengthOBOWtoSQ; /* default OFFalse */
220
221
/** This flag enables the "silent" conversion of incorrectly encoded
222
 *  VOI LUT Sequence elements with VR=OW and explicit length into a sequence.
223
 *  This incorrect encoding was detected "in the wild" in 2016.
224
 */
225
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmConvertVOILUTSequenceOWtoSQ; /* default OFFalse */
226
227
/** This flag influences the behaviour when reading Pixel Data elements.
228
 *  Pixel Data in those top level datasets that are using a compression-enabled
229
 *  Transfer Syntax (with few exceptions such as Deflated TS),
230
 *  is being stored in an encapsulated way. That means DICOM requires that the
231
 *  Pixel Data then element uses an undefined length and internally uses a
232
 *  pseudo sequence structure called Pixel Sequence with Pixel items inside.
233
 *  If this flag is set to OFFalse (default), an error is reported when reading
234
 *  datasets with encapsulated Transfer Syntaxes but with Pixel Data being
235
 *  stored using explicit length encoding.
236
 *  If this flag is set to OFTrue, such an invalid Pixel Data encoding is
237
 *  accepted and the element is read with the given length as if it would be the
238
 *  case for datasets in uncompressed transfer syntaxes.
239
 */
240
extern DCMTK_DCMDATA_EXPORT OFGlobal<OFBool> dcmUseExplLengthPixDataForEncTS; /* default OFFalse */
241
242
/** Abstract base class for most classes in module dcmdata. As a rule of thumb,
243
 *  everything that is either a dataset or that can be identified with a DICOM
244
 *  attribute tag is derived from class DcmObject.
245
 */
246
class DCMTK_DCMDATA_EXPORT DcmObject
247
{
248
 public:
249
250
    /** constructor.
251
     *  Create new object from given tag and length.
252
     *  @param tag DICOM tag for the new element
253
     *  @param len value length for the new element
254
     */
255
    DcmObject(const DcmTag &tag, const Uint32 len = 0);
256
257
    /** copy constructor
258
     *  @param obj item to be copied
259
     */
260
    DcmObject(const DcmObject &obj);
261
262
    /// destructor
263
    virtual ~DcmObject();
264
265
    /** clone method
266
     *  @return deep copy of this object
267
     */
268
    virtual DcmObject *clone() const = 0;
269
270
    /** copy assignment operator
271
     *  @param obj object to be copied
272
     *  @return reference to this object
273
     */
274
    DcmObject &operator=(const DcmObject &obj);
275
276
    /** Virtual object copying. This method can be used for DcmObject
277
     *  and derived classes to get a deep copy of an object. Internally
278
     *  the assignment operator is called if the given DcmObject parameter
279
     *  is of the same type as "this" object instance. If not, an error
280
     *  is returned. This function permits copying an object by value
281
     *  in a virtual way which therefore is different to just calling the
282
     *  assignment operator of DcmElement which could result in slicing
283
     *  the object.
284
     *  @param rhs - [in] The instance to copy from. Has to be of the same
285
     *                class type as "this" object
286
     *  @return EC_Normal if copying was successful, error otherwise
287
     */
288
    virtual OFCondition copyFrom(const DcmObject &rhs) = 0;
289
290
    /** return identifier for this class. Every class derived from this class
291
     *  returns a unique value of type enum DcmEVR for this call. This is used
292
     *  as a "poor man's RTTI" to correctly identify instances derived from
293
     *  this class even on compilers not supporting RTTI.
294
     *  @return type identifier of this class
295
     */
296
    virtual DcmEVR ident() const = 0;
297
298
    /** return the value representation assigned to this object.
299
     *  If object was read from a stream, this method returns the VR
300
     *  that was defined in the stream for this object. It is, therefore,
301
     *  possible that the VR does not match the one defined in the data
302
     *  dictionary for the tag assigned to this object.
303
     *  @return VR of this object
304
     */
305
    inline DcmEVR getVR() const { return Tag.getEVR(); }
306
307
    /** check if this element is a string type, based on the VR.
308
     *  Since the check is based on the VR and not on the class,
309
     *  the result of this method is not a guarantee that the object
310
     *  can be safely casted to one of the string-VR subclasses.
311
     *  @return true if this object is a string VR, false otherwise
312
     */
313
0
    inline OFBool isaString() const { return Tag.getVR().isaString(); }
314
315
    /** check if this element is a leaf node in a dataset tree.
316
     *  All subclasses of DcmElement except for DcmSequenceOfItems
317
     *  are leaf nodes, while DcmSequenceOfItems, DcmItem, DcmDataset etc.
318
     *  are not.
319
     *  @return true if leaf node, false otherwise
320
     */
321
    virtual OFBool isLeaf() const = 0;
322
323
    /** check if this element can be safely casted to DcmElement
324
     *  @return true if DcmElement, false otherwise
325
     */
326
    virtual OFBool isElement() const { return OFFalse; }
327
328
    /** check if this element is nested in a sequence of items, i.e.\ not a
329
     *  top-level or stand-alone element
330
     *  @return true if this element is nested, false otherwise
331
     */
332
    virtual OFBool isNested() const;
333
334
    /** print object to a stream
335
     *  @param out output stream
336
     *  @param flags optional flag used to customize the output (see DCMTypes::PF_xxx)
337
     *  @param level current level of nested items. Used for indentation.
338
     *  @param pixelFileName not used (used in certain sub-classes of this class)
339
     *  @param pixelCounter not used (used in certain sub-classes of this class)
340
     */
341
    virtual void print(STD_NAMESPACE ostream &out,
342
                       const size_t flags = 0,
343
                       const int level = 0,
344
                       const char *pixelFileName = NULL,
345
                       size_t *pixelCounter = NULL) = 0;
346
347
    /** return the current transfer (read/write) state of this object.
348
     *  @return transfer state of this object
349
     */
350
    inline E_TransferState transferState() const { return fTransferState; }
351
352
    /** initialize the transfer state of this object. This method must be called
353
     *  before this object is written to a stream or read (parsed) from a stream.
354
     */
355
    virtual void transferInit(void);
356
357
    /** finalize the transfer state of this object. This method must be called
358
     *  when reading/writing this object from/to a stream has been completed.
359
     */
360
    virtual void transferEnd(void);
361
362
    /** get root dataset/item (top-level) that contains this object. Internally,
363
     *  the list of parent pointers is followed in order to find the root. If
364
     *  this object has no parent item, a pointer to this object is returned
365
     *  instead.
366
     *  @return pointer to the root dataset/item (might be NULL)
367
     */
368
    DcmItem *getRootItem();
369
370
    /** get parent item of this object. In case of a top-level element, this is
371
     *  either the main dataset or the file meta-information. In case of a nested
372
     *  element, this is the surrounding item.
373
     *  @return pointer to the parent item of this object (might be NULL)
374
     */
375
    virtual DcmItem *getParentItem();
376
377
    /** get parent of this object. If this object is an element that has been
378
     *  inserted into a dataset/item, the parent is this particular dataset/item.
379
     *  If this object is an item that has been inserted into a sequence, the
380
     *  parent is this particular sequence. If this object has not been inserted
381
     *  into a dataset/item or sequence, NULL is returned.
382
     *  @return pointer to the parent of this object (might be NULL)
383
     */
384
    inline DcmObject *getParent() { return Parent; }
385
386
    /** get parent of this object. If this object is an element that has been
387
     *  inserted into a dataset/item, the parent is this particular dataset/item.
388
     *  If this object is an item that has been inserted into a sequence, the
389
     *  parent is this particular sequence. If this object has not been inserted
390
     *  into a dataset/item or sequence, NULL is returned.
391
     *  @return pointer to the parent of this object (might be NULL)
392
     */
393
    inline const DcmObject *getParent() const { return Parent; }
394
395
    /** set parent of this object. NULL means no parent.
396
     *  NB: This method is used by derived classes for internal purposes only.
397
     *  @param parent pointer to the parent of this object
398
     */
399
    inline void setParent(DcmObject *parent) { Parent = parent; }
400
401
    /** return the group number of the attribute tag for this object
402
     *  @return group number of the attribute tag for this object
403
     */
404
    inline Uint16 getGTag() const { return Tag.getGTag(); }
405
406
    /** return the element number of the attribute tag for this object
407
     *  @return element number of the attribute tag for this object
408
     */
409
    inline Uint16 getETag() const { return Tag.getETag(); }
410
411
    /** return const reference to the attribute tag for this object
412
     *  @return const reference to the attribute tag for this object
413
     */
414
1.26M
    inline const DcmTag &getTag() const { return Tag; }
415
416
    /** assign group tag (but not element tag) of the attribute tag for this object.
417
     *  This is sometimes useful when creating repeating group elements.
418
     *  @param gtag new attribute group tag
419
     */
420
0
    inline void setGTag(Uint16 gtag) { Tag.setGroup(gtag); }
421
422
    /** assign a new Value Representation (VR) to this object. This operation
423
     *  is only supported for very few subclasses derived from this class,
424
     *  in particular for classes handling pixel data which may either be
425
     *  of OB or OW value representation.
426
     *  @param vr value representation
427
     *  @return EC_Normal if successful, an error code otherwise
428
     */
429
#ifdef DOXYGEN
430
    virtual OFCondition setVR(DcmEVR vr)
431
#else
432
    virtual OFCondition setVR(DcmEVR /* vr */)
433
#endif
434
    {
435
      return EC_IllegalCall;
436
    }
437
438
    /** get value multiplicity of this object.
439
     *  Please note that depending on the Value Representation (VR), subclasses
440
     *  derived from this class either return the number of currently stored
441
     *  values or the constant value 1 (as defined in the DICOM standard).
442
     *  See getNumberOfValues(), which always returns the number of stored values.
443
     *  @return value multiplicity of this object
444
     */
445
    virtual unsigned long getVM() = 0;
446
447
    /** get number of values stored in this object
448
     *  @return number of values in this object
449
     */
450
    virtual unsigned long getNumberOfValues() = 0;
451
452
    /** calculate the length of this DICOM element when encoded with the
453
     *  given transfer syntax and the given encoding type for sequences.
454
     *  For elements, the length includes the length of the tag, length field,
455
     *  VR field and the value itself, for items and sequences it returns
456
     *  the length of the complete item or sequence including delimitation tags
457
     *  if applicable.
458
     *  @warning Since calcElementLength() returns a 32 bit integer, an
459
     *    overflow during calculation is possible for some derived classes that
460
     *    actually represent a compound value (e.g. items like DcmPixelItem).
461
     *    Such overflows will be detected, in which case the maximum possible
462
     *    value will be returned instead, coinciding with DCM_UndefinedLength.
463
     *  @warning The implementation in DcmPixelData may return zero if no
464
     *    conforming representation exists and set the
465
     *    EC_RepresentationNotFound error flag to indicated it.
466
     *  @warning When calculation the length of a sequence or an item
467
     *    containing multiple attributes, the implementation may return
468
     *    DCM_UndefinedLength to indicate a value that can not be encoded as
469
     *    a 32 bit length field. It will even do so if
470
     *    "dcmWriteOversizedSeqsAndItemsUndefined" is disabled, but then also
471
     *    set the EC_SeqOrItemContentOverflow error flag (inside getLength())
472
     *    to indicated it.
473
     *  @note Just check for zero or DCM_UndefinedLength return value and then
474
     *    have a look at the error flag in either case.
475
     *  @param xfer transfer syntax for length calculation
476
     *  @param enctype sequence encoding type for length calculation
477
     *  @return length of DICOM element
478
     */
479
    virtual Uint32 calcElementLength(const E_TransferSyntax xfer,
480
                                     const E_EncodingType enctype) = 0;
481
482
    /** calculate the value length (without attribute tag, VR and length field)
483
     *  of this DICOM element when encoded with the given transfer syntax and
484
     *  the given encoding type for sequences. Never returns undefined length.
485
     *  @param xfer transfer syntax for length calculation
486
     *  @param enctype sequence encoding type for length calculation
487
     *  @return value length of DICOM element
488
     */
489
    virtual Uint32 getLength(const E_TransferSyntax xfer = EXS_LittleEndianImplicit,
490
                             const E_EncodingType enctype = EET_UndefinedLength) = 0;
491
492
    /** check if this DICOM object can be encoded in the given transfer syntax.
493
     *  @param newXfer transfer syntax in which the DICOM object is to be encoded
494
     *  @param oldXfer transfer syntax in which the DICOM object was read or created.
495
     *  @return true if object can be encoded in desired transfer syntax, false otherwise.
496
     */
497
    virtual OFBool canWriteXfer(const E_TransferSyntax newXfer,
498
                                const E_TransferSyntax oldXfer) = 0;
499
500
    /** read object from a stream.
501
     *  @param inStream DICOM input stream
502
     *  @param ixfer transfer syntax to use when parsing
503
     *  @param glenc handling of group length parameters
504
     *  @param maxReadLength attribute values larger than this value are skipped
505
     *    while parsing and read later upon first access if the stream type supports
506
     *    this.
507
     *  @return EC_Normal if successful, an error code otherwise
508
     */
509
    virtual OFCondition read(DcmInputStream &inStream,
510
                             const E_TransferSyntax ixfer,
511
                             const E_GrpLenEncoding glenc = EGL_noChange,
512
                             const Uint32 maxReadLength = DCM_MaxReadLength) = 0;
513
514
    /** write object to a stream (abstract)
515
     *  @param outStream DICOM output stream
516
     *  @param oxfer output transfer syntax
517
     *  @param enctype encoding types (undefined or explicit length)
518
     *  @param wcache pointer to write cache object, may be NULL
519
     *  @return status, EC_Normal if successful, an error code otherwise
520
     */
521
    virtual OFCondition write(DcmOutputStream &outStream,
522
                              const E_TransferSyntax oxfer,
523
                              const E_EncodingType enctype,
524
                              DcmWriteCache *wcache) = 0;
525
526
    /** write object in XML format to a stream
527
     *  @param out output stream to which the XML document is written
528
     *  @param flags optional flag used to customize the output (see DCMTypes::XF_xxx)
529
     *  @return status, always returns EC_Illegal Call
530
     */
531
    virtual OFCondition writeXML(STD_NAMESPACE ostream &out,
532
                                 const size_t flags = 0);
533
534
    /** write object in JSON format to a stream
535
     *  @param out output stream to which the JSON document is written
536
     *  @param format used to format and customize the output
537
     *  @return status, always returns EC_Illegal Call
538
     */
539
    virtual OFCondition writeJson(STD_NAMESPACE ostream &out,
540
                                  DcmJsonFormat &format);
541
542
    /** special write method for creation of digital signatures (abstract)
543
     *  @param outStream DICOM output stream
544
     *  @param oxfer output transfer syntax
545
     *  @param enctype encoding types (undefined or explicit length)
546
     *  @param wcache pointer to write cache object, may be NULL
547
     *  @return status, EC_Normal if successful, an error code otherwise
548
     */
549
    virtual OFCondition writeSignatureFormat(DcmOutputStream &outStream,
550
                                             const E_TransferSyntax oxfer,
551
                                             const E_EncodingType enctype,
552
                                             DcmWriteCache *wcache) = 0;
553
554
    /** returns true if the current object may be included in a digital signature
555
     *  @return true if signable, false otherwise
556
     */
557
    virtual OFBool isSignable() const;
558
559
    /** returns true if the object contains an element with Unknown VR at any nesting level
560
     *  @return true if the object contains an element with Unknown VR, false otherwise
561
     */
562
    virtual OFBool containsUnknownVR() const;
563
564
    /** check if this object contains non-ASCII characters
565
     *  @param checkAllStrings not used in this class
566
     *  @return always returns false, i.e. no extended characters used
567
     */
568
    virtual OFBool containsExtendedCharacters(const OFBool checkAllStrings = OFFalse);
569
570
    /** check if this object is affected by SpecificCharacterSet
571
     *  @return always returns false, i.e. not affected by SpecificCharacterSet
572
     */
573
    virtual OFBool isAffectedBySpecificCharacterSet() const;
574
575
    /** convert this object from the currently selected source character set to the
576
     *  currently selected destination character set (if affected by SpecificCharacterSet)
577
     *  @param converter character set converter to be used to convert the element values
578
     *  @return always returns EC_Normal, since there is nothing to do in this base class
579
     */
580
    virtual OFCondition convertCharacterSet(DcmSpecificCharacterSet &converter);
581
582
    /** check if this object is empty
583
     *  @param normalize normalize value before checking (ignore non-significant characters)
584
     *  @return true if object is empty, i.e. has no value, false otherwise
585
     */
586
    virtual OFBool isEmpty(const OFBool normalize = OFTrue);
587
588
    /** clear (remove) attribute value
589
     *  @return EC_Normal if successful, an error code otherwise
590
     */
591
    virtual OFCondition clear() = 0;
592
593
    /** check the currently stored element value
594
     *  @param autocorrect correct value length if OFTrue
595
     *  @return status, EC_Normal if value length is correct, an error code otherwise
596
     */
597
    virtual OFCondition verify(const OFBool autocorrect = OFFalse) = 0;
598
599
    /** this method is only used in container classes derived from this class,
600
     *  that is, DcmItem and DcmSequenceOfItems. It returns a pointer to the
601
     *  next object in the list AFTER the given object. If the caller passes NULL,
602
     *  a pointer to the first object in the list is returned. If the given object
603
     *  is not found, the given object is the last one in the list or the list is empty,
604
     *  NULL is returned.
605
     *  @param obj pointer to one object in the container; we are looking for the
606
     *    next entry after this one. NULL if looking for the first entry.
607
     *  @return pointer to next object in container or NULL if not found
608
     */
609
    virtual DcmObject *nextInContainer(const DcmObject *obj);
610
611
    /** this method enables a stack based, depth-first traversal of a complete
612
     *  hierarchical DICOM dataset (that is, classes derived from DcmItem or
613
     *  DcmSequenceOfItems). With each call of this method, the next object
614
     *  in the tree is located and marked on the stack.
615
     *  @param stack "cursor" for current position in the dataset. The stack
616
     *    will contain a pointer to each dataset, sequence, item and element
617
     *    from the main dataset down to the current element, and is updated
618
     *    upon each call to this method. An empty stack is equivalent to a stack
619
     *    containing a pointer to this object only.
620
     *  @param intoSub if true, the nextObject method will perform a hierarchical
621
     *    search through the dataset (depth-first), if false, only the current
622
     *    container object will be traversed (e.g., all elements of an item
623
     *    or all items of a sequence).
624
     *  @return EC_Normal if value length is correct, an error code otherwise
625
     */
626
    virtual OFCondition nextObject(DcmStack &stack,
627
                                   const OFBool intoSub);
628
629
    /** a complex, stack-based, hierarchical search method. It allows for a search
630
     *  for a DICOM object with a given attribute within a given container,
631
     *  hierarchically, from a starting position identified through a cursor stack.
632
     *  @param xtag the DICOM attribute tag we are searching for
633
     *  @param resultStack Depending on the search mode (see below), this parameter
634
     *     either serves as an input and output parameter, or as an output parameter
635
     *     only (the latter being the default). When used as an input parameter,
636
     *     the cursor stack defines the start position for the search within a
637
     *     hierarchical DICOM dataset. Upon successful return, the stack contains
638
     *     the position of the element found, in the form of a pointer to each dataset,
639
     *     sequence, item and element from the main dataset down to the found element.
640
     *  @param mode search mode, controls how the search stack is handled.
641
     *     In the default mode, ESM_fromHere, the stack is ignored on input, and
642
     *     the search starts in the object for which this method is called.
643
     *     In the other modes, the stack is used both as an input and an output
644
     *     parameter and defines the starting point for the search.
645
     *  @param searchIntoSub if true, the search will be performed hierarchically descending
646
     *    into the sequences and items of the dataset. If false, only the current container
647
     *    (sequence or item) will be traversed.
648
     *  @return EC_Normal if found, EC_TagNotFound if not found, an error code is something went wrong.
649
     */
650
    virtual OFCondition search(const DcmTagKey &xtag,
651
                               DcmStack &resultStack,
652
                               E_SearchMode mode = ESM_fromHere,
653
                               OFBool searchIntoSub = OFTrue);
654
655
    /** this method loads all attribute values maintained by this object and
656
     *  all sub-objects (in case of a container such as DcmDataset) into memory.
657
     *  After a call to this method, the file from which a dataset was read may safely
658
     *  be deleted or replaced. For large files, this method may obviously allocate large
659
     *  amounts of memory.
660
     *  @return EC_Normal if successful, an error code otherwise
661
     */
662
    virtual OFCondition loadAllDataIntoMemory() = 0;
663
664
    /** return the current value of the Length field (which is different from the functionality
665
     *  of the public getLength() method). Only needed for internal purposes and for checker tools
666
     *  that verify values against the length field.
667
     *  @return current value of length field
668
     */
669
    Uint32 getLengthField() const { return Length; }
670
671
 protected:
672
673
    /** print line indentation, e.g.\ a couple of spaces for each nesting level.
674
     *  Depending on the value of 'flags' other visualizations are also possible.
675
     *  @param out output stream
676
     *  @param flags used to customize the output (see DCMTypes::PF_xxx)
677
     *  @param level current level of nested items. Used for indentation.
678
     */
679
    void printNestingLevel(STD_NAMESPACE ostream &out,
680
                           const size_t flags,
681
                           const int level);
682
683
    /** print beginning of the info line.
684
     *  The default output is tag and value representation, though other
685
     *  visualizations are possible depending on the value of 'flags'.
686
     *  @param out output stream
687
     *  @param flags used to customize the output (see DCMTypes::PF_xxx)
688
     *  @param level current level of nested items. Used for indentation.
689
     *  @param tag optional tag used to print the data element information
690
     */
691
    void printInfoLineStart(STD_NAMESPACE ostream &out,
692
                            const size_t flags,
693
                            const int level,
694
                            DcmTag *tag = NULL);
695
696
    /** print end of the info line.
697
     *  The default output is length, value multiplicity and tag name, though
698
     *  other visualizations are possible depending on the value of 'flags'.
699
     *  @param out output stream
700
     *  @param flags used to customize the output (see DCMTypes::PF_xxx)
701
     *  @param printedLength number of characters printed after line start.
702
     *    Used for padding purposes.
703
     *  @param tag optional tag used to print the data element information
704
     */
705
    void printInfoLineEnd(STD_NAMESPACE ostream &out,
706
                          const size_t flags,
707
                          const unsigned long printedLength = 0xffffffff /*no padding*/,
708
                          DcmTag *tag = NULL);
709
710
    /** print given text with element information.
711
     *  Calls printInfoLineStart() and printInfoLineEnd() to frame the 'info' text.
712
     *  @param out output stream
713
     *  @param flags used to customize the output (see DCMTypes::PF_xxx)
714
     *  @param level current level of nested items. Used for indentation.
715
     *  @param info text to be printed
716
     *  @param tag optional tag used to print the data element information
717
     *  @param isInfo optional flag indicating whether this text is really given for
718
     *    informational purposes only. Used to choose the correct output color.
719
     */
720
    virtual void printInfoLine(STD_NAMESPACE ostream &out,
721
                               const size_t flags,
722
                               const int level = 0,
723
                               const char *info = NULL,
724
                               DcmTag *tag = NULL,
725
                               const OFBool isInfo = OFTrue);
726
727
    /** static helper function that writes a given attribute tag to a binary
728
     *  output stream using the byte order indicated by the transfer syntax.
729
     *  @param outStream output stream
730
     *  @param tag tag to write to the stream
731
     *  @param oxfer transfer syntax defining the byte order
732
     *  @return EC_Normal if successful, an error code otherwise
733
     */
734
    static OFCondition writeTag(DcmOutputStream &outStream,
735
                                const DcmTag &tag,
736
                                const E_TransferSyntax oxfer);
737
738
    /** write tag, VR and length field to the given output stream
739
     *  @param outStream output stream
740
     *  @param oxfer transfer syntax for writing
741
     *  @param writtenBytes number of bytes written to stream returned in this parameter
742
     *  @return EC_Normal if successful, an error code otherwise
743
     */
744
    virtual OFCondition writeTagAndLength(DcmOutputStream &outStream,
745
                                          const E_TransferSyntax oxfer, // in
746
                                          Uint32 &writtenBytes) const;  // out
747
748
    /** return the number of bytes needed to serialize the
749
     *  tag, VR and length information of the current object using the given
750
     *  transfer syntax.
751
     *  @param oxfer The transfer syntax used for encoding
752
     *  @return number of bytes, may be 8 or 12 depending on VR and transfer syntax.
753
     */
754
    virtual Uint32 getTagAndLengthSize(const E_TransferSyntax oxfer) const;
755
756
    /** return the DICOM attribute tag name for this object. If not known yet, will
757
     *  be looked up in the dictionary and cached. Therefore, method is not const.
758
     *  @return tag name for this attribute
759
     */
760
    const char *getTagName() { return Tag.getTagName(); }
761
762
    /** set the VR for this attribute
763
     *  @param vr new VR for this attribute.
764
     */
765
    void setTagVR(DcmEVR vr) { Tag.setVR(vr); }
766
767
    /** return the current transfer state of this object during serialization/deserialization
768
     *  @return current transfer state of this object
769
     */
770
    E_TransferState getTransferState() const { return fTransferState; }
771
772
    /** set the current transfer state of this object during serialization/deserialization
773
     *  @param newState new transfer state of this object
774
     */
775
    void setTransferState(E_TransferState newState) { fTransferState = newState; }
776
777
    /** return the number of transferred bytes for this object during serialization/deserialization
778
     *  @return number of transferred bytes
779
     */
780
    Uint32 getTransferredBytes() const { return fTransferredBytes; }
781
782
    /** set the number of transferred bytes for this object during serialization/deserialization
783
     *  @param val number of transferred bytes
784
     */
785
    void setTransferredBytes(Uint32 val) { fTransferredBytes = val; }
786
787
    /** add to the number of transferred bytes for this object during serialization/deserialization
788
     *  @param val number of additional transferred bytes to add to existing value
789
     */
790
    void incTransferredBytes(Uint32 val) { fTransferredBytes += val; }
791
792
    /** set the current value of the Length field
793
     *  @param val new value of the Length field
794
     */
795
    void setLengthField(Uint32 val) { Length = val; }
796
797
 public:
798
799
    /** helper class to print a DcmObject to an ostream using operator<<
800
     */
801
    class DCMTK_DCMDATA_EXPORT PrintHelper
802
    {
803
      private:
804
        /** Undefined assignment operator. This is needed to work around a
805
         *  compiler warning on VC2008 with the highest warning level.
806
         */
807
        PrintHelper& operator=(PrintHelper &);
808
809
      public:
810
        /** construct a PrintHelper
811
         *  @param dcmobj DcmObject you want to print
812
         *  @param flags flags to use for DcmObject::print()
813
         *  @param level level to use for DcmObject::print()
814
         */
815
        explicit PrintHelper(DcmObject &dcmobj, size_t flags = 0, int level = 0)
816
          : dcmobj_(dcmobj), flags_(flags), level_(level)
817
0
        {}
818
819
        DcmObject &dcmobj_;
820
        const size_t flags_;
821
        const int level_;
822
    };
823
824
    /* member variables */
825
826
 protected:
827
828
    /// error flag for this object.
829
    OFCondition errorFlag;
830
831
 private:
832
833
    /// the DICOM attribute tag and VR for this object
834
    DcmTag Tag;
835
836
    /// the length of this attribute as read from stream, may be undefined length
837
    Uint32 Length;
838
839
    /// transfer state during read and write operations
840
    E_TransferState fTransferState;
841
842
    /// number of bytes already read/written during transfer
843
    Uint32 fTransferredBytes;
844
845
    /// pointer to parent object if contained in a dataset/item (might be NULL)
846
    DcmObject *Parent;
847
 }; // class DcmObject
848
849
/** Print a DcmObject::PrintHelper to an ostream.
850
 *  @param stream stream to print to
851
 *  @param obj object which will be print()ed
852
 *  @return the stream argument
853
 */
854
static inline STD_NAMESPACE ostream& operator<<(STD_NAMESPACE ostream &stream, DcmObject::PrintHelper obj)
855
0
{
856
0
    obj.dcmobj_.print(stream, obj.flags_, obj.level_);
857
0
    return stream;
858
0
}
Unexecuted instantiation: dcmtk_dicom_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper)
Unexecuted instantiation: dcmtk_meta_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper)
Unexecuted instantiation: dcmtk_image_fuzzer.cc:operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, DcmObject::PrintHelper)
859
860
#endif // DCOBJECT_H