gdcmDataElement.h

Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program: GDCM (Grassroots DICOM). A DICOM library
00004   Module:  $URL$
00005 
00006   Copyright (c) 2006-2010 Mathieu Malaterre
00007   All rights reserved.
00008   See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 #ifndef GDCMDATAELEMENT_H
00016 #define GDCMDATAELEMENT_H
00017 
00018 #include "gdcmTag.h"
00019 #include "gdcmVL.h"
00020 #include "gdcmVR.h"
00021 #include "gdcmByteValue.h"
00022 #include "gdcmSmartPointer.h"
00023 
00024 #include <set>
00025 
00026 namespace gdcm
00027 {
00028 // Data Element
00029 // Contains multiple fields:
00030 // -> Tag
00031 // -> Optional VR (Explicit Transfer Syntax)
00032 // -> ValueLength
00033 // -> Value
00034 // TODO: This class SHOULD be pure virtual. I dont want a user
00035 // to shoot himself in the foot.
00036 
00037 class SequenceOfItems;
00038 class SequenceOfFragments;
00059 class GDCM_EXPORT DataElement
00060 {
00061 public:
00062   DataElement(const Tag& t = Tag(0), const VL& vl = 0, const VR &vr = VR::INVALID):TagField(t),ValueLengthField(vl),VRField(vr),ValueField(0) {}
00063   //DataElement( Attribute const &att );
00064 
00065   friend std::ostream& operator<<(std::ostream &_os, const DataElement &_val);
00066 
00068   const Tag& GetTag() const { return TagField; }
00069   Tag& GetTag() { return TagField; }
00072   void SetTag(const Tag &t) { TagField = t; }
00073 
00075   const VL& GetVL() const { return ValueLengthField; }
00076   VL& GetVL() { return ValueLengthField; }
00080   void SetVL(const VL &vl) { ValueLengthField = vl; }
00081   void SetVLToUndefined();
00082 
00085   VR const &GetVR() const { return VRField; }
00089   void SetVR(VR const &vr) {
00090     // assert( vr.IsVRFile() );
00091     VRField = vr;
00092   }
00093 
00095   Value const &GetValue() const { return *ValueField; }
00096   Value &GetValue() { return *ValueField; }
00098   void SetValue(Value const & vl) {
00099     //assert( ValueField == 0 );
00100     ValueField = vl;
00101     ValueLengthField = vl.GetLength();
00102   }
00104   bool IsEmpty() const { return ValueField == 0 || (GetByteValue() && GetByteValue()->IsEmpty()); }
00105 
00107   void Empty() { ValueField = 0; ValueLengthField = 0; }
00108 
00110   void Clear()
00111     {
00112     TagField = 0;
00113     VRField = VR::INVALID;
00114     ValueField = 0;
00115     ValueLengthField = 0;
00116     }
00117 
00118   // Helper:
00124   void SetByteValue(const char *array, VL length)
00125     {
00126     ByteValue *bv = new ByteValue(array,length);
00127     SetValue( *bv );
00128     }
00131   const ByteValue* GetByteValue() const {
00132     // Get the raw pointer from the gdcm::SmartPointer
00133     const ByteValue *bv = dynamic_cast<const ByteValue*>(ValueField.GetPointer());
00134     return bv; // Will return NULL if not ByteValue
00135   }
00136   ByteValue* GetByteValue() {
00137     // Get the raw pointer from the gdcm::SmartPointer
00138     ByteValue *bv = dynamic_cast<ByteValue*>(ValueField.GetPointer());
00139     return bv; // Will return NULL if not ByteValue
00140   }
00141 
00150   GDCM_LEGACY(const SequenceOfItems* GetSequenceOfItems() const)
00151   GDCM_LEGACY(SequenceOfItems* GetSequenceOfItems())
00152 
00159   SmartPointer<SequenceOfItems> GetValueAsSQ() const;
00160 
00163   const SequenceOfFragments* GetSequenceOfFragments() const;
00164 
00166   bool IsUndefinedLength() const {
00167     return ValueLengthField.IsUndefined();
00168   }
00169 
00170   DataElement(const DataElement &_val)
00171     {
00172     if( this != &_val)
00173       {
00174       *this = _val;
00175       }
00176     }
00177 
00178   bool operator<(const DataElement &de) const
00179     {
00180     return GetTag() < de.GetTag();
00181     }
00182   DataElement &operator=(const DataElement &de)
00183     {
00184     TagField = de.TagField;
00185     ValueLengthField = de.ValueLengthField;
00186     VRField = de.VRField;
00187     ValueField = de.ValueField; // Pointer copy
00188     return *this;
00189     }
00190 
00191   bool operator==(const DataElement &de) const
00192     {
00193     bool b = TagField == de.TagField
00194       && ValueLengthField == de.ValueLengthField
00195       && VRField == de.VRField;
00196     if( !ValueField && !de.ValueField )
00197       {
00198       return b;
00199       }
00200     if( ValueField && de.ValueField )
00201       {
00202       return b && (*ValueField == *de.ValueField);
00203       }
00204     // ValueField != de.ValueField
00205     return false;
00206     }
00207 
00208   // The following fonctionalities are dependant on:
00209   // # The Transfer Syntax: Explicit or Implicit
00210   // # The Byte encoding: Little Endian / Big Endian
00211 
00212   /*
00213    * The following was inspired by a C++ idiom: Curiously Recurring Template Pattern
00214    * Ref: http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern
00215    * The typename TDE is typically a derived class *without* any data
00216    * while TSwap is a simple template parameter to achieve byteswapping (and allow factorization of
00217    * highly identical code)
00218    */
00219   template <typename TDE>
00220   VL GetLength() const {
00221     return static_cast<const TDE*>(this)->GetLength();
00222   }
00223 
00224   template <typename TDE, typename TSwap>
00225   std::istream &Read(std::istream &is) {
00226     return static_cast<TDE*>(this)->template Read<TSwap>(is);
00227   }
00228 
00229   template <typename TDE, typename TSwap>
00230   std::istream &ReadOrSkip(std::istream &is, std::set<Tag> const &skiptags) {
00231     (void)skiptags;
00232     return static_cast<TDE*>(this)->template Read<TSwap>(is);
00233   }
00234 
00235   template <typename TDE, typename TSwap>
00236   std::istream &ReadWithLength(std::istream &is, VL &length) {
00237     return static_cast<TDE*>(this)->template ReadWithLength<TSwap>(is,length);
00238   }
00239 
00240   template <typename TDE, typename TSwap>
00241   const std::ostream &Write(std::ostream &os) const {
00242     return static_cast<const TDE*>(this)->template Write<TSwap>(os);
00243   }
00244 
00245 protected:
00246   Tag TagField;
00247   // This is the value read from the file, might be different from the length of Value Field
00248   VL ValueLengthField; // Can be 0xFFFFFFFF
00249 
00250   // Value Representation
00251   VR VRField;
00252   typedef SmartPointer<Value> ValuePtr;
00253   ValuePtr ValueField;
00254 };
00255 //-----------------------------------------------------------------------------
00256 inline std::ostream& operator<<(std::ostream &os, const DataElement &val)
00257 {
00258   os << val.TagField;
00259   os << "\t" << val.VRField;
00260   os << "\t" << val.ValueLengthField;
00261   if( val.ValueField )
00262     {
00263     val.ValueField->Print( os << "\t" );
00264     }
00265   return os;
00266 }
00267 
00268 } // end namespace gdcm
00269 
00270 #endif //GDCMDATAELEMENT_H
00271 

Generated on Sat Dec 4 2010 08:58:40 for GDCM by doxygen 1.7.2
SourceForge.net Logo