GDCM  2.0.18
gdcmAttribute.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 GDCMATTRIBUTE_H
00015 #define GDCMATTRIBUTE_H
00016 
00017 #include "gdcmTypes.h"
00018 #include "gdcmVR.h"
00019 #include "gdcmTagToType.h"
00020 #include "gdcmVM.h"
00021 #include "gdcmElement.h"
00022 #include "gdcmDataElement.h"
00023 #include "gdcmDataSet.h"
00024 #include "gdcmStaticAssert.h"
00025 
00026 #include <string>
00027 #include <vector>
00028 #include <sstream>
00029 
00030 namespace gdcm
00031 {
00032 
00033 struct void_;
00034 
00035 // Declaration, also serve as forward declaration
00036 template<int T> class VRVLSize;
00037 
00038 // Implementation when VL is coded on 16 bits:
00039 template<> class VRVLSize<0> {
00040 public:
00041   static inline uint16_t Read(std::istream &_is) {
00042     uint16_t l;
00043     _is.read((char*)&l, 2);
00044     return l;
00045     }
00046 
00047   static inline void Write(std::ostream &os)  { (void)os;
00048     }
00049 };
00050 // Implementation when VL is coded on 32 bits:
00051 template<> class VRVLSize<1> {
00052 public:
00053   static inline uint32_t Read(std::istream &_is) {
00054     char dummy[2];
00055     _is.read(dummy, 2);
00056 
00057     uint32_t l;
00058     _is.read((char*)&l, 4);
00059     return l;
00060     }
00061 
00062   static inline void Write(std::ostream &os)  { (void)os;
00063     }
00064 };
00065 
00081 template<uint16_t Group, uint16_t Element,
00082    int TVR = TagToType<Group, Element>::VRType, // can the user override this value ?
00083    int TVM = TagToType<Group, Element>::VMType // can the user override this value ?
00084    /*typename SQAttribute = void_*/ > // if only I had variadic template...
00085 class Attribute
00086 {
00087 public:
00088   typedef typename VRToType<TVR>::Type ArrayType;
00089   enum { VMType = VMToLength<TVM>::Length };
00090   ArrayType Internal[VMToLength<TVM>::Length];
00091 
00092   // Make sure that user specified VR/VM are compatible with the public dictionary:
00093   GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
00094   GDCM_STATIC_ASSERT( ((VM::VMType)TVM & (VM::VMType)(TagToType<Group, Element>::VMType)) );
00095   GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TVM == VM::VM1) )
00096                     || !((VR::VRType)TVR & VR::VR_VM1) ) );
00097 
00098   static Tag GetTag() { return Tag(Group,Element); }
00099   static VR  GetVR()  { return (VR::VRType)TVR; }
00100   static VM  GetVM()  { return (VM::VMType)TVM; }
00101 
00102   // The following two methods do make sense only in case of public element,
00103   // when the template is intanciated with private element the VR/VM are simply
00104   // defaulted to allow everything (see gdcmTagToType.h default template for TagToType)
00105   static VR  GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
00106   static VM  GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); }
00107 
00108   // Some extra dummy checks:
00109   // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
00110 
00111   unsigned int GetNumberOfValues() const {
00112     return VMToLength<TVM>::Length;
00113   }
00114   // Implementation of Print is common to all Mode (ASCII/Binary)
00115   // TODO: Can we print a \ when in ASCII...well I don't think so
00116   // it would mean we used a bad VM then, right ?
00117   void Print(std::ostream &os) const {
00118     os << GetTag() << " ";
00119     os << TagToType<Group,Element>::GetVRString()  << " ";
00120     os << TagToType<Group,Element>::GetVMString()  << " ";
00121     os << Internal[0]; // VM is at least garantee to be one
00122     for(unsigned int i=1; i<GetNumberOfValues(); ++i)
00123       os << "," << Internal[i];
00124     }
00125 
00126   // copy:
00127   //ArrayType GetValue(unsigned int idx = 0) {
00128   //  assert( idx < GetNumberOfValues() );
00129   //  return Internal[idx];
00130   //}
00131   //ArrayType operator[] (unsigned int idx) {
00132   //  return GetValue(idx);
00133   //}
00134   // FIXME: is this always a good idea ?
00135   // I do not think so, I prefer operator
00136   //operator ArrayType () const { return Internal[0]; }
00137 
00138   bool operator==(const Attribute &att) const
00139     {
00140     return std::equal(Internal, Internal+GetNumberOfValues(),
00141       att.GetValues());
00142     }
00143   bool operator!=(const Attribute &att) const
00144     {
00145     return !std::equal(Internal, Internal+GetNumberOfValues(),
00146       att.GetValues());
00147     }
00148   bool operator<(const Attribute &att) const
00149     {
00150     return std::lexicographical_compare(Internal, Internal+GetNumberOfValues(),
00151       att.GetValues(), att.GetValues() + att.GetNumberOfValues() );
00152     }
00153 
00154   ArrayType &GetValue(unsigned int idx = 0) {
00155     assert( idx < GetNumberOfValues() );
00156     return Internal[idx];
00157   }
00158   ArrayType & operator[] (unsigned int idx) {
00159     return GetValue(idx);
00160   }
00161   // const reference
00162   ArrayType const &GetValue(unsigned int idx = 0) const {
00163     assert( idx < GetNumberOfValues() );
00164     return Internal[idx];
00165   }
00166   ArrayType const & operator[] (unsigned int idx) const {
00167     return GetValue(idx);
00168   }
00169   void SetValue(ArrayType v, unsigned int idx = 0) {
00170     assert( idx < GetNumberOfValues() );
00171     Internal[idx] = v;
00172   }
00173   void SetValues(const ArrayType* array, unsigned int numel = VMType ) {
00174     assert( array && numel && numel == GetNumberOfValues() );
00175     // std::copy is smarted than a memcpy, and will call memcpy when POD type
00176     std::copy(array, array+numel, Internal);
00177   }
00178   const ArrayType* GetValues() const {
00179     return Internal;
00180   }
00181 
00182   // API to talk to the run-time layer: gdcm::DataElement
00183   DataElement GetAsDataElement() const {
00184     DataElement ret( GetTag() );
00185     std::ostringstream os;
00186     // os.imbue(std::locale::classic()); // This is not required AFAIK
00187     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00188       GetNumberOfValues(),os);
00189     ret.SetVR( GetVR() );
00190     assert( ret.GetVR() != VR::SQ );
00191     if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00192       {
00193       if( GetVR() != VR::UI )
00194         {
00195         if( os.str().size() % 2 )
00196           {
00197           os << " ";
00198           }
00199         }
00200       }
00201     VL::Type osStrSize = (VL::Type)os.str().size();
00202     ret.SetByteValue( os.str().c_str(), osStrSize );
00203     return ret;
00204   }
00205 
00206   void SetFromDataElement(DataElement const &de) {
00207     // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
00208     assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 );
00209     assert( GetVR() != VR::INVALID );
00210     assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator
00211     if( de.IsEmpty() ) return;
00212     const ByteValue *bv = de.GetByteValue();
00213 #ifdef GDCM_WORDS_BIGENDIAN
00214     if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
00215 #else
00216     if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
00217 #endif
00218       {
00219       SetByteValue(bv);
00220       }
00221     else
00222       {
00223       SetByteValueNoSwap(bv);
00224       }
00225   }
00226   void Set(DataSet const &ds) {
00227     SetFromDataElement( ds.GetDataElement( GetTag() ) );
00228   }
00229   void SetFromDataSet(DataSet const &ds) {
00230     if( ds.FindDataElement( GetTag() ) &&
00231       !ds.GetDataElement( GetTag() ).IsEmpty() )
00232       {
00233       SetFromDataElement( ds.GetDataElement( GetTag() ) );
00234       }
00235   }
00236 protected:
00237   void SetByteValueNoSwap(const ByteValue *bv) {
00238     if( !bv ) return; // That would be bad...
00239     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00240     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00241     //  {
00242     //  // always do a copy !
00243     //  SetValues(bv->GetPointer(), bv->GetLength());
00244     //  }
00245     //else
00246       {
00247       std::stringstream ss;
00248       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00249       ss.str( s );
00250       EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(Internal,
00251         GetNumberOfValues(),ss);
00252       }
00253   }
00254   void SetByteValue(const ByteValue *bv) {
00255     if( !bv ) return; // That would be bad...
00256     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00257     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00258     //  {
00259     //  // always do a copy !
00260     //  SetValues(bv->GetPointer(), bv->GetLength());
00261     //  }
00262     //else
00263       {
00264       std::stringstream ss;
00265       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00266       ss.str( s );
00267       EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00268         GetNumberOfValues(),ss);
00269       }
00270   }
00271 #if 0 // TODO  FIXME the implicit way:
00272   // explicit:
00273   void Read(std::istream &_is) {
00274     const uint16_t cref[] = { Group, Element };
00275     uint16_t c[2];
00276     _is.read((char*)&c, sizeof(c));
00277     assert( c[0] == cref[0] && c[1] == cref[1] );
00278     char vr[2];
00279     _is.read(vr, 2); // Check consistency ?
00280     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00281     uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is);
00282     l /= sizeof( typename VRToType<TVR>::Type );
00283     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00284       l,_is);
00285   }
00286   void Write(std::ostream &_os) const {
00287     uint16_t c[] = { Group, Element };
00288     _os.write((char*)&c, 4);
00289     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00290     _os.write((char*)&l, 4);
00291     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00292       GetLength(),_os);
00293     }
00294   void Read(std::istream &_is) {
00295     uint16_t cref[] = { Group, Element };
00296     uint16_t c[2];
00297     _is.read((char*)&c, 4);
00298     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00299     uint32_t l;
00300     _is.read((char*)&l, 4);
00301     l /= sizeof( typename VRToType<TVR>::Type );
00302      return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00303       l,_is);
00304     }
00305   void Write(std::ostream &_os) const {
00306     uint16_t c[] = { Group, Element };
00307     _os.write((char*)&c, 4);
00308     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00309     _os.write((char*)&l, 4);
00310     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00311       GetLength(),_os);
00312     }
00313 #endif
00314 
00315 };
00316 
00317 template<uint16_t Group, uint16_t Element, int TVR >
00318 class Attribute<Group,Element,TVR,VM::VM1>
00319 {
00320 public:
00321   typedef typename VRToType<TVR>::Type ArrayType;
00322   enum { VMType = VMToLength<VM::VM1>::Length };
00323   //ArrayType Internal[VMToLength<TVM>::Length];
00324   ArrayType Internal;
00325   GDCM_STATIC_ASSERT( VMToLength<VM::VM1>::Length == 1 );
00326 
00327   // Make sure that user specified VR/VM are compatible with the public dictionary:
00328   GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
00329   GDCM_STATIC_ASSERT( ((VM::VMType)VM::VM1 & (VM::VMType)(TagToType<Group, Element>::VMType)) );
00330   GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)VM::VM1 == VM::VM1) )
00331                     || !((VR::VRType)TVR & VR::VR_VM1) ) );
00332 
00333   static Tag GetTag() { return Tag(Group,Element); }
00334   static VR  GetVR()  { return (VR::VRType)TVR; }
00335   static VM  GetVM()  { return (VM::VMType)VM::VM1; }
00336 
00337   // The following two methods do make sense only in case of public element,
00338   // when the template is intanciated with private element the VR/VM are simply
00339   // defaulted to allow everything (see gdcmTagToType.h default template for TagToType)
00340   static VR  GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
00341   static VM  GetDictVM() { return (VM::VMType)(TagToType<Group, Element>::VMType); }
00342 
00343   // Some extra dummy checks:
00344   // Data Elements with a VR of SQ, OF, OW, OB or UN shall always have a Value Multiplicity of one.
00345 
00346   unsigned int GetNumberOfValues() const {
00347     return VMToLength<VM::VM1>::Length;
00348   }
00349   // Implementation of Print is common to all Mode (ASCII/Binary)
00350   // TODO: Can we print a \ when in ASCII...well I don't think so
00351   // it would mean we used a bad VM then, right ?
00352   void Print(std::ostream &os) const {
00353     os << GetTag() << " ";
00354     os << TagToType<Group,Element>::GetVRString()  << " ";
00355     os << TagToType<Group,Element>::GetVMString()  << " ";
00356     os << Internal; // VM is at least garantee to be one
00357   }
00358   // copy:
00359   //ArrayType GetValue(unsigned int idx = 0) {
00360   //  assert( idx < GetNumberOfValues() );
00361   //  return Internal[idx];
00362   //}
00363   //ArrayType operator[] (unsigned int idx) {
00364   //  return GetValue(idx);
00365   //}
00366   // FIXME: is this always a good idea ?
00367   // I do not think so, I prefer operator
00368   //operator ArrayType () const { return Internal[0]; }
00369 
00370   bool operator==(const Attribute &att) const
00371     {
00372     return std::equal(&Internal, &Internal+GetNumberOfValues(),
00373       att.GetValues());
00374     }
00375   bool operator!=(const Attribute &att) const
00376     {
00377     return !std::equal(&Internal, &Internal+GetNumberOfValues(),
00378       att.GetValues());
00379     }
00380   bool operator<(const Attribute &att) const
00381     {
00382     return std::lexicographical_compare(&Internal, &Internal+GetNumberOfValues(),
00383       att.GetValues(), att.GetValues() + att.GetNumberOfValues() );
00384     }
00385 
00386   ArrayType &GetValue() {
00387 //    assert( idx < GetNumberOfValues() );
00388     return Internal;
00389   }
00390 //  ArrayType & operator[] (unsigned int idx) {
00391 //    return GetValue(idx);
00392 //  }
00393   // const reference
00394   ArrayType const &GetValue() const {
00395     //assert( idx < GetNumberOfValues() );
00396     return Internal;
00397   }
00398   //ArrayType const & operator[] () const {
00399   //  return GetValue();
00400   //}
00401   void SetValue(ArrayType v) {
00402 //    assert( idx < GetNumberOfValues() );
00403     Internal = v;
00404   }
00405 /*  void SetValues(const ArrayType* array, unsigned int numel = VMType ) {
00406     assert( array && numel && numel == GetNumberOfValues() );
00407     // std::copy is smarted than a memcpy, and will call memcpy when POD type
00408     std::copy(array, array+numel, Internal);
00409   }
00410 */
00411 
00412   // FIXME Should we remove this function ?
00413   const ArrayType* GetValues() const {
00414     return &Internal;
00415   }
00416 
00417   // API to talk to the run-time layer: gdcm::DataElement
00418   DataElement GetAsDataElement() const {
00419     DataElement ret( GetTag() );
00420     std::ostringstream os;
00421     // os.imbue(std::locale::classic()); // This is not required AFAIK
00422     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(&Internal,
00423       GetNumberOfValues(),os);
00424     ret.SetVR( GetVR() );
00425     assert( ret.GetVR() != VR::SQ );
00426     if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00427       {
00428       if( GetVR() != VR::UI )
00429         {
00430         if( os.str().size() % 2 )
00431           {
00432           os << " ";
00433           }
00434         }
00435       }
00436     VL::Type osStrSize = (VL::Type)os.str().size();
00437     ret.SetByteValue( os.str().c_str(), osStrSize );
00438     return ret;
00439   }
00440 
00441   void SetFromDataElement(DataElement const &de) {
00442     // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
00443     assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 || GetTag().GetGroup() == 0x5000 );
00444     assert( GetVR() != VR::INVALID );
00445     assert( GetVR().Compatible( de.GetVR() ) || de.GetVR() == VR::INVALID ); // In case of VR::INVALID cannot use the & operator
00446     if( de.IsEmpty() ) return;
00447     const ByteValue *bv = de.GetByteValue();
00448 #ifdef GDCM_WORDS_BIGENDIAN
00449     if( de.GetVR() == VR::UN /*|| de.GetVR() == VR::INVALID*/ )
00450 #else
00451     if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
00452 #endif
00453       {
00454       SetByteValue(bv);
00455       }
00456     else
00457       {
00458       SetByteValueNoSwap(bv);
00459       }
00460   }
00461   void Set(DataSet const &ds) {
00462     SetFromDataElement( ds.GetDataElement( GetTag() ) );
00463   }
00464   void SetFromDataSet(DataSet const &ds) {
00465     if( ds.FindDataElement( GetTag() ) &&
00466       !ds.GetDataElement( GetTag() ).IsEmpty() )
00467       {
00468       SetFromDataElement( ds.GetDataElement( GetTag() ) );
00469       }
00470   }
00471 protected:
00472   void SetByteValueNoSwap(const ByteValue *bv) {
00473     if( !bv ) return; // That would be bad...
00474     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00475     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00476     //  {
00477     //  // always do a copy !
00478     //  SetValues(bv->GetPointer(), bv->GetLength());
00479     //  }
00480     //else
00481       {
00482       std::stringstream ss;
00483       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00484       ss.str( s );
00485       EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(&Internal,
00486         GetNumberOfValues(),ss);
00487       }
00488   }
00489   void SetByteValue(const ByteValue *bv) {
00490     if( !bv ) return; // That would be bad...
00491     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00492     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00493     //  {
00494     //  // always do a copy !
00495     //  SetValues(bv->GetPointer(), bv->GetLength());
00496     //  }
00497     //else
00498       {
00499       std::stringstream ss;
00500       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00501       ss.str( s );
00502       EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(&Internal,
00503         GetNumberOfValues(),ss);
00504       }
00505   }
00506 #if 0 // TODO  FIXME the implicit way:
00507   // explicit:
00508   void Read(std::istream &_is) {
00509     const uint16_t cref[] = { Group, Element };
00510     uint16_t c[2];
00511     _is.read((char*)&c, sizeof(c));
00512     assert( c[0] == cref[0] && c[1] == cref[1] );
00513     char vr[2];
00514     _is.read(vr, 2); // Check consistency ?
00515     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00516     uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is);
00517     l /= sizeof( typename VRToType<TVR>::Type );
00518     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00519       l,_is);
00520   }
00521   void Write(std::ostream &_os) const {
00522     uint16_t c[] = { Group, Element };
00523     _os.write((char*)&c, 4);
00524     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00525     _os.write((char*)&l, 4);
00526     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00527       GetLength(),_os);
00528     }
00529   void Read(std::istream &_is) {
00530     uint16_t cref[] = { Group, Element };
00531     uint16_t c[2];
00532     _is.read((char*)&c, 4);
00533     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00534     uint32_t l;
00535     _is.read((char*)&l, 4);
00536     l /= sizeof( typename VRToType<TVR>::Type );
00537      return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00538       l,_is);
00539     }
00540   void Write(std::ostream &_os) const {
00541     uint16_t c[] = { Group, Element };
00542     _os.write((char*)&c, 4);
00543     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00544     _os.write((char*)&l, 4);
00545     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00546       GetLength(),_os);
00547     }
00548 #endif
00549 
00550 };
00551 
00552 // No need to repeat default template arg, since primary template
00553 // will be used to generate the default arguments
00554 template<uint16_t Group, uint16_t Element, int TVR >
00555 class Attribute<Group,Element,TVR,VM::VM1_n>
00556 {
00557 public:
00558   typedef typename VRToType<TVR>::Type ArrayType;
00559 
00560   // Make sure that user specified VR/VM are compatible with the public dictionary:
00561   GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
00562   GDCM_STATIC_ASSERT( (VM::VM1_n & (VM::VMType)(TagToType<Group, Element>::VMType)) );
00563   GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TagToType<Group,Element>::VMType == VM::VM1) )
00564                     || !((VR::VRType)TVR & VR::VR_VM1) ) );
00565 
00566   static Tag GetTag() { return Tag(Group,Element); }
00567   static VR  GetVR()  { return (VR::VRType)TVR; }
00568   static VM  GetVM()  { return VM::VM1_n; }
00569 
00570   static VR  GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
00571   static VM  GetDictVM() { return GetVM(); }
00572 
00573   // This the way to prevent default initialization
00574   explicit Attribute() { Internal=0; Length=0; Own = true; }
00575   ~Attribute() {
00576     if( Own ) {
00577       delete[] Internal;
00578     }
00579     Internal = 0; // paranoid
00580   }
00581 
00582   unsigned int GetNumberOfValues() const { return Length; }
00583 
00584   void SetNumberOfValues(unsigned int numel)
00585     {
00586     SetValues(NULL, numel, true);
00587     }
00588 
00589   const ArrayType* GetValues() const {
00590     return Internal;
00591   }
00592   void Print(std::ostream &os) const {
00593     os << GetTag() << " ";
00594     os << GetVR()  << " ";
00595     os << GetVM()  << " ";
00596     os << Internal[0]; // VM is at least garantee to be one
00597     for(unsigned int i=1; i<GetNumberOfValues(); ++i)
00598       os << "," << Internal[i];
00599     }
00600   ArrayType &GetValue(unsigned int idx = 0) {
00601     assert( idx < GetNumberOfValues() );
00602     return Internal[idx];
00603   }
00604   ArrayType &operator[] (unsigned int idx) {
00605     return GetValue(idx);
00606   }
00607   // const reference
00608   ArrayType const &GetValue(unsigned int idx = 0) const {
00609     assert( idx < GetNumberOfValues() );
00610     return Internal[idx];
00611   }
00612   ArrayType const & operator[] (unsigned int idx) const {
00613     return GetValue(idx);
00614   }
00615   void SetValue(unsigned int idx, ArrayType v) {
00616     assert( idx < GetNumberOfValues() );
00617     Internal[idx] = v;
00618   }
00619   void SetValue(ArrayType v) { SetValue(0, v); }
00620 
00621   void SetValues(const ArrayType *array, unsigned int numel, bool own = false)
00622     {
00623     if( Internal ) // were we used before ?
00624       {
00625       // yes !
00626       if( Own ) delete[] Internal;
00627       Internal = 0;
00628       }
00629     Own = own;
00630     Length = numel;
00631     assert( Internal == 0 );
00632     if( own ) // make a copy:
00633       {
00634       assert( /*array &&*/ numel );
00635       Internal = new ArrayType[numel];
00636       if( array && numel )
00637         std::copy(array, array+numel, Internal);
00638       }
00639     else // pass pointer
00640       {
00641       Internal = const_cast<ArrayType*>(array);
00642       }
00643     // postcondition
00644     assert( numel == GetNumberOfValues() );
00645     }
00646 
00647   DataElement GetAsDataElement() const {
00648     DataElement ret( GetTag() );
00649     std::ostringstream os;
00650     if( Internal )
00651       {
00652       EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00653         GetNumberOfValues(),os);
00654       if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00655         {
00656         if( GetVR() != VR::UI )
00657           {
00658           if( os.str().size() % 2 )
00659             {
00660             os << " ";
00661             }
00662           }
00663         }
00664       }
00665     ret.SetVR( GetVR() );
00666     assert( ret.GetVR() != VR::SQ );
00667     VL::Type osStrSize = (VL::Type) os.str().size();
00668     ret.SetByteValue( os.str().c_str(), osStrSize);
00669     return ret;
00670   }
00671   void SetFromDataElement(DataElement const &de) {
00672     // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
00673     assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 );
00674     assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator
00675     assert( !de.IsEmpty() );
00676     const ByteValue *bv = de.GetByteValue();
00677     SetByteValue(bv);
00678   }
00679 protected:
00680   void SetByteValue(const ByteValue *bv) {
00681     assert( bv ); // FIXME
00682     std::stringstream ss;
00683     std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00684     Length = bv->GetLength(); // HACK FIXME
00685     ss.str( s );
00686     ArrayType *internal;
00687     ArrayType buffer[256];
00688     if( bv->GetLength() < 256 )
00689       {
00690       internal = buffer;
00691       }
00692     else
00693       {
00694       internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation
00695       }
00696     EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss);
00697     SetValues( internal, Length, true );
00698     if( !(bv->GetLength() < 256) )
00699       {
00700       delete[] internal;
00701       }
00702     //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00703     //  GetNumberOfValues(),ss);
00704   }
00705 
00706 private:
00707   ArrayType *Internal;
00708   unsigned int Length;
00709   bool Own : 1;
00710 };
00711 
00712 template<uint16_t Group, uint16_t Element, int TVR>
00713 class Attribute<Group,Element,TVR,VM::VM1_3> : public Attribute<Group,Element,TVR,VM::VM1_n>
00714 {
00715 public:
00716   VM  GetVM() const { return VM::VM1_3; }
00717 };
00718 
00719 template<uint16_t Group, uint16_t Element, int TVR>
00720 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n>
00721 {
00722 public:
00723   VM  GetVM() const { return VM::VM1_8; }
00724 };
00725 
00726 template<uint16_t Group, uint16_t Element, int TVR>
00727 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00728 {
00729 public:
00730   VM  GetVM() const { return VM::VM2_n; }
00731 };
00732 
00733 template<uint16_t Group, uint16_t Element, int TVR>
00734 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n>
00735 {
00736 public:
00737   static VM  GetVM() { return VM::VM2_2n; }
00738 };
00739 
00740 template<uint16_t Group, uint16_t Element, int TVR>
00741 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00742 {
00743 public:
00744   static VM  GetVM() { return VM::VM3_n; }
00745 };
00746 
00747 template<uint16_t Group, uint16_t Element, int TVR>
00748 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n>
00749 {
00750 public:
00751   static VM  GetVM() { return VM::VM3_3n; }
00752 };
00753 
00754 
00755 // For particular case for ASCII string
00756 // WARNING: This template explicitely instanciates a particular
00757 // EncodingImplementation THEREFORE it is required to be declared after the
00758 // EncodingImplementation is needs (doh!)
00759 #if 0
00760 template<int TVM>
00761 class Attribute<TVM>
00762 {
00763 public:
00764   Attribute(const char array[])
00765     {
00766     unsigned int i = 0;
00767     const char sep = '\\';
00768     std::string sarray = array;
00769     std::string::size_type pos1 = 0;
00770     std::string::size_type pos2 = sarray.find(sep, pos1+1);
00771     while(pos2 != std::string::npos)
00772       {
00773       Internal[i++] = sarray.substr(pos1, pos2-pos1);
00774       pos1 = pos2+1;
00775       pos2 = sarray.find(sep, pos1+1);
00776       }
00777     Internal[i] = sarray.substr(pos1, pos2-pos1);
00778     // Shouldn't we do the contrary, since we know how many separators
00779     // (and default behavior is to discard anything after the VM declared
00780     assert( GetLength()-1 == i );
00781     }
00782 
00783   unsigned long GetLength() const {
00784     return VMToLength<TVM>::Length;
00785   }
00786   // Implementation of Print is common to all Mode (ASCII/Binary)
00787   void Print(std::ostream &_os) const {
00788     _os << Internal[0]; // VM is at least garantee to be one
00789     for(int i=1; i<VMToLength<TVM>::Length; ++i)
00790       _os << "," << Internal[i];
00791     }
00792 
00793   void Read(std::istream &_is) {
00794     EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
00795     }
00796   void Write(std::ostream &_os) const {
00797     EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
00798     }
00799 private:
00800   typename String Internal[VMToLength<TVM>::Length];
00801 };
00802 
00803 template< int TVM>
00804 class Attribute<VR::PN, TVM> : public StringAttribute<TVM>
00805 {
00806 };
00807 #endif
00808 
00809 #if 0
00810 
00811 // Implementation for the undefined length (dynamically allocated array)
00812 template<int TVR>
00813 class Attribute<TVR, VM::VM1_n>
00814 {
00815 public:
00816   // This the way to prevent default initialization
00817   explicit Attribute() { Internal=0; Length=0; }
00818   ~Attribute() {
00819     delete[] Internal;
00820     Internal = 0;
00821   }
00822 
00823   // Length manipulation
00824   // SetLength should really be protected anyway...all operation
00825   // should go through SetArray
00826   unsigned long GetLength() const { return Length; }
00827   typedef typename VRToType<TVR>::Type ArrayType;
00828   void SetLength(unsigned long len) {
00829     const unsigned int size = sizeof(ArrayType);
00830     if( len ) {
00831       if( len > Length ) {
00832         // perform realloc
00833         assert( (len / size) * size == len );
00834         ArrayType *internal = new ArrayType[len / size];
00835         memcpy(internal, Internal, Length * size);
00836         delete[] Internal;
00837         Internal = internal;
00838         }
00839       }
00840     Length = len / size;
00841   }
00842 
00843   // If save is set to zero user should not delete the pointer
00844   //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false)
00845   void SetArray(const ArrayType *array, unsigned long len,
00846     bool save = false) {
00847     if( save ) {
00848       SetLength(len); // realloc
00849       memcpy(Internal, array, len/*/sizeof(ArrayType)*/);
00850       }
00851     else {
00852       // TODO rewrite this stupid code:
00853       Length = len;
00854       //Internal = array;
00855       assert(0);
00856       }
00857   }
00858   // Implementation of Print is common to all Mode (ASCII/Binary)
00859   void Print(std::ostream &_os) const {
00860     assert( Length );
00861     assert( Internal );
00862     _os << Internal[0]; // VM is at least garantee to be one
00863     const unsigned long length = GetLength() < 25 ? GetLength() : 25;
00864     for(unsigned long i=1; i<length; ++i)
00865       _os << "," << Internal[i];
00866     }
00867   void Read(std::istream &_is) {
00868     EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00869       GetLength(),_is);
00870     }
00871   void Write(std::ostream &_os) const {
00872     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00873       GetLength(),_os);
00874     }
00875 
00876   Attribute(const Attribute&_val) {
00877     if( this != &_val) {
00878       *this = _val;
00879       }
00880     }
00881 
00882   Attribute &operator=(const Attribute &_val) {
00883     Length = 0; // SYITF
00884     Internal = 0;
00885     SetArray(_val.Internal, _val.Length, true);
00886     return *this;
00887     }
00888 
00889 private:
00890   typename VRToType<TVR>::Type *Internal;
00891   unsigned long Length; // unsigned int ??
00892 };
00893 
00894 //template <int TVM = VM::VM1_n>
00895 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {};
00896 
00897 // Partial specialization for derivatives of 1-n : 2-n, 3-n ...
00898 template<int TVR>
00899 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n>
00900 {
00901 public:
00902   typedef Attribute<TVR, VM::VM1_n> Parent;
00903   void SetLength(int len) {
00904     if( len <= 1 ) return;
00905     Parent::SetLength(len);
00906   }
00907 };
00908 template<int TVR>
00909 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n>
00910 {
00911 public:
00912   typedef Attribute<TVR, VM::VM2_n> Parent;
00913   void SetLength(int len) {
00914     if( len % 2 ) return;
00915     Parent::SetLength(len);
00916   }
00917 };
00918 template<int TVR>
00919 class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n>
00920 {
00921 public:
00922   typedef Attribute<TVR, VM::VM1_n> Parent;
00923   void SetLength(int len) {
00924     if( len <= 2 ) return;
00925     Parent::SetLength(len);
00926   }
00927 };
00928 template<int TVR>
00929 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n>
00930 {
00931 public:
00932   typedef Attribute<TVR, VM::VM3_n> Parent;
00933   void SetLength(int len) {
00934     if( len % 3 ) return;
00935     Parent::SetLength(len);
00936   }
00937 };
00938 
00939 
00940 //template<int T> struct VRToLength;
00941 //template <> struct VRToLength<VR::AS>
00942 //{ enum { Length  = VM::VM1 }; }
00943 //template<>
00944 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length >
00945 
00946 // only 0010 1010 AS 1 Patient’s Age
00947 template<>
00948 class Attribute<VR::AS, VM::VM5>
00949 {
00950 public:
00951   char Internal[VMToLength<VM::VM5>::Length];
00952   void Print(std::ostream &_os) const {
00953     _os << Internal;
00954     }
00955 };
00956 
00957 template <>
00958 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {};
00959 // Make it impossible to compile any other cases:
00960 template <int TVM> class Attribute<VR::OB, TVM>;
00961 
00962 // Same for OW:
00963 template <>
00964 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {};
00965 // Make it impossible to compile any other cases:
00966 template <int TVM> class Attribute<VR::OW, TVM>;
00967 #endif
00968 
00969 #if 0
00970 template<>
00971 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1>
00972 {
00973 public:
00974   char *Internal;
00975   unsigned long Length; // unsigned int ??
00976 
00977   void Print(std::ostream &_os) const {
00978     _os << Internal[0];
00979     }
00980   void SetBytes(char *bytes, unsigned long length) {
00981     Internal = bytes;
00982     Length = length;
00983   }
00984   void Read(std::istream &_is) {
00985      uint16_t c[2];
00986     _is.read((char*)&c, 4);
00987     uint32_t l;
00988     _is.read((char*)&l, 4);
00989     Length = l;
00990     _is.read( Internal, Length );
00991     }
00992   void Write(std::ostream &_os) const {
00993      uint16_t c[] = {0x7fe0, 0x0010};
00994     _os.write((char*)&c, 4);
00995     _os.write((char*)&Length, 4);
00996     _os.write( Internal, Length );
00997     }
00998 };
00999 #endif
01000 
01001 /*
01002 // Removing Attribute for SQ for now...
01003 template<uint16_t Group, uint16_t Element, typename SQA>
01004 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA>
01005 {
01006 public:
01007   SQA sqa;
01008   void Print(std::ostream &_os) const {
01009     _os << Tag(Group,Element);
01010     sqa.Print(_os << std::endl << '\t');
01011     }
01012  void Write(std::ostream &_os) const {
01013     uint16_t c[] = {Group, Element};
01014     _os.write((char*)&c, 4);
01015     uint32_t undef = 0xffffffff;
01016     _os.write((char*)&undef, 4);
01017     uint16_t item_beg[] = {0xfffe,0xe000};
01018     _os.write((char*)&item_beg, 4);
01019     _os.write((char*)&undef, 4);
01020     sqa.Write(_os);
01021     uint16_t item_end[] = {0xfffe,0xe00d};
01022     _os.write((char*)&item_end, 4);
01023     uint32_t zero = 0x0;
01024     _os.write((char*)&zero, 4);
01025     uint16_t seq_end[] = {0xfffe, 0xe0dd};
01026     _os.write((char*)&seq_end, 4);
01027     _os.write((char*)&zero, 4);
01028     }
01029 };
01030 */
01031 
01037 } // namespace gdcm
01038 
01039 #endif //GDCMATTRIBUTE_H

Generated on Tue Dec 6 2011 20:36:26 for GDCM by doxygen 1.7.5.1
SourceForge.net Logo