GDCM  2.2.3
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       || GetTag().GetGroup() == 0x5000 );
00675     assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator
00676     assert( !de.IsEmpty() );
00677     const ByteValue *bv = de.GetByteValue();
00678     SetByteValue(bv);
00679   }
00680   void Set(DataSet const &ds) {
00681     SetFromDataElement( ds.GetDataElement( GetTag() ) );
00682   }
00683   void SetFromDataSet(DataSet const &ds) {
00684     if( ds.FindDataElement( GetTag() ) &&
00685       !ds.GetDataElement( GetTag() ).IsEmpty() )
00686       {
00687       SetFromDataElement( ds.GetDataElement( GetTag() ) );
00688       }
00689   }
00690 protected:
00691   void SetByteValue(const ByteValue *bv) {
00692     assert( bv ); // FIXME
00693     std::stringstream ss;
00694     std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00695     Length = bv->GetLength(); // HACK FIXME
00696     ss.str( s );
00697     ArrayType *internal;
00698     ArrayType buffer[256];
00699     if( bv->GetLength() < 256 )
00700       {
00701       internal = buffer;
00702       }
00703     else
00704       {
00705       internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation
00706       }
00707     EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss);
00708     SetValues( internal, Length, true );
00709     if( !(bv->GetLength() < 256) )
00710       {
00711       delete[] internal;
00712       }
00713     //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00714     //  GetNumberOfValues(),ss);
00715   }
00716 
00717 private:
00718   ArrayType *Internal;
00719   unsigned int Length;
00720   bool Own : 1;
00721 };
00722 
00723 template<uint16_t Group, uint16_t Element, int TVR>
00724 class Attribute<Group,Element,TVR,VM::VM1_3> : public Attribute<Group,Element,TVR,VM::VM1_n>
00725 {
00726 public:
00727   VM  GetVM() const { return VM::VM1_3; }
00728 };
00729 
00730 template<uint16_t Group, uint16_t Element, int TVR>
00731 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n>
00732 {
00733 public:
00734   VM  GetVM() const { return VM::VM1_8; }
00735 };
00736 
00737 template<uint16_t Group, uint16_t Element, int TVR>
00738 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00739 {
00740 public:
00741   VM  GetVM() const { return VM::VM2_n; }
00742 };
00743 
00744 template<uint16_t Group, uint16_t Element, int TVR>
00745 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n>
00746 {
00747 public:
00748   static VM  GetVM() { return VM::VM2_2n; }
00749 };
00750 
00751 template<uint16_t Group, uint16_t Element, int TVR>
00752 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00753 {
00754 public:
00755   static VM  GetVM() { return VM::VM3_n; }
00756 };
00757 
00758 template<uint16_t Group, uint16_t Element, int TVR>
00759 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n>
00760 {
00761 public:
00762   static VM  GetVM() { return VM::VM3_3n; }
00763 };
00764 
00765 
00766 // For particular case for ASCII string
00767 // WARNING: This template explicitely instanciates a particular
00768 // EncodingImplementation THEREFORE it is required to be declared after the
00769 // EncodingImplementation is needs (doh!)
00770 #if 0
00771 template<int TVM>
00772 class Attribute<TVM>
00773 {
00774 public:
00775   Attribute(const char array[])
00776     {
00777     unsigned int i = 0;
00778     const char sep = '\\';
00779     std::string sarray = array;
00780     std::string::size_type pos1 = 0;
00781     std::string::size_type pos2 = sarray.find(sep, pos1+1);
00782     while(pos2 != std::string::npos)
00783       {
00784       Internal[i++] = sarray.substr(pos1, pos2-pos1);
00785       pos1 = pos2+1;
00786       pos2 = sarray.find(sep, pos1+1);
00787       }
00788     Internal[i] = sarray.substr(pos1, pos2-pos1);
00789     // Shouldn't we do the contrary, since we know how many separators
00790     // (and default behavior is to discard anything after the VM declared
00791     assert( GetLength()-1 == i );
00792     }
00793 
00794   unsigned long GetLength() const {
00795     return VMToLength<TVM>::Length;
00796   }
00797   // Implementation of Print is common to all Mode (ASCII/Binary)
00798   void Print(std::ostream &_os) const {
00799     _os << Internal[0]; // VM is at least garantee to be one
00800     for(int i=1; i<VMToLength<TVM>::Length; ++i)
00801       _os << "," << Internal[i];
00802     }
00803 
00804   void Read(std::istream &_is) {
00805     EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
00806     }
00807   void Write(std::ostream &_os) const {
00808     EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
00809     }
00810 private:
00811   typename String Internal[VMToLength<TVM>::Length];
00812 };
00813 
00814 template< int TVM>
00815 class Attribute<VR::PN, TVM> : public StringAttribute<TVM>
00816 {
00817 };
00818 #endif
00819 
00820 #if 0
00821 
00822 // Implementation for the undefined length (dynamically allocated array)
00823 template<int TVR>
00824 class Attribute<TVR, VM::VM1_n>
00825 {
00826 public:
00827   // This the way to prevent default initialization
00828   explicit Attribute() { Internal=0; Length=0; }
00829   ~Attribute() {
00830     delete[] Internal;
00831     Internal = 0;
00832   }
00833 
00834   // Length manipulation
00835   // SetLength should really be protected anyway...all operation
00836   // should go through SetArray
00837   unsigned long GetLength() const { return Length; }
00838   typedef typename VRToType<TVR>::Type ArrayType;
00839   void SetLength(unsigned long len) {
00840     const unsigned int size = sizeof(ArrayType);
00841     if( len ) {
00842       if( len > Length ) {
00843         // perform realloc
00844         assert( (len / size) * size == len );
00845         ArrayType *internal = new ArrayType[len / size];
00846         memcpy(internal, Internal, Length * size);
00847         delete[] Internal;
00848         Internal = internal;
00849         }
00850       }
00851     Length = len / size;
00852   }
00853 
00854   // If save is set to zero user should not delete the pointer
00855   //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false)
00856   void SetArray(const ArrayType *array, unsigned long len,
00857     bool save = false) {
00858     if( save ) {
00859       SetLength(len); // realloc
00860       memcpy(Internal, array, len/*/sizeof(ArrayType)*/);
00861       }
00862     else {
00863       // TODO rewrite this stupid code:
00864       Length = len;
00865       //Internal = array;
00866       assert(0);
00867       }
00868   }
00869   // Implementation of Print is common to all Mode (ASCII/Binary)
00870   void Print(std::ostream &_os) const {
00871     assert( Length );
00872     assert( Internal );
00873     _os << Internal[0]; // VM is at least garantee to be one
00874     const unsigned long length = GetLength() < 25 ? GetLength() : 25;
00875     for(unsigned long i=1; i<length; ++i)
00876       _os << "," << Internal[i];
00877     }
00878   void Read(std::istream &_is) {
00879     EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal,
00880       GetLength(),_is);
00881     }
00882   void Write(std::ostream &_os) const {
00883     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal,
00884       GetLength(),_os);
00885     }
00886 
00887   Attribute(const Attribute&_val) {
00888     if( this != &_val) {
00889       *this = _val;
00890       }
00891     }
00892 
00893   Attribute &operator=(const Attribute &_val) {
00894     Length = 0; // SYITF
00895     Internal = 0;
00896     SetArray(_val.Internal, _val.Length, true);
00897     return *this;
00898     }
00899 
00900 private:
00901   typename VRToType<TVR>::Type *Internal;
00902   unsigned long Length; // unsigned int ??
00903 };
00904 
00905 //template <int TVM = VM::VM1_n>
00906 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {};
00907 
00908 // Partial specialization for derivatives of 1-n : 2-n, 3-n ...
00909 template<int TVR>
00910 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n>
00911 {
00912 public:
00913   typedef Attribute<TVR, VM::VM1_n> Parent;
00914   void SetLength(int len) {
00915     if( len <= 1 ) return;
00916     Parent::SetLength(len);
00917   }
00918 };
00919 template<int TVR>
00920 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n>
00921 {
00922 public:
00923   typedef Attribute<TVR, VM::VM2_n> Parent;
00924   void SetLength(int len) {
00925     if( len % 2 ) return;
00926     Parent::SetLength(len);
00927   }
00928 };
00929 template<int TVR>
00930 class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n>
00931 {
00932 public:
00933   typedef Attribute<TVR, VM::VM1_n> Parent;
00934   void SetLength(int len) {
00935     if( len <= 2 ) return;
00936     Parent::SetLength(len);
00937   }
00938 };
00939 template<int TVR>
00940 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n>
00941 {
00942 public:
00943   typedef Attribute<TVR, VM::VM3_n> Parent;
00944   void SetLength(int len) {
00945     if( len % 3 ) return;
00946     Parent::SetLength(len);
00947   }
00948 };
00949 
00950 
00951 //template<int T> struct VRToLength;
00952 //template <> struct VRToLength<VR::AS>
00953 //{ enum { Length  = VM::VM1 }; }
00954 //template<>
00955 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length >
00956 
00957 // only 0010 1010 AS 1 Patient’s Age
00958 template<>
00959 class Attribute<VR::AS, VM::VM5>
00960 {
00961 public:
00962   char Internal[VMToLength<VM::VM5>::Length];
00963   void Print(std::ostream &_os) const {
00964     _os << Internal;
00965     }
00966 };
00967 
00968 template <>
00969 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {};
00970 // Make it impossible to compile any other cases:
00971 template <int TVM> class Attribute<VR::OB, TVM>;
00972 
00973 // Same for OW:
00974 template <>
00975 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {};
00976 // Make it impossible to compile any other cases:
00977 template <int TVM> class Attribute<VR::OW, TVM>;
00978 #endif
00979 
00980 #if 0
00981 template<>
00982 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1>
00983 {
00984 public:
00985   char *Internal;
00986   unsigned long Length; // unsigned int ??
00987 
00988   void Print(std::ostream &_os) const {
00989     _os << Internal[0];
00990     }
00991   void SetBytes(char *bytes, unsigned long length) {
00992     Internal = bytes;
00993     Length = length;
00994   }
00995   void Read(std::istream &_is) {
00996      uint16_t c[2];
00997     _is.read((char*)&c, 4);
00998     uint32_t l;
00999     _is.read((char*)&l, 4);
01000     Length = l;
01001     _is.read( Internal, Length );
01002     }
01003   void Write(std::ostream &_os) const {
01004      uint16_t c[] = {0x7fe0, 0x0010};
01005     _os.write((char*)&c, 4);
01006     _os.write((char*)&Length, 4);
01007     _os.write( Internal, Length );
01008     }
01009 };
01010 #endif
01011 
01012 /*
01013 // Removing Attribute for SQ for now...
01014 template<uint16_t Group, uint16_t Element, typename SQA>
01015 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA>
01016 {
01017 public:
01018   SQA sqa;
01019   void Print(std::ostream &_os) const {
01020     _os << Tag(Group,Element);
01021     sqa.Print(_os << std::endl << '\t');
01022     }
01023  void Write(std::ostream &_os) const {
01024     uint16_t c[] = {Group, Element};
01025     _os.write((char*)&c, 4);
01026     uint32_t undef = 0xffffffff;
01027     _os.write((char*)&undef, 4);
01028     uint16_t item_beg[] = {0xfffe,0xe000};
01029     _os.write((char*)&item_beg, 4);
01030     _os.write((char*)&undef, 4);
01031     sqa.Write(_os);
01032     uint16_t item_end[] = {0xfffe,0xe00d};
01033     _os.write((char*)&item_end, 4);
01034     uint32_t zero = 0x0;
01035     _os.write((char*)&zero, 4);
01036     uint16_t seq_end[] = {0xfffe, 0xe0dd};
01037     _os.write((char*)&seq_end, 4);
01038     _os.write((char*)&zero, 4);
01039     }
01040 };
01041 */
01042 
01048 } // namespace gdcm
01049 
01050 #endif //GDCMATTRIBUTE_H

Generated on Thu Nov 28 2013 07:02:50 for GDCM by doxygen 1.7.6.1
SourceForge.net Logo