Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-03-28 08:05:22

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