This file is indexed.

/usr/include/dcmtk/dcmdata/dcpath.h is in libdcmtk-dev 3.6.2-3build3.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
/*
 *
 *  Copyright (C) 2008-2012, OFFIS e.V.
 *  All rights reserved.  See COPYRIGHT file for details.
 *
 *  This software and supporting documentation were developed by
 *
 *    OFFIS e.V.
 *    R&D Division Health
 *    Escherweg 2
 *    D-26121 Oldenburg, Germany
 *
 *
 *  Module:  dcmdata
 *
 *  Author:  Michael Onken
 *
 *  Purpose: Class declarations for accessing DICOM dataset structures (items,
 *           sequences and leaf elements via string-based path access.
 *
 */

#ifndef DCPATH_H
#define DCPATH_H

#include "dcmtk/config/osconfig.h"    /* make sure OS specific configuration is included first */

#include "dcmtk/dcmdata/dcdatset.h"


/** Class representing a node in DcmPath. A node contains just
  * a pointer to a DcmObject (e.g. a sequence or an item). Additionally
  * an item number is stored which also makes sense in case that the
  * object pointed to is an item. The item number is necessary because
  * when having only a pointer to a DcmItem there is no way to find out
  * at which position the item actually has in the surrounding sequence.
  */
class DCMTK_DCMDATA_EXPORT DcmPathNode
{

public:

  /** Constructor. Creates empty path node.
   */
  DcmPathNode() : m_obj(NULL), m_itemNo(0) {}

  /** Constructor. Creates search node from object pointer and item number.
   *  @param obj [in] The object the search node points to. The memory of the
   *             given DICOM object is not handled by the node itself but
   *             must be handled (i.e. freed) from outside.
   *  @param itemNo [in] The item number that should be set. Only relevant
   *                if obj parameter contains an item
   */
  DcmPathNode(DcmObject* obj, Uint32 itemNo)    : m_obj(obj), m_itemNo(itemNo) {}

  /** Destructor. Nothing to do, the DICOM object is not freed automatically!
   */
  ~DcmPathNode() { }

  /// Pointer to object this search node points to
  DcmObject* m_obj;

  /// The item number of the item in m_obj; only useful if m_obj is an item
  Uint32 m_itemNo;

private:

  /** Private undefined copy constructor
   */
  DcmPathNode(const DcmPathNode& rhs);

  /** Private undefined assignment operator
   */
  DcmPathNode& operator=(const DcmPathNode& arg);
};


/** Class representing a path of DICOM objects. A path is a "way" through
 *  a DICOM dataset, i.e. it starts e.g. with an item, followed by a sequence
 *  originally contained in this item. The sequence then could be followed by
 *  another item which is part of the sequence and so on. Thus the path
 *  should be well-formed, but if it is created manually (e.g. using append())
 *  there is no corresponding checking.
 */
class DCMTK_DCMDATA_EXPORT DcmPath
{

public:

  /** Constructor, creates an empty search result
   */
  DcmPath();

  /** Constructor, creates a search result from a list of search nodes.
   *  @param currentPath [in] The list of search nodes representing a
   *                     "path" through a DICOM dataset
   */
  DcmPath(const OFList<DcmPathNode*>& currentPath);

  /** Appends a search node at the end of the search result path. It is not
   *  checked whether the resulting path is still valid.
   *  @param node [in] The node to append.
   *
   */
  void append(DcmPathNode* node);

  /** Removes last path node from path. Also frees memory of path node
   *  but does _not_ free memory of the underlying DICOM item or element.
   *  @return none
   */
  void deleteBackNode();

  /** Returns iterator pointing to first path component.
   *  @return Iterator to first path node.
   */
  OFListIterator(DcmPathNode*) begin();

  /** Returns last path component.
   *  @return The last path component, NULL if none exists.
   */
  DcmPathNode* back();

  /** Returns iterator pointing to last path component.
   *  @return Iterator to last path node.
   */
  OFListIterator(DcmPathNode*) end();

  /** Returns number of path components.
   *  @return The number of path components
   */
  Uint32 size() const;

  /** Returns whether path is empty, ie does not contain any path nodes
   *  @return OFTrue, if path is empty, OFFalse otherwise
   */
  OFBool empty() const;

