GDCM  2.2.0
gdcmByteValue.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: GDCM (Grassroots DICOM). A DICOM library
4 
5  Copyright (c) 2006-2011 Mathieu Malaterre
6  All rights reserved.
7  See Copyright.txt or http://gdcm.sourceforge.net/Copyright.html for details.
8 
9  This software is distributed WITHOUT ANY WARRANTY; without even
10  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11  PURPOSE. See the above copyright notice for more information.
12 
13 =========================================================================*/
14 #ifndef GDCMBYTEVALUE_H
15 #define GDCMBYTEVALUE_H
16 
17 #include "gdcmValue.h"
18 #include "gdcmTrace.h"
19 #include "gdcmVL.h"
20 
21 #include <vector>
22 #include <iterator>
23 #include <iomanip>
24 
25 //#include <stdlib.h> // abort
26 
27 namespace gdcm
28 {
33 class GDCM_EXPORT ByteValue : public Value
34 {
35 public:
36  ByteValue(const char* array = 0, VL const &vl = 0):
37  Internal(array, array+vl),Length(vl) {
38  if( vl.IsOdd() )
39  {
40  gdcmDebugMacro( "Odd length" );
41  Internal.resize(vl+1);
42  Length++;
43  }
44  }
45 
47  ByteValue(std::vector<char> &v):Internal(v),Length((uint32_t)v.size()) {}
48  //ByteValue(std::ostringstream const &os) {
49  // (void)os;
50  // assert(0); // TODO
51  //}
53  Internal.clear();
54  }
55 
56  // When 'dumping' dicom file we still have some information from
57  // Either the VR: eg LO (private tag)
58  void PrintASCII(std::ostream &os, VL maxlength ) const;
59 
60  void PrintHex(std::ostream &os, VL maxlength) const;
61 
62  // Either from Element Number (== 0x0000)
63  void PrintGroupLength(std::ostream &os) {
64  assert( Length == 2 );
65  (void)os;
66  }
67 
68  bool IsEmpty() const {
69  if( Internal.empty() ) assert( Length == 0 );
70  return Internal.empty();
71  }
72  VL GetLength() const { return Length; }
73  // Does a reallocation
74  void SetLength(VL vl) {
75  VL l(vl);
76 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
77  // CompressedLossy.dcm
78  if( l.IsUndefined() ) throw Exception( "Impossible" );
79  if ( l.IsOdd() ) {
81  "BUGGY HEADER: Your dicom contain odd length value field." );
82  ++l;
83  }
84 #else
85  assert( !l.IsUndefined() && !l.IsOdd() );
86 #endif
87  // I cannot use reserve for now. I need to implement:
88  // STL - vector<> and istream
89  // http://groups.google.com/group/comp.lang.c++/msg/37ec052ed8283e74
90 //#define SHORT_READ_HACK
91  try
92  {
93 #ifdef SHORT_READ_HACK
94  if( l <= 0xff )
95 #endif
96  Internal.resize(l);
97  //Internal.reserve(l);
98  }
99  catch(...)
100  {
101  //throw Exception("Impossible to allocate: " << l << " bytes." );
102  throw Exception("Impossible to allocate" );
103  }
104  // Keep the exact length
105  Length = vl;
106  }
107 
108  operator const std::vector<char>& () const { return Internal; }
109 
111  Internal = val.Internal;
112  Length = val.Length;
113  return *this;
114  }
115 
116  bool operator==(const ByteValue &val) const {
117  if( Length != val.Length )
118  return false;
119  if( Internal == val.Internal )
120  return true;
121  return false;
122  }
123  bool operator==(const Value &val) const
124  {
125  const ByteValue &bv = dynamic_cast<const ByteValue&>(val);
126  return Length == bv.Length && Internal == bv.Internal;
127  }
128 
129 
130  void Clear() {
131  Internal.clear();
132  }
133  // Use that only if you understand what you are doing
134  const char *GetPointer() const {
135  if(!Internal.empty()) return &Internal[0];
136  return 0;
137  }
138  void Fill(char c) {
139  //if( Internal.empty() ) return;
140  std::vector<char>::iterator it = Internal.begin();
141  for(; it != Internal.end(); ++it) *it = c;
142  }
143  bool GetBuffer(char *buffer, unsigned long length) const;
144  bool WriteBuffer(std::ostream &os) const {
145  if( Length ) {
146  //assert( Internal.size() <= Length );
147  assert( !(Internal.size() % 2) );
148  os.write(&Internal[0], Internal.size() );
149  }
150  return true;
151  }
152 
153  template <typename TSwap, typename TType>
154  std::istream &Read(std::istream &is) {
155  // If Length is odd we have detected that in SetLength
156  // and calling std::vector::resize make sure to allocate *AND*
157  // initialize values to 0 so we are sure to have a \0 at the end
158  // even in this case
159  if(Length)
160  {
161  is.read(&Internal[0], Length);
162  assert( Internal.size() == Length || Internal.size() == Length + 1 );
163  TSwap::SwapArray((TType*)&Internal[0], Internal.size() / sizeof(TType) );
164  }
165  return is;
166  }
167 
168  template <typename TSwap>
169  std::istream &Read(std::istream &is) {
170  return Read<TSwap,uint8_t>(is);
171  }
172 
173 
174  template <typename TSwap, typename TType>
175  std::ostream const &Write(std::ostream &os) const {
176  assert( !(Internal.size() % 2) );
177  if( !Internal.empty() ) {
178  //os.write(&Internal[0], Internal.size());
179  std::vector<char> copy = Internal;
180  TSwap::SwapArray((TType*)&copy[0], Internal.size() / sizeof(TType) );
181  os.write(&copy[0], copy.size());
182  }
183  return os;
184  }
185 
186  template <typename TSwap>
187  std::ostream const &Write(std::ostream &os) const {
188  return Write<TSwap,uint8_t>(os);
189  }
190 
197  bool IsPrintable(VL length) const {
198  assert( length <= Length );
199  for(unsigned int i=0; i<length; i++)
200  {
201  if ( i == (length-1) && Internal[i] == '\0') continue;
202  if ( !( isprint((unsigned char)Internal[i]) || isspace((unsigned char)Internal[i]) ) )
203  {
204  //gdcmWarningMacro( "Cannot print :" << i );
205  return false;
206  }
207  }
208  return true;
209  }
210 
211 protected:
212  void Print(std::ostream &os) const {
213  // This is perfectly valid to have a Length = 0 , so we cannot check
214  // the length for printing
215  if( !Internal.empty() )
216  {
217  if( IsPrintable(Length) )
218  {
219  // WARNING: Internal.end() != Internal.begin()+Length
220  std::vector<char>::size_type length = Length;
221  if( Internal.back() == 0 ) --length;
222  std::copy(Internal.begin(), Internal.begin()+length,
223  std::ostream_iterator<char>(os));
224  }
225  else
226  os << "Loaded:" << Internal.size();
227  }
228  else
229  {
230  //os << "Not Loaded";
231  os << "(no value available)";
232  }
233  }
234 
235 
236 private:
237  std::vector<char> Internal;
238 
239  // WARNING Length IS NOT Internal.size() some *featured* DICOM
240  // implementation define odd length, we always load them as even number
241  // of byte, so we need to keep the right Length
242  VL Length;
243 };
244 
245 } // end namespace gdcm
246 
247 #endif //GDCMBYTEVALUE_H

Generated on Wed Jun 13 2012 20:40:37 for GDCM by doxygen 1.8.1
SourceForge.net Logo