Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:38:30

0001 //////////////////////////////////////////////////////////////////////////////
0002 //
0003 // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
0004 // Software License, Version 1.0. (See accompanying file
0005 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0006 //
0007 // See http://www.boost.org/libs/interprocess for documentation.
0008 //
0009 //////////////////////////////////////////////////////////////////////////////
0010 //
0011 // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
0012 // Changed internal SGI string to a buffer. Added efficient
0013 // internal buffer get/set/swap functions, so that we can obtain/establish the
0014 // internal buffer without any reallocation or copy. Kill those temporaries!
0015 ///////////////////////////////////////////////////////////////////////////////
0016 /*
0017  * Copyright (c) 1998
0018  * Silicon Graphics Computer Systems, Inc.
0019  *
0020  * Permission to use, copy, modify, distribute and sell this software
0021  * and its documentation for any purpose is hereby granted without fee,
0022  * provided that the above copyright notice appear in all copies and
0023  * that both that copyright notice and this permission notice appear
0024  * in supporting documentation.  Silicon Graphics makes no
0025  * representations about the suitability of this software for any
0026  * purpose.  It is provided "as is" without express or implied warranty.
0027  */
0028 
0029 //!\file
0030 //!This file defines basic_bufferbuf, basic_ibufferstream,
0031 //!basic_obufferstream, and basic_bufferstream classes. These classes
0032 //!represent streamsbufs and streams whose sources or destinations
0033 //!are fixed size character buffers.
0034 
0035 #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
0036 #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
0037 
0038 #ifndef BOOST_CONFIG_HPP
0039 #  include <boost/config.hpp>
0040 #endif
0041 #
0042 #if defined(BOOST_HAS_PRAGMA_ONCE)
0043 #  pragma once
0044 #endif
0045 
0046 #include <boost/interprocess/detail/config_begin.hpp>
0047 #include <boost/interprocess/detail/workaround.hpp>
0048 
0049 #include <iosfwd>
0050 #include <ios>
0051 #include <istream>
0052 #include <ostream>
0053 #include <string>    // char traits
0054 #include <cstddef>   // ptrdiff_t
0055 #include <boost/assert.hpp>
0056 #include <boost/interprocess/interprocess_fwd.hpp>
0057 
0058 namespace boost {  namespace interprocess {
0059 
0060 //!A streambuf class that controls the transmission of elements to and from
0061 //!a basic_xbufferstream. The elements are transmitted from a to a fixed
0062 //!size buffer
0063 template <class CharT, class CharTraits>
0064 class basic_bufferbuf
0065    : public std::basic_streambuf<CharT, CharTraits>
0066 {
0067    public:
0068    typedef CharT                                         char_type;
0069    typedef typename CharTraits::int_type                 int_type;
0070    typedef typename CharTraits::pos_type                 pos_type;
0071    typedef typename CharTraits::off_type                 off_type;
0072    typedef CharTraits                                    traits_type;
0073    typedef std::basic_streambuf<char_type, traits_type>  basic_streambuf_t;
0074 
0075    public:
0076    //!Constructor.
0077    //!Does not throw.
0078    explicit basic_bufferbuf(std::ios_base::openmode mode
0079                             = std::ios_base::in | std::ios_base::out)
0080       :  basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0)
0081       {}
0082 
0083    //!Constructor. Assigns formatting buffer.
0084    //!Does not throw.
0085    explicit basic_bufferbuf(CharT *buf, std::size_t length,
0086                             std::ios_base::openmode mode
0087                               = std::ios_base::in | std::ios_base::out)
0088       :  basic_streambuf_t(), m_mode(mode), m_buffer(buf), m_length(length)
0089       {  this->set_pointers();   }
0090 
0091    virtual ~basic_bufferbuf() BOOST_OVERRIDE {}
0092 
0093    public:
0094    //!Returns the pointer and size of the internal buffer.
0095    //!Does not throw.
0096    std::pair<CharT *, std::size_t> buffer() const
0097       { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
0098 
0099    //!Sets the underlying buffer to a new value
0100    //!Does not throw.
0101    void buffer(CharT *buf, std::size_t length)
0102       {  m_buffer = buf;   m_length = length;   this->set_pointers();   }
0103 
0104    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0105    private:
0106    void set_pointers()
0107    {
0108       // The initial read position is the beginning of the buffer.
0109       if(m_mode & std::ios_base::in)
0110          this->setg(m_buffer, m_buffer, m_buffer + m_length);
0111 
0112       // The initial write position is the beginning of the buffer.
0113       if(m_mode & std::ios_base::out)
0114          this->setp(m_buffer, m_buffer + m_length);
0115    }
0116 
0117    protected:
0118    virtual int_type underflow() BOOST_OVERRIDE
0119    {
0120       // Precondition: gptr() >= egptr(). Returns a character, if available.
0121       return this->gptr() != this->egptr() ?
0122          CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
0123    }
0124 
0125    virtual int_type pbackfail(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0126    {
0127       if(this->gptr() != this->eback()) {
0128          if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0129             if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
0130                this->gbump(-1);
0131                return c;
0132             }
0133             else if(m_mode & std::ios_base::out) {
0134                this->gbump(-1);
0135                *this->gptr() = CharTraits::to_char_type(c);
0136                return c;
0137             }
0138             else
0139                return CharTraits::eof();
0140          }
0141          else {
0142             this->gbump(-1);
0143             return CharTraits::not_eof(c);
0144          }
0145       }
0146       else
0147          return CharTraits::eof();
0148    }
0149 
0150    virtual int_type overflow(int_type c = CharTraits::eof()) BOOST_OVERRIDE
0151    {
0152       if(m_mode & std::ios_base::out) {
0153          if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
0154 //            if(!(m_mode & std::ios_base::in)) {
0155 //               if(this->pptr() != this->epptr()) {
0156 //                  *this->pptr() = CharTraits::to_char_type(c);
0157 //                  this->pbump(1);
0158 //                  return c;
0159 //               }
0160 //               else
0161 //                  return CharTraits::eof();
0162 //            }
0163 //            else {
0164                if(this->pptr() == this->epptr()) {
0165                   //We can't append to a static buffer
0166                   return CharTraits::eof();
0167                }
0168                else {
0169                   *this->pptr() = CharTraits::to_char_type(c);
0170                   this->pbump(1);
0171                   return c;
0172                }
0173 //            }
0174          }
0175          else  // c is EOF, so we don't have to do anything
0176             return CharTraits::not_eof(c);
0177       }
0178       else     // Overflow always fails if it's read-only.
0179          return CharTraits::eof();
0180    }
0181 
0182    virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
0183                               std::ios_base::openmode mode
0184                                  = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0185    {
0186       bool in  = false;
0187       bool out = false;
0188 
0189       const std::ios_base::openmode inout =
0190          std::ios_base::in | std::ios_base::out;
0191 
0192       if((mode & inout) == inout) {
0193          if(dir == std::ios_base::beg || dir == std::ios_base::end)
0194             in = out = true;
0195       }
0196       else if(mode & std::ios_base::in)
0197          in = true;
0198       else if(mode & std::ios_base::out)
0199          out = true;
0200 
0201       if(!in && !out)
0202          return pos_type(off_type(-1));
0203       else if((in  && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
0204                (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
0205          return pos_type(off_type(-1));
0206 
0207       std::streamoff newoff;
0208       switch(dir) {
0209          case std::ios_base::beg:
0210             newoff = 0;
0211          break;
0212          case std::ios_base::end:
0213             newoff = static_cast<std::streamoff>(m_length);
0214          break;
0215          case std::ios_base::cur:
0216             newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
0217                         : static_cast<std::streamoff>(this->pptr() - this->pbase());
0218          break;
0219          default:
0220             return pos_type(off_type(-1));
0221       }
0222 
0223       off += newoff;
0224 
0225       if(in) {
0226          std::ptrdiff_t n = this->egptr() - this->eback();
0227 
0228          if(off < 0 || off > n)
0229             return pos_type(off_type(-1));
0230          else
0231             this->setg(this->eback(), this->eback() + off, this->eback() + n);
0232       }
0233 
0234       if(out) {
0235          std::ptrdiff_t n = this->epptr() - this->pbase();
0236 
0237          if(off < 0 || off > n)
0238             return pos_type(off_type(-1));
0239          else {
0240             this->setp(this->pbase(), this->pbase() + n);
0241             this->pbump(static_cast<int>(off));
0242          }
0243       }
0244 
0245       return pos_type(off);
0246    }
0247 
0248    virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
0249                                  = std::ios_base::in | std::ios_base::out) BOOST_OVERRIDE
0250    {  return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);  }
0251 
0252    private:
0253    std::ios_base::openmode m_mode;
0254    CharT *                 m_buffer;
0255    std::size_t             m_length;
0256    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0257 };
0258 
0259 //!A basic_istream class that uses a fixed size character buffer
0260 //!as its formatting buffer.
0261 template <class CharT, class CharTraits>
0262 class basic_ibufferstream :
0263    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0264    private basic_bufferbuf<CharT, CharTraits>,
0265    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0266    public std::basic_istream<CharT, CharTraits>
0267 {
0268    public:                         // Typedefs
0269    typedef typename std::basic_ios
0270       <CharT, CharTraits>::char_type          char_type;
0271    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
0272    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
0273    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
0274    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
0275 
0276    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0277    private:
0278    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
0279    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
0280    typedef std::basic_istream<char_type, CharTraits>  basic_streambuf_t;
0281    bufferbuf_t &       get_buf()      {  return *this;  }
0282    const bufferbuf_t & get_buf() const{  return *this;  }
0283    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0284 
0285    public:
0286    //!Constructor.
0287    //!Does not throw.
0288    basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
0289       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0290          //virtual base of basic_istream. The class will be initialized when
0291          //basic_istream is constructed calling basic_ios_t::init().
0292          //As bufferbuf_t's constructor does not throw there is no risk of
0293          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0294         bufferbuf_t(mode | std::ios_base::in)
0295       , basic_streambuf_t(this)
0296       {}
0297 
0298    //!Constructor. Assigns formatting buffer.
0299    //!Does not throw.
0300    basic_ibufferstream(const CharT *buf, std::size_t length,
0301                        std::ios_base::openmode mode = std::ios_base::in)
0302       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0303          //virtual base of basic_istream. The class will be initialized when
0304          //basic_istream is constructed calling basic_ios_t::init().
0305          //As bufferbuf_t's constructor does not throw there is no risk of
0306          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0307         bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
0308       , basic_streambuf_t(this)
0309       {}
0310 
0311    ~basic_ibufferstream(){}
0312 
0313    public:
0314    //!Returns the address of the stored
0315    //!stream buffer.
0316    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0317       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0318 
0319    //!Returns the pointer and size of the internal buffer.
0320    //!Does not throw.
0321    std::pair<const CharT *, std::size_t> buffer() const
0322       { return get_buf().buffer(); }
0323 
0324    //!Sets the underlying buffer to a new value. Resets
0325    //!stream position. Does not throw.
0326    void buffer(const CharT *buf, std::size_t length)
0327       {  get_buf().buffer(const_cast<CharT*>(buf), length);  }
0328 };
0329 
0330 //!A basic_ostream class that uses a fixed size character buffer
0331 //!as its formatting buffer.
0332 template <class CharT, class CharTraits>
0333 class basic_obufferstream :
0334    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0335    private basic_bufferbuf<CharT, CharTraits>,
0336    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0337    public std::basic_ostream<CharT, CharTraits>
0338 {
0339    public:
0340    typedef typename std::basic_ios
0341       <CharT, CharTraits>::char_type          char_type;
0342    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
0343    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
0344    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
0345    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
0346 
0347    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0348    private:
0349    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
0350    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
0351    typedef std::basic_ostream<char_type, CharTraits>  basic_ostream_t;
0352    bufferbuf_t &       get_buf()      {  return *this;  }
0353    const bufferbuf_t & get_buf() const{  return *this;  }
0354    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0355 
0356    public:
0357    //!Constructor.
0358    //!Does not throw.
0359    basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
0360       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0361          //virtual base of basic_istream. The class will be initialized when
0362          //basic_istream is constructed calling basic_ios_t::init().
0363          //As bufferbuf_t's constructor does not throw there is no risk of
0364          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0365          bufferbuf_t(mode | std::ios_base::out)
0366       ,  basic_ostream_t(this)
0367       {}
0368 
0369    //!Constructor. Assigns formatting buffer.
0370    //!Does not throw.
0371    basic_obufferstream(CharT *buf, std::size_t length,
0372                        std::ios_base::openmode mode = std::ios_base::out)
0373       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0374          //virtual base of basic_istream. The class will be initialized when
0375          //basic_istream is constructed calling basic_ios_t::init().
0376          //As bufferbuf_t's constructor does not throw there is no risk of
0377          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0378          bufferbuf_t(buf, length, mode | std::ios_base::out)
0379       ,  basic_ostream_t(this)
0380       {}
0381 
0382    ~basic_obufferstream(){}
0383 
0384    public:
0385    //!Returns the address of the stored
0386    //!stream buffer.
0387    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0388       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0389 
0390    //!Returns the pointer and size of the internal buffer.
0391    //!Does not throw.
0392    std::pair<CharT *, std::size_t> buffer() const
0393       { return get_buf().buffer(); }
0394 
0395    //!Sets the underlying buffer to a new value. Resets
0396    //!stream position. Does not throw.
0397    void buffer(CharT *buf, std::size_t length)
0398       {  get_buf().buffer(buf, length);  }
0399 };
0400 
0401 
0402 //!A basic_iostream class that uses a fixed size character buffer
0403 //!as its formatting buffer.
0404 template <class CharT, class CharTraits>
0405 class basic_bufferstream :
0406    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0407    private basic_bufferbuf<CharT, CharTraits>,
0408    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0409    public std::basic_iostream<CharT, CharTraits>
0410 {
0411    public:                         // Typedefs
0412    typedef typename std::basic_ios
0413       <CharT, CharTraits>::char_type          char_type;
0414    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
0415    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
0416    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
0417    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
0418 
0419    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
0420    private:
0421    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
0422    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
0423    typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t;
0424    bufferbuf_t &       get_buf()      {  return *this;  }
0425    const bufferbuf_t & get_buf() const{  return *this;  }
0426    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
0427 
0428    public:
0429    //!Constructor.
0430    //!Does not throw.
0431    basic_bufferstream(std::ios_base::openmode mode
0432                       = std::ios_base::in | std::ios_base::out)
0433       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0434          //virtual base of basic_istream. The class will be initialized when
0435          //basic_istream is constructed calling basic_ios_t::init().
0436          //As bufferbuf_t's constructor does not throw there is no risk of
0437          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0438          bufferbuf_t(mode)
0439       ,  basic_iostream_t(this)
0440       {}
0441 
0442    //!Constructor. Assigns formatting buffer.
0443    //!Does not throw.
0444    basic_bufferstream(CharT *buf, std::size_t length,
0445                       std::ios_base::openmode mode
0446                         = std::ios_base::in | std::ios_base::out)
0447       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
0448          //virtual base of basic_istream. The class will be initialized when
0449          //basic_istream is constructed calling basic_ios_t::init().
0450          //As bufferbuf_t's constructor does not throw there is no risk of
0451          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
0452          bufferbuf_t(buf, length, mode)
0453       ,  basic_iostream_t(this)
0454       {}
0455 
0456    ~basic_bufferstream(){}
0457 
0458    public:
0459    //!Returns the address of the stored
0460    //!stream buffer.
0461    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
0462       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
0463 
0464    //!Returns the pointer and size of the internal buffer.
0465    //!Does not throw.
0466    std::pair<CharT *, std::size_t> buffer() const
0467       { return get_buf().buffer(); }
0468 
0469    //!Sets the underlying buffer to a new value. Resets
0470    //!stream position. Does not throw.
0471    void buffer(CharT *buf, std::size_t length)
0472       {  get_buf().buffer(buf, length);  }
0473 };
0474 
0475 //Some typedefs to simplify usage
0476 typedef basic_bufferbuf<char>        bufferbuf;
0477 typedef basic_bufferstream<char>     bufferstream;
0478 typedef basic_ibufferstream<char>    ibufferstream;
0479 typedef basic_obufferstream<char>    obufferstream;
0480 
0481 typedef basic_bufferbuf<wchar_t>     wbufferbuf;
0482 typedef basic_bufferstream<wchar_t>  wbufferstream;
0483 typedef basic_ibufferstream<wchar_t> wibufferstream;
0484 typedef basic_obufferstream<wchar_t> wobufferstream;
0485 
0486 
0487 }} //namespace boost {  namespace interprocess {
0488 
0489 #include <boost/interprocess/detail/config_end.hpp>
0490 
0491 #endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */