| ////////////////////////////////////////////////////////////////////////////// |
| // |
| // (C) Copyright Ion Gaztanaga 2005-2008. Distributed under the Boost |
| // Software License, Version 1.0. (See accompanying file |
| // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| // |
| // See http://www.boost.org/libs/interprocess for documentation. |
| // |
| ////////////////////////////////////////////////////////////////////////////// |
| // |
| // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005. |
| // Changed internal SGI string to a buffer. Added efficient |
| // internal buffer get/set/swap functions, so that we can obtain/establish the |
| // internal buffer without any reallocation or copy. Kill those temporaries! |
| /////////////////////////////////////////////////////////////////////////////// |
| /* |
| * Copyright (c) 1998 |
| * Silicon Graphics Computer Systems, Inc. |
| * |
| * Permission to use, copy, modify, distribute and sell this software |
| * and its documentation for any purpose is hereby granted without fee, |
| * provided that the above copyright notice appear in all copies and |
| * that both that copyright notice and this permission notice appear |
| * in supporting documentation. Silicon Graphics makes no |
| * representations about the suitability of this software for any |
| * purpose. It is provided "as is" without express or implied warranty. |
| */ |
| |
| //!\file |
| //!This file defines basic_bufferbuf, basic_ibufferstream, |
| //!basic_obufferstream, and basic_bufferstream classes. These classes |
| //!represent streamsbufs and streams whose sources or destinations |
| //!are fixed size character buffers. |
| |
| #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP |
| #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP |
| |
| #include <boost/interprocess/detail/config_begin.hpp> |
| #include <boost/interprocess/detail/workaround.hpp> |
| |
| #include <iosfwd> |
| #include <ios> |
| #include <istream> |
| #include <ostream> |
| #include <string> // char traits |
| #include <cstddef> // ptrdiff_t |
| #include <cassert> |
| #include <boost/interprocess/interprocess_fwd.hpp> |
| |
| namespace boost { namespace interprocess { |
| |
| //!A streambuf class that controls the transmission of elements to and from |
| //!a basic_xbufferstream. The elements are transmitted from a to a fixed |
| //!size buffer |
| template <class CharT, class CharTraits> |
| class basic_bufferbuf |
| : public std::basic_streambuf<CharT, CharTraits> |
| { |
| public: |
| typedef CharT char_type; |
| typedef typename CharTraits::int_type int_type; |
| typedef typename CharTraits::pos_type pos_type; |
| typedef typename CharTraits::off_type off_type; |
| typedef CharTraits traits_type; |
| typedef std::basic_streambuf<char_type, traits_type> base_t; |
| |
| public: |
| //!Constructor. |
| //!Does not throw. |
| explicit basic_bufferbuf(std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| : base_t(), m_mode(mode), m_buffer(0), m_length(0) |
| {} |
| |
| //!Constructor. Assigns formatting buffer. |
| //!Does not throw. |
| explicit basic_bufferbuf(CharT *buffer, std::size_t length, |
| std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| : base_t(), m_mode(mode), m_buffer(buffer), m_length(length) |
| { this->set_pointers(); } |
| |
| virtual ~basic_bufferbuf(){} |
| |
| public: |
| //!Returns the pointer and size of the internal buffer. |
| //!Does not throw. |
| std::pair<CharT *, std::size_t> buffer() const |
| { return std::pair<CharT *, std::size_t>(m_buffer, m_length); } |
| |
| //!Sets the underlying buffer to a new value |
| //!Does not throw. |
| void buffer(CharT *buffer, std::size_t length) |
| { m_buffer = buffer; m_length = length; this->set_pointers(); } |
| |
| /// @cond |
| private: |
| void set_pointers() |
| { |
| // The initial read position is the beginning of the buffer. |
| if(m_mode & std::ios_base::in) |
| this->setg(m_buffer, m_buffer, m_buffer + m_length); |
| |
| // The initial write position is the beginning of the buffer. |
| if(m_mode & std::ios_base::out) |
| this->setp(m_buffer, m_buffer + m_length); |
| } |
| |
| protected: |
| virtual int_type underflow() |
| { |
| // Precondition: gptr() >= egptr(). Returns a character, if available. |
| return this->gptr() != this->egptr() ? |
| CharTraits::to_int_type(*this->gptr()) : CharTraits::eof(); |
| } |
| |
| virtual int_type pbackfail(int_type c = CharTraits::eof()) |
| { |
| if(this->gptr() != this->eback()) { |
| if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
| if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) { |
| this->gbump(-1); |
| return c; |
| } |
| else if(m_mode & std::ios_base::out) { |
| this->gbump(-1); |
| *this->gptr() = c; |
| return c; |
| } |
| else |
| return CharTraits::eof(); |
| } |
| else { |
| this->gbump(-1); |
| return CharTraits::not_eof(c); |
| } |
| } |
| else |
| return CharTraits::eof(); |
| } |
| |
| virtual int_type overflow(int_type c = CharTraits::eof()) |
| { |
| if(m_mode & std::ios_base::out) { |
| if(!CharTraits::eq_int_type(c, CharTraits::eof())) { |
| // if(!(m_mode & std::ios_base::in)) { |
| // if(this->pptr() != this->epptr()) { |
| // *this->pptr() = CharTraits::to_char_type(c); |
| // this->pbump(1); |
| // return c; |
| // } |
| // else |
| // return CharTraits::eof(); |
| // } |
| // else { |
| if(this->pptr() == this->epptr()) { |
| //We can't append to a static buffer |
| return CharTraits::eof(); |
| } |
| else { |
| *this->pptr() = CharTraits::to_char_type(c); |
| this->pbump(1); |
| return c; |
| } |
| // } |
| } |
| else // c is EOF, so we don't have to do anything |
| return CharTraits::not_eof(c); |
| } |
| else // Overflow always fails if it's read-only. |
| return CharTraits::eof(); |
| } |
| |
| virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir, |
| std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| { |
| bool in = false; |
| bool out = false; |
| |
| const std::ios_base::openmode inout = |
| std::ios_base::in | std::ios_base::out; |
| |
| if((mode & inout) == inout) { |
| if(dir == std::ios_base::beg || dir == std::ios_base::end) |
| in = out = true; |
| } |
| else if(mode & std::ios_base::in) |
| in = true; |
| else if(mode & std::ios_base::out) |
| out = true; |
| |
| if(!in && !out) |
| return pos_type(off_type(-1)); |
| else if((in && (!(m_mode & std::ios_base::in) || this->gptr() == 0)) || |
| (out && (!(m_mode & std::ios_base::out) || this->pptr() == 0))) |
| return pos_type(off_type(-1)); |
| |
| std::streamoff newoff; |
| switch(dir) { |
| case std::ios_base::beg: |
| newoff = 0; |
| break; |
| case std::ios_base::end: |
| newoff = static_cast<std::streamoff>(m_length); |
| break; |
| case std::ios_base::cur: |
| newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback()) |
| : static_cast<std::streamoff>(this->pptr() - this->pbase()); |
| break; |
| default: |
| return pos_type(off_type(-1)); |
| } |
| |
| off += newoff; |
| |
| if(in) { |
| std::ptrdiff_t n = this->egptr() - this->eback(); |
| |
| if(off < 0 || off > n) |
| return pos_type(off_type(-1)); |
| else |
| this->setg(this->eback(), this->eback() + off, this->eback() + n); |
| } |
| |
| if(out) { |
| std::ptrdiff_t n = this->epptr() - this->pbase(); |
| |
| if(off < 0 || off > n) |
| return pos_type(off_type(-1)); |
| else { |
| this->setp(this->pbase(), this->pbase() + n); |
| this->pbump(off); |
| } |
| } |
| |
| return pos_type(off); |
| } |
| |
| virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| { return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode); } |
| |
| private: |
| std::ios_base::openmode m_mode; |
| CharT * m_buffer; |
| std::size_t m_length; |
| /// @endcond |
| }; |
| |
| //!A basic_istream class that uses a fixed size character buffer |
| //!as its formatting buffer. |
| template <class CharT, class CharTraits> |
| class basic_ibufferstream |
| : public std::basic_istream<CharT, CharTraits> |
| { |
| public: // Typedefs |
| typedef typename std::basic_ios |
| <CharT, CharTraits>::char_type char_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
| |
| private: |
| typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
| typedef std::basic_istream<char_type, CharTraits> base_t; |
| |
| public: |
| //!Constructor. |
| //!Does not throw. |
| basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in) |
| : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::in) |
| { basic_ios_t::init(&m_buf); } |
| |
| //!Constructor. Assigns formatting buffer. |
| //!Does not throw. |
| basic_ibufferstream(const CharT *buffer, std::size_t length, |
| std::ios_base::openmode mode = std::ios_base::in) |
| : basic_ios_t(), base_t(0), |
| m_buf(const_cast<CharT*>(buffer), length, mode | std::ios_base::in) |
| { basic_ios_t::init(&m_buf); } |
| |
| ~basic_ibufferstream(){}; |
| |
| public: |
| //!Returns the address of the stored |
| //!stream buffer. |
| basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
| { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); } |
| |
| //!Returns the pointer and size of the internal buffer. |
| //!Does not throw. |
| std::pair<const CharT *, std::size_t> buffer() const |
| { return m_buf.buffer(); } |
| |
| //!Sets the underlying buffer to a new value. Resets |
| //!stream position. Does not throw. |
| void buffer(const CharT *buffer, std::size_t length) |
| { m_buf.buffer(const_cast<CharT*>(buffer), length); } |
| |
| /// @cond |
| private: |
| basic_bufferbuf<CharT, CharTraits> m_buf; |
| /// @endcond |
| }; |
| |
| //!A basic_ostream class that uses a fixed size character buffer |
| //!as its formatting buffer. |
| template <class CharT, class CharTraits> |
| class basic_obufferstream |
| : public std::basic_ostream<CharT, CharTraits> |
| { |
| public: |
| typedef typename std::basic_ios |
| <CharT, CharTraits>::char_type char_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
| |
| /// @cond |
| private: |
| typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
| typedef std::basic_ostream<char_type, CharTraits> base_t; |
| /// @endcond |
| public: |
| //!Constructor. |
| //!Does not throw. |
| basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out) |
| : basic_ios_t(), base_t(0), m_buf(mode | std::ios_base::out) |
| { basic_ios_t::init(&m_buf); } |
| |
| //!Constructor. Assigns formatting buffer. |
| //!Does not throw. |
| basic_obufferstream(CharT *buffer, std::size_t length, |
| std::ios_base::openmode mode = std::ios_base::out) |
| : basic_ios_t(), base_t(0), |
| m_buf(buffer, length, mode | std::ios_base::out) |
| { basic_ios_t::init(&m_buf); } |
| |
| ~basic_obufferstream(){} |
| |
| public: |
| //!Returns the address of the stored |
| //!stream buffer. |
| basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
| { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); } |
| |
| //!Returns the pointer and size of the internal buffer. |
| //!Does not throw. |
| std::pair<CharT *, std::size_t> buffer() const |
| { return m_buf.buffer(); } |
| |
| //!Sets the underlying buffer to a new value. Resets |
| //!stream position. Does not throw. |
| void buffer(CharT *buffer, std::size_t length) |
| { m_buf.buffer(buffer, length); } |
| |
| /// @cond |
| private: |
| basic_bufferbuf<CharT, CharTraits> m_buf; |
| /// @endcond |
| }; |
| |
| |
| //!A basic_iostream class that uses a fixed size character buffer |
| //!as its formatting buffer. |
| template <class CharT, class CharTraits> |
| class basic_bufferstream |
| : public std::basic_iostream<CharT, CharTraits> |
| |
| { |
| public: // Typedefs |
| typedef typename std::basic_ios |
| <CharT, CharTraits>::char_type char_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::int_type int_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::pos_type pos_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type; |
| typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type; |
| |
| /// @cond |
| private: |
| typedef std::basic_ios<char_type, CharTraits> basic_ios_t; |
| typedef std::basic_iostream<char_type, CharTraits> base_t; |
| /// @endcond |
| |
| public: |
| //!Constructor. |
| //!Does not throw. |
| basic_bufferstream(std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| : basic_ios_t(), base_t(0), m_buf(mode) |
| { basic_ios_t::init(&m_buf); } |
| |
| //!Constructor. Assigns formatting buffer. |
| //!Does not throw. |
| basic_bufferstream(CharT *buffer, std::size_t length, |
| std::ios_base::openmode mode |
| = std::ios_base::in | std::ios_base::out) |
| : basic_ios_t(), base_t(0), m_buf(buffer, length, mode) |
| { basic_ios_t::init(&m_buf); } |
| |
| ~basic_bufferstream(){} |
| |
| public: |
| //!Returns the address of the stored |
| //!stream buffer. |
| basic_bufferbuf<CharT, CharTraits>* rdbuf() const |
| { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&m_buf); } |
| |
| //!Returns the pointer and size of the internal buffer. |
| //!Does not throw. |
| std::pair<CharT *, std::size_t> buffer() const |
| { return m_buf.buffer(); } |
| |
| //!Sets the underlying buffer to a new value. Resets |
| //!stream position. Does not throw. |
| void buffer(CharT *buffer, std::size_t length) |
| { m_buf.buffer(buffer, length); } |
| |
| /// @cond |
| private: |
| basic_bufferbuf<CharT, CharTraits> m_buf; |
| /// @endcond |
| }; |
| |
| //Some typedefs to simplify usage |
| typedef basic_bufferbuf<char> bufferbuf; |
| typedef basic_bufferstream<char> bufferstream; |
| typedef basic_ibufferstream<char> ibufferstream; |
| typedef basic_obufferstream<char> obufferstream; |
| |
| typedef basic_bufferbuf<wchar_t> wbufferbuf; |
| typedef basic_bufferstream<wchar_t> wbufferstream; |
| typedef basic_ibufferstream<wchar_t> wibufferstream; |
| typedef basic_obufferstream<wchar_t> wobufferstream; |
| |
| |
| }} //namespace boost { namespace interprocess { |
| |
| #include <boost/interprocess/detail/config_end.hpp> |
| |
| #endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */ |