| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491 | ////////////////////////////////////////////////////////////////////////////////// (C) Copyright Ion Gaztanaga 2005-2012. 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-2012.// 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#ifndef BOOST_CONFIG_HPP#  include <boost/config.hpp>#endif##if defined(BOOST_HAS_PRAGMA_ONCE)#  pragma once#endif#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 <boost/assert.hpp>#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 buffertemplate <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>  basic_streambuf_t;   public:   //!Constructor.   //!Does not throw.   explicit basic_bufferbuf(std::ios_base::openmode mode                            = std::ios_base::in | std::ios_base::out)      :  basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0)      {}   //!Constructor. Assigns formatting buffer.   //!Does not throw.   explicit basic_bufferbuf(CharT *buf, std::size_t length,                            std::ios_base::openmode mode                              = std::ios_base::in | std::ios_base::out)      :  basic_streambuf_t(), m_mode(mode), m_buffer(buf), 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 *buf, std::size_t length)      {  m_buffer = buf;   m_length = length;   this->set_pointers();   }   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   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) || (off != 0 && this->gptr() == 0) )) ||               (out && (!(m_mode & std::ios_base::out) || (off != 0 && 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(static_cast<int>(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;   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED};//!A basic_istream class that uses a fixed size character buffer//!as its formatting buffer.template <class CharT, class CharTraits>class basic_ibufferstream :   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private basic_bufferbuf<CharT, CharTraits>,   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   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;   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private:   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;   typedef std::basic_istream<char_type, CharTraits>  basic_streambuf_t;   bufferbuf_t &       get_buf()      {  return *this;  }   const bufferbuf_t & get_buf() const{  return *this;  }   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   public:   //!Constructor.   //!Does not throw.   basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()        bufferbuf_t(mode | std::ios_base::in)      , basic_streambuf_t(this)      {}   //!Constructor. Assigns formatting buffer.   //!Does not throw.   basic_ibufferstream(const CharT *buf, std::size_t length,                       std::ios_base::openmode mode = std::ios_base::in)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()        bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)      , basic_streambuf_t(this)      {}   ~basic_ibufferstream(){}   public:   //!Returns the address of the stored   //!stream buffer.   basic_bufferbuf<CharT, CharTraits>* rdbuf() const      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }   //!Returns the pointer and size of the internal buffer.   //!Does not throw.   std::pair<const CharT *, std::size_t> buffer() const      { return get_buf().buffer(); }   //!Sets the underlying buffer to a new value. Resets   //!stream position. Does not throw.   void buffer(const CharT *buf, std::size_t length)      {  get_buf().buffer(const_cast<CharT*>(buf), length);  }};//!A basic_ostream class that uses a fixed size character buffer//!as its formatting buffer.template <class CharT, class CharTraits>class basic_obufferstream :   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private basic_bufferbuf<CharT, CharTraits>,   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   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;   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private:   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;   typedef std::basic_ostream<char_type, CharTraits>  basic_ostream_t;   bufferbuf_t &       get_buf()      {  return *this;  }   const bufferbuf_t & get_buf() const{  return *this;  }   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   public:   //!Constructor.   //!Does not throw.   basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()         bufferbuf_t(mode | std::ios_base::out)      ,  basic_ostream_t(this)      {}   //!Constructor. Assigns formatting buffer.   //!Does not throw.   basic_obufferstream(CharT *buf, std::size_t length,                       std::ios_base::openmode mode = std::ios_base::out)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()         bufferbuf_t(buf, length, mode | std::ios_base::out)      ,  basic_ostream_t(this)      {}   ~basic_obufferstream(){}   public:   //!Returns the address of the stored   //!stream buffer.   basic_bufferbuf<CharT, CharTraits>* rdbuf() const      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }   //!Returns the pointer and size of the internal buffer.   //!Does not throw.   std::pair<CharT *, std::size_t> buffer() const      { return get_buf().buffer(); }   //!Sets the underlying buffer to a new value. Resets   //!stream position. Does not throw.   void buffer(CharT *buf, std::size_t length)      {  get_buf().buffer(buf, length);  }};//!A basic_iostream class that uses a fixed size character buffer//!as its formatting buffer.template <class CharT, class CharTraits>class basic_bufferstream :   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private basic_bufferbuf<CharT, CharTraits>,   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   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;   #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)   private:   typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;   typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;   typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t;   bufferbuf_t &       get_buf()      {  return *this;  }   const bufferbuf_t & get_buf() const{  return *this;  }   #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED   public:   //!Constructor.   //!Does not throw.   basic_bufferstream(std::ios_base::openmode mode                      = std::ios_base::in | std::ios_base::out)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()         bufferbuf_t(mode)      ,  basic_iostream_t(this)      {}   //!Constructor. Assigns formatting buffer.   //!Does not throw.   basic_bufferstream(CharT *buf, std::size_t length,                      std::ios_base::openmode mode                        = std::ios_base::in | std::ios_base::out)      :  //basic_ios_t() is called first (lefting it uninitialized) as it's a         //virtual base of basic_istream. The class will be initialized when         //basic_istream is constructed calling basic_ios_t::init().         //As bufferbuf_t's constructor does not throw there is no risk of         //calling the basic_ios_t's destructor without calling basic_ios_t::init()         bufferbuf_t(buf, length, mode)      ,  basic_iostream_t(this)      {}   ~basic_bufferstream(){}   public:   //!Returns the address of the stored   //!stream buffer.   basic_bufferbuf<CharT, CharTraits>* rdbuf() const      { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }   //!Returns the pointer and size of the internal buffer.   //!Does not throw.   std::pair<CharT *, std::size_t> buffer() const      { return get_buf().buffer(); }   //!Sets the underlying buffer to a new value. Resets   //!stream position. Does not throw.   void buffer(CharT *buf, std::size_t length)      {  get_buf().buffer(buf, length);  }};//Some typedefs to simplify usagetypedef 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 */
 |