1 | 1 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,491 @@ |
1 |
+////////////////////////////////////////////////////////////////////////////// |
|
2 |
+// |
|
3 |
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost |
|
4 |
+// Software License, Version 1.0. (See accompanying file |
|
5 |
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
6 |
+// |
|
7 |
+// See http://www.boost.org/libs/interprocess for documentation. |
|
8 |
+// |
|
9 |
+////////////////////////////////////////////////////////////////////////////// |
|
10 |
+// |
|
11 |
+// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012. |
|
12 |
+// Changed internal SGI string to a buffer. Added efficient |
|
13 |
+// internal buffer get/set/swap functions, so that we can obtain/establish the |
|
14 |
+// internal buffer without any reallocation or copy. Kill those temporaries! |
|
15 |
+/////////////////////////////////////////////////////////////////////////////// |
|
16 |
+/* |
|
17 |
+ * Copyright (c) 1998 |
|
18 |
+ * Silicon Graphics Computer Systems, Inc. |
|
19 |
+ * |
|
20 |
+ * Permission to use, copy, modify, distribute and sell this software |
|
21 |
+ * and its documentation for any purpose is hereby granted without fee, |
|
22 |
+ * provided that the above copyright notice appear in all copies and |
|
23 |
+ * that both that copyright notice and this permission notice appear |
|
24 |
+ * in supporting documentation. Silicon Graphics makes no |
|
25 |
+ * representations about the suitability of this software for any |
|
26 |
+ * purpose. It is provided "as is" without express or implied warranty. |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+//!\file |
|
30 |
+//!This file defines basic_bufferbuf, basic_ibufferstream, |
|
31 |
+//!basic_obufferstream, and basic_bufferstream classes. These classes |
|
32 |
+//!represent streamsbufs and streams whose sources or destinations |
|
33 |
+//!are fixed size character buffers. |
|
34 |
+ |
|
35 |
+#ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP |
|
36 |
+#define BOOST_INTERPROCESS_BUFFERSTREAM_HPP |
|
37 |
+ |
|
38 |
+#ifndef BOOST_CONFIG_HPP |
|
39 |
+# include <boost/config.hpp> |
|
40 |
+#endif |
|
41 |
+# |
|
42 |
+#if defined(BOOST_HAS_PRAGMA_ONCE) |
|
43 |
+# pragma once |
|
44 |
+#endif |
|
45 |
+ |
|
46 |
+#include <boost/interprocess/detail/config_begin.hpp> |
|
47 |
+#include <boost/interprocess/detail/workaround.hpp> |
|
48 |
+ |
|
49 |
+#include <iosfwd> |
|
50 |
+#include <ios> |
|
51 |
+#include <istream> |
|
52 |
+#include <ostream> |
|
53 |
+#include <string> // char traits |
|
54 |
+#include <cstddef> // ptrdiff_t |
|
55 |
+#include <boost/assert.hpp> |
|
56 |
+#include <boost/interprocess/interprocess_fwd.hpp> |
|
57 |
+ |
|
58 |
+namespace boost { namespace interprocess { |
|
59 |
+ |
|
60 |
+//!A streambuf class that controls the transmission of elements to and from |
|
61 |
+//!a basic_xbufferstream. The elements are transmitted from a to a fixed |
|
62 |
+//!size buffer |
|
63 |
+template <class CharT, class CharTraits> |
|
64 |
+class basic_bufferbuf |
|
65 |
+ : public std::basic_streambuf<CharT, CharTraits> |
|
66 |
+{ |
|
67 |
+ public: |
|
68 |
+ typedef CharT char_type; |
|
69 |
+ typedef typename CharTraits::int_type int_type; |
|
70 |
+ typedef typename CharTraits::pos_type pos_type; |
|
71 |
+ typedef typename CharTraits::off_type off_type; |
|
72 |
+ typedef CharTraits traits_type; |
|
73 |
+ typedef std::basic_streambuf<char_type, traits_type> basic_streambuf_t; |
|
74 |
+ |
|
75 |
+ public: |
|
76 |
+ //!Constructor. |
|
77 |
+ //!Does not throw. |
|
78 |
+ explicit basic_bufferbuf(std::ios_base::openmode mode |
|
79 |
+ = std::ios_base::in | std::ios_base::out) |
|
80 |
+ : basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0) |
|
81 |
+ {} |
|
82 |
+ |
|
83 |
+ //!Constructor. Assigns formatting buffer. |
|
84 |
+ //!Does not throw. |
|
85 |
+ explicit basic_bufferbuf(CharT *buf, std::size_t length, |
|
86 |
+ std::ios_base::openmode mode |
|
87 |
+ = std::ios_base::in | std::ios_base::out) |
|
88 |
+ : basic_streambuf_t(), m_mode(mode), m_buffer(buf), m_length(length) |
|
89 |
+ { this->set_pointers(); } |
|
90 |
+ |
|
91 |
+ virtual ~basic_bufferbuf(){} |
|
92 |
+ |
|
93 |
+ public: |
|
94 |
+ //!Returns the pointer and size of the internal buffer. |
|
95 |
+ //!Does not throw. |
|
96 |
+ std::pair<CharT *, std::size_t> buffer() const |
|
97 |
+ { return std::pair<CharT *, std::size_t>(m_buffer, m_length); } |
|
98 |
+ |
|
99 |
+ //!Sets the underlying buffer to a new value |
|
100 |
+ //!Does not throw. |
|
101 |
+ void buffer(CharT *buf, std::size_t length) |
|
102 |
+ { m_buffer = buf; m_length = length; this->set_pointers(); } |
|
103 |
+ |
|
104 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
105 |
+ private: |
|
106 |
+ void set_pointers() |
|
107 |
+ { |
|
108 |
+ // The initial read position is the beginning of the buffer. |
|
109 |
+ if(m_mode & std::ios_base::in) |
|
110 |
+ this->setg(m_buffer, m_buffer, m_buffer + m_length); |
|
111 |
+ |
|
112 |
+ // The initial write position is the beginning of the buffer. |
|
113 |
+ if(m_mode & std::ios_base::out) |
|
114 |
+ this->setp(m_buffer, m_buffer + m_length); |
|
115 |
+ } |
|
116 |
+ |
|
117 |
+ protected: |
|
118 |
+ virtual int_type underflow() |
|
119 |
+ { |
|
120 |
+ // Precondition: gptr() >= egptr(). Returns a character, if available. |
|
121 |
+ return this->gptr() != this->egptr() ? |
|
122 |
+ CharTraits::to_int_type(*this->gptr()) : CharTraits::eof(); |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ virtual int_type pbackfail(int_type c = CharTraits::eof()) |
|
126 |
+ { |
|
127 |
+ if(this->gptr() != this->eback()) { |
|
128 |
+ if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
|
129 |
+ if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { |
|
130 |
+ this->gbump(-1); |
|
131 |
+ return c; |
|
132 |
+ } |
|
133 |
+ else if(m_mode & std::ios_base::out) { |
|
134 |
+ this->gbump(-1); |
|
135 |
+ *this->gptr() = CharTraits::to_char_type(c); |
|
136 |
+ return c; |
|
137 |
+ } |
|
138 |
+ else |
|
139 |
+ return CharTraits::eof(); |
|
140 |
+ } |
|
141 |
+ else { |
|
142 |
+ this->gbump(-1); |
|
143 |
+ return CharTraits::not_eof(c); |
|
144 |
+ } |
|
145 |
+ } |
|
146 |
+ else |
|
147 |
+ return CharTraits::eof(); |
|
148 |
+ } |
|
149 |
+ |
|
150 |
+ virtual int_type overflow(int_type c = CharTraits::eof()) |
|
151 |
+ { |
|
152 |
+ if(m_mode & std::ios_base::out) { |
|
153 |
+ if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
|
154 |
+// if(!(m_mode & std::ios_base::in)) { |
|
155 |
+// if(this->pptr() != this->epptr()) { |
|
156 |
+// *this->pptr() = CharTraits::to_char_type(c); |
|
157 |
+// this->pbump(1); |
|
158 |
+// return c; |
|
159 |
+// } |
|
160 |
+// else |
|
161 |
+// return CharTraits::eof(); |
|
162 |
+// } |
|
163 |
+// else { |
|
164 |
+ if(this->pptr() == this->epptr()) { |
|
165 |
+ //We can't append to a static buffer |
|
166 |
+ return CharTraits::eof(); |
|
167 |
+ } |
|
168 |
+ else { |
|
169 |
+ *this->pptr() = CharTraits::to_char_type(c); |
|
170 |
+ this->pbump(1); |
|
171 |
+ return c; |
|
172 |
+ } |
|
173 |
+// } |
|
174 |
+ } |
|
175 |
+ else // c is EOF, so we don't have to do anything |
|
176 |
+ return CharTraits::not_eof(c); |
|
177 |
+ } |
|
178 |
+ else // Overflow always fails if it's read-only. |
|
179 |
+ return CharTraits::eof(); |
|
180 |
+ } |
|
181 |
+ |
|
182 |
+ virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, |
|
183 |
+ std::ios_base::openmode mode |
|
184 |
+ = std::ios_base::in | std::ios_base::out) |
|
185 |
+ { |
|
186 |
+ bool in = false; |
|
187 |
+ bool out = false; |
|
188 |
+ |
|
189 |
+ const std::ios_base::openmode inout = |
|
190 |
+ std::ios_base::in | std::ios_base::out; |
|
191 |
+ |
|
192 |
+ if((mode & inout) == inout) { |
|
193 |
+ if(dir == std::ios_base::beg || dir == std::ios_base::end) |
|
194 |
+ in = out = true; |
|
195 |
+ } |
|
196 |
+ else if(mode & std::ios_base::in) |
|
197 |
+ in = true; |
|
198 |
+ else if(mode & std::ios_base::out) |
|
199 |
+ out = true; |
|
200 |
+ |
|
201 |
+ if(!in && !out) |
|
202 |
+ return pos_type(off_type(-1)); |
|
203 |
+ else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) || |
|
204 |
+ (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0)))) |
|
205 |
+ return pos_type(off_type(-1)); |
|
206 |
+ |
|
207 |
+ std::streamoff newoff; |
|
208 |
+ switch(dir) { |
|
209 |
+ case std::ios_base::beg: |
|
210 |
+ newoff = 0; |
|
211 |
+ break; |
|
212 |
+ case std::ios_base::end: |
|
213 |
+ newoff = static_cast<std::streamoff>(m_length); |
|
214 |
+ break; |
|
215 |
+ case std::ios_base::cur: |
|
216 |
+ newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback()) |
|
217 |
+ : static_cast<std::streamoff>(this->pptr() - this->pbase()); |
|
218 |
+ break; |
|
219 |
+ default: |
|
220 |
+ return pos_type(off_type(-1)); |
|
221 |
+ } |
|
222 |
+ |
|
223 |
+ off += newoff; |
|
224 |
+ |
|
225 |
+ if(in) { |
|
226 |
+ std::ptrdiff_t n = this->egptr() - this->eback(); |
|
227 |
+ |
|
228 |
+ if(off < 0 || off > n) |
|
229 |
+ return pos_type(off_type(-1)); |
|
230 |
+ else |
|
231 |
+ this->setg(this->eback(), this->eback() + off, this->eback() + n); |
|
232 |
+ } |
|
233 |
+ |
|
234 |
+ if(out) { |
|
235 |
+ std::ptrdiff_t n = this->epptr() - this->pbase(); |
|
236 |
+ |
|
237 |
+ if(off < 0 || off > n) |
|
238 |
+ return pos_type(off_type(-1)); |
|
239 |
+ else { |
|
240 |
+ this->setp(this->pbase(), this->pbase() + n); |
|
241 |
+ this->pbump(static_cast<int>(off)); |
|
242 |
+ } |
|
243 |
+ } |
|
244 |
+ |
|
245 |
+ return pos_type(off); |
|
246 |
+ } |
|
247 |
+ |
|
248 |
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode |
|
249 |
+ = std::ios_base::in | std::ios_base::out) |
|
250 |
+ { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } |
|
251 |
+ |
|
252 |
+ private: |
|
253 |
+ std::ios_base::openmode m_mode; |
|
254 |
+ CharT * m_buffer; |
|
255 |
+ std::size_t m_length; |
|
256 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
257 |
+}; |
|
258 |
+ |
|
259 |
+//!A basic_istream class that uses a fixed size character buffer |
|
260 |
+//!as its formatting buffer. |
|
261 |
+template <class CharT, class CharTraits> |
|
262 |
+class basic_ibufferstream : |
|
263 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
264 |
+ private basic_bufferbuf<CharT, CharTraits>, |
|
265 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
266 |
+ public std::basic_istream<CharT, CharTraits> |
|
267 |
+{ |
|
268 |
+ public: // Typedefs |
|
269 |
+ typedef typename std::basic_ios |
|
270 |
+ <CharT, CharTraits>::char_type char_type; |
|
271 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
272 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
273 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
274 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
275 |
+ |
|
276 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
277 |
+ private: |
|
278 |
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t; |
|
279 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
280 |
+ typedef std::basic_istream<char_type, CharTraits> basic_streambuf_t; |
|
281 |
+ bufferbuf_t & get_buf() { return *this; } |
|
282 |
+ const bufferbuf_t & get_buf() const{ return *this; } |
|
283 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
284 |
+ |
|
285 |
+ public: |
|
286 |
+ //!Constructor. |
|
287 |
+ //!Does not throw. |
|
288 |
+ basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in) |
|
289 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
290 |
+ //virtual base of basic_istream. The class will be initialized when |
|
291 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
292 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
293 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
294 |
+ bufferbuf_t(mode | std::ios_base::in) |
|
295 |
+ , basic_streambuf_t(this) |
|
296 |
+ {} |
|
297 |
+ |
|
298 |
+ //!Constructor. Assigns formatting buffer. |
|
299 |
+ //!Does not throw. |
|
300 |
+ basic_ibufferstream(const CharT *buf, std::size_t length, |
|
301 |
+ std::ios_base::openmode mode = std::ios_base::in) |
|
302 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
303 |
+ //virtual base of basic_istream. The class will be initialized when |
|
304 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
305 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
306 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
307 |
+ bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in) |
|
308 |
+ , basic_streambuf_t(this) |
|
309 |
+ {} |
|
310 |
+ |
|
311 |
+ ~basic_ibufferstream(){} |
|
312 |
+ |
|
313 |
+ public: |
|
314 |
+ //!Returns the address of the stored |
|
315 |
+ //!stream buffer. |
|
316 |
+ basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
|
317 |
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); } |
|
318 |
+ |
|
319 |
+ //!Returns the pointer and size of the internal buffer. |
|
320 |
+ //!Does not throw. |
|
321 |
+ std::pair<const CharT *, std::size_t> buffer() const |
|
322 |
+ { return get_buf().buffer(); } |
|
323 |
+ |
|
324 |
+ //!Sets the underlying buffer to a new value. Resets |
|
325 |
+ //!stream position. Does not throw. |
|
326 |
+ void buffer(const CharT *buf, std::size_t length) |
|
327 |
+ { get_buf().buffer(const_cast<CharT*>(buf), length); } |
|
328 |
+}; |
|
329 |
+ |
|
330 |
+//!A basic_ostream class that uses a fixed size character buffer |
|
331 |
+//!as its formatting buffer. |
|
332 |
+template <class CharT, class CharTraits> |
|
333 |
+class basic_obufferstream : |
|
334 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
335 |
+ private basic_bufferbuf<CharT, CharTraits>, |
|
336 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
337 |
+ public std::basic_ostream<CharT, CharTraits> |
|
338 |
+{ |
|
339 |
+ public: |
|
340 |
+ typedef typename std::basic_ios |
|
341 |
+ <CharT, CharTraits>::char_type char_type; |
|
342 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
343 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
344 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
345 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
346 |
+ |
|
347 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
348 |
+ private: |
|
349 |
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t; |
|
350 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
351 |
+ typedef std::basic_ostream<char_type, CharTraits> basic_ostream_t; |
|
352 |
+ bufferbuf_t & get_buf() { return *this; } |
|
353 |
+ const bufferbuf_t & get_buf() const{ return *this; } |
|
354 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
355 |
+ |
|
356 |
+ public: |
|
357 |
+ //!Constructor. |
|
358 |
+ //!Does not throw. |
|
359 |
+ basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out) |
|
360 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
361 |
+ //virtual base of basic_istream. The class will be initialized when |
|
362 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
363 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
364 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
365 |
+ bufferbuf_t(mode | std::ios_base::out) |
|
366 |
+ , basic_ostream_t(this) |
|
367 |
+ {} |
|
368 |
+ |
|
369 |
+ //!Constructor. Assigns formatting buffer. |
|
370 |
+ //!Does not throw. |
|
371 |
+ basic_obufferstream(CharT *buf, std::size_t length, |
|
372 |
+ std::ios_base::openmode mode = std::ios_base::out) |
|
373 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
374 |
+ //virtual base of basic_istream. The class will be initialized when |
|
375 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
376 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
377 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
378 |
+ bufferbuf_t(buf, length, mode | std::ios_base::out) |
|
379 |
+ , basic_ostream_t(this) |
|
380 |
+ {} |
|
381 |
+ |
|
382 |
+ ~basic_obufferstream(){} |
|
383 |
+ |
|
384 |
+ public: |
|
385 |
+ //!Returns the address of the stored |
|
386 |
+ //!stream buffer. |
|
387 |
+ basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
|
388 |
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); } |
|
389 |
+ |
|
390 |
+ //!Returns the pointer and size of the internal buffer. |
|
391 |
+ //!Does not throw. |
|
392 |
+ std::pair<CharT *, std::size_t> buffer() const |
|
393 |
+ { return get_buf().buffer(); } |
|
394 |
+ |
|
395 |
+ //!Sets the underlying buffer to a new value. Resets |
|
396 |
+ //!stream position. Does not throw. |
|
397 |
+ void buffer(CharT *buf, std::size_t length) |
|
398 |
+ { get_buf().buffer(buf, length); } |
|
399 |
+}; |
|
400 |
+ |
|
401 |
+ |
|
402 |
+//!A basic_iostream class that uses a fixed size character buffer |
|
403 |
+//!as its formatting buffer. |
|
404 |
+template <class CharT, class CharTraits> |
|
405 |
+class basic_bufferstream : |
|
406 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
407 |
+ private basic_bufferbuf<CharT, CharTraits>, |
|
408 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
409 |
+ public std::basic_iostream<CharT, CharTraits> |
|
410 |
+{ |
|
411 |
+ public: // Typedefs |
|
412 |
+ typedef typename std::basic_ios |
|
413 |
+ <CharT, CharTraits>::char_type char_type; |
|
414 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
415 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
416 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
417 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
418 |
+ |
|
419 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
420 |
+ private: |
|
421 |
+ typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t; |
|
422 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
423 |
+ typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t; |
|
424 |
+ bufferbuf_t & get_buf() { return *this; } |
|
425 |
+ const bufferbuf_t & get_buf() const{ return *this; } |
|
426 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
427 |
+ |
|
428 |
+ public: |
|
429 |
+ //!Constructor. |
|
430 |
+ //!Does not throw. |
|
431 |
+ basic_bufferstream(std::ios_base::openmode mode |
|
432 |
+ = std::ios_base::in | std::ios_base::out) |
|
433 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
434 |
+ //virtual base of basic_istream. The class will be initialized when |
|
435 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
436 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
437 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
438 |
+ bufferbuf_t(mode) |
|
439 |
+ , basic_iostream_t(this) |
|
440 |
+ {} |
|
441 |
+ |
|
442 |
+ //!Constructor. Assigns formatting buffer. |
|
443 |
+ //!Does not throw. |
|
444 |
+ basic_bufferstream(CharT *buf, std::size_t length, |
|
445 |
+ std::ios_base::openmode mode |
|
446 |
+ = std::ios_base::in | std::ios_base::out) |
|
447 |
+ : //basic_ios_t() is called first (lefting it uninitialized) as it's a |
|
448 |
+ //virtual base of basic_istream. The class will be initialized when |
|
449 |
+ //basic_istream is constructed calling basic_ios_t::init(). |
|
450 |
+ //As bufferbuf_t's constructor does not throw there is no risk of |
|
451 |
+ //calling the basic_ios_t's destructor without calling basic_ios_t::init() |
|
452 |
+ bufferbuf_t(buf, length, mode) |
|
453 |
+ , basic_iostream_t(this) |
|
454 |
+ {} |
|
455 |
+ |
|
456 |
+ ~basic_bufferstream(){} |
|
457 |
+ |
|
458 |
+ public: |
|
459 |
+ //!Returns the address of the stored |
|
460 |
+ //!stream buffer. |
|
461 |
+ basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
|
462 |
+ { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); } |
|
463 |
+ |
|
464 |
+ //!Returns the pointer and size of the internal buffer. |
|
465 |
+ //!Does not throw. |
|
466 |
+ std::pair<CharT *, std::size_t> buffer() const |
|
467 |
+ { return get_buf().buffer(); } |
|
468 |
+ |
|
469 |
+ //!Sets the underlying buffer to a new value. Resets |
|
470 |
+ //!stream position. Does not throw. |
|
471 |
+ void buffer(CharT *buf, std::size_t length) |
|
472 |
+ { get_buf().buffer(buf, length); } |
|
473 |
+}; |
|
474 |
+ |
|
475 |
+//Some typedefs to simplify usage |
|
476 |
+typedef basic_bufferbuf<char> bufferbuf; |
|
477 |
+typedef basic_bufferstream<char> bufferstream; |
|
478 |
+typedef basic_ibufferstream<char> ibufferstream; |
|
479 |
+typedef basic_obufferstream<char> obufferstream; |
|
480 |
+ |
|
481 |
+typedef basic_bufferbuf<wchar_t> wbufferbuf; |
|
482 |
+typedef basic_bufferstream<wchar_t> wbufferstream; |
|
483 |
+typedef basic_ibufferstream<wchar_t> wibufferstream; |
|
484 |
+typedef basic_obufferstream<wchar_t> wobufferstream; |
|
485 |
+ |
|
486 |
+ |
|
487 |
+}} //namespace boost { namespace interprocess { |
|
488 |
+ |
|
489 |
+#include <boost/interprocess/detail/config_end.hpp> |
|
490 |
+ |
|
491 |
+#endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */ |
0 | 492 |
new file mode 100755 |
... | ... |
@@ -0,0 +1,622 @@ |
1 |
+////////////////////////////////////////////////////////////////////////////// |
|
2 |
+// |
|
3 |
+// (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost |
|
4 |
+// Software License, Version 1.0. (See accompanying file |
|
5 |
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
|
6 |
+// |
|
7 |
+// See http://www.boost.org/libs/interprocess for documentation. |
|
8 |
+// |
|
9 |
+////////////////////////////////////////////////////////////////////////////// |
|
10 |
+// |
|
11 |
+// This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012. |
|
12 |
+// Changed internal SGI string to a generic, templatized vector. Added efficient |
|
13 |
+// internal buffer get/set/swap functions, so that we can obtain/establish the |
|
14 |
+// internal buffer without any reallocation or copy. Kill those temporaries! |
|
15 |
+/////////////////////////////////////////////////////////////////////////////// |
|
16 |
+/* |
|
17 |
+ * Copyright (c) 1998 |
|
18 |
+ * Silicon Graphics Computer Systems, Inc. |
|
19 |
+ * |
|
20 |
+ * Permission to use, copy, modify, distribute and sell this software |
|
21 |
+ * and its documentation for any purpose is hereby granted without fee, |
|
22 |
+ * provided that the above copyright notice appear in all copies and |
|
23 |
+ * that both that copyright notice and this permission notice appear |
|
24 |
+ * in supporting documentation. Silicon Graphics makes no |
|
25 |
+ * representations about the suitability of this software for any |
|
26 |
+ * purpose. It is provided "as is" without express or implied warranty. |
|
27 |
+ */ |
|
28 |
+ |
|
29 |
+//!\file |
|
30 |
+//!This file defines basic_vectorbuf, basic_ivectorstream, |
|
31 |
+//!basic_ovectorstream, and basic_vectorstreamclasses. These classes |
|
32 |
+//!represent streamsbufs and streams whose sources or destinations are |
|
33 |
+//!STL-like vectors that can be swapped with external vectors to avoid |
|
34 |
+//!unnecessary allocations/copies. |
|
35 |
+ |
|
36 |
+#ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP |
|
37 |
+#define BOOST_INTERPROCESS_VECTORSTREAM_HPP |
|
38 |
+ |
|
39 |
+#ifndef BOOST_CONFIG_HPP |
|
40 |
+# include <boost/config.hpp> |
|
41 |
+#endif |
|
42 |
+# |
|
43 |
+#if defined(BOOST_HAS_PRAGMA_ONCE) |
|
44 |
+# pragma once |
|
45 |
+#endif |
|
46 |
+ |
|
47 |
+#include <boost/interprocess/detail/config_begin.hpp> |
|
48 |
+#include <boost/interprocess/detail/workaround.hpp> |
|
49 |
+ |
|
50 |
+#include <iosfwd> |
|
51 |
+#include <ios> |
|
52 |
+#include <istream> |
|
53 |
+#include <ostream> |
|
54 |
+#include <string> // char traits |
|
55 |
+#include <cstddef> // ptrdiff_t |
|
56 |
+#include <boost/interprocess/interprocess_fwd.hpp> |
|
57 |
+#include <boost/assert.hpp> |
|
58 |
+ |
|
59 |
+namespace boost { namespace interprocess { |
|
60 |
+ |
|
61 |
+//!A streambuf class that controls the transmission of elements to and from |
|
62 |
+//!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream. |
|
63 |
+//!It holds a character vector specified by CharVector template parameter |
|
64 |
+//!as its formatting buffer. The vector must have contiguous storage, like |
|
65 |
+//!std::vector, boost::interprocess::vector or boost::interprocess::basic_string |
|
66 |
+template <class CharVector, class CharTraits> |
|
67 |
+class basic_vectorbuf |
|
68 |
+ : public std::basic_streambuf<typename CharVector::value_type, CharTraits> |
|
69 |
+{ |
|
70 |
+ public: |
|
71 |
+ typedef CharVector vector_type; |
|
72 |
+ typedef typename CharVector::value_type char_type; |
|
73 |
+ typedef typename CharTraits::int_type int_type; |
|
74 |
+ typedef typename CharTraits::pos_type pos_type; |
|
75 |
+ typedef typename CharTraits::off_type off_type; |
|
76 |
+ typedef CharTraits traits_type; |
|
77 |
+ |
|
78 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
79 |
+ private: |
|
80 |
+ typedef std::basic_streambuf<char_type, traits_type> base_t; |
|
81 |
+ |
|
82 |
+ basic_vectorbuf(const basic_vectorbuf&); |
|
83 |
+ basic_vectorbuf & operator =(const basic_vectorbuf&); |
|
84 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
85 |
+ |
|
86 |
+ public: |
|
87 |
+ //!Constructor. Throws if vector_type default |
|
88 |
+ //!constructor throws. |
|
89 |
+ explicit basic_vectorbuf(std::ios_base::openmode mode |
|
90 |
+ = std::ios_base::in | std::ios_base::out) |
|
91 |
+ : base_t(), m_mode(mode) |
|
92 |
+ { this->initialize_pointers(); } |
|
93 |
+ |
|
94 |
+ //!Constructor. Throws if |
|
95 |
+ //!vector_type(const VectorParameter ¶m) throws. |
|
96 |
+ template<class VectorParameter> |
|
97 |
+ explicit basic_vectorbuf(const VectorParameter ¶m, |
|
98 |
+ std::ios_base::openmode mode |
|
99 |
+ = std::ios_base::in | std::ios_base::out) |
|
100 |
+ : base_t(), m_mode(mode), m_vect(param) |
|
101 |
+ { this->initialize_pointers(); } |
|
102 |
+ |
|
103 |
+ public: |
|
104 |
+ |
|
105 |
+ //!Swaps the underlying vector with the passed vector. |
|
106 |
+ //!This function resets the read/write position in the stream. |
|
107 |
+ //!Does not throw. |
|
108 |
+ void swap_vector(vector_type &vect) |
|
109 |
+ { |
|
110 |
+ if (this->m_mode & std::ios_base::out){ |
|
111 |
+ //Update high water if necessary |
|
112 |
+ //And resize vector to remove extra size |
|
113 |
+ if (mp_high_water < base_t::pptr()){ |
|
114 |
+ //Restore the vector's size if necessary |
|
115 |
+ mp_high_water = base_t::pptr(); |
|
116 |
+ } |
|
117 |
+ //This does not reallocate |
|
118 |
+ m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)); |
|
119 |
+ } |
|
120 |
+ //Now swap vector |
|
121 |
+ m_vect.swap(vect); |
|
122 |
+ this->initialize_pointers(); |
|
123 |
+ } |
|
124 |
+ |
|
125 |
+ //!Returns a const reference to the internal vector. |
|
126 |
+ //!Does not throw. |
|
127 |
+ const vector_type &vector() const |
|
128 |
+ { |
|
129 |
+ if (this->m_mode & std::ios_base::out){ |
|
130 |
+ if (mp_high_water < base_t::pptr()){ |
|
131 |
+ //Restore the vector's size if necessary |
|
132 |
+ mp_high_water = base_t::pptr(); |
|
133 |
+ } |
|
134 |
+ //This shouldn't reallocate |
|
135 |
+ typedef typename vector_type::size_type size_type; |
|
136 |
+ char_type *old_ptr = base_t::pbase(); |
|
137 |
+ size_type high_pos = size_type(mp_high_water-old_ptr); |
|
138 |
+ if(m_vect.size() > high_pos){ |
|
139 |
+ m_vect.resize(high_pos); |
|
140 |
+ //But we must update end write pointer because vector size is now shorter |
|
141 |
+ int old_pos = base_t::pptr() - base_t::pbase(); |
|
142 |
+ const_cast<basic_vectorbuf*>(this)->base_t::setp(old_ptr, old_ptr + high_pos); |
|
143 |
+ const_cast<basic_vectorbuf*>(this)->base_t::pbump(old_pos); |
|
144 |
+ } |
|
145 |
+ } |
|
146 |
+ return m_vect; |
|
147 |
+ } |
|
148 |
+ |
|
149 |
+ //!Preallocates memory from the internal vector. |
|
150 |
+ //!Resets the stream to the first position. |
|
151 |
+ //!Throws if the internals vector's memory allocation throws. |
|
152 |
+ void reserve(typename vector_type::size_type size) |
|
153 |
+ { |
|
154 |
+ if (this->m_mode & std::ios_base::out && size > m_vect.size()){ |
|
155 |
+ typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase(); |
|
156 |
+ typename vector_type::difference_type read_pos = base_t::gptr() - base_t::eback(); |
|
157 |
+ //Now update pointer data |
|
158 |
+ m_vect.reserve(size); |
|
159 |
+ this->initialize_pointers(); |
|
160 |
+ base_t::pbump((int)write_pos); |
|
161 |
+ if(this->m_mode & std::ios_base::in){ |
|
162 |
+ base_t::gbump((int)read_pos); |
|
163 |
+ } |
|
164 |
+ } |
|
165 |
+ } |
|
166 |
+ |
|
167 |
+ //!Calls clear() method of the internal vector. |
|
168 |
+ //!Resets the stream to the first position. |
|
169 |
+ void clear() |
|
170 |
+ { m_vect.clear(); this->initialize_pointers(); } |
|
171 |
+ |
|
172 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
173 |
+ private: |
|
174 |
+ //Maximizes high watermark to the initial vector size, |
|
175 |
+ //initializes read and write iostream buffers to the capacity |
|
176 |
+ //and resets stream positions |
|
177 |
+ void initialize_pointers() |
|
178 |
+ { |
|
179 |
+ // The initial read position is the beginning of the vector. |
|
180 |
+ if(!(m_mode & std::ios_base::out)){ |
|
181 |
+ if(m_vect.empty()){ |
|
182 |
+ this->setg(0, 0, 0); |
|
183 |
+ } |
|
184 |
+ else{ |
|
185 |
+ this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size()); |
|
186 |
+ } |
|
187 |
+ } |
|
188 |
+ |
|
189 |
+ // The initial write position is the beginning of the vector. |
|
190 |
+ if(m_mode & std::ios_base::out){ |
|
191 |
+ //First get real size |
|
192 |
+ int real_size = (int)m_vect.size(); |
|
193 |
+ //Then maximize size for high watermarking |
|
194 |
+ m_vect.resize(m_vect.capacity()); |
|
195 |
+ BOOST_ASSERT(m_vect.size() == m_vect.capacity()); |
|
196 |
+ //Set high watermarking with the expanded size |
|
197 |
+ mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0; |
|
198 |
+ //Now set formatting pointers |
|
199 |
+ if(m_vect.empty()){ |
|
200 |
+ this->setp(0, 0); |
|
201 |
+ if(m_mode & std::ios_base::in) |
|
202 |
+ this->setg(0, 0, 0); |
|
203 |
+ } |
|
204 |
+ else{ |
|
205 |
+ char_type *p = &m_vect[0]; |
|
206 |
+ this->setp(p, p + m_vect.size()); |
|
207 |
+ if(m_mode & std::ios_base::in) |
|
208 |
+ this->setg(p, p, p + real_size); |
|
209 |
+ } |
|
210 |
+ if (m_mode & (std::ios_base::app | std::ios_base::ate)){ |
|
211 |
+ base_t::pbump((int)real_size); |
|
212 |
+ } |
|
213 |
+ } |
|
214 |
+ } |
|
215 |
+ |
|
216 |
+ protected: |
|
217 |
+ virtual int_type underflow() |
|
218 |
+ { |
|
219 |
+ if (base_t::gptr() == 0) |
|
220 |
+ return CharTraits::eof(); |
|
221 |
+ if(m_mode & std::ios_base::out){ |
|
222 |
+ if (mp_high_water < base_t::pptr()) |
|
223 |
+ mp_high_water = base_t::pptr(); |
|
224 |
+ if (base_t::egptr() < mp_high_water) |
|
225 |
+ base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); |
|
226 |
+ } |
|
227 |
+ if (base_t::gptr() < base_t::egptr()) |
|
228 |
+ return CharTraits::to_int_type(*base_t::gptr()); |
|
229 |
+ return CharTraits::eof(); |
|
230 |
+ } |
|
231 |
+ |
|
232 |
+ virtual int_type pbackfail(int_type c = CharTraits::eof()) |
|
233 |
+ { |
|
234 |
+ if(this->gptr() != this->eback()) { |
|
235 |
+ if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
|
236 |
+ if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { |
|
237 |
+ this->gbump(-1); |
|
238 |
+ return c; |
|
239 |
+ } |
|
240 |
+ else if(m_mode & std::ios_base::out) { |
|
241 |
+ this->gbump(-1); |
|
242 |
+ *this->gptr() = c; |
|
243 |
+ return c; |
|
244 |
+ } |
|
245 |
+ else |
|
246 |
+ return CharTraits::eof(); |
|
247 |
+ } |
|
248 |
+ else { |
|
249 |
+ this->gbump(-1); |
|
250 |
+ return CharTraits::not_eof(c); |
|
251 |
+ } |
|
252 |
+ } |
|
253 |
+ else |
|
254 |
+ return CharTraits::eof(); |
|
255 |
+ } |
|
256 |
+ |
|
257 |
+ virtual int_type overflow(int_type c = CharTraits::eof()) |
|
258 |
+ { |
|
259 |
+ if(m_mode & std::ios_base::out) { |
|
260 |
+ if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
|
261 |
+ typedef typename vector_type::difference_type dif_t; |
|
262 |
+ //The new output position is the previous one plus one |
|
263 |
+ //because 'overflow' requires putting 'c' on the buffer |
|
264 |
+ dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1; |
|
265 |
+ //Adjust high water if necessary |
|
266 |
+ dif_t hipos = mp_high_water - base_t::pbase(); |
|
267 |
+ if (hipos < new_outpos) |
|
268 |
+ hipos = new_outpos; |
|
269 |
+ //Insert the new data |
|
270 |
+ m_vect.push_back(CharTraits::to_char_type(c)); |
|
271 |
+ m_vect.resize(m_vect.capacity()); |
|
272 |
+ BOOST_ASSERT(m_vect.size() == m_vect.capacity()); |
|
273 |
+ char_type* p = const_cast<char_type*>(&m_vect[0]); |
|
274 |
+ //A reallocation might have happened, update pointers |
|
275 |
+ base_t::setp(p, p + (dif_t)m_vect.size()); |
|
276 |
+ mp_high_water = p + hipos; |
|
277 |
+ if (m_mode & std::ios_base::in) |
|
278 |
+ base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water); |
|
279 |
+ //Update write position to the old position + 1 |
|
280 |
+ base_t::pbump((int)new_outpos); |
|
281 |
+ return c; |
|
282 |
+ } |
|
283 |
+ else // c is EOF, so we don't have to do anything |
|
284 |
+ return CharTraits::not_eof(c); |
|
285 |
+ } |
|
286 |
+ else // Overflow always fails if it's read-only. |
|
287 |
+ return CharTraits::eof(); |
|
288 |
+ } |
|
289 |
+ |
|
290 |
+ virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, |
|
291 |
+ std::ios_base::openmode mode |
|
292 |
+ = std::ios_base::in | std::ios_base::out) |
|
293 |
+ { |
|
294 |
+ //Get seek mode |
|
295 |
+ bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out)); |
|
296 |
+ //Test for logic errors |
|
297 |
+ if(!in & !out) |
|
298 |
+ return pos_type(off_type(-1)); |
|
299 |
+ else if((in && out) && (dir == std::ios_base::cur)) |
|
300 |
+ return pos_type(off_type(-1)); |
|
301 |
+ else if((in && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) || |
|
302 |
+ (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0)))) |
|
303 |
+ return pos_type(off_type(-1)); |
|
304 |
+ |
|
305 |
+ off_type newoff; |
|
306 |
+ //Just calculate the end of the stream. If the stream is read-only |
|
307 |
+ //the limit is the size of the vector. Otherwise, the high water mark |
|
308 |
+ //will mark the real size. |
|
309 |
+ off_type limit; |
|
310 |
+ if(m_mode & std::ios_base::out){ |
|
311 |
+ //Update high water marking because pptr() is going to change and it might |
|
312 |
+ //have been updated since last overflow() |
|
313 |
+ if(mp_high_water < base_t::pptr()) |
|
314 |
+ mp_high_water = base_t::pptr(); |
|
315 |
+ //Update read limits in case high water mark was changed |
|
316 |
+ if(m_mode & std::ios_base::in){ |
|
317 |
+ if (base_t::egptr() < mp_high_water) |
|
318 |
+ base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); |
|
319 |
+ } |
|
320 |
+ limit = static_cast<off_type>(mp_high_water - base_t::pbase()); |
|
321 |
+ } |
|
322 |
+ else{ |
|
323 |
+ limit = static_cast<off_type>(m_vect.size()); |
|
324 |
+ } |
|
325 |
+ |
|
326 |
+ switch(dir) { |
|
327 |
+ case std::ios_base::beg: |
|
328 |
+ newoff = 0; |
|
329 |
+ break; |
|
330 |
+ case std::ios_base::end: |
|
331 |
+ newoff = limit; |
|
332 |
+ break; |
|
333 |
+ case std::ios_base::cur: |
|
334 |
+ newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback()) |
|
335 |
+ : static_cast<std::streamoff>(this->pptr() - this->pbase()); |
|
336 |
+ break; |
|
337 |
+ default: |
|
338 |
+ return pos_type(off_type(-1)); |
|
339 |
+ } |
|
340 |
+ |
|
341 |
+ newoff += off; |
|
342 |
+ |
|
343 |
+ if (newoff < 0 || newoff > limit) |
|
344 |
+ return pos_type(-1); |
|
345 |
+ if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit) |
|
346 |
+ return pos_type(-1); |
|
347 |
+ //This can reassign pointers |
|
348 |
+ //if(m_vect.size() != m_vect.capacity()) |
|
349 |
+ //this->initialize_pointers(); |
|
350 |
+ if (in) |
|
351 |
+ base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr()); |
|
352 |
+ if (out){ |
|
353 |
+ base_t::setp(base_t::pbase(), base_t::epptr()); |
|
354 |
+ base_t::pbump(newoff); |
|
355 |
+ } |
|
356 |
+ return pos_type(newoff); |
|
357 |
+ } |
|
358 |
+ |
|
359 |
+ virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode |
|
360 |
+ = std::ios_base::in | std::ios_base::out) |
|
361 |
+ { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } |
|
362 |
+ |
|
363 |
+ private: |
|
364 |
+ std::ios_base::openmode m_mode; |
|
365 |
+ mutable vector_type m_vect; |
|
366 |
+ mutable char_type* mp_high_water; |
|
367 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
368 |
+}; |
|
369 |
+ |
|
370 |
+//!A basic_istream class that holds a character vector specified by CharVector |
|
371 |
+//!template parameter as its formatting buffer. The vector must have |
|
372 |
+//!contiguous storage, like std::vector, boost::interprocess::vector or |
|
373 |
+//!boost::interprocess::basic_string |
|
374 |
+template <class CharVector, class CharTraits> |
|
375 |
+class basic_ivectorstream |
|
376 |
+ : public std::basic_istream<typename CharVector::value_type, CharTraits> |
|
377 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
378 |
+ , private basic_vectorbuf<CharVector, CharTraits> |
|
379 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
380 |
+{ |
|
381 |
+ public: |
|
382 |
+ typedef CharVector vector_type; |
|
383 |
+ typedef typename std::basic_ios |
|
384 |
+ <typename CharVector::value_type, CharTraits>::char_type char_type; |
|
385 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
386 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
387 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
388 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
389 |
+ |
|
390 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
391 |
+ private: |
|
392 |
+ typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; |
|
393 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
394 |
+ typedef std::basic_istream<char_type, CharTraits> base_t; |
|
395 |
+ |
|
396 |
+ vectorbuf_t & get_buf() { return *this; } |
|
397 |
+ const vectorbuf_t & get_buf() const{ return *this; } |
|
398 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
399 |
+ |
|
400 |
+ public: |
|
401 |
+ |
|
402 |
+ //!Constructor. Throws if vector_type default |
|
403 |
+ //!constructor throws. |
|
404 |
+ basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) |
|
405 |
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base |
|
406 |
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a |
|
407 |
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. |
|
408 |
+ , vectorbuf_t(mode | std::ios_base::in) |
|
409 |
+ { this->base_t::rdbuf(&get_buf()); } |
|
410 |
+ |
|
411 |
+ //!Constructor. Throws if vector_type(const VectorParameter ¶m) |
|
412 |
+ //!throws. |
|
413 |
+ template<class VectorParameter> |
|
414 |
+ basic_ivectorstream(const VectorParameter ¶m, |
|
415 |
+ std::ios_base::openmode mode = std::ios_base::in) |
|
416 |
+ : vectorbuf_t(param, mode | std::ios_base::in) |
|
417 |
+ //basic_ios_t() is constructed uninitialized as virtual base |
|
418 |
+ //and initialized inside base_t calling basic_ios::init() |
|
419 |
+ , base_t(&get_buf()) |
|
420 |
+ {} |
|
421 |
+ |
|
422 |
+ public: |
|
423 |
+ //!Returns the address of the stored |
|
424 |
+ //!stream buffer. |
|
425 |
+ basic_vectorbuf<CharVector, CharTraits>* rdbuf() const |
|
426 |
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); } |
|
427 |
+ |
|
428 |
+ //!Swaps the underlying vector with the passed vector. |
|
429 |
+ //!This function resets the read position in the stream. |
|
430 |
+ //!Does not throw. |
|
431 |
+ void swap_vector(vector_type &vect) |
|
432 |
+ { get_buf().swap_vector(vect); } |
|
433 |
+ |
|
434 |
+ //!Returns a const reference to the internal vector. |
|
435 |
+ //!Does not throw. |
|
436 |
+ const vector_type &vector() const |
|
437 |
+ { return get_buf().vector(); } |
|
438 |
+ |
|
439 |
+ //!Calls reserve() method of the internal vector. |
|
440 |
+ //!Resets the stream to the first position. |
|
441 |
+ //!Throws if the internals vector's reserve throws. |
|
442 |
+ void reserve(typename vector_type::size_type size) |
|
443 |
+ { get_buf().reserve(size); } |
|
444 |
+ |
|
445 |
+ //!Calls clear() method of the internal vector. |
|
446 |
+ //!Resets the stream to the first position. |
|
447 |
+ void clear() |
|
448 |
+ { get_buf().clear(); } |
|
449 |
+}; |
|
450 |
+ |
|
451 |
+//!A basic_ostream class that holds a character vector specified by CharVector |
|
452 |
+//!template parameter as its formatting buffer. The vector must have |
|
453 |
+//!contiguous storage, like std::vector, boost::interprocess::vector or |
|
454 |
+//!boost::interprocess::basic_string |
|
455 |
+template <class CharVector, class CharTraits> |
|
456 |
+class basic_ovectorstream |
|
457 |
+ : public std::basic_ostream<typename CharVector::value_type, CharTraits> |
|
458 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
459 |
+ , private basic_vectorbuf<CharVector, CharTraits> |
|
460 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
461 |
+{ |
|
462 |
+ public: |
|
463 |
+ typedef CharVector vector_type; |
|
464 |
+ typedef typename std::basic_ios |
|
465 |
+ <typename CharVector::value_type, CharTraits>::char_type char_type; |
|
466 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
467 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
468 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
469 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
470 |
+ |
|
471 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
472 |
+ private: |
|
473 |
+ typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; |
|
474 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
475 |
+ typedef std::basic_ostream<char_type, CharTraits> base_t; |
|
476 |
+ |
|
477 |
+ vectorbuf_t & get_buf() { return *this; } |
|
478 |
+ const vectorbuf_t & get_buf()const { return *this; } |
|
479 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
480 |
+ |
|
481 |
+ public: |
|
482 |
+ //!Constructor. Throws if vector_type default |
|
483 |
+ //!constructor throws. |
|
484 |
+ basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) |
|
485 |
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base |
|
486 |
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a |
|
487 |
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. |
|
488 |
+ , vectorbuf_t(mode | std::ios_base::out) |
|
489 |
+ { this->base_t::rdbuf(&get_buf()); } |
|
490 |
+ |
|
491 |
+ //!Constructor. Throws if vector_type(const VectorParameter ¶m) |
|
492 |
+ //!throws. |
|
493 |
+ template<class VectorParameter> |
|
494 |
+ basic_ovectorstream(const VectorParameter ¶m, |
|
495 |
+ std::ios_base::openmode mode = std::ios_base::out) |
|
496 |
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base |
|
497 |
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a |
|
498 |
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. |
|
499 |
+ , vectorbuf_t(param, mode | std::ios_base::out) |
|
500 |
+ { this->base_t::rdbuf(&get_buf()); } |
|
501 |
+ |
|
502 |
+ public: |
|
503 |
+ //!Returns the address of the stored |
|
504 |
+ //!stream buffer. |
|
505 |
+ basic_vectorbuf<CharVector, CharTraits>* rdbuf() const |
|
506 |
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); } |
|
507 |
+ |
|
508 |
+ //!Swaps the underlying vector with the passed vector. |
|
509 |
+ //!This function resets the write position in the stream. |
|
510 |
+ //!Does not throw. |
|
511 |
+ void swap_vector(vector_type &vect) |
|
512 |
+ { get_buf().swap_vector(vect); } |
|
513 |
+ |
|
514 |
+ //!Returns a const reference to the internal vector. |
|
515 |
+ //!Does not throw. |
|
516 |
+ const vector_type &vector() const |
|
517 |
+ { return get_buf().vector(); } |
|
518 |
+ |
|
519 |
+ //!Calls reserve() method of the internal vector. |
|
520 |
+ //!Resets the stream to the first position. |
|
521 |
+ //!Throws if the internals vector's reserve throws. |
|
522 |
+ void reserve(typename vector_type::size_type size) |
|
523 |
+ { get_buf().reserve(size); } |
|
524 |
+}; |
|
525 |
+ |
|
526 |
+//!A basic_iostream class that holds a character vector specified by CharVector |
|
527 |
+//!template parameter as its formatting buffer. The vector must have |
|
528 |
+//!contiguous storage, like std::vector, boost::interprocess::vector or |
|
529 |
+//!boost::interprocess::basic_string |
|
530 |
+template <class CharVector, class CharTraits> |
|
531 |
+class basic_vectorstream |
|
532 |
+ : public std::basic_iostream<typename CharVector::value_type, CharTraits> |
|
533 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
534 |
+ , private basic_vectorbuf<CharVector, CharTraits> |
|
535 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
536 |
+{ |
|
537 |
+ public: |
|
538 |
+ typedef CharVector vector_type; |
|
539 |
+ typedef typename std::basic_ios |
|
540 |
+ <typename CharVector::value_type, CharTraits>::char_type char_type; |
|
541 |
+ typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
|
542 |
+ typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
|
543 |
+ typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
|
544 |
+ typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
|
545 |
+ |
|
546 |
+ #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) |
|
547 |
+ private: |
|
548 |
+ typedef basic_vectorbuf<CharVector, CharTraits> vectorbuf_t; |
|
549 |
+ typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
|
550 |
+ typedef std::basic_iostream<char_type, CharTraits> base_t; |
|
551 |
+ |
|
552 |
+ vectorbuf_t & get_buf() { return *this; } |
|
553 |
+ const vectorbuf_t & get_buf() const{ return *this; } |
|
554 |
+ #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED |
|
555 |
+ |
|
556 |
+ public: |
|
557 |
+ //!Constructor. Throws if vector_type default |
|
558 |
+ //!constructor throws. |
|
559 |
+ basic_vectorstream(std::ios_base::openmode mode |
|
560 |
+ = std::ios_base::in | std::ios_base::out) |
|
561 |
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base |
|
562 |
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a |
|
563 |
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. |
|
564 |
+ , vectorbuf_t(mode) |
|
565 |
+ { this->base_t::rdbuf(&get_buf()); } |
|
566 |
+ |
|
567 |
+ //!Constructor. Throws if vector_type(const VectorParameter ¶m) |
|
568 |
+ //!throws. |
|
569 |
+ template<class VectorParameter> |
|
570 |
+ basic_vectorstream(const VectorParameter ¶m, std::ios_base::openmode mode |
|
571 |
+ = std::ios_base::in | std::ios_base::out) |
|
572 |
+ : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base |
|
573 |
+ //(via basic_ios::init() call in base_t's constructor) without the risk of a |
|
574 |
+ //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. |
|
575 |
+ , vectorbuf_t(param, mode) |
|
576 |
+ { this->base_t::rdbuf(&get_buf()); } |
|
577 |
+ |
|
578 |
+ public: |
|
579 |
+ //Returns the address of the stored stream buffer. |
|
580 |
+ basic_vectorbuf<CharVector, CharTraits>* rdbuf() const |
|
581 |
+ { return const_cast<basic_vectorbuf<CharVector, CharTraits>*>(&get_buf()); } |
|
582 |
+ |
|
583 |
+ //!Swaps the underlying vector with the passed vector. |
|
584 |
+ //!This function resets the read/write position in the stream. |
|
585 |
+ //!Does not throw. |
|
586 |
+ void swap_vector(vector_type &vect) |
|
587 |
+ { get_buf().swap_vector(vect); } |
|
588 |
+ |
|
589 |
+ //!Returns a const reference to the internal vector. |
|
590 |
+ //!Does not throw. |
|
591 |
+ const vector_type &vector() const |
|
592 |
+ { return get_buf().vector(); } |
|
593 |
+ |
|
594 |
+ //!Calls reserve() method of the internal vector. |
|
595 |
+ //!Resets the stream to the first position. |
|
596 |
+ //!Throws if the internals vector's reserve throws. |
|
597 |
+ void reserve(typename vector_type::size_type size) |
|
598 |
+ { get_buf().reserve(size); } |
|
599 |
+ |
|
600 |
+ //!Calls clear() method of the internal vector. |
|
601 |
+ //!Resets the stream to the first position. |
|
602 |
+ void clear() |
|
603 |
+ { get_buf().clear(); } |
|
604 |
+}; |
|
605 |
+ |
|
606 |
+//Some typedefs to simplify usage |
|
607 |
+//! |
|
608 |
+//!typedef basic_vectorbuf<std::vector<char> > vectorbuf; |
|
609 |
+//!typedef basic_vectorstream<std::vector<char> > vectorstream; |
|
610 |
+//!typedef basic_ivectorstream<std::vector<char> > ivectorstream; |
|
611 |
+//!typedef basic_ovectorstream<std::vector<char> > ovectorstream; |
|
612 |
+//! |
|
613 |
+//!typedef basic_vectorbuf<std::vector<wchar_t> > wvectorbuf; |
|
614 |
+//!typedef basic_vectorstream<std::vector<wchar_t> > wvectorstream; |
|
615 |
+//!typedef basic_ivectorstream<std::vector<wchar_t> > wivectorstream; |
|
616 |
+//!typedef basic_ovectorstream<std::vector<wchar_t> > wovectorstream; |
|
617 |
+ |
|
618 |
+}} //namespace boost { namespace interprocess { |
|
619 |
+ |
|
620 |
+#include <boost/interprocess/detail/config_end.hpp> |
|
621 |
+ |
|
622 |
+#endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */ |