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