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

Generated on Tue Sep 30 2014 16:05:22 for GDCM by doxygen 1.8.8
SourceForge.net Logo