Chris@16
|
1 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
2 //
|
Chris@16
|
3 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
|
Chris@16
|
4 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
5 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
6 //
|
Chris@16
|
7 // See http://www.boost.org/libs/interprocess for documentation.
|
Chris@16
|
8 //
|
Chris@16
|
9 //////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
10 //
|
Chris@16
|
11 // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
|
Chris@16
|
12 // Changed internal SGI string to a buffer. Added efficient
|
Chris@16
|
13 // internal buffer get/set/swap functions, so that we can obtain/establish the
|
Chris@16
|
14 // internal buffer without any reallocation or copy. Kill those temporaries!
|
Chris@16
|
15 ///////////////////////////////////////////////////////////////////////////////
|
Chris@16
|
16 /*
|
Chris@16
|
17 * Copyright (c) 1998
|
Chris@16
|
18 * Silicon Graphics Computer Systems, Inc.
|
Chris@16
|
19 *
|
Chris@16
|
20 * Permission to use, copy, modify, distribute and sell this software
|
Chris@16
|
21 * and its documentation for any purpose is hereby granted without fee,
|
Chris@16
|
22 * provided that the above copyright notice appear in all copies and
|
Chris@16
|
23 * that both that copyright notice and this permission notice appear
|
Chris@16
|
24 * in supporting documentation. Silicon Graphics makes no
|
Chris@16
|
25 * representations about the suitability of this software for any
|
Chris@16
|
26 * purpose. It is provided "as is" without express or implied warranty.
|
Chris@16
|
27 */
|
Chris@16
|
28
|
Chris@16
|
29 //!\file
|
Chris@16
|
30 //!This file defines basic_bufferbuf, basic_ibufferstream,
|
Chris@16
|
31 //!basic_obufferstream, and basic_bufferstream classes. These classes
|
Chris@16
|
32 //!represent streamsbufs and streams whose sources or destinations
|
Chris@16
|
33 //!are fixed size character buffers.
|
Chris@16
|
34
|
Chris@16
|
35 #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
|
Chris@16
|
36 #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
|
Chris@16
|
37
|
Chris@101
|
38 #ifndef BOOST_CONFIG_HPP
|
Chris@101
|
39 # include <boost/config.hpp>
|
Chris@101
|
40 #endif
|
Chris@101
|
41 #
|
Chris@101
|
42 #if defined(BOOST_HAS_PRAGMA_ONCE)
|
Chris@101
|
43 # pragma once
|
Chris@101
|
44 #endif
|
Chris@101
|
45
|
Chris@16
|
46 #include <boost/interprocess/detail/config_begin.hpp>
|
Chris@16
|
47 #include <boost/interprocess/detail/workaround.hpp>
|
Chris@16
|
48
|
Chris@16
|
49 #include <iosfwd>
|
Chris@16
|
50 #include <ios>
|
Chris@16
|
51 #include <istream>
|
Chris@16
|
52 #include <ostream>
|
Chris@16
|
53 #include <string> // char traits
|
Chris@16
|
54 #include <cstddef> // ptrdiff_t
|
Chris@16
|
55 #include <boost/assert.hpp>
|
Chris@16
|
56 #include <boost/interprocess/interprocess_fwd.hpp>
|
Chris@16
|
57
|
Chris@16
|
58 namespace boost { namespace interprocess {
|
Chris@16
|
59
|
Chris@16
|
60 //!A streambuf class that controls the transmission of elements to and from
|
Chris@16
|
61 //!a basic_xbufferstream. The elements are transmitted from a to a fixed
|
Chris@16
|
62 //!size buffer
|
Chris@16
|
63 template <class CharT, class CharTraits>
|
Chris@16
|
64 class basic_bufferbuf
|
Chris@16
|
65 : public std::basic_streambuf<CharT, CharTraits>
|
Chris@16
|
66 {
|
Chris@16
|
67 public:
|
Chris@16
|
68 typedef CharT char_type;
|
Chris@16
|
69 typedef typename CharTraits::int_type int_type;
|
Chris@16
|
70 typedef typename CharTraits::pos_type pos_type;
|
Chris@16
|
71 typedef typename CharTraits::off_type off_type;
|
Chris@16
|
72 typedef CharTraits traits_type;
|
Chris@16
|
73 typedef std::basic_streambuf<char_type, traits_type> base_t;
|
Chris@16
|
74
|
Chris@16
|
75 public:
|
Chris@16
|
76 //!Constructor.
|
Chris@16
|
77 //!Does not throw.
|
Chris@16
|
78 explicit basic_bufferbuf(std::ios_base::openmode mode
|
Chris@16
|
79 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
80 : base_t(), m_mode(mode), m_buffer(0), m_length(0)
|
Chris@16
|
81 {}
|
Chris@16
|
82
|
Chris@16
|
83 //!Constructor. Assigns formatting buffer.
|
Chris@16
|
84 //!Does not throw.
|
Chris@16
|
85 explicit basic_bufferbuf(CharT *buf, std::size_t length,
|
Chris@16
|
86 std::ios_base::openmode mode
|
Chris@16
|
87 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
88 : base_t(), m_mode(mode), m_buffer(buf), m_length(length)
|
Chris@16
|
89 { this->set_pointers(); }
|
Chris@16
|
90
|
Chris@16
|
91 virtual ~basic_bufferbuf(){}
|
Chris@16
|
92
|
Chris@16
|
93 public:
|
Chris@16
|
94 //!Returns the pointer and size of the internal buffer.
|
Chris@16
|
95 //!Does not throw.
|
Chris@16
|
96 std::pair<CharT *, std::size_t> buffer() const
|
Chris@16
|
97 { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
|
Chris@16
|
98
|
Chris@16
|
99 //!Sets the underlying buffer to a new value
|
Chris@16
|
100 //!Does not throw.
|
Chris@16
|
101 void buffer(CharT *buf, std::size_t length)
|
Chris@16
|
102 { m_buffer = buf; m_length = length; this->set_pointers(); }
|
Chris@16
|
103
|
Chris@101
|
104 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
105 private:
|
Chris@16
|
106 void set_pointers()
|
Chris@16
|
107 {
|
Chris@16
|
108 // The initial read position is the beginning of the buffer.
|
Chris@16
|
109 if(m_mode & std::ios_base::in)
|
Chris@16
|
110 this->setg(m_buffer, m_buffer, m_buffer + m_length);
|
Chris@16
|
111
|
Chris@16
|
112 // The initial write position is the beginning of the buffer.
|
Chris@16
|
113 if(m_mode & std::ios_base::out)
|
Chris@16
|
114 this->setp(m_buffer, m_buffer + m_length);
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 protected:
|
Chris@16
|
118 virtual int_type underflow()
|
Chris@16
|
119 {
|
Chris@16
|
120 // Precondition: gptr() >= egptr(). Returns a character, if available.
|
Chris@16
|
121 return this->gptr() != this->egptr() ?
|
Chris@16
|
122 CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
|
Chris@16
|
123 }
|
Chris@16
|
124
|
Chris@16
|
125 virtual int_type pbackfail(int_type c = CharTraits::eof())
|
Chris@16
|
126 {
|
Chris@16
|
127 if(this->gptr() != this->eback()) {
|
Chris@16
|
128 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
|
Chris@16
|
129 if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
|
Chris@16
|
130 this->gbump(-1);
|
Chris@16
|
131 return c;
|
Chris@16
|
132 }
|
Chris@16
|
133 else if(m_mode & std::ios_base::out) {
|
Chris@16
|
134 this->gbump(-1);
|
Chris@16
|
135 *this->gptr() = c;
|
Chris@16
|
136 return c;
|
Chris@16
|
137 }
|
Chris@16
|
138 else
|
Chris@16
|
139 return CharTraits::eof();
|
Chris@16
|
140 }
|
Chris@16
|
141 else {
|
Chris@16
|
142 this->gbump(-1);
|
Chris@16
|
143 return CharTraits::not_eof(c);
|
Chris@16
|
144 }
|
Chris@16
|
145 }
|
Chris@16
|
146 else
|
Chris@16
|
147 return CharTraits::eof();
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 virtual int_type overflow(int_type c = CharTraits::eof())
|
Chris@16
|
151 {
|
Chris@16
|
152 if(m_mode & std::ios_base::out) {
|
Chris@16
|
153 if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
|
Chris@16
|
154 // if(!(m_mode & std::ios_base::in)) {
|
Chris@16
|
155 // if(this->pptr() != this->epptr()) {
|
Chris@16
|
156 // *this->pptr() = CharTraits::to_char_type(c);
|
Chris@16
|
157 // this->pbump(1);
|
Chris@16
|
158 // return c;
|
Chris@16
|
159 // }
|
Chris@16
|
160 // else
|
Chris@16
|
161 // return CharTraits::eof();
|
Chris@16
|
162 // }
|
Chris@16
|
163 // else {
|
Chris@16
|
164 if(this->pptr() == this->epptr()) {
|
Chris@16
|
165 //We can't append to a static buffer
|
Chris@16
|
166 return CharTraits::eof();
|
Chris@16
|
167 }
|
Chris@16
|
168 else {
|
Chris@16
|
169 *this->pptr() = CharTraits::to_char_type(c);
|
Chris@16
|
170 this->pbump(1);
|
Chris@16
|
171 return c;
|
Chris@16
|
172 }
|
Chris@16
|
173 // }
|
Chris@16
|
174 }
|
Chris@16
|
175 else // c is EOF, so we don't have to do anything
|
Chris@16
|
176 return CharTraits::not_eof(c);
|
Chris@16
|
177 }
|
Chris@16
|
178 else // Overflow always fails if it's read-only.
|
Chris@16
|
179 return CharTraits::eof();
|
Chris@16
|
180 }
|
Chris@16
|
181
|
Chris@16
|
182 virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
|
Chris@16
|
183 std::ios_base::openmode mode
|
Chris@16
|
184 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
185 {
|
Chris@16
|
186 bool in = false;
|
Chris@16
|
187 bool out = false;
|
Chris@16
|
188
|
Chris@16
|
189 const std::ios_base::openmode inout =
|
Chris@16
|
190 std::ios_base::in | std::ios_base::out;
|
Chris@16
|
191
|
Chris@16
|
192 if((mode & inout) == inout) {
|
Chris@16
|
193 if(dir == std::ios_base::beg || dir == std::ios_base::end)
|
Chris@16
|
194 in = out = true;
|
Chris@16
|
195 }
|
Chris@16
|
196 else if(mode & std::ios_base::in)
|
Chris@16
|
197 in = true;
|
Chris@16
|
198 else if(mode & std::ios_base::out)
|
Chris@16
|
199 out = true;
|
Chris@16
|
200
|
Chris@16
|
201 if(!in && !out)
|
Chris@16
|
202 return pos_type(off_type(-1));
|
Chris@16
|
203 else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) ||
|
Chris@16
|
204 (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0)))
|
Chris@16
|
205 return pos_type(off_type(-1));
|
Chris@16
|
206
|
Chris@16
|
207 std::streamoff newoff;
|
Chris@16
|
208 switch(dir) {
|
Chris@16
|
209 case std::ios_base::beg:
|
Chris@16
|
210 newoff = 0;
|
Chris@16
|
211 break;
|
Chris@16
|
212 case std::ios_base::end:
|
Chris@16
|
213 newoff = static_cast<std::streamoff>(m_length);
|
Chris@16
|
214 break;
|
Chris@16
|
215 case std::ios_base::cur:
|
Chris@16
|
216 newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
|
Chris@16
|
217 : static_cast<std::streamoff>(this->pptr() - this->pbase());
|
Chris@16
|
218 break;
|
Chris@16
|
219 default:
|
Chris@16
|
220 return pos_type(off_type(-1));
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 off += newoff;
|
Chris@16
|
224
|
Chris@16
|
225 if(in) {
|
Chris@16
|
226 std::ptrdiff_t n = this->egptr() - this->eback();
|
Chris@16
|
227
|
Chris@16
|
228 if(off < 0 || off > n)
|
Chris@16
|
229 return pos_type(off_type(-1));
|
Chris@16
|
230 else
|
Chris@16
|
231 this->setg(this->eback(), this->eback() + off, this->eback() + n);
|
Chris@16
|
232 }
|
Chris@16
|
233
|
Chris@16
|
234 if(out) {
|
Chris@16
|
235 std::ptrdiff_t n = this->epptr() - this->pbase();
|
Chris@16
|
236
|
Chris@16
|
237 if(off < 0 || off > n)
|
Chris@16
|
238 return pos_type(off_type(-1));
|
Chris@16
|
239 else {
|
Chris@16
|
240 this->setp(this->pbase(), this->pbase() + n);
|
Chris@16
|
241 this->pbump(off);
|
Chris@16
|
242 }
|
Chris@16
|
243 }
|
Chris@16
|
244
|
Chris@16
|
245 return pos_type(off);
|
Chris@16
|
246 }
|
Chris@16
|
247
|
Chris@16
|
248 virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
|
Chris@16
|
249 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
250 { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); }
|
Chris@16
|
251
|
Chris@16
|
252 private:
|
Chris@16
|
253 std::ios_base::openmode m_mode;
|
Chris@16
|
254 CharT * m_buffer;
|
Chris@16
|
255 std::size_t m_length;
|
Chris@101
|
256 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
257 };
|
Chris@16
|
258
|
Chris@16
|
259 //!A basic_istream class that uses a fixed size character buffer
|
Chris@16
|
260 //!as its formatting buffer.
|
Chris@16
|
261 template <class CharT, class CharTraits>
|
Chris@16
|
262 class basic_ibufferstream :
|
Chris@101
|
263 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
264 private basic_bufferbuf<CharT, CharTraits>,
|
Chris@101
|
265 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
266 public std::basic_istream<CharT, CharTraits>
|
Chris@16
|
267 {
|
Chris@16
|
268 public: // Typedefs
|
Chris@16
|
269 typedef typename std::basic_ios
|
Chris@16
|
270 <CharT, CharTraits>::char_type char_type;
|
Chris@16
|
271 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
|
Chris@16
|
272 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
|
Chris@16
|
273 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
|
Chris@16
|
274 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
|
Chris@16
|
275
|
Chris@101
|
276 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
277 private:
|
Chris@16
|
278 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
|
Chris@16
|
279 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
|
Chris@16
|
280 typedef std::basic_istream<char_type, CharTraits> base_t;
|
Chris@16
|
281 bufferbuf_t & get_buf() { return *this; }
|
Chris@16
|
282 const bufferbuf_t & get_buf() const{ return *this; }
|
Chris@101
|
283 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
284
|
Chris@16
|
285 public:
|
Chris@16
|
286 //!Constructor.
|
Chris@16
|
287 //!Does not throw.
|
Chris@16
|
288 basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
|
Chris@16
|
289 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
290 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
291 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
292 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
293 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
294 bufferbuf_t(mode | std::ios_base::in)
|
Chris@16
|
295 , base_t(&get_buf())
|
Chris@16
|
296 {}
|
Chris@16
|
297
|
Chris@16
|
298 //!Constructor. Assigns formatting buffer.
|
Chris@16
|
299 //!Does not throw.
|
Chris@16
|
300 basic_ibufferstream(const CharT *buf, std::size_t length,
|
Chris@16
|
301 std::ios_base::openmode mode = std::ios_base::in)
|
Chris@16
|
302 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
303 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
304 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
305 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
306 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
307 bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
|
Chris@16
|
308 , base_t(&get_buf())
|
Chris@16
|
309 {}
|
Chris@16
|
310
|
Chris@16
|
311 ~basic_ibufferstream(){};
|
Chris@16
|
312
|
Chris@16
|
313 public:
|
Chris@16
|
314 //!Returns the address of the stored
|
Chris@16
|
315 //!stream buffer.
|
Chris@16
|
316 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
|
Chris@16
|
317 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
|
Chris@16
|
318
|
Chris@16
|
319 //!Returns the pointer and size of the internal buffer.
|
Chris@16
|
320 //!Does not throw.
|
Chris@16
|
321 std::pair<const CharT *, std::size_t> buffer() const
|
Chris@16
|
322 { return get_buf().buffer(); }
|
Chris@16
|
323
|
Chris@16
|
324 //!Sets the underlying buffer to a new value. Resets
|
Chris@16
|
325 //!stream position. Does not throw.
|
Chris@16
|
326 void buffer(const CharT *buf, std::size_t length)
|
Chris@16
|
327 { get_buf().buffer(const_cast<CharT*>(buf), length); }
|
Chris@16
|
328 };
|
Chris@16
|
329
|
Chris@16
|
330 //!A basic_ostream class that uses a fixed size character buffer
|
Chris@16
|
331 //!as its formatting buffer.
|
Chris@16
|
332 template <class CharT, class CharTraits>
|
Chris@16
|
333 class basic_obufferstream :
|
Chris@101
|
334 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
335 private basic_bufferbuf<CharT, CharTraits>,
|
Chris@101
|
336 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
337 public std::basic_ostream<CharT, CharTraits>
|
Chris@16
|
338 {
|
Chris@16
|
339 public:
|
Chris@16
|
340 typedef typename std::basic_ios
|
Chris@16
|
341 <CharT, CharTraits>::char_type char_type;
|
Chris@16
|
342 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
|
Chris@16
|
343 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
|
Chris@16
|
344 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
|
Chris@16
|
345 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
|
Chris@16
|
346
|
Chris@101
|
347 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
348 private:
|
Chris@16
|
349 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
|
Chris@16
|
350 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
|
Chris@16
|
351 typedef std::basic_ostream<char_type, CharTraits> base_t;
|
Chris@16
|
352 bufferbuf_t & get_buf() { return *this; }
|
Chris@16
|
353 const bufferbuf_t & get_buf() const{ return *this; }
|
Chris@101
|
354 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
355
|
Chris@16
|
356 public:
|
Chris@16
|
357 //!Constructor.
|
Chris@16
|
358 //!Does not throw.
|
Chris@16
|
359 basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
|
Chris@16
|
360 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
361 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
362 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
363 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
364 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
365 bufferbuf_t(mode | std::ios_base::out)
|
Chris@16
|
366 , base_t(&get_buf())
|
Chris@16
|
367 {}
|
Chris@16
|
368
|
Chris@16
|
369 //!Constructor. Assigns formatting buffer.
|
Chris@16
|
370 //!Does not throw.
|
Chris@16
|
371 basic_obufferstream(CharT *buf, std::size_t length,
|
Chris@16
|
372 std::ios_base::openmode mode = std::ios_base::out)
|
Chris@16
|
373 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
374 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
375 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
376 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
377 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
378 bufferbuf_t(buf, length, mode | std::ios_base::out)
|
Chris@16
|
379 , base_t(&get_buf())
|
Chris@16
|
380 {}
|
Chris@16
|
381
|
Chris@16
|
382 ~basic_obufferstream(){}
|
Chris@16
|
383
|
Chris@16
|
384 public:
|
Chris@16
|
385 //!Returns the address of the stored
|
Chris@16
|
386 //!stream buffer.
|
Chris@16
|
387 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
|
Chris@16
|
388 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
|
Chris@16
|
389
|
Chris@16
|
390 //!Returns the pointer and size of the internal buffer.
|
Chris@16
|
391 //!Does not throw.
|
Chris@16
|
392 std::pair<CharT *, std::size_t> buffer() const
|
Chris@16
|
393 { return get_buf().buffer(); }
|
Chris@16
|
394
|
Chris@16
|
395 //!Sets the underlying buffer to a new value. Resets
|
Chris@16
|
396 //!stream position. Does not throw.
|
Chris@16
|
397 void buffer(CharT *buf, std::size_t length)
|
Chris@16
|
398 { get_buf().buffer(buf, length); }
|
Chris@16
|
399 };
|
Chris@16
|
400
|
Chris@16
|
401
|
Chris@16
|
402 //!A basic_iostream class that uses a fixed size character buffer
|
Chris@16
|
403 //!as its formatting buffer.
|
Chris@16
|
404 template <class CharT, class CharTraits>
|
Chris@16
|
405 class basic_bufferstream :
|
Chris@101
|
406 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
407 private basic_bufferbuf<CharT, CharTraits>,
|
Chris@101
|
408 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
409 public std::basic_iostream<CharT, CharTraits>
|
Chris@16
|
410 {
|
Chris@16
|
411 public: // Typedefs
|
Chris@16
|
412 typedef typename std::basic_ios
|
Chris@16
|
413 <CharT, CharTraits>::char_type char_type;
|
Chris@16
|
414 typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type;
|
Chris@16
|
415 typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type;
|
Chris@16
|
416 typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
|
Chris@16
|
417 typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
|
Chris@16
|
418
|
Chris@101
|
419 #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
|
Chris@16
|
420 private:
|
Chris@16
|
421 typedef basic_bufferbuf<CharT, CharTraits> bufferbuf_t;
|
Chris@16
|
422 typedef std::basic_ios<char_type, CharTraits> basic_ios_t;
|
Chris@16
|
423 typedef std::basic_iostream<char_type, CharTraits> base_t;
|
Chris@16
|
424 bufferbuf_t & get_buf() { return *this; }
|
Chris@16
|
425 const bufferbuf_t & get_buf() const{ return *this; }
|
Chris@101
|
426 #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
|
Chris@16
|
427
|
Chris@16
|
428 public:
|
Chris@16
|
429 //!Constructor.
|
Chris@16
|
430 //!Does not throw.
|
Chris@16
|
431 basic_bufferstream(std::ios_base::openmode mode
|
Chris@16
|
432 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
433 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
434 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
435 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
436 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
437 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
438 bufferbuf_t(mode)
|
Chris@16
|
439 , base_t(&get_buf())
|
Chris@16
|
440 {}
|
Chris@16
|
441
|
Chris@16
|
442 //!Constructor. Assigns formatting buffer.
|
Chris@16
|
443 //!Does not throw.
|
Chris@16
|
444 basic_bufferstream(CharT *buf, std::size_t length,
|
Chris@16
|
445 std::ios_base::openmode mode
|
Chris@16
|
446 = std::ios_base::in | std::ios_base::out)
|
Chris@16
|
447 : //basic_ios_t() is called first (lefting it uninitialized) as it's a
|
Chris@16
|
448 //virtual base of basic_istream. The class will be initialized when
|
Chris@16
|
449 //basic_istream is constructed calling basic_ios_t::init().
|
Chris@16
|
450 //As bufferbuf_t's constructor does not throw there is no risk of
|
Chris@16
|
451 //calling the basic_ios_t's destructor without calling basic_ios_t::init()
|
Chris@16
|
452 bufferbuf_t(buf, length, mode)
|
Chris@16
|
453 , base_t(&get_buf())
|
Chris@16
|
454 {}
|
Chris@16
|
455
|
Chris@16
|
456 ~basic_bufferstream(){}
|
Chris@16
|
457
|
Chris@16
|
458 public:
|
Chris@16
|
459 //!Returns the address of the stored
|
Chris@16
|
460 //!stream buffer.
|
Chris@16
|
461 basic_bufferbuf<CharT, CharTraits>* rdbuf() const
|
Chris@16
|
462 { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
|
Chris@16
|
463
|
Chris@16
|
464 //!Returns the pointer and size of the internal buffer.
|
Chris@16
|
465 //!Does not throw.
|
Chris@16
|
466 std::pair<CharT *, std::size_t> buffer() const
|
Chris@16
|
467 { return get_buf().buffer(); }
|
Chris@16
|
468
|
Chris@16
|
469 //!Sets the underlying buffer to a new value. Resets
|
Chris@16
|
470 //!stream position. Does not throw.
|
Chris@16
|
471 void buffer(CharT *buf, std::size_t length)
|
Chris@16
|
472 { get_buf().buffer(buf, length); }
|
Chris@16
|
473 };
|
Chris@16
|
474
|
Chris@16
|
475 //Some typedefs to simplify usage
|
Chris@16
|
476 typedef basic_bufferbuf<char> bufferbuf;
|
Chris@16
|
477 typedef basic_bufferstream<char> bufferstream;
|
Chris@16
|
478 typedef basic_ibufferstream<char> ibufferstream;
|
Chris@16
|
479 typedef basic_obufferstream<char> obufferstream;
|
Chris@16
|
480
|
Chris@16
|
481 typedef basic_bufferbuf<wchar_t> wbufferbuf;
|
Chris@16
|
482 typedef basic_bufferstream<wchar_t> wbufferstream;
|
Chris@16
|
483 typedef basic_ibufferstream<wchar_t> wibufferstream;
|
Chris@16
|
484 typedef basic_obufferstream<wchar_t> wobufferstream;
|
Chris@16
|
485
|
Chris@16
|
486
|
Chris@16
|
487 }} //namespace boost { namespace interprocess {
|
Chris@16
|
488
|
Chris@16
|
489 #include <boost/interprocess/detail/config_end.hpp>
|
Chris@16
|
490
|
Chris@16
|
491 #endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */
|