GDCM  2.4.0
gdcmDataElement.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: GDCM (Grassroots DICOM). A DICOM library
4 
5  Copyright (c) 2006-2011 Mathieu Malaterre
6  All rights reserved.
7  See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without even
10  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  PURPOSE. See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef GDCMDATAELEMENT_H
15 #define GDCMDATAELEMENT_H
16 
17 #include "gdcmTag.h"
18 #include "gdcmVL.h"
19 #include "gdcmVR.h"
20 #include "gdcmByteValue.h"
21 #include "gdcmSmartPointer.h"
22 
23 #include <set>
24 
25 namespace gdcm
26 {
27 // Data Element
28 // Contains multiple fields:
29 // -> Tag
30 // -> Optional VR (Explicit Transfer Syntax)
31 // -> ValueLength
32 // -> Value
33 // TODO: This class SHOULD be pure virtual. I dont want a user
34 // to shoot himself in the foot.
35 
36 class SequenceOfItems;
37 class SequenceOfFragments;
59 {
60 public:
61  DataElement(const Tag& t = Tag(0), const VL& vl = 0, const VR &vr = VR::INVALID):TagField(t),ValueLengthField(vl),VRField(vr),ValueField(0) {}
62  //DataElement( Attribute const &att );
63 
64  friend std::ostream& operator<<(std::ostream &_os, const DataElement &_val);
65 
67  const Tag& GetTag() const { return TagField; }
68  Tag& GetTag() { return TagField; }
71  void SetTag(const Tag &t) { TagField = t; }
72 
74  const VL& GetVL() const { return ValueLengthField; }
75  VL& GetVL() { return ValueLengthField; }
79  void SetVL(const VL &vl) { ValueLengthField = vl; }
80  void SetVLToUndefined();
81 
84  VR const &GetVR() const { return VRField; }
88  void SetVR(VR const &vr) {
89  if( vr.IsVRFile() )
90  VRField = vr;
91  }
92 
94  Value const &GetValue() const { return *ValueField; }
95  Value &GetValue() { return *ValueField; }
97  void SetValue(Value const & vl) {
98  //assert( ValueField == 0 );
99  ValueField = vl;
100  ValueLengthField = vl.GetLength();
101  }
103  bool IsEmpty() const { return ValueField == 0 || (GetByteValue() && GetByteValue()->IsEmpty()); }
104 
106  void Empty() { ValueField = 0; ValueLengthField = 0; }
107 
109  void Clear()
110  {
111  TagField = 0;
112  VRField = VR::INVALID;
113  ValueField = 0;
114  ValueLengthField = 0;
115  }
116 
117  // Helper:
123  void SetByteValue(const char *array, VL length)
124  {
125  ByteValue *bv = new ByteValue(array,length);
126  SetValue( *bv );
127  }
130  const ByteValue* GetByteValue() const {
131  // Get the raw pointer from the gdcm::SmartPointer
132  const ByteValue *bv = dynamic_cast<const ByteValue*>(ValueField.GetPointer());
133  return bv; // Will return NULL if not ByteValue
134  }
135 
142  SmartPointer<SequenceOfItems> GetValueAsSQ() const;
143 
146  const SequenceOfFragments* GetSequenceOfFragments() const;
147  SequenceOfFragments* GetSequenceOfFragments();
148 
150  bool IsUndefinedLength() const {
151  return ValueLengthField.IsUndefined();
152  }
153 
155  {
156  if( this != &_val)
157  {
158  *this = _val;
159  }
160  }
161 
162  bool operator<(const DataElement &de) const
163  {
164  return GetTag() < de.GetTag();
165  }
167  {
168  TagField = de.TagField;
169  ValueLengthField = de.ValueLengthField;
170  VRField = de.VRField;
171  ValueField = de.ValueField; // Pointer copy
172  return *this;
173  }
174 
175  bool operator==(const DataElement &de) const
176  {
177  bool b = TagField == de.TagField
178  && ValueLengthField == de.ValueLengthField
179  && VRField == de.VRField;
180  if( !ValueField && !de.ValueField )
181  {
182  return b;
183  }
184  if( ValueField && de.ValueField )
185  {
186  return b && (*ValueField == *de.ValueField);
187  }
188  // ValueField != de.ValueField
189  return false;
190  }
191 
192  // The following fonctionalities are dependant on:
193  // # The Transfer Syntax: Explicit or Implicit
194  // # The Byte encoding: Little Endian / Big Endian
195 
196  /*
197  * The following was inspired by a C++ idiom: Curiously Recurring Template Pattern
198  * Ref: http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern
199  * The typename TDE is typically a derived class *without* any data
200  * while TSwap is a simple template parameter to achieve byteswapping (and allow factorization of
201  * highly identical code)
202  */
203  template <typename TDE>
204  VL GetLength() const {
205  return static_cast<const TDE*>(this)->GetLength();
206  }
207 
208  template <typename TDE, typename TSwap>
209  std::istream &Read(std::istream &is) {
210  return static_cast<TDE*>(this)->template Read<TSwap>(is);
211  }
212 
213  template <typename TDE, typename TSwap>
214  std::istream &ReadOrSkip(std::istream &is, std::set<Tag> const &skiptags) {
215  (void)skiptags;
216  return static_cast<TDE*>(this)->template Read<TSwap>(is);
217  }
218 
219  template <typename TDE, typename TSwap>
220  std::istream &ReadPreValue(std::istream &is, std::set<Tag> const &skiptags) {
221  (void)skiptags;
222  return static_cast<TDE*>(this)->template ReadPreValue<TSwap>(is);
223  }
224  template <typename TDE, typename TSwap>
225  std::istream &ReadValue(std::istream &is, std::set<Tag> const &skiptags) {
226  (void)skiptags;
227  return static_cast<TDE*>(this)->template ReadValue<TSwap>(is);
228  }
229  template <typename TDE, typename TSwap>
230  std::istream &ReadValueWithLength(std::istream &is, VL & length, std::set<Tag> const &skiptags) {
231  (void)skiptags;
232  return static_cast<TDE*>(this)->template ReadValueWithLength<TSwap>(is, length);
233  }
234 
235  template <typename TDE, typename TSwap>
236  std::istream &ReadWithLength(std::istream &is, VL &length) {
237  return static_cast<TDE*>(this)->template ReadWithLength<TSwap>(is,length);
238  }
239 
240  template <typename TDE, typename TSwap>
241  const std::ostream &Write(std::ostream &os) const {
242  return static_cast<const TDE*>(this)->template Write<TSwap>(os);
243  }
244 
245 protected:
247  // This is the value read from the file, might be different from the length of Value Field
248  VL ValueLengthField; // Can be 0xFFFFFFFF
249 
250  // Value Representation
254 
255  void SetValueFieldLength( VL vl, bool readvalues );
256 };
257 //-----------------------------------------------------------------------------
258 inline std::ostream& operator<<(std::ostream &os, const DataElement &val)
259 {
260  os << val.TagField;
261  os << "\t" << val.VRField;
262  os << "\t" << val.ValueLengthField;
263  if( val.ValueField )
264  {
265  val.ValueField->Print( os << "\t" );
266  }
267  return os;
268 }
269 
270 inline bool operator!=(const DataElement& lhs, const DataElement& rhs)
271 {
272  return ! ( lhs == rhs );
273 }
274 
275 } // end namespace gdcm
276 
277 #endif //GDCMDATAELEMENT_H

Generated on Thu Oct 17 2013 10:05:56 for GDCM by doxygen 1.8.4
SourceForge.net Logo