  /** Returns a string representation of the path,
   *  e.g.\ "SourceImageSequence[0].ReferencedSOPInstanceUID"
   *  @return String representing path
   */
  OFString toString() const;

  /** Returns whether the path contains tags of a given group.
   *  Might be useful for looking after (unwanted) meta header tags etc.
   *  @param groupNo [in] The group number to look for
   *  @return OFTrue if group number is found in path, OFFalse otherwise
   */
  OFBool containsGroup(const Uint16 groupNo) const;

  /** Returns a string representation of each path node separately.
   *  Tags are represented as numbers surrounded by braces "(gggg,eeee)",
   *  not dictionary names. Items are represented by a number or wildcard
   *  in square brackets, eg. "[12]" or "[*]".
   *  @param path The path to parse into different nodes
   *  @param result [out] List containing the resulting strings
   *  @return none
   */
  static OFCondition separatePathNodes(const OFString& path, OFList<OFString>& result);

  /** Helper function for findOrCreatePath(). Parses an item number from
   *  the beginning of the path string. The item number must be positive,
   *  starting with 0.
   *  The path must start like "[itemnumber]...".
   *  @param path [in/out] The path starting with the item number in square
   *              brackets, e.g.\ "[3]". The parsed item number and a
   *              potentially following "." are removed from the path
   *  @param itemNo [out] The parsed item number. If a wildcard was parsed,
   *                this output parameter is not set at all.
   *  @param wasWildcard [out] Is set to OFTrue, if wildcard was parsed
   *                     (instead of concrete item number).
   *  @return EC_Normal, if concrete item number or wildcard was parsed
   */
  static OFCondition parseItemNoFromPath(OFString& path,                   // inout
                                         Uint32& itemNo,                   // out
                                         OFBool& wasWildcard);             // out

  /** Function that parses a tag from the beginning of a path string.
   *  The tag has to be either in numeric format, e.g. "(0010,0010)" or
   *  a dictionary name, e.g. "PatientName". If successful, the
   *  parsed tag is removed from the path string.
   *  @param path [in/out] The path string, starting with the attribute
   *              to parse
   *  @param tag [out] The tag parsed
   *  @return EC_Normal if successful, error code otherwise
   */
  static OFCondition parseTagFromPath(OFString& path,         // inout
                                      DcmTag& tag);           // out

  /** Desctructor, cleans up memory of path nodes. Does not delete
   *  the DcmObjects the nodes point to (this is also not done
   *  by the desctructor of the path nodes, so the caller is responsible
   *  for freeing any related DICOM objects.
   */
  ~DcmPath();

private:

  /// Internal list representing the nodes in the path.
  OFList<DcmPathNode*> m_path;

  /** Private undefined copy constructor
   */
  DcmPath(const DcmPath& rhs);

  /** Private undefined assignment operator
   */
  DcmPath& operator=(const DcmPath& arg);
};


class DCMTK_DCMDATA_EXPORT DcmPathProcessor
{

public:

  /** Constructor, creates an empty search object.
   */
  DcmPathProcessor();

  /** Sets whether searching/creating paths will support wildcard for
   *  items. If set to false, any path operation with item wildcard characters
   *  will return an error.
   *  @param supported [in] If true, wildcard are enabled (default)
   *                   If false, item wildcard support is disabled.
   */
  void setItemWildcardSupport(const OFBool supported);


  /** Enables (class default: enabled) or disables checking of private
   *  reservations when inserting private tags. If enabled and a private
   *  tag is created that has no private reservation, an error is returned.
   *  If disabled, it is possible to insert private tags that do not have
   *  a reservation in the corresponding item/dataset.
   *  @param doChecking [in] OFTrue enables reservation checking,
   *                    OFFalse disables it.
   */
  void checkPrivateReservations(const OFBool doChecking);

  /** Checks in item, whether a private reservation for a given
   *  tag key exists.
   *  @param item   [in] The item to search in
   *  @param tagKey [in/out] The tag to be checked.
   *  @param privateCreator [in] The private creator to check for (if known,
   *                        can be left empty)
   *  @return Return EC_Normal if reservation checking was successful.
   *          Otherwise an error code is returned.
   */
  static OFCondition checkPrivateTagReservation(DcmItem* item,
                                                const DcmTagKey& tagKey,
                                                const OFString& privateCreator = "");

