This file is indexed.

/usr/include/gdcm-2.6/gdcmScanner.h is in libgdcm2-dev 2.6.3-3ubuntu3.

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
/*=========================================================================

  Program: GDCM (Grassroots DICOM). A DICOM library

  Copyright (c) 2006-2011 Mathieu Malaterre
  All rights reserved.
  See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#ifndef GDCMSCANNER_H
#define GDCMSCANNER_H

#include "gdcmDirectory.h"
#include "gdcmSubject.h"
#include "gdcmTag.h"
#include "gdcmPrivateTag.h"
#include "gdcmSmartPointer.h"

#include <map>
#include <set>
#include <string>

#include <string.h> // strcmp

namespace gdcm
{
class StringFilter;

/**
 * \brief Scanner
 * This filter is meant for quickly browsing a FileSet (a set of files on
 * disk). Special consideration are taken so as to read the mimimum amount of
 * information in each file in order to retrieve the user specified set of
 * DICOM Attribute.
 *
 * This filter is dealing with both VRASCII and VRBINARY element, thanks to the
 * help of StringFilter
 *
 * \warning IMPORTANT In case of file where tags are not ordered (illegal as
 * per DICOM specification), the output will be missing information
 *
 * \note implementation details. All values are stored in a std::set of
 * std::string. Then the address of the cstring underlying the std::string is
 * used in the std::map.
 *
 * This class implement the Subject/Observer pattern trigger the following events:
 * \li ProgressEvent
 * \li StartEvent
 * \li EndEvent
 */
class GDCM_EXPORT Scanner : public Subject
{
  friend std::ostream& operator<<(std::ostream &_os, const Scanner &s);
public:
  Scanner():Values(),Filenames(),Mappings() {}
  ~Scanner();

  /// struct to map a filename to a value
  /// Implementation note:
  /// all std::map in this class will be using const char * and not std::string
  /// since we are pointing to existing std::string (hold in a std::vector)
  /// this avoid an extra copy of the byte array.
  /// Tag are used as Tag class since sizeof(tag) <= sizeof(pointer)
  typedef std::map<Tag, const char*> TagToValue;
  //typedef std::map<Tag, ConstCharWrapper> TagToValue; //StringMap;
  //typedef TagToStringMap TagToValue;
  typedef TagToValue::value_type TagToValueValueType;

  /// Add a tag that will need to be read. Those are root level tags
  void AddTag( Tag const & t );
  void ClearTags();

  // Work in progress do not use:
  void AddPrivateTag( PrivateTag const & t );

  /// Add a tag that will need to be skipped. Those are root level skip tags
  void AddSkipTag( Tag const & t );
  void ClearSkipTags();

  /// Start the scan !
  bool Scan( Directory::FilenamesType const & filenames );

  Directory::FilenamesType const &GetFilenames() const { return Filenames; }

  /// Print result
  void Print( std::ostream & os ) const;

  /// Check if filename is a key in the Mapping table.
  /// returns true only of file can be found, which means
  /// the file was indeed a DICOM file that could be processed
  bool IsKey( const char * filename ) const;

  /// Return the list of filename that are key in the internal map,
  /// which means those filename were properly parsed
  Directory::FilenamesType GetKeys() const;

  // struct to store all the values found:
  typedef std::set< std::string > ValuesType;

  /// Get all the values found (in lexicographic order)
  ValuesType const & GetValues() const { return Values; }

  /// Get all the values found (in lexicographic order) associated with Tag 't'
  ValuesType GetValues(Tag const &t) const;

  /// Get all the values found (in a vector) associated with Tag 't'
  /// This function is identical to GetValues, but is accessible from the wrapped
  /// layer (python, C#, java)
  Directory::FilenamesType GetOrderedValues(Tag const &t) const;

  /* ltstr is CRITICAL, otherwise pointers value are used to do the key comparison */
  struct ltstr
    {
    bool operator()(const char* s1, const char* s2) const
      {
      assert( s1 && s2 );
      return strcmp(s1, s2) < 0;
      }
    };
  typedef std::map<const char *,TagToValue, ltstr> MappingType;
  typedef MappingType::const_iterator ConstIterator;
  ConstIterator Begin() const { return Mappings.begin(); }
  ConstIterator End() const { return Mappings.end(); }

  /// Mappings are the mapping from a particular tag to the map, mapping filename to value:
  MappingType const & GetMappings() const { return Mappings; }

  /// Get the std::map mapping filenames to value for file 'filename'
  TagToValue const & GetMapping(const char *filename) const;

  /// Will loop over all files and return the first file where value match the reference value
  /// 'valueref'
  const char *GetFilenameFromTagToValue(Tag const &t, const char *valueref) const;

  /// Will loop over all files and return a vector of std::strings of filenames
  /// where value match the reference value 'valueref'
  Directory::FilenamesType GetAllFilenamesFromTagToValue(Tag const &t, const char *valueref) const;

  /// See GetFilenameFromTagToValue(). This is simply GetFilenameFromTagToValue followed
  // by a call to GetMapping()
  TagToValue const & GetMappingFromTagToValue(Tag const &t, const char *value) const;

  /// Retrieve the value found for tag: t associated with file: filename
  /// This is meant for a single short call. If multiple calls (multiple tags)
  /// should be done, prefer the GetMapping function, and then reuse the TagToValue
  /// hash table.
  /// \warning Tag 't' should have been added via AddTag() prior to the Scan() call !
  const char* GetValue(const char *filename, Tag const &t) const;

  /// for wrapped language: instanciate a reference counted object
  static SmartPointer<Scanner> New() { return new Scanner; }

protected:
  void ProcessPublicTag(StringFilter &sf, const char *filename);
private:
  // struct to store all uniq tags in ascending order:
  typedef std::set< Tag > TagsType;
  typedef std::set< PrivateTag > PrivateTagsType;
  std::set< Tag > Tags;
  std::set< PrivateTag > PrivateTags;
  std::set< Tag > SkipTags;
  ValuesType Values;
  Directory::FilenamesType Filenames;

  // Main struct that will hold all mapping:
  MappingType Mappings;

  double Progress;
};
//-----------------------------------------------------------------------------
inline std::ostream& operator<<(std::ostream &os, const Scanner &s)
{
  s.Print( os );
  return os;
}

#if defined(SWIGPYTHON) || defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPHP)
/*
 * HACK: I need this temp class to be able to manipulate a std::map from python,
 * swig does not support wrapping of simple class like std::map...
 */
class SWIGTagToValue
{
public:
  SWIGTagToValue(Scanner::TagToValue const &t2v):Internal(t2v),it(t2v.begin()) {}
  const Scanner::TagToValueValueType& GetCurrent() const { return *it; }
  const Tag& GetCurrentTag() const { return it->first; }
  const char *GetCurrentValue() const { return it->second; }
  void Start() { it = Internal.begin(); }
  bool IsAtEnd() const { return it == Internal.end(); }
  void Next() { ++it; }
private:
  const Scanner::TagToValue& Internal;
  Scanner::TagToValue::const_iterator it;
};
#endif /* SWIG */

/**
 * \example ScanDirectory.cs
 * This is a C# example on how to use Scanner
 */

} // end namespace gdcm

#endif //GDCMSCANNER_H