FEAT 3
Finite Element Analysis Toolbox
Loading...
Searching...
No Matches
binary_stream.hpp
1// FEAT3: Finite Element Analysis Toolbox, Version 3
2// Copyright (C) 2010 by Stefan Turek & the FEAT group
3// FEAT3 is released under the GNU General Public License version 3,
4// see the file 'copyright.txt' in the top level directory for details.
5
6#pragma once
7
8// includes, system
9#include <vector>
10#include <iostream>
11
12namespace FEAT
13{
29 public std::iostream
30 {
31 private:
33
40 class BinaryBuffer :
41 public std::basic_streambuf<char>
42 {
43 private:
44 typedef std::basic_streambuf<char> base_class;
45 typedef typename base_class::traits_type traits_type;
46 typedef std::vector<char>::size_type datasize;
47 typedef std::streamsize streamsize;
48
50 std::vector<char> _data;
52 datasize _data_pos;
53
54 public:
55 BinaryBuffer() :
56 _data_pos(0)
57 {
58 }
59
60 streamsize size() const
61 {
62 return streamsize(_data.size());
63 }
64
65 void clear()
66 {
67 _data.clear();
68 _data_pos = datasize(0);
69 }
70
71 char* data()
72 {
73 return _data.data();
74 }
75
76 const char* data() const
77 {
78 return _data.data();
79 }
80
81 std::vector<char>& container()
82 {
83 return _data;
84 }
85
86 const std::vector<char>& container() const
87 {
88 return _data;
89 }
90
91 protected:
92 virtual std::streamsize xsputn(const char* ptr, std::streamsize count) override
93 {
94 streamsize copied(0);
95
96 // Ensure that the vector has sufficient length; if not, then resize the vector
97 if(_data_pos + datasize(count) > _data.size())
98 _data.resize(_data_pos + datasize(count));
99
100 // copy the data
101 for(; copied < count; ++_data_pos, ++copied, ++ptr)
102 _data[_data_pos] = *ptr;
103
104 return copied;
105 }
106
107 virtual std::streamsize xsgetn(char* ptr, std::streamsize count) override
108 {
109 streamsize copied(0);
110 datasize len(_data.size());
111
112 // Ensure that we do not read beyond the end of the buffer.
113 if(_data_pos + datasize(count) > len)
114 count = streamsize(len - _data_pos);
115
116 // copy the data
117 for(; copied < count; ++_data_pos, ++copied, ++ptr)
118 *ptr = _data[_data_pos];
119
120 return copied;
121 }
122
123 virtual pos_type seekoff(
124 off_type off,
125 std::ios_base::seekdir way,
126 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
127 {
128 if((which & (std::ios_base::in|std::ios_base::out)) == 0)
129 return pos_type(-1);
130
131 switch(way)
132 {
133 case std::ios_base::beg:
134 if((off < 0) || (off > off_type(_data.size())))
135 return pos_type(-1);
136 return pos_type(std::streamoff(_data_pos = datasize(off)));
137
138 case std::ios_base::cur:
139 if((off < 0) && (-off > off_type(_data_pos)))
140 return pos_type(-1);
141 if((off > 0) && (off_type(_data_pos) + off > off_type(_data.size())))
142 return pos_type(-1);
143 return pos_type(std::streamoff(_data_pos = datasize(off_type(_data_pos) + off)));
144
145 case std::ios_base::end:
146 if((off > 0) || (-off > off_type(_data.size())))
147 return pos_type(-1);
148 return pos_type(std::streamoff(_data_pos = datasize(off_type(_data.size()) + off)));
149
150 default:
151 return pos_type(-1);
152 }
153 }
154
155 virtual pos_type seekpos(
156 pos_type pos,
157 std::ios_base::openmode which = std::ios_base::in | std::ios_base::out) override
158 {
159 if((which & (std::ios_base::in|std::ios_base::out)) == 0)
160 return pos_type(-1);
161
162 // Ensure the position is not out-of-bounds
163 if (pos >= pos_type(std::streamoff(_data.size())))
164 return pos_type(-1);
165
166 // move stream position
167 return pos_type(std::streamoff(_data_pos = datasize(pos)));
168 }
169
170 virtual int overflow(int c = EOF) override
171 {
172 if(c == EOF)
173 return EOF;
174
175 // convert to char
176 const char cc = traits_type::to_char_type(c);
177
178 // push to vector
179 _data.push_back(cc);
180
181 // return put character
182 return traits_type::to_int_type(cc);
183 }
184 }; // class BinaryBuffer
186
187 // the stream's buffer
188 BinaryBuffer _buffer;
189
190 public:
193 std::iostream(&_buffer)
194 {
195 }
196
201 std::streamsize size() const
202 {
203 return _buffer.size();
204 }
205
209 void clear()
210 {
211 _buffer.clear();
212 }
213
218 char* data()
219 {
220 return _buffer.data();
221 }
222
227 const char* data() const
228 {
229 return _buffer.data();
230 }
231
236 std::vector<char>& container()
237 {
238 return _buffer.container();
239 }
240
245 const std::vector<char>& container() const
246 {
247 return _buffer.container();
248 }
249
260 void read_stream(std::istream& is)
261 {
262 clear();
263
264 // seek to end of file
265 is.seekg(std::streamoff(0), std::ios_base::end);
266
267 // get filesize
268 const std::streampos filesize = is.tellg();
269
270 // seek to beginning of file
271 is.seekg(std::streamoff(0), std::ios_base::beg);
272
273 // get our stream container
274 std::vector<char>& content = _buffer.container();
275
276 // resize container
277 content.resize(std::size_t(filesize));
278
279 // read into our stream buffer
280 is.read(content.data(), filesize);
281 }
282
292 void write_stream(std::ostream& os) const
293 {
294 os.write(data(), size());
295 }
296 }; // class BinaryStream
297} // namespace FEAT
Binary Stream class.
std::vector< char > & container()
Returns a reference to the internal vector container.
char * data()
Returns the data array of the stream.
const char * data() const
Returns the data array of the stream.
BinaryStream()
default CTOR
void read_stream(std::istream &is)
Reads the content of a binary input stream.
std::streamsize size() const
Returns the current size of the stream.
void clear()
Clears the current stream.
void write_stream(std::ostream &os) const
Writes the content to a binary output stream.
const std::vector< char > & container() const
Returns a reference to the internal vector container.
FEAT namespace.
Definition: adjactor.hpp:12