  /** Checks in item, whether a private reservation for a given
   *  tag key. If so, a dictionary lookup is performed and the VR and private
   *  creator of the tag is updated correspondingly.
   *  @param item [in] The item to search in
   *  @param tag [in/out] The tag to be checked. Will be updated with VR and
   *                      private creator.
   *  @param privateCreator [in] The private creator to check for (if known,
   *                        can be left empty)
   *  @return Return EC_Normal if reservation checking and updating the
   *          tag was successful. Otherwise an error code is returned.
   */
  static OFCondition checkPrivateTagReservation(DcmItem* item,
                                                DcmTag& tag,
                                                const OFString& privateCreator = "");

  /** Function that allows for finding and/or inserting a hierarchy of items
   *  and attributes as defined by a path string; also returns a list of
   *  pointers for each successfully found or inserted paths. Every list
   *  contains pointers pointing to all the objects along the path
   *  starting from the object given as parameter. The pointer to the
   *  starting object will not be part of the result.
   *
   *  In principle, the path string must have the following format (in
   *  arbitrary depth). Note that for searching a sequence, the example
   *  below would start with [ITEMNO] instead:
   *  SEQUENCE[ITEMNO].SEQUENCE[ITEMNO].ATTRIBUTE
   *  . ITEMNO must be a positive integer starting with 0.
   *  SEQUENCE and ATTRIBUTE must be a tag, written e.g.
   *  "(0010,0010)" or as a dictionary name, e.g. "PatientName". If the
   *  path cannot be fully created (see option createIfNecessary), any
   *  possibly object changes are reverted. So a path is either fully created
   *  or no path component is created at all. The result can be obtained
   *  by calling the getResults() function.
   *
   *  Example: The path
   *  "ContentSequence[4].(0040,a043)[0].CodeValue" selects the Content
   *  Sequence in the given object, therein the 5th item, therein the "Concept
   *  Name Code Sequence" denoted by (0040,a043), therein the first item
   *  and finally therein the tag "Code Value".
   *  The resulting object list should (if success is returned) contain
   *  1 result, consisting of a list with 5 pointers to 5 objects in the order
   *  in their logical order as they occur in the path string
   *  (in total 2 sequences, 2 items, and one leaf attribute).
   *  @param obj [in] The object to search (or create) a path in
   *  @param path [in] The path either starting with an attribute (either a
   *              sequence or a a leaf attribute as a dicitionary name or
   *              tag) or starting with an item
   *  @param createIfNecessary [in] If set, all missing objects found
   *                           in the path string are created. If not set,
   *                           only existing paths can be accessed and
   *                           no new attribute or item is created.
   *  @return EC_Normal if successful, error code otherwise.
   */
  OFCondition findOrCreatePath(DcmObject* obj,
                               const OFString& path,
                               OFBool createIfNecessary = OFFalse);

  /** Function that allows for deleting elements and items from
   *  a DICOM object tree.
   *  In principle, the path string must have the following format (in
   *  arbitrary depth). Note that for searching in a sequence, the example
   *  below would start with [ITEMNO] instead:
   *  SEQUENCE[ITEMNO].SEQUENCE[ITEMNO].ATTRIBUTE
   *  . ITEMNO must be a positive integer starting with 0.
   *  SEQUENCE and ATTRIBUTE must be a tag, written e.g.
   *  "(0010,0010)" or as a dictionary name, e.g. "PatientName".
   *
   *  Example: The path
   *  "ContentSequence[4].(0040,a043)[0].CodeValue" selects the Content
   *  Sequence in the given object, therein the 5th item, therein the "Concept
   *  Name Code Sequence" denoted by (0040,a043), therein the first item
   *  and finally therein the tag "Code Value". Only "Code Value" will be
   *  deleted by the function.
   *  @param obj [in] The object to delete attribute or item from
   *  @param path [in] The path either starting with an attribute (either a
   *              sequence or a a leaf attribute as a dicitionary name or
   *              tag) or starting with an item
   *  @param numDeleted [out] Number of deleted attributes/items
   *  @return EC_Normal if successful, error code otherwise. If the desired
   *  attribute/item was not found, EC_TagNotFound is returned.
   */
  OFCondition findOrDeletePath(DcmObject* obj,
                               const OFString& path,
                               Uint32& numDeleted);

