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

Generated on Sun Mar 7 03:17:19 2010 for GDCM by doxygen 1.6.3
SourceForge.net Logo