GDCM 2.2.0

- Main Page
- Related Pages
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

gdcmDataElement.h
Go to the documentation of this file.

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