  /** Returns the results from the search / creation call.
   *  @param searchResults [out] The resulting paths that were created/searched
   *                       Note that the memory of the search results is freed
   *                       automatically by the destructor and must not be freed
   *                       by the caller.
   *  @return Number of results returned
   */
  Uint32 getResults(OFList<DcmPath*>& searchResults);


  /** Helper function that applies a specified "override key" in path syntax
   *  to the given dataset. The name "override" indicates that these keys have
   *  higher precedence than identical keys in a request dataset that might
   *  possibly read from a DICOM query file.
   *  @param dataset [in/out] the dataset (e.g.\ query keys) the override key is
   *                 applied to. Must be non-NULL.
   *  @param overrideKey [in] the override key in path syntax (see class DcmPath).
   *                     Also the path can end with a value assignment, e.g.
   *                     "PatientName=Doe^John". An empty (or missing value) will
   *                     not be ignored but will be written as empty to the
   *                     attribute (if not a sequence or item).
   *  @return EC_Normal if adding was successful, error code otherwise
   */
  OFCondition applyPathWithValue(DcmDataset* dataset,
                                 const OFString& overrideKey);

  /** Deconstructor, cleans up memory that was allocated for any
   *  search results.
   */
  ~DcmPathProcessor();

protected:

  /** Function that allows for finding and/or inserting a hierarchy of items
   *  and attributes as defined by a path string; also returns a list of
   *  pointers for each successfully found or inserted paths. Every list
   *  contains pointers pointing to all the objects along the path
   *  starting from the object given as parameter. The pointer to the
   *  starting object will not be part of the result.
   *
   *  In principle, the path string must have the following format (in
   *  arbitrary depth).
   *  SEQUENCE[ITEMNO].SEQUENCE[ITEMNO].ATTRIBUTE
   *  . ITEMNO must be a positive integer starting with 0.
   *  SEQUENCE and ATTRIBUTE must be a tag, written e.g.
   *  "(0010,0010)" or as a dictionary name, e.g. "PatientName". If the
   *  path cannot be fully created (see option createIfNecessary), any
   *  possibly object changes are reverted. So a path is either fully created
   *  or no path component is created at all. The result can be obtained
   *  by calling the getResults() function.
   *
   *  Example: The path
   *  "ContentSequence[4].(0040,a043)[0].CodeValue" selects the Content
   *  Sequence in the given item, therein the 5th item, therein the "Concept
   *  Name Code Sequence" denoted by (0040,a043), therein the first item
   *  and finally therein the tag "Code Value".
   *  The resulting object list should (if success is returned) contain
   *  1 result, consisting of a list with 5 pointers to 5 objects in the order
   *  in their logical order as they occur in the path string
   *  (in total 2 sequences, 2 items, and one leaf attribute).
   *  @param item [in] The object to search (or create) a path in
   *  @param path [in] The path starting with an attribute (either a
   *              sequence or a a leaf attribute) as a dicitionary name or
   *              tag. The parsed attribute is removed from the path string.
   *  @return EC_Normal if successful, error code otherwise.
   */
  OFCondition findOrCreateItemPath(DcmItem* item,
                                   OFString& path);

