Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: // See http://www.boost.org/libs/interprocess for documentation. Chris@16: // Chris@16: ////////////////////////////////////////////////////////////////////////////// Chris@16: // Chris@16: // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012. Chris@16: // Changed internal SGI string to a generic, templatized vector. Added efficient Chris@16: // internal buffer get/set/swap functions, so that we can obtain/establish the Chris@16: // internal buffer without any reallocation or copy. Kill those temporaries! Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: /* Chris@16: * Copyright (c) 1998 Chris@16: * Silicon Graphics Computer Systems, Inc. Chris@16: * Chris@16: * Permission to use, copy, modify, distribute and sell this software Chris@16: * and its documentation for any purpose is hereby granted without fee, Chris@16: * provided that the above copyright notice appear in all copies and Chris@16: * that both that copyright notice and this permission notice appear Chris@16: * in supporting documentation. Silicon Graphics makes no Chris@16: * representations about the suitability of this software for any Chris@16: * purpose. It is provided "as is" without express or implied warranty. Chris@16: */ Chris@16: Chris@16: //!\file Chris@16: //!This file defines basic_vectorbuf, basic_ivectorstream, Chris@16: //!basic_ovectorstream, and basic_vectorstreamclasses. These classes Chris@16: //!represent streamsbufs and streams whose sources or destinations are Chris@16: //!STL-like vectors that can be swapped with external vectors to avoid Chris@16: //!unnecessary allocations/copies. Chris@16: Chris@16: #ifndef BOOST_INTERPROCESS_VECTORSTREAM_HPP Chris@16: #define BOOST_INTERPROCESS_VECTORSTREAM_HPP Chris@16: Chris@101: #ifndef BOOST_CONFIG_HPP Chris@101: # include Chris@101: #endif Chris@101: # Chris@101: #if defined(BOOST_HAS_PRAGMA_ONCE) Chris@101: # pragma once Chris@101: #endif Chris@101: Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // char traits Chris@16: #include // ptrdiff_t Chris@16: #include Chris@16: #include Chris@16: Chris@16: namespace boost { namespace interprocess { Chris@16: Chris@16: //!A streambuf class that controls the transmission of elements to and from Chris@16: //!a basic_ivectorstream, basic_ovectorstream or basic_vectorstream. Chris@16: //!It holds a character vector specified by CharVector template parameter Chris@16: //!as its formatting buffer. The vector must have contiguous storage, like Chris@16: //!std::vector, boost::interprocess::vector or boost::interprocess::basic_string Chris@16: template Chris@16: class basic_vectorbuf Chris@16: : public std::basic_streambuf Chris@16: { Chris@16: public: Chris@16: typedef CharVector vector_type; Chris@16: typedef typename CharVector::value_type char_type; Chris@16: typedef typename CharTraits::int_type int_type; Chris@16: typedef typename CharTraits::pos_type pos_type; Chris@16: typedef typename CharTraits::off_type off_type; Chris@16: typedef CharTraits traits_type; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: typedef std::basic_streambuf base_t; Chris@16: Chris@16: basic_vectorbuf(const basic_vectorbuf&); Chris@16: basic_vectorbuf & operator =(const basic_vectorbuf&); Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Constructor. Throws if vector_type default Chris@16: //!constructor throws. Chris@16: explicit basic_vectorbuf(std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: : base_t(), m_mode(mode) Chris@16: { this->initialize_pointers(); } Chris@16: Chris@16: //!Constructor. Throws if Chris@16: //!vector_type(const VectorParameter ¶m) throws. Chris@16: template Chris@16: explicit basic_vectorbuf(const VectorParameter ¶m, Chris@16: std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: : base_t(), m_mode(mode), m_vect(param) Chris@16: { this->initialize_pointers(); } Chris@16: Chris@16: public: Chris@16: Chris@16: //!Swaps the underlying vector with the passed vector. Chris@16: //!This function resets the read/write position in the stream. Chris@16: //!Does not throw. Chris@16: void swap_vector(vector_type &vect) Chris@16: { Chris@16: if (this->m_mode & std::ios_base::out){ Chris@16: //Update high water if necessary Chris@16: //And resize vector to remove extra size Chris@16: if (mp_high_water < base_t::pptr()){ Chris@16: //Restore the vector's size if necessary Chris@16: mp_high_water = base_t::pptr(); Chris@16: } Chris@16: //This does not reallocate Chris@16: m_vect.resize(mp_high_water - (m_vect.size() ? &m_vect[0] : 0)); Chris@16: } Chris@16: //Now swap vector Chris@16: m_vect.swap(vect); Chris@16: this->initialize_pointers(); Chris@16: } Chris@16: Chris@16: //!Returns a const reference to the internal vector. Chris@16: //!Does not throw. Chris@16: const vector_type &vector() const Chris@16: { Chris@16: if (this->m_mode & std::ios_base::out){ Chris@16: if (mp_high_water < base_t::pptr()){ Chris@16: //Restore the vector's size if necessary Chris@16: mp_high_water = base_t::pptr(); Chris@16: } Chris@16: //This shouldn't reallocate Chris@16: typedef typename vector_type::size_type size_type; Chris@16: char_type *old_ptr = base_t::pbase(); Chris@16: size_type high_pos = size_type(mp_high_water-old_ptr); Chris@16: if(m_vect.size() > high_pos){ Chris@16: m_vect.resize(high_pos); Chris@16: //But we must update end write pointer because vector size is now shorter Chris@16: int old_pos = base_t::pptr() - base_t::pbase(); Chris@16: const_cast(this)->base_t::setp(old_ptr, old_ptr + high_pos); Chris@16: const_cast(this)->base_t::pbump(old_pos); Chris@16: } Chris@16: } Chris@16: return m_vect; Chris@16: } Chris@16: Chris@16: //!Preallocates memory from the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: //!Throws if the internals vector's memory allocation throws. Chris@16: void reserve(typename vector_type::size_type size) Chris@16: { Chris@16: if (this->m_mode & std::ios_base::out && size > m_vect.size()){ Chris@16: typename vector_type::difference_type write_pos = base_t::pptr() - base_t::pbase(); Chris@16: typename vector_type::difference_type read_pos = base_t::gptr() - base_t::eback(); Chris@16: //Now update pointer data Chris@16: m_vect.reserve(size); Chris@16: this->initialize_pointers(); Chris@16: base_t::pbump((int)write_pos); Chris@16: if(this->m_mode & std::ios_base::in){ Chris@16: base_t::gbump((int)read_pos); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: //!Calls clear() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: void clear() Chris@16: { m_vect.clear(); this->initialize_pointers(); } Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: //Maximizes high watermark to the initial vector size, Chris@16: //initializes read and write iostream buffers to the capacity Chris@16: //and resets stream positions Chris@16: void initialize_pointers() Chris@16: { Chris@16: // The initial read position is the beginning of the vector. Chris@16: if(!(m_mode & std::ios_base::out)){ Chris@16: if(m_vect.empty()){ Chris@16: this->setg(0, 0, 0); Chris@16: } Chris@16: else{ Chris@16: this->setg(&m_vect[0], &m_vect[0], &m_vect[0] + m_vect.size()); Chris@16: } Chris@16: } Chris@16: Chris@16: // The initial write position is the beginning of the vector. Chris@16: if(m_mode & std::ios_base::out){ Chris@16: //First get real size Chris@16: int real_size = (int)m_vect.size(); Chris@16: //Then maximize size for high watermarking Chris@16: m_vect.resize(m_vect.capacity()); Chris@16: BOOST_ASSERT(m_vect.size() == m_vect.capacity()); Chris@16: //Set high watermarking with the expanded size Chris@16: mp_high_water = m_vect.size() ? (&m_vect[0] + real_size) : 0; Chris@16: //Now set formatting pointers Chris@16: if(m_vect.empty()){ Chris@16: this->setp(0, 0); Chris@16: if(m_mode & std::ios_base::in) Chris@16: this->setg(0, 0, 0); Chris@16: } Chris@16: else{ Chris@16: char_type *p = &m_vect[0]; Chris@16: this->setp(p, p + m_vect.size()); Chris@16: if(m_mode & std::ios_base::in) Chris@16: this->setg(p, p, p + real_size); Chris@16: } Chris@16: if (m_mode & (std::ios_base::app | std::ios_base::ate)){ Chris@16: base_t::pbump((int)real_size); Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: protected: Chris@16: virtual int_type underflow() Chris@16: { Chris@16: if (base_t::gptr() == 0) Chris@16: return CharTraits::eof(); Chris@16: if(m_mode & std::ios_base::out){ Chris@16: if (mp_high_water < base_t::pptr()) Chris@16: mp_high_water = base_t::pptr(); Chris@16: if (base_t::egptr() < mp_high_water) Chris@16: base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); Chris@16: } Chris@16: if (base_t::gptr() < base_t::egptr()) Chris@16: return CharTraits::to_int_type(*base_t::gptr()); Chris@16: return CharTraits::eof(); Chris@16: } Chris@16: Chris@16: virtual int_type pbackfail(int_type c = CharTraits::eof()) Chris@16: { Chris@16: if(this->gptr() != this->eback()) { Chris@16: if(!CharTraits::eq_int_type(c, CharTraits::eof())) { Chris@16: if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { Chris@16: this->gbump(-1); Chris@16: return c; Chris@16: } Chris@16: else if(m_mode & std::ios_base::out) { Chris@16: this->gbump(-1); Chris@16: *this->gptr() = c; Chris@16: return c; Chris@16: } Chris@16: else Chris@16: return CharTraits::eof(); Chris@16: } Chris@16: else { Chris@16: this->gbump(-1); Chris@16: return CharTraits::not_eof(c); Chris@16: } Chris@16: } Chris@16: else Chris@16: return CharTraits::eof(); Chris@16: } Chris@16: Chris@16: virtual int_type overflow(int_type c = CharTraits::eof()) Chris@16: { Chris@16: if(m_mode & std::ios_base::out) { Chris@16: if(!CharTraits::eq_int_type(c, CharTraits::eof())) { Chris@16: typedef typename vector_type::difference_type dif_t; Chris@16: //The new output position is the previous one plus one Chris@16: //because 'overflow' requires putting 'c' on the buffer Chris@16: dif_t new_outpos = base_t::pptr() - base_t::pbase() + 1; Chris@16: //Adjust high water if necessary Chris@16: dif_t hipos = mp_high_water - base_t::pbase(); Chris@16: if (hipos < new_outpos) Chris@16: hipos = new_outpos; Chris@16: //Insert the new data Chris@16: m_vect.push_back(CharTraits::to_char_type(c)); Chris@16: m_vect.resize(m_vect.capacity()); Chris@16: BOOST_ASSERT(m_vect.size() == m_vect.capacity()); Chris@16: char_type* p = const_cast(&m_vect[0]); Chris@16: //A reallocation might have happened, update pointers Chris@16: base_t::setp(p, p + (dif_t)m_vect.size()); Chris@16: mp_high_water = p + hipos; Chris@16: if (m_mode & std::ios_base::in) Chris@16: base_t::setg(p, p + (base_t::gptr() - base_t::eback()), mp_high_water); Chris@16: //Update write position to the old position + 1 Chris@16: base_t::pbump((int)new_outpos); Chris@16: return c; Chris@16: } Chris@16: else // c is EOF, so we don't have to do anything Chris@16: return CharTraits::not_eof(c); Chris@16: } Chris@16: else // Overflow always fails if it's read-only. Chris@16: return CharTraits::eof(); Chris@16: } Chris@16: Chris@16: virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, Chris@16: std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: { Chris@16: //Get seek mode Chris@16: bool in(0 != (mode & std::ios_base::in)), out(0 != (mode & std::ios_base::out)); Chris@16: //Test for logic errors Chris@16: if(!in & !out) Chris@16: return pos_type(off_type(-1)); Chris@16: else if((in && out) && (dir == std::ios_base::cur)) Chris@16: return pos_type(off_type(-1)); Chris@16: else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || Chris@16: (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) Chris@16: return pos_type(off_type(-1)); Chris@16: Chris@16: off_type newoff; Chris@16: //Just calculate the end of the stream. If the stream is read-only Chris@16: //the limit is the size of the vector. Otherwise, the high water mark Chris@16: //will mark the real size. Chris@16: off_type limit; Chris@16: if(m_mode & std::ios_base::out){ Chris@16: //Update high water marking because pptr() is going to change and it might Chris@16: //have been updated since last overflow() Chris@16: if(mp_high_water < base_t::pptr()) Chris@16: mp_high_water = base_t::pptr(); Chris@16: //Update read limits in case high water mark was changed Chris@16: if(m_mode & std::ios_base::in){ Chris@16: if (base_t::egptr() < mp_high_water) Chris@16: base_t::setg(base_t::eback(), base_t::gptr(), mp_high_water); Chris@16: } Chris@16: limit = static_cast(mp_high_water - base_t::pbase()); Chris@16: } Chris@16: else{ Chris@16: limit = static_cast(m_vect.size()); Chris@16: } Chris@16: Chris@16: switch(dir) { Chris@16: case std::ios_base::beg: Chris@16: newoff = 0; Chris@16: break; Chris@16: case std::ios_base::end: Chris@16: newoff = limit; Chris@16: break; Chris@16: case std::ios_base::cur: Chris@16: newoff = in ? static_cast(this->gptr() - this->eback()) Chris@16: : static_cast(this->pptr() - this->pbase()); Chris@16: break; Chris@16: default: Chris@16: return pos_type(off_type(-1)); Chris@16: } Chris@16: Chris@16: newoff += off; Chris@16: Chris@16: if (newoff < 0 || newoff > limit) Chris@16: return pos_type(-1); Chris@16: if (m_mode & std::ios_base::app && mode & std::ios_base::out && newoff != limit) Chris@16: return pos_type(-1); Chris@16: //This can reassign pointers Chris@16: //if(m_vect.size() != m_vect.capacity()) Chris@16: //this->initialize_pointers(); Chris@16: if (in) Chris@16: base_t::setg(base_t::eback(), base_t::eback() + newoff, base_t::egptr()); Chris@16: if (out){ Chris@16: base_t::setp(base_t::pbase(), base_t::epptr()); Chris@16: base_t::pbump(newoff); Chris@16: } Chris@16: return pos_type(newoff); Chris@16: } Chris@16: Chris@16: virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } Chris@16: Chris@16: private: Chris@16: std::ios_base::openmode m_mode; Chris@16: mutable vector_type m_vect; Chris@16: mutable char_type* mp_high_water; Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: }; Chris@16: Chris@16: //!A basic_istream class that holds a character vector specified by CharVector Chris@16: //!template parameter as its formatting buffer. The vector must have Chris@16: //!contiguous storage, like std::vector, boost::interprocess::vector or Chris@16: //!boost::interprocess::basic_string Chris@16: template Chris@16: class basic_ivectorstream Chris@16: : public std::basic_istream Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: , private basic_vectorbuf Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: { Chris@16: public: Chris@16: typedef CharVector vector_type; Chris@16: typedef typename std::basic_ios Chris@16: ::char_type char_type; Chris@16: typedef typename std::basic_ios::int_type int_type; Chris@16: typedef typename std::basic_ios::pos_type pos_type; Chris@16: typedef typename std::basic_ios::off_type off_type; Chris@16: typedef typename std::basic_ios::traits_type traits_type; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: typedef basic_vectorbuf vectorbuf_t; Chris@16: typedef std::basic_ios basic_ios_t; Chris@16: typedef std::basic_istream base_t; Chris@16: Chris@16: vectorbuf_t & get_buf() { return *this; } Chris@16: const vectorbuf_t & get_buf() const{ return *this; } Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: Chris@16: //!Constructor. Throws if vector_type default Chris@16: //!constructor throws. Chris@16: basic_ivectorstream(std::ios_base::openmode mode = std::ios_base::in) Chris@16: : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base Chris@16: //(via basic_ios::init() call in base_t's constructor) without the risk of a Chris@16: //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. Chris@16: , vectorbuf_t(mode | std::ios_base::in) Chris@16: { this->base_t::rdbuf(&get_buf()); } Chris@16: Chris@16: //!Constructor. Throws if vector_type(const VectorParameter ¶m) Chris@16: //!throws. Chris@16: template Chris@16: basic_ivectorstream(const VectorParameter ¶m, Chris@16: std::ios_base::openmode mode = std::ios_base::in) Chris@16: : vectorbuf_t(param, mode | std::ios_base::in) Chris@16: //basic_ios_t() is constructed uninitialized as virtual base Chris@16: //and initialized inside base_t calling basic_ios::init() Chris@16: , base_t(&get_buf()) Chris@16: {} Chris@16: Chris@16: public: Chris@16: //!Returns the address of the stored Chris@16: //!stream buffer. Chris@16: basic_vectorbuf* rdbuf() const Chris@16: { return const_cast*>(&get_buf()); } Chris@16: Chris@16: //!Swaps the underlying vector with the passed vector. Chris@16: //!This function resets the read position in the stream. Chris@16: //!Does not throw. Chris@16: void swap_vector(vector_type &vect) Chris@16: { get_buf().swap_vector(vect); } Chris@16: Chris@16: //!Returns a const reference to the internal vector. Chris@16: //!Does not throw. Chris@16: const vector_type &vector() const Chris@16: { return get_buf().vector(); } Chris@16: Chris@16: //!Calls reserve() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: //!Throws if the internals vector's reserve throws. Chris@16: void reserve(typename vector_type::size_type size) Chris@16: { get_buf().reserve(size); } Chris@16: Chris@16: //!Calls clear() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: void clear() Chris@16: { get_buf().clear(); } Chris@16: }; Chris@16: Chris@16: //!A basic_ostream class that holds a character vector specified by CharVector Chris@16: //!template parameter as its formatting buffer. The vector must have Chris@16: //!contiguous storage, like std::vector, boost::interprocess::vector or Chris@16: //!boost::interprocess::basic_string Chris@16: template Chris@16: class basic_ovectorstream Chris@16: : public std::basic_ostream Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: , private basic_vectorbuf Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: { Chris@16: public: Chris@16: typedef CharVector vector_type; Chris@16: typedef typename std::basic_ios Chris@16: ::char_type char_type; Chris@16: typedef typename std::basic_ios::int_type int_type; Chris@16: typedef typename std::basic_ios::pos_type pos_type; Chris@16: typedef typename std::basic_ios::off_type off_type; Chris@16: typedef typename std::basic_ios::traits_type traits_type; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: typedef basic_vectorbuf vectorbuf_t; Chris@16: typedef std::basic_ios basic_ios_t; Chris@16: typedef std::basic_ostream base_t; Chris@16: Chris@16: vectorbuf_t & get_buf() { return *this; } Chris@16: const vectorbuf_t & get_buf()const { return *this; } Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Constructor. Throws if vector_type default Chris@16: //!constructor throws. Chris@16: basic_ovectorstream(std::ios_base::openmode mode = std::ios_base::out) Chris@16: : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base Chris@16: //(via basic_ios::init() call in base_t's constructor) without the risk of a Chris@16: //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. Chris@16: , vectorbuf_t(mode | std::ios_base::out) Chris@16: { this->base_t::rdbuf(&get_buf()); } Chris@16: Chris@16: //!Constructor. Throws if vector_type(const VectorParameter ¶m) Chris@16: //!throws. Chris@16: template Chris@16: basic_ovectorstream(const VectorParameter ¶m, Chris@16: std::ios_base::openmode mode = std::ios_base::out) Chris@16: : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base Chris@16: //(via basic_ios::init() call in base_t's constructor) without the risk of a Chris@16: //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. Chris@16: , vectorbuf_t(param, mode | std::ios_base::out) Chris@16: { this->base_t::rdbuf(&get_buf()); } Chris@16: Chris@16: public: Chris@16: //!Returns the address of the stored Chris@16: //!stream buffer. Chris@16: basic_vectorbuf* rdbuf() const Chris@16: { return const_cast*>(&get_buf()); } Chris@16: Chris@16: //!Swaps the underlying vector with the passed vector. Chris@16: //!This function resets the write position in the stream. Chris@16: //!Does not throw. Chris@16: void swap_vector(vector_type &vect) Chris@16: { get_buf().swap_vector(vect); } Chris@16: Chris@16: //!Returns a const reference to the internal vector. Chris@16: //!Does not throw. Chris@16: const vector_type &vector() const Chris@16: { return get_buf().vector(); } Chris@16: Chris@16: //!Calls reserve() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: //!Throws if the internals vector's reserve throws. Chris@16: void reserve(typename vector_type::size_type size) Chris@16: { get_buf().reserve(size); } Chris@16: }; Chris@16: Chris@16: //!A basic_iostream class that holds a character vector specified by CharVector Chris@16: //!template parameter as its formatting buffer. The vector must have Chris@16: //!contiguous storage, like std::vector, boost::interprocess::vector or Chris@16: //!boost::interprocess::basic_string Chris@16: template Chris@16: class basic_vectorstream Chris@16: : public std::basic_iostream Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: , private basic_vectorbuf Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: { Chris@16: public: Chris@16: typedef CharVector vector_type; Chris@16: typedef typename std::basic_ios Chris@16: ::char_type char_type; Chris@16: typedef typename std::basic_ios::int_type int_type; Chris@16: typedef typename std::basic_ios::pos_type pos_type; Chris@16: typedef typename std::basic_ios::off_type off_type; Chris@16: typedef typename std::basic_ios::traits_type traits_type; Chris@16: Chris@101: #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED) Chris@16: private: Chris@16: typedef basic_vectorbuf vectorbuf_t; Chris@16: typedef std::basic_ios basic_ios_t; Chris@16: typedef std::basic_iostream base_t; Chris@16: Chris@16: vectorbuf_t & get_buf() { return *this; } Chris@16: const vectorbuf_t & get_buf() const{ return *this; } Chris@101: #endif //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED Chris@16: Chris@16: public: Chris@16: //!Constructor. Throws if vector_type default Chris@16: //!constructor throws. Chris@16: basic_vectorstream(std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base Chris@16: //(via basic_ios::init() call in base_t's constructor) without the risk of a Chris@16: //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. Chris@16: , vectorbuf_t(mode) Chris@16: { this->base_t::rdbuf(&get_buf()); } Chris@16: Chris@16: //!Constructor. Throws if vector_type(const VectorParameter ¶m) Chris@16: //!throws. Chris@16: template Chris@16: basic_vectorstream(const VectorParameter ¶m, std::ios_base::openmode mode Chris@16: = std::ios_base::in | std::ios_base::out) Chris@16: : base_t(0) //Initializes first the base class to safely init the virtual basic_ios base Chris@16: //(via basic_ios::init() call in base_t's constructor) without the risk of a Chris@16: //previous throwing vectorbuf constructor. Set the streambuf after risk has gone. Chris@16: , vectorbuf_t(param, mode) Chris@16: { this->base_t::rdbuf(&get_buf()); } Chris@16: Chris@16: public: Chris@16: //Returns the address of the stored stream buffer. Chris@16: basic_vectorbuf* rdbuf() const Chris@16: { return const_cast*>(&get_buf()); } Chris@16: Chris@16: //!Swaps the underlying vector with the passed vector. Chris@16: //!This function resets the read/write position in the stream. Chris@16: //!Does not throw. Chris@16: void swap_vector(vector_type &vect) Chris@16: { get_buf().swap_vector(vect); } Chris@16: Chris@16: //!Returns a const reference to the internal vector. Chris@16: //!Does not throw. Chris@16: const vector_type &vector() const Chris@16: { return get_buf().vector(); } Chris@16: Chris@16: //!Calls reserve() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: //!Throws if the internals vector's reserve throws. Chris@16: void reserve(typename vector_type::size_type size) Chris@16: { get_buf().reserve(size); } Chris@16: Chris@16: //!Calls clear() method of the internal vector. Chris@16: //!Resets the stream to the first position. Chris@16: void clear() Chris@16: { get_buf().clear(); } Chris@16: }; Chris@16: Chris@16: //Some typedefs to simplify usage Chris@16: //! Chris@16: //!typedef basic_vectorbuf > vectorbuf; Chris@16: //!typedef basic_vectorstream > vectorstream; Chris@16: //!typedef basic_ivectorstream > ivectorstream; Chris@16: //!typedef basic_ovectorstream > ovectorstream; Chris@16: //! Chris@16: //!typedef basic_vectorbuf > wvectorbuf; Chris@16: //!typedef basic_vectorstream > wvectorstream; Chris@16: //!typedef basic_ivectorstream > wivectorstream; Chris@16: //!typedef basic_ovectorstream > wovectorstream; Chris@16: Chris@16: }} //namespace boost { namespace interprocess { Chris@16: Chris@16: #include Chris@16: Chris@16: #endif /* BOOST_INTERPROCESS_VECTORSTREAM_HPP */