GDCM  2.2.6
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 0
70  if( Internal.empty() ) assert( Length == 0 );
71  return Internal.empty();
72 #else
73  return Length == 0;
74 #endif
75  }
76  VL GetLength() const { return Length; }
77  // Does a reallocation
78  void SetLength(VL vl) {
79  VL l(vl);
80 #ifdef GDCM_SUPPORT_BROKEN_IMPLEMENTATION
81  // CompressedLossy.dcm
82  if( l.IsUndefined() ) throw Exception( "Impossible" );
83  if ( l.IsOdd() ) {
85  "BUGGY HEADER: Your dicom contain odd length value field." );
86  ++l;
87  }
88 #else
89  assert( !l.IsUndefined() && !l.IsOdd() );
90 #endif
91  // I cannot use reserve for now. I need to implement:
92  // STL - vector<> and istream
93  // http://groups.google.com/group/comp.lang.c++/msg/37ec052ed8283e74
94 //#define SHORT_READ_HACK
95  try
96  {
97 #ifdef SHORT_READ_HACK
98  if( l <= 0xff )
99 #endif
100  Internal.resize(l);
101  //Internal.reserve(l);
102  }
103  catch(...)
104  {
105  //throw Exception("Impossible to allocate: " << l << " bytes." );
106  throw Exception("Impossible to allocate" );
107  }
108  // Keep the exact length
109  Length = vl;
110  }
111 
112  operator const std::vector<char>& () const { return Internal; }
113 
115  Internal = val.Internal;
116  Length = val.Length;
117  return *this;
118  }
119 
120  bool operator==(const ByteValue &val) const {
121  if( Length != val.Length )
122  return false;
123  if( Internal == val.Internal )
124  return true;
125  return false;
126  }
127  bool operator==(const Value &val) const
128  {
129  const ByteValue &bv = dynamic_cast<const ByteValue&>(val);
130  return Length == bv.Length && Internal == bv.Internal;
131  }
132 
133 
134  void Clear() {
135  Internal.clear();
136  }
137  // Use that only if you understand what you are doing
138  const char *GetPointer() const {
139  if(!Internal.empty()) return &Internal[0];
140  return 0;
141  }
142  void Fill(char c) {
143  //if( Internal.empty() ) return;
144  std::vector<char>::iterator it = Internal.begin();
145  for(; it != Internal.end(); ++it) *it = c;
146  }
147  bool GetBuffer(char *buffer, unsigned long length) const;
148  bool WriteBuffer(std::ostream &os) const {
149  if( Length ) {
150  //assert( Internal.size() <= Length );
151  assert( !(Internal.size() % 2) );
152  os.write(&Internal[0], Internal.size() );
153  }
154  return true;
155  }
156 
157  template <typename TSwap, typename TType>
158  std::istream &Read(std::istream &is, bool readvalues = true) {
159  // If Length is odd we have detected that in SetLength
160  // and calling std::vector::resize make sure to allocate *AND*
161  // initialize values to 0 so we are sure to have a \0 at the end
162  // even in this case
163  if(Length)
164  {
165  if( readvalues )
166  {
167  is.read(&Internal[0], Length);
168  assert( Internal.size() == Length || Internal.size() == Length + 1 );
169  TSwap::SwapArray((TType*)&Internal[0], Internal.size() / sizeof(TType) );
170  }
171  else
172  {
173  is.seekg(Length, std::ios::cur);
174  }
175  }
176  return is;
177  }
178 
179  template <typename TSwap>
180  std::istream &Read(std::istream &is) {
181  return Read<TSwap,uint8_t>(is);
182  }
183 
184 
185  template <typename TSwap, typename TType>
186  std::ostream const &Write(std::ostream &os) const {
187  assert( !(Internal.size() % 2) );
188  if( !Internal.empty() ) {
189  //os.write(&Internal[0], Internal.size());
190  std::vector<char> copy = Internal;
191  TSwap::SwapArray((TType*)&copy[0], Internal.size() / sizeof(TType) );
192  os.write(&copy[0], copy.size());
193  }
194  return os;
195  }
196 
197  template <typename TSwap>
198  std::ostream const &Write(std::ostream &os) const {
199  return Write<TSwap,uint8_t>(os);
200  }
201 
208  bool IsPrintable(VL length) const {
209  assert( length <= Length );
210  for(unsigned int i=0; i<length; i++)
211  {
212  if ( i == (length-1) && Internal[i] == '\0') continue;
213  if ( !( isprint((unsigned char)Internal[i]) || isspace((unsigned char)Internal[i]) ) )
214  {
215  //gdcmWarningMacro( "Cannot print :" << i );
216  return false;
217  }
218  }
219  return true;
220  }
221 
222 protected:
223  void Print(std::ostream &os) const {
224  // This is perfectly valid to have a Length = 0 , so we cannot check
225  // the length for printing
226  if( !Internal.empty() )
227  {
228  if( IsPrintable(Length) )
229  {
230  // WARNING: Internal.end() != Internal.begin()+Length
231  std::vector<char>::size_type length = Length;
232  if( Internal.back() == 0 ) --length;
233  std::copy(Internal.begin(), Internal.begin()+length,
234  std::ostream_iterator<char>(os));
235  }
236  else
237  os << "Loaded:" << Internal.size();
238  }
239  else
240  {
241  //os << "Not Loaded";
242  os << "(no value available)";
243  }
244  }
245 
246  void SetLengthOnly(VL vl) {
247  Length = vl;
248  }
249 
250 private:
251  std::vector<char> Internal;
252 
253  // WARNING Length IS NOT Internal.size() some *featured* DICOM
254  // implementation define odd length, we always load them as even number
255  // of byte, so we need to keep the right Length
256  VL Length;
257 };
258 
259 } // end namespace gdcm
260 
261 #endif //GDCMBYTEVALUE_H
ByteValue(std::vector< char > &v)
Definition: gdcmByteValue.h:47
std::istream & Read(std::istream &is, bool readvalues=true)
Definition: gdcmByteValue.h:158
bool IsPrintable(VL length) const
Checks whether a &#39;ByteValue&#39; is printable or not (in order to avoid corrupting the terminal of invoca...
Definition: gdcmByteValue.h:208
Class to represent the value of a Data Element.
Definition: gdcmValue.h:29
VL GetLength() const
Definition: gdcmByteValue.h:76
~ByteValue()
Definition: gdcmByteValue.h:52
std::ostream const & Write(std::ostream &os) const
Definition: gdcmByteValue.h:186
#define GDCM_EXPORT
Definition: gdcmWin32.h:34
bool operator==(const ByteValue &val) const
Definition: gdcmByteValue.h:120
void Print(std::ostream &os) const
Definition: gdcmByteValue.h:223
Value Length.
Definition: gdcmVL.h:29
#define gdcmDebugMacro(msg)
Debug.
Definition: gdcmTrace.h:119
ByteValue(const char *array=0, VL const &vl=0)
Definition: gdcmByteValue.h:36
bool IsOdd() const
Return whether or not the VL is odd or not.
Definition: gdcmVL.h:47
void Fill(char c)
Definition: gdcmByteValue.h:142
bool operator==(const Value &val) const
Definition: gdcmByteValue.h:127
Class to represent binary value (array of bytes)
Definition: gdcmByteValue.h:33
void PrintGroupLength(std::ostream &os)
Definition: gdcmByteValue.h:63
bool WriteBuffer(std::ostream &os) const
Definition: gdcmByteValue.h:148
std::ostream const & Write(std::ostream &os) const
Definition: gdcmByteValue.h:198
void SetLengthOnly(VL vl)
Definition: gdcmByteValue.h:246
std::istream & Read(std::istream &is)
Definition: gdcmByteValue.h:180
bool IsUndefined() const
Definition: gdcmVL.h:39
void Clear()
Definition: gdcmByteValue.h:134
bool IsEmpty() const
Definition: gdcmByteValue.h:68
const char * GetPointer() const
Definition: gdcmByteValue.h:138
Exception.
Definition: gdcmException.h:33
ByteValue & operator=(const ByteValue &val)
Definition: gdcmByteValue.h:114
void SetLength(VL vl)
Definition: gdcmByteValue.h:78

Generated on Sat Dec 21 2013 05:56:16 for GDCM by doxygen 1.8.5
SourceForge.net Logo