  /** Function that allows for finding and/or inserting a hierarchy of items
   *  and attributes as defined by a path string; also returns a list of
   *  pointers for each successfully found or inserted paths. Every list
   *  contains pointers pointing to all the objects along the path
   *  starting from the object given as parameter. The pointer to the
   *  starting object will not be part of the result.
   *
   *  In principle, the path string must have the following format (in
   *  arbitrary depth).
   *  [ITEMNO].SEQUENCE[ITEMNO].ATTRIBUTE
   *  . ITEMNO must be a positive integer starting with 0.
   *  SEQUENCE and ATTRIBUTE must be a tag, written e.g.
   *  "(0010,0010)" or as a dictionary name, e.g. "PatientName". If the
   *  path cannot be fully created (see option createIfNecessary), any
   *  possibly object changes are reverted. So a path is either fully created
   *  or no path component is created at all. The result can be obtained
   *  by calling the getResults() function.
   *
   *  Example: The path
   *  "[4].(0040,a043)[0].CodeValue" selects the 5th item in the given
   *  sequence, therein the "Concept Name Code Sequence" denoted by
   *  (0040,a043), therein the first item and finally therein the
   *  tag "Code Value".
   *  The resulting object list should (if success is returned) contain
   *  1 result, consisting of a list with 4 pointers to 4 objects in the order
   *  in their logical order as they occur in the path string
   *  (in total 1 sequence, 2 items, and one leaf element).
   *  @param seq  [in] The object to search (or create) a path in
   *  @param path [in] The path starting with an item. The parsed item number
   *  (e.g. "[0]") is removed from the path string.
   *  @return EC_Normal if successful, error code otherwise.
   */
  OFCondition findOrCreateSequencePath(DcmSequenceOfItems* seq,
                                       OFString& path);

  /** Helper function that looks at the last node in a given path and deletes
   *  the corresponding DICOM object. Does not delete the path node itself:
   *  That is done by the calling function, findOrCreateItemPath().
   *  @param objSearchedIn [in/out] The object the given path starts in.
   *  @param path [in/out] The complete path to the DICOM object to delete
   *  @param toDelete [in/out] The path node to delete. This node must be
   *                  identical to the last node in the path parameter. Also
   *                  the node must represent a DICOM sequence or leaf element,
   *                  not an item. However, because it is isolated already by
   *                  the calling function, it is provided here for convenience.
   */
  static OFCondition deleteLastElemFromPath(DcmObject* objSearchedIn,
                                            DcmPath* path,
                                            DcmPathNode* toDelete);

  /** Helper function that looks at the last node in a given path and deletes
   *  the corresponding DICOM object. Does not delete the path node itself:
   *  That is done by the calling function, findOrCreateItemPath().
   *  @param objSearchedIn [in/out] The object the given path starts in.
   *  @param path [in/out] The complete path to the DICOM object to delete
   *  @param toDelete [in/out] The path node to delete. This node must be
   *                  identical to the last node in the path parameter. Also
   *                  the node must represent a DICOM item, not a sequence
   *                  However, because it is isolated already by the calling
   *                  function, it is provided here for convenience.
   */
  static OFCondition deleteLastItemFromPath(DcmObject* objSearchedIn,
                                            DcmPath* path,
                                            DcmPathNode* toDelete);

  /** Returns the private reservation tag key for a given private tag
   *  @param privateKey [in] The private key to calculate reservation tag for
   *  @return The reservation key. If given key is not private or an error,
   *          return DCM_UndefinedTagKey. If the given key is a reservation
   *          itself, it is directly returned.
   */
  static DcmTagKey calcPrivateReservationTag(const DcmTagKey& privateKey);

  /** Cleans up memory that was allocated for any search results.
   *  Called when a new search is started or during object destruction.
   *  The DICOM data all freed paths and path nodes point to, is not
   *  touched, i.e. all memory to the DICOM objects pointed to must be
   *  freed from outside. Processing options like checking for private
   *  reservations and so on are not reset to default values but
   *  keep valid.
   */
  void clear();

private:

  /// Internal list that is during search for keeping track of current path
  OFList<DcmPathNode*> m_currentPath;

  /// Internal list that represents the search results found
  OFList<DcmPath*> m_results;

  /// Denotes whether missing items/sequences/attributes should be
  /// automatically inserted when using findAndCreate routines
  OFBool m_createIfNecessary;

  /// If enabled (default), any insertions of private tags will fail, if no
  /// corresponding reservation exists in the underlying item
  OFBool m_checkPrivateReservations;

  /// Denotes, whether a path is accepted that contains wildcards.
  /// If false, then any search containing wildcards will return an error.
  OFBool m_itemWildcardsEnabled;

  /** Private undefined copy constructor
   */
  DcmPathProcessor(const DcmPathProcessor& rhs);

  /** Private undefined assignment operator
   */
  DcmPathProcessor& operator=(const DcmPathProcessor& arg);
};


#endif // DCPATH_H