GDCM 2.0.17

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

Generated on Wed Feb 2 2011 19:21:01 for GDCM by doxygen 1.7.3
SourceForge.net Logo