GDCM 3.2.1

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#include <algorithm>
25#include <cstring>
26
27 namespace gdcm_ns
28{
29#if !defined(SWIGPYTHON) && !defined(SWIGCSHARP) && !defined(SWIGJAVA) && !defined(SWIGPHP)
30 using namespace gdcm;
31#endif
35 class GDCM_EXPORT ByteValue : public Value
36{
37 public:
38 ByteValue(const char* array = nullptr, VL const &vl = 0): Length(vl) {
39 VL bytes_count_to_copy = Length;
40 if( vl.IsOdd() )
41 {
42 gdcmDebugMacro( "Odd length" );
43 Internal.resize(vl+1);
44 ++Length;
45 }
46 Internal.resize(Length);
47 if( array )
48 std::memcpy(Internal.data(), array, bytes_count_to_copy);
49 }
50
52 ByteValue(std::vector<char> &v):Internal(v),Length((uint32_t)v.size()) {}
53 //ByteValue(std::ostringstream const &os) {
54 // (void)os;
55 // gdcm_assert(0); // TODO
56 //}
57 ~ByteValue() override {
58 Internal.clear();
59 }
60
61 // When 'dumping' dicom file we still have some information from
62 // Either the VR: eg LO (private tag)
63 void PrintASCII(std::ostream &os, VL maxlength ) const;
64
65 void PrintHex(std::ostream &os, VL maxlength) const;
66
67 // Either from Element Number (== 0x0000)
68 void PrintGroupLength(std::ostream &os) {
69 gdcm_assert( Length == 2 );
70 (void)os;
71 }
72
73 bool IsEmpty() const {
74#if 0
75 if( Internal.empty() ) gdcm_assert( Length == 0 );
76 return Internal.empty();
77#else
78 return Length == 0;
79#endif
80 }
81 VL GetLength() const override { return Length; }
82
83 VL ComputeLength() const { return Length + Length % 2; }
84 // Does a reallocation
85 void SetLength(VL vl) override;
86
87 operator const std::vector<char>& () const { return Internal; }
88
89 ByteValue &operator=(const ByteValue &val) {
90 Internal = val.Internal;
91 Length = val.Length;
92 return *this;
93 }
94
95 bool operator==(const ByteValue &val) const {
96 if( Length != val.Length )
97 return false;
98 if( Internal == val.Internal )
99 return true;
100 return false;
101 }
102 bool operator==(const Value &val) const override
103 {
104 const ByteValue &bv = dynamic_cast<const ByteValue&>(val);
105 return Length == bv.Length && Internal == bv.Internal;
106 }
107
108 void Append(ByteValue const & bv);
109
110 void Clear() override {
111 Internal.clear();
112 }
113 // Use that only if you understand what you are doing
114 const char *GetPointer() const {
115 if(!Internal.empty()) return &Internal[0];
116 return nullptr;
117 }
118 // Use that only if you really understand what you are doing
119 const void *GetVoidPointer() const {
120 if(!Internal.empty()) return &Internal[0];
121 return nullptr;
122 }
123 void *GetVoidPointer() {
124 if(!Internal.empty()) return &Internal[0];
125 return nullptr;
126 }
127 void Fill(char c) {
128 //if( Internal.empty() ) return;
129 std::vector<char>::iterator it = Internal.begin();
130 for(; it != Internal.end(); ++it) *it = c;
131 }
132 bool GetBuffer(char *buffer, unsigned long length) const;
133 bool WriteBuffer(std::ostream &os) const {
134 if( Length ) {
135 //gdcm_assert( Internal.size() <= Length );
136 gdcm_assert( !(Internal.size() % 2) );
137 os.write(&Internal[0], Internal.size() );
138 }
139 return true;
140 }
141
142 template <typename TSwap, typename TType>
143 std::istream &Read(std::istream &is, bool readvalues = true) {
144 // If Length is odd we have detected that in SetLength
145 // and calling std::vector::resize make sure to allocate *AND*
146 // initialize values to 0 so we are sure to have a \0 at the end
147 // even in this case
148 if(Length)
149 {
150 if( readvalues )
151 {
152 is.read(&Internal[0], Length);
153 gdcm_assert( Internal.size() == Length || Internal.size() == Length + 1 );
154 TSwap::SwapArray((TType*)GetVoidPointer(), Internal.size() / sizeof(TType) );
155 }
156 else
157 {
158 is.seekg(Length, std::ios::cur);
159 }
160 }
161 return is;
162 }
163
164 template <typename TSwap>
165 std::istream &Read(std::istream &is) {
166 return Read<TSwap,uint8_t>(is);
167 }
168
169
170 template <typename TSwap, typename TType>
171 std::ostream const &Write(std::ostream &os) const {
172 gdcm_assert( !(Internal.size() % 2) );
173 if( !Internal.empty() ) {
174 //os.write(&Internal[0], Internal.size());
175 std::vector<char> copy = Internal;
176 TSwap::SwapArray((TType*)(void*)&copy[0], Internal.size() / sizeof(TType) );
177 os.write(&copy[0], copy.size());
178 }
179 return os;
180 }
181
182 template <typename TSwap>
183 std::ostream const &Write(std::ostream &os) const {
184 return Write<TSwap,uint8_t>(os);
185 }
186
193 bool IsPrintable(VL length) const {
194 gdcm_assert( length <= Length );
195 for(unsigned int i=0; i<length; i++)
196 {
197 if ( i == (length-1) && Internal[i] == '\0') continue;
198 if ( !( isprint((unsigned char)Internal[i]) || isspace((unsigned char)Internal[i]) ) )
199 {
200 //gdcmWarningMacro( "Cannot print :" << i );
201 return false;
202 }
203 }
204 return true;
205 }
206
208 void PrintPNXML(std::ostream &os) const;
209 void PrintASCIIXML(std::ostream &os) const;
210 void PrintHexXML(std::ostream &os) const;
211 protected:
212 void Print(std::ostream &os) const override {
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//Introduce check for invalid XML characters
236 friend std::ostream& operator<<(std::ostream &os,const char c);
237*/
238
239 void SetLengthOnly(VL vl) override {
240 Length = vl;
241 }
242
243 private:
244 std::vector<char> Internal;
245
246 // WARNING Length IS NOT Internal.size() some *featured* DICOM
247 // implementation define odd length, we always load them as even number
248 // of byte, so we need to keep the right Length
249 VL Length;
250};
251
252} // end namespace gdcm_ns
253
254#endif //GDCMBYTEVALUE_H
gdcm::ByteValue::operator==
bool operator==(const ByteValue &val) const
Definition gdcmByteValue.h:95
gdcm::ByteValue::IsPrintable
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:193
gdcm::ByteValue::Append
void Append(ByteValue const &bv)
gdcm::ByteValue::operator=
ByteValue & operator=(const ByteValue &val)
Definition gdcmByteValue.h:89
gdcm::ByteValue::Read
std::istream & Read(std::istream &is, bool readvalues=true)
Definition gdcmByteValue.h:143
gdcm::ByteValue::SetLengthOnly
void SetLengthOnly(VL vl) override
Definition gdcmByteValue.h:239
gdcm::ByteValue::operator==
bool operator==(const Value &val) const override
Definition gdcmByteValue.h:102
gdcm::ByteValue::IsEmpty
bool IsEmpty() const
Definition gdcmByteValue.h:73
gdcm::ByteValue::GetVoidPointer
const void * GetVoidPointer() const
Definition gdcmByteValue.h:119
gdcm::ByteValue::Write
std::ostream const & Write(std::ostream &os) const
Definition gdcmByteValue.h:183
gdcm::ByteValue::SetLength
void SetLength(VL vl) override
gdcm::ByteValue::Read
std::istream & Read(std::istream &is)
Definition gdcmByteValue.h:165
gdcm::ByteValue::GetBuffer
bool GetBuffer(char *buffer, unsigned long length) const
gdcm::ByteValue::Write
std::ostream const & Write(std::ostream &os) const
Definition gdcmByteValue.h:171
gdcm::ByteValue::PrintGroupLength
void PrintGroupLength(std::ostream &os)
Definition gdcmByteValue.h:68
gdcm::ByteValue::PrintPNXML
void PrintPNXML(std::ostream &os) const
gdcm::ByteValue::PrintASCIIXML
void PrintASCIIXML(std::ostream &os) const
gdcm::ByteValue::Fill
void Fill(char c)
Definition gdcmByteValue.h:127
gdcm::ByteValue::WriteBuffer
bool WriteBuffer(std::ostream &os) const
Definition gdcmByteValue.h:133
gdcm::ByteValue::GetPointer
const char * GetPointer() const
Definition gdcmByteValue.h:114
gdcm::ByteValue::PrintHexXML
void PrintHexXML(std::ostream &os) const
gdcm::ByteValue::Clear
void Clear() override
Definition gdcmByteValue.h:110
gdcm::ByteValue::ByteValue
ByteValue(const char *array=nullptr, VL const &vl=0)
Definition gdcmByteValue.h:38
gdcm::ByteValue::ComputeLength
VL ComputeLength() const
Definition gdcmByteValue.h:83
gdcm::ByteValue::Print
void Print(std::ostream &os) const override
Definition gdcmByteValue.h:212
gdcm::ByteValue::GetVoidPointer
void * GetVoidPointer()
Definition gdcmByteValue.h:123
gdcm::ByteValue::GetLength
VL GetLength() const override
Definition gdcmByteValue.h:81
gdcm::ByteValue::PrintHex
void PrintHex(std::ostream &os, VL maxlength) const
gdcm::ByteValue::~ByteValue
~ByteValue() override
Definition gdcmByteValue.h:57
gdcm::ByteValue::PrintASCII
void PrintASCII(std::ostream &os, VL maxlength) const
gdcm::ByteValue::ByteValue
ByteValue(std::vector< char > &v)
Definition gdcmByteValue.h:52
gdcm::VL
Value Length.
Definition gdcmVL.h:30
gdcm::Value::Value
Value()=default
gdcm_assert
#define gdcm_assert(cond)
Definition gdcmException.h:104
gdcmTrace.h
gdcmVL.h
gdcmValue.h
GDCM_EXPORT
#define GDCM_EXPORT
Definition gdcmWin32.h:34