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     ret.SetByteValue( os.str().c_str(), os.str().size() );
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     if( de.GetVR() == VR::UN || de.GetVR() == VR::INVALID )
00214       {
00215       SetByteValue(bv);
00216       }
00217     else
00218       {
00219       SetByteValueNoSwap(bv);
00220       }
00221   }
00222   void Set(DataSet const &ds) {
00223     SetFromDataElement( ds.GetDataElement( GetTag() ) );
00224   }
00225   void SetFromDataSet(DataSet const &ds) {
00226     if( ds.FindDataElement( GetTag() ) &&
00227       !ds.GetDataElement( GetTag() ).IsEmpty() )
00228       {
00229       SetFromDataElement( ds.GetDataElement( GetTag() ) );
00230       }
00231   }
00232 protected:
00233   void SetByteValueNoSwap(const ByteValue *bv) {
00234     if( !bv ) return; // That would be bad...
00235     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00236     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00237     //  {
00238     //  // always do a copy !
00239     //  SetValues(bv->GetPointer(), bv->GetLength());
00240     //  }
00241     //else
00242       {
00243       std::stringstream ss;
00244       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00245       ss.str( s );
00246       EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadNoSwap(Internal, 
00247         GetNumberOfValues(),ss);
00248       }
00249   }
00250   void SetByteValue(const ByteValue *bv) {
00251     if( !bv ) return; // That would be bad...
00252     assert( bv->GetPointer() && bv->GetLength() ); // [123]C element can be empty
00253     //if( VRToEncoding<TVR>::Mode == VR::VRBINARY )
00254     //  {
00255     //  // always do a copy !
00256     //  SetValues(bv->GetPointer(), bv->GetLength());
00257     //  }
00258     //else
00259       {
00260       std::stringstream ss;
00261       std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00262       ss.str( s );
00263       EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 
00264         GetNumberOfValues(),ss);
00265       }
00266   }
00267 #if 0 // TODO  FIXME the implicit way:
00268   // explicit:
00269   void Read(std::istream &_is) {
00270     const uint16_t cref[] = { Group, Element };
00271     uint16_t c[2];
00272     _is.read((char*)&c, sizeof(c));
00273     assert( c[0] == cref[0] && c[1] == cref[1] );
00274     char vr[2];
00275     _is.read(vr, 2); // Check consistency ?
00276     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00277     uint32_t l = VRVLSize< (TVR & VR::VL32) >::Read(_is);
00278     l /= sizeof( typename VRToType<TVR>::Type );
00279     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 
00280       l,_is);
00281   }
00282   void Write(std::ostream &_os) const {
00283     uint16_t c[] = { Group, Element };
00284     _os.write((char*)&c, 4);
00285     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00286     _os.write((char*)&l, 4);
00287     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 
00288       GetLength(),_os);
00289     }
00290   void Read(std::istream &_is) {
00291     uint16_t cref[] = { Group, Element };
00292     uint16_t c[2];
00293     _is.read((char*)&c, 4);
00294     const uint32_t lref = GetLength() * sizeof( typename VRToType<TVR>::Type );
00295     uint32_t l;
00296     _is.read((char*)&l, 4);
00297     l /= sizeof( typename VRToType<TVR>::Type );
00298      return EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 
00299       l,_is);
00300     }
00301   void Write(std::ostream &_os) const {
00302     uint16_t c[] = { Group, Element };
00303     _os.write((char*)&c, 4);
00304     uint32_t l = GetLength() * sizeof( typename VRToType<TVR>::Type );
00305     _os.write((char*)&l, 4);
00306     return EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 
00307       GetLength(),_os);
00308     }
00309 #endif
00310 
00311 };
00312 
00313 
00314 // No need to repeat default template arg, since primary template
00315 // will be used to generate the default arguments
00316 template<uint16_t Group, uint16_t Element, int TVR > 
00317 class Attribute<Group,Element,TVR,VM::VM1_n>
00318 {
00319 public:
00320   typedef typename VRToType<TVR>::Type ArrayType;
00321 
00322   // Make sure that user specified VR/VM are compatible with the public dictionary:
00323   GDCM_STATIC_ASSERT( ((VR::VRType)TVR & (VR::VRType)(TagToType<Group, Element>::VRType)) );
00324   GDCM_STATIC_ASSERT( (VM::VM1_n & (VM::VMType)(TagToType<Group, Element>::VMType)) );
00325   GDCM_STATIC_ASSERT( ((((VR::VRType)TVR & VR::VR_VM1) && ((VM::VMType)TagToType<Group,Element>::VMType == VM::VM1) )
00326                     || !((VR::VRType)TVR & VR::VR_VM1) ) );
00327 
00328   static Tag GetTag() { return Tag(Group,Element); }
00329   static VR  GetVR()  { return (VR::VRType)TVR; }
00330   static VM  GetVM()  { return VM::VM1_n; }
00331 
00332   static VR  GetDictVR() { return (VR::VRType)(TagToType<Group, Element>::VRType); }
00333   static VM  GetDictVM() { return GetVM(); }
00334 
00335   // This the way to prevent default initialization
00336   explicit Attribute() { Internal=0; Length=0; Own = true; }
00337   ~Attribute() {
00338     if( Own ) {
00339       delete[] Internal;
00340     }
00341     Internal = 0; // paranoid
00342   }
00343 
00344   unsigned int GetNumberOfValues() const { return Length; }
00345 
00346   void SetNumberOfValues(unsigned int numel)
00347     {
00348     SetValues(NULL, numel, true);
00349     }
00350 
00351   const ArrayType* GetValues() const {
00352     return Internal;
00353   }
00354   void Print(std::ostream &os) const {
00355     os << GetTag() << " ";
00356     os << GetVR()  << " ";
00357     os << GetVM()  << " ";
00358     os << Internal[0]; // VM is at least garantee to be one
00359     for(unsigned int i=1; i<GetNumberOfValues(); ++i)
00360       os << "," << Internal[i];
00361     }
00362   ArrayType &GetValue(unsigned int idx = 0) {
00363     assert( idx < GetNumberOfValues() );
00364     return Internal[idx];
00365   }
00366   ArrayType &operator[] (unsigned int idx) {
00367     return GetValue(idx);
00368   }
00369   // const reference
00370   ArrayType const &GetValue(unsigned int idx = 0) const {
00371     assert( idx < GetNumberOfValues() );
00372     return Internal[idx];
00373   }
00374   ArrayType const & operator[] (unsigned int idx) const {
00375     return GetValue(idx);
00376   }
00377   void SetValue(unsigned int idx, ArrayType v) {
00378     assert( idx < GetNumberOfValues() );
00379     Internal[idx] = v;
00380   }
00381   void SetValue(ArrayType v) { SetValue(0, v); }
00382 
00383   void SetValues(const ArrayType *array, unsigned int numel, bool own = false)
00384     {
00385     if( Internal ) // were we used before ?
00386       {
00387       // yes !
00388       if( Own ) delete[] Internal;
00389       Internal = 0;
00390       }
00391     Own = own;
00392     Length = numel;
00393     assert( Internal == 0 );
00394     if( own ) // make a copy:
00395       {
00396       assert( /*array &&*/ numel );
00397       Internal = new ArrayType[numel];
00398       if( array && numel )
00399         std::copy(array, array+numel, Internal);
00400       }
00401     else // pass pointer
00402       {
00403       Internal = const_cast<ArrayType*>(array);
00404       }
00405     // postcondition
00406     assert( numel == GetNumberOfValues() );
00407     }
00408 
00409   DataElement GetAsDataElement() const {
00410     DataElement ret( GetTag() );
00411     std::ostringstream os;
00412     if( Internal )
00413       {
00414       EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 
00415         GetNumberOfValues(),os);
00416       if( (VR::VRType)VRToEncoding<TVR>::Mode == VR::VRASCII )
00417         {
00418         if( GetVR() != VR::UI )
00419           {
00420           if( os.str().size() % 2 )
00421             {
00422             os << " ";
00423             }
00424           }
00425         }
00426       }
00427     ret.SetVR( GetVR() );
00428     assert( ret.GetVR() != VR::SQ );
00429     ret.SetByteValue( os.str().c_str(), os.str().size() );
00430     return ret;
00431   }
00432   void SetFromDataElement(DataElement const &de) {
00433     // This is kind of hackish but since I do not generate other element than the first one: 0x6000 I should be ok:
00434     assert( GetTag() == de.GetTag() || GetTag().GetGroup() == 0x6000 );
00435     assert( GetVR().Compatible( de.GetVR() ) ); // In case of VR::INVALID cannot use the & operator
00436     assert( !de.IsEmpty() );
00437     const ByteValue *bv = de.GetByteValue();
00438     SetByteValue(bv);
00439   }
00440 protected:
00441   void SetByteValue(const ByteValue *bv) {
00442     assert( bv ); // FIXME
00443     std::stringstream ss;
00444     std::string s = std::string( bv->GetPointer(), bv->GetLength() );
00445     Length = bv->GetLength(); // HACK FIXME
00446     ss.str( s );
00447     ArrayType *internal;
00448     ArrayType buffer[256];
00449     if( bv->GetLength() < 256 )
00450       {
00451       internal = buffer;
00452       }
00453     else
00454       {
00455       internal = new ArrayType[(VL::Type)bv->GetLength()]; // over allocation
00456       }
00457     EncodingImplementation<VRToEncoding<TVR>::Mode>::ReadComputeLength(internal, Length, ss);
00458     SetValues( internal, Length, true );
00459     if( !(bv->GetLength() < 256) )
00460       {
00461       delete[] internal;
00462       }
00463     //EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 
00464     //  GetNumberOfValues(),ss);
00465   }
00466 
00467 private:
00468   ArrayType *Internal;
00469   unsigned int Length;
00470   bool Own : 1;
00471 };
00472 
00473 template<uint16_t Group, uint16_t Element, int TVR> 
00474 class Attribute<Group,Element,TVR,VM::VM1_8> : public Attribute<Group,Element,TVR,VM::VM1_n>
00475 {
00476 public:
00477   VM  GetVM() const { return VM::VM1_8; }
00478 };
00479 
00480 template<uint16_t Group, uint16_t Element, int TVR> 
00481 class Attribute<Group,Element,TVR,VM::VM2_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00482 {
00483 public:
00484   VM  GetVM() const { return VM::VM2_n; }
00485 };
00486 
00487 template<uint16_t Group, uint16_t Element, int TVR> 
00488 class Attribute<Group,Element,TVR,VM::VM2_2n> : public Attribute<Group,Element,TVR,VM::VM2_n>
00489 {
00490 public:
00491   static VM  GetVM() { return VM::VM2_2n; }
00492 };
00493 
00494 template<uint16_t Group, uint16_t Element, int TVR> 
00495 class Attribute<Group,Element,TVR,VM::VM3_n> : public Attribute<Group,Element,TVR,VM::VM1_n>
00496 {
00497 public:
00498   static VM  GetVM() { return VM::VM3_n; }
00499 };
00500 
00501 template<uint16_t Group, uint16_t Element, int TVR> 
00502 class Attribute<Group,Element,TVR,VM::VM3_3n> : public Attribute<Group,Element,TVR,VM::VM3_n>
00503 {
00504 public:
00505   static VM  GetVM() { return VM::VM3_3n; }
00506 };
00507 
00508 
00509 // For particular case for ASCII string
00510 // WARNING: This template explicitely instanciates a particular 
00511 // EncodingImplementation THEREFORE it is required to be declared after the
00512 // EncodingImplementation is needs (doh!)
00513 #if 0
00514 template<int TVM>
00515 class Attribute<TVM>
00516 {
00517 public:
00518   Attribute(const char array[])
00519     {
00520     unsigned int i = 0;
00521     const char sep = '\\';
00522     std::string sarray = array;
00523     std::string::size_type pos1 = 0;
00524     std::string::size_type pos2 = sarray.find(sep, pos1+1);
00525     while(pos2 != std::string::npos)
00526       {
00527       Internal[i++] = sarray.substr(pos1, pos2-pos1);
00528       pos1 = pos2+1;
00529       pos2 = sarray.find(sep, pos1+1);
00530       } 
00531     Internal[i] = sarray.substr(pos1, pos2-pos1);
00532     // Shouldn't we do the contrary, since we know how many separators
00533     // (and default behavior is to discard anything after the VM declared
00534     assert( GetLength()-1 == i );
00535     }
00536 
00537   unsigned long GetLength() const {
00538     return VMToLength<TVM>::Length;
00539   }
00540   // Implementation of Print is common to all Mode (ASCII/Binary)
00541   void Print(std::ostream &_os) const {
00542     _os << Internal[0]; // VM is at least garantee to be one
00543     for(int i=1; i<VMToLength<TVM>::Length; ++i)
00544       _os << "," << Internal[i];
00545     }
00546 
00547   void Read(std::istream &_is) {
00548     EncodingImplementation<VR::VRASCII>::Read(Internal, GetLength(),_is);
00549     }
00550   void Write(std::ostream &_os) const {
00551     EncodingImplementation<VR::VRASCII>::Write(Internal, GetLength(),_os);
00552     }
00553 private:
00554   typename String Internal[VMToLength<TVM>::Length];
00555 };
00556 
00557 template< int TVM>
00558 class Attribute<VR::PN, TVM> : public StringAttribute<TVM>
00559 {
00560 };
00561 #endif
00562 
00563 #if 0
00564 
00565 // Implementation for the undefined length (dynamically allocated array) 
00566 template<int TVR>
00567 class Attribute<TVR, VM::VM1_n>
00568 {
00569 public:
00570   // This the way to prevent default initialization
00571   explicit Attribute() { Internal=0; Length=0; }
00572   ~Attribute() {
00573     delete[] Internal;
00574     Internal = 0;
00575   }
00576 
00577   // Length manipulation
00578   // SetLength should really be protected anyway...all operation
00579   // should go through SetArray
00580   unsigned long GetLength() const { return Length; }
00581   typedef typename VRToType<TVR>::Type ArrayType;
00582   void SetLength(unsigned long len) {
00583     const unsigned int size = sizeof(ArrayType);
00584     if( len ) {
00585       if( len > Length ) {
00586         // perform realloc
00587         assert( (len / size) * size == len );
00588         ArrayType *internal = new ArrayType[len / size];
00589         memcpy(internal, Internal, Length * size);
00590         delete[] Internal;
00591         Internal = internal;
00592         }
00593       }
00594     Length = len / size;
00595   }
00596 
00597   // If save is set to zero user should not delete the pointer
00598   //void SetArray(const typename VRToType<TVR>::Type *array, int len, bool save = false) 
00599   void SetArray(const ArrayType *array, unsigned long len,
00600     bool save = false) {
00601     if( save ) {
00602       SetLength(len); // realloc
00603       memcpy(Internal, array, len/*/sizeof(ArrayType)*/);
00604       }
00605     else {
00606       // TODO rewrite this stupid code:
00607       Length = len;
00608       //Internal = array;
00609       assert(0);
00610       }
00611   }
00612   // Implementation of Print is common to all Mode (ASCII/Binary)
00613   void Print(std::ostream &_os) const {
00614     assert( Length );
00615     assert( Internal );
00616     _os << Internal[0]; // VM is at least garantee to be one
00617     const unsigned long length = GetLength() < 25 ? GetLength() : 25;
00618     for(unsigned long i=1; i<length; ++i)
00619       _os << "," << Internal[i];
00620     }
00621   void Read(std::istream &_is) {
00622     EncodingImplementation<VRToEncoding<TVR>::Mode>::Read(Internal, 
00623       GetLength(),_is);
00624     }
00625   void Write(std::ostream &_os) const {
00626     EncodingImplementation<VRToEncoding<TVR>::Mode>::Write(Internal, 
00627       GetLength(),_os);
00628     }
00629 
00630   Attribute(const Attribute&_val) {
00631     if( this != &_val) {
00632       *this = _val;
00633       }
00634     }
00635 
00636   Attribute &operator=(const Attribute &_val) {
00637     Length = 0; // SYITF
00638     Internal = 0;
00639     SetArray(_val.Internal, _val.Length, true);
00640     return *this;
00641     }
00642 
00643 private:
00644   typename VRToType<TVR>::Type *Internal;
00645   unsigned long Length; // unsigned int ??
00646 };
00647 
00648 //template <int TVM = VM::VM1_n>
00649 //class Attribute<VR::OB, TVM > : public Attribute<VR::OB, VM::VM1_n> {};
00650 
00651 // Partial specialization for derivatives of 1-n : 2-n, 3-n ...
00652 template<int TVR>
00653 class Attribute<TVR, VM::VM2_n> : public Attribute<TVR, VM::VM1_n>
00654 {
00655 public:
00656   typedef Attribute<TVR, VM::VM1_n> Parent;
00657   void SetLength(int len) {
00658     if( len <= 1 ) return;
00659     Parent::SetLength(len);
00660   }
00661 };
00662 template<int TVR>
00663 class Attribute<TVR, VM::VM2_2n> : public Attribute<TVR, VM::VM2_n>
00664 {
00665 public:
00666   typedef Attribute<TVR, VM::VM2_n> Parent;
00667   void SetLength(int len) {
00668     if( len % 2 ) return;
00669     Parent::SetLength(len);
00670   }
00671 };
00672 template<int TVR>
00673 class Attribute<TVR, VM::VM3_n> : public Attribute<TVR, VM::VM1_n>
00674 {
00675 public:
00676   typedef Attribute<TVR, VM::VM1_n> Parent;
00677   void SetLength(int len) {
00678     if( len <= 2 ) return;
00679     Parent::SetLength(len);
00680   }
00681 };
00682 template<int TVR>
00683 class Attribute<TVR, VM::VM3_3n> : public Attribute<TVR, VM::VM3_n>
00684 {
00685 public:
00686   typedef Attribute<TVR, VM::VM3_n> Parent;
00687   void SetLength(int len) {
00688     if( len % 3 ) return;
00689     Parent::SetLength(len);
00690   }
00691 };
00692 
00693 
00694 //template<int T> struct VRToLength;
00695 //template <> struct VRToLength<VR::AS>
00696 //{ enum { Length  = VM::VM1 }; }
00697 //template<>
00698 //class Attribute<VR::AS> : public Attribute<VR::AS, VRToLength<VR::AS>::Length >
00699 
00700 // only 0010 1010 AS 1 Patient’s Age
00701 template<>
00702 class Attribute<VR::AS, VM::VM5>
00703 {
00704 public:
00705   char Internal[VMToLength<VM::VM5>::Length];
00706   void Print(std::ostream &_os) const {
00707     _os << Internal;
00708     }
00709 };
00710 
00711 template <>
00712 class Attribute<VR::OB, VM::VM1> : public Attribute<VR::OB, VM::VM1_n> {};
00713 // Make it impossible to compile any other cases:
00714 template <int TVM> class Attribute<VR::OB, TVM>;
00715 
00716 // Same for OW:
00717 template <>
00718 class Attribute<VR::OW, VM::VM1> : public Attribute<VR::OW, VM::VM1_n> {};
00719 // Make it impossible to compile any other cases:
00720 template <int TVM> class Attribute<VR::OW, TVM>;
00721 #endif
00722 
00723 #if 0
00724 template<>
00725 class Attribute<0x7fe0,0x0010, VR::OW, VM::VM1>
00726 {
00727 public:
00728   char *Internal;
00729   unsigned long Length; // unsigned int ??
00730 
00731   void Print(std::ostream &_os) const {
00732     _os << Internal[0];
00733     }
00734   void SetBytes(char *bytes, unsigned long length) {
00735     Internal = bytes;
00736     Length = length;
00737   }
00738   void Read(std::istream &_is) {
00739      uint16_t c[2];
00740     _is.read((char*)&c, 4);
00741     uint32_t l;
00742     _is.read((char*)&l, 4);
00743     Length = l;
00744     _is.read( Internal, Length );
00745     }
00746   void Write(std::ostream &_os) const {
00747      uint16_t c[] = {0x7fe0, 0x0010};
00748     _os.write((char*)&c, 4);
00749     _os.write((char*)&Length, 4);
00750     _os.write( Internal, Length );
00751     }
00752 };
00753 #endif
00754 
00755 /*
00756 // Removing Attribute for SQ for now...
00757 template<uint16_t Group, uint16_t Element, typename SQA>
00758 class Attribute<Group,Element, VR::SQ, VM::VM1, SQA>
00759 {
00760 public:
00761   SQA sqa;
00762   void Print(std::ostream &_os) const {
00763     _os << Tag(Group,Element);
00764     sqa.Print(_os << std::endl << '\t');
00765     }
00766  void Write(std::ostream &_os) const {
00767     uint16_t c[] = {Group, Element};
00768     _os.write((char*)&c, 4);
00769     uint32_t undef = 0xffffffff;
00770     _os.write((char*)&undef, 4);
00771     uint16_t item_beg[] = {0xfffe,0xe000};
00772     _os.write((char*)&item_beg, 4);
00773     _os.write((char*)&undef, 4);
00774     sqa.Write(_os);
00775     uint16_t item_end[] = {0xfffe,0xe00d};
00776     _os.write((char*)&item_end, 4);
00777     uint32_t zero = 0x0;
00778     _os.write((char*)&zero, 4);
00779     uint16_t seq_end[] = {0xfffe, 0xe0dd};
00780     _os.write((char*)&seq_end, 4);
00781     _os.write((char*)&zero, 4);
00782     }
00783 };
00784 */
00785 
00791 } // namespace gdcm
00792 
00793 #endif //GDCMATTRIBUTE_H

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