LCOV - code coverage report
Current view: top level - usr/include/boost/interprocess/streams - bufferstream.hpp (source / functions) Hit Total Coverage
Test: ROSE Lines: 0 7 0.0 %
Date: 2022-12-08 13:48:47 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //////////////////////////////////////////////////////////////////////////////
       2             : //
       3             : // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost
       4             : // Software License, Version 1.0. (See accompanying file
       5             : // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
       6             : //
       7             : // See http://www.boost.org/libs/interprocess for documentation.
       8             : //
       9             : //////////////////////////////////////////////////////////////////////////////
      10             : //
      11             : // This file comes from SGI's sstream file. Modified by Ion Gaztanaga 2005-2012.
      12             : // Changed internal SGI string to a buffer. Added efficient
      13             : // internal buffer get/set/swap functions, so that we can obtain/establish the
      14             : // internal buffer without any reallocation or copy. Kill those temporaries!
      15             : ///////////////////////////////////////////////////////////////////////////////
      16             : /*
      17             :  * Copyright (c) 1998
      18             :  * Silicon Graphics Computer Systems, Inc.
      19             :  *
      20             :  * Permission to use, copy, modify, distribute and sell this software
      21             :  * and its documentation for any purpose is hereby granted without fee,
      22             :  * provided that the above copyright notice appear in all copies and
      23             :  * that both that copyright notice and this permission notice appear
      24             :  * in supporting documentation.  Silicon Graphics makes no
      25             :  * representations about the suitability of this software for any
      26             :  * purpose.  It is provided "as is" without express or implied warranty.
      27             :  */
      28             : 
      29             : //!\file
      30             : //!This file defines basic_bufferbuf, basic_ibufferstream,
      31             : //!basic_obufferstream, and basic_bufferstream classes. These classes
      32             : //!represent streamsbufs and streams whose sources or destinations
      33             : //!are fixed size character buffers.
      34             : 
      35             : #ifndef BOOST_INTERPROCESS_BUFFERSTREAM_HPP
      36             : #define BOOST_INTERPROCESS_BUFFERSTREAM_HPP
      37             : 
      38             : #ifndef BOOST_CONFIG_HPP
      39             : #  include <boost/config.hpp>
      40             : #endif
      41             : #
      42             : #if defined(BOOST_HAS_PRAGMA_ONCE)
      43             : #  pragma once
      44             : #endif
      45             : 
      46             : #include <boost/interprocess/detail/config_begin.hpp>
      47             : #include <boost/interprocess/detail/workaround.hpp>
      48             : 
      49             : #include <iosfwd>
      50             : #include <ios>
      51             : #include <istream>
      52             : #include <ostream>
      53             : #include <string>    // char traits
      54             : #include <cstddef>   // ptrdiff_t
      55             : #include <boost/assert.hpp>
      56             : #include <boost/interprocess/interprocess_fwd.hpp>
      57             : 
      58             : namespace boost {  namespace interprocess {
      59             : 
      60             : //!A streambuf class that controls the transmission of elements to and from
      61             : //!a basic_xbufferstream. The elements are transmitted from a to a fixed
      62             : //!size buffer
      63             : template <class CharT, class CharTraits>
      64             : class basic_bufferbuf
      65             :    : public std::basic_streambuf<CharT, CharTraits>
      66             : {
      67             :    public:
      68             :    typedef CharT                                         char_type;
      69             :    typedef typename CharTraits::int_type                 int_type;
      70             :    typedef typename CharTraits::pos_type                 pos_type;
      71             :    typedef typename CharTraits::off_type                 off_type;
      72             :    typedef CharTraits                                    traits_type;
      73             :    typedef std::basic_streambuf<char_type, traits_type>  basic_streambuf_t;
      74             : 
      75             :    public:
      76             :    //!Constructor.
      77             :    //!Does not throw.
      78             :    explicit basic_bufferbuf(std::ios_base::openmode mode
      79             :                             = std::ios_base::in | std::ios_base::out)
      80             :       :  basic_streambuf_t(), m_mode(mode), m_buffer(0), m_length(0)
      81             :       {}
      82             : 
      83             :    //!Constructor. Assigns formatting buffer.
      84             :    //!Does not throw.
      85             :    explicit basic_bufferbuf(CharT *buf, std::size_t length,
      86             :                             std::ios_base::openmode mode
      87             :                               = std::ios_base::in | std::ios_base::out)
      88             :       :  basic_streambuf_t(), m_mode(mode), m_buffer(buf), m_length(length)
      89             :       {  this->set_pointers();   }
      90             : 
      91             :    virtual ~basic_bufferbuf(){}
      92             : 
      93             :    public:
      94             :    //!Returns the pointer and size of the internal buffer.
      95             :    //!Does not throw.
      96             :    std::pair<CharT *, std::size_t> buffer() const
      97             :       { return std::pair<CharT *, std::size_t>(m_buffer, m_length); }
      98             : 
      99             :    //!Sets the underlying buffer to a new value
     100             :    //!Does not throw.
     101             :    void buffer(CharT *buf, std::size_t length)
     102             :       {  m_buffer = buf;   m_length = length;   this->set_pointers();   }
     103             : 
     104             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     105             :    private:
     106             :    void set_pointers()
     107             :    {
     108             :       // The initial read position is the beginning of the buffer.
     109             :       if(m_mode & std::ios_base::in)
     110             :          this->setg(m_buffer, m_buffer, m_buffer + m_length);
     111             : 
     112             :       // The initial write position is the beginning of the buffer.
     113             :       if(m_mode & std::ios_base::out)
     114             :          this->setp(m_buffer, m_buffer + m_length);
     115             :    }
     116             : 
     117             :    protected:
     118             :    virtual int_type underflow()
     119             :    {
     120             :       // Precondition: gptr() >= egptr(). Returns a character, if available.
     121             :       return this->gptr() != this->egptr() ?
     122             :          CharTraits::to_int_type(*this->gptr()) : CharTraits::eof();
     123             :    }
     124             : 
     125             :    virtual int_type pbackfail(int_type c = CharTraits::eof())
     126             :    {
     127             :       if(this->gptr() != this->eback()) {
     128             :          if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
     129             :             if(CharTraits::eq(CharTraits::to_char_type(c), this->gptr()[-1])) {
     130             :                this->gbump(-1);
     131             :                return c;
     132             :             }
     133             :             else if(m_mode & std::ios_base::out) {
     134             :                this->gbump(-1);
     135             :                *this->gptr() = c;
     136             :                return c;
     137             :             }
     138             :             else
     139             :                return CharTraits::eof();
     140             :          }
     141             :          else {
     142             :             this->gbump(-1);
     143             :             return CharTraits::not_eof(c);
     144             :          }
     145             :       }
     146             :       else
     147             :          return CharTraits::eof();
     148             :    }
     149             : 
     150           0 :    virtual int_type overflow(int_type c = CharTraits::eof())
     151             :    {
     152           0 :       if(m_mode & std::ios_base::out) {
     153           0 :          if(!CharTraits::eq_int_type(c, CharTraits::eof())) {
     154             : //            if(!(m_mode & std::ios_base::in)) {
     155             : //               if(this->pptr() != this->epptr()) {
     156             : //                  *this->pptr() = CharTraits::to_char_type(c);
     157             : //                  this->pbump(1);
     158             : //                  return c;
     159             : //               }
     160             : //               else
     161             : //                  return CharTraits::eof();
     162             : //            }
     163             : //            else {
     164           0 :                if(this->pptr() == this->epptr()) {
     165             :                   //We can't append to a static buffer
     166             :                   return CharTraits::eof();
     167             :                }
     168             :                else {
     169           0 :                   *this->pptr() = CharTraits::to_char_type(c);
     170           0 :                   this->pbump(1);
     171           0 :                   return c;
     172             :                }
     173             : //            }
     174             :          }
     175             :          else  // c is EOF, so we don't have to do anything
     176             :             return CharTraits::not_eof(c);
     177             :       }
     178             :       else     // Overflow always fails if it's read-only.
     179             :          return CharTraits::eof();
     180             :    }
     181             : 
     182             :    virtual pos_type seekoff(off_type off, std::ios_base::seekdir dir,
     183             :                               std::ios_base::openmode mode
     184             :                                  = std::ios_base::in | std::ios_base::out)
     185             :    {
     186             :       bool in  = false;
     187             :       bool out = false;
     188             : 
     189             :       const std::ios_base::openmode inout =
     190             :          std::ios_base::in | std::ios_base::out;
     191             : 
     192             :       if((mode & inout) == inout) {
     193             :          if(dir == std::ios_base::beg || dir == std::ios_base::end)
     194             :             in = out = true;
     195             :       }
     196             :       else if(mode & std::ios_base::in)
     197             :          in = true;
     198             :       else if(mode & std::ios_base::out)
     199             :          out = true;
     200             : 
     201             :       if(!in && !out)
     202             :          return pos_type(off_type(-1));
     203             :       else if((in  && (!(m_mode & std::ios_base::in) || (off != 0 && this->gptr() == 0) )) ||
     204             :                (out && (!(m_mode & std::ios_base::out) || (off != 0 && this->pptr() == 0))))
     205             :          return pos_type(off_type(-1));
     206             : 
     207             :       std::streamoff newoff;
     208             :       switch(dir) {
     209             :          case std::ios_base::beg:
     210             :             newoff = 0;
     211             :          break;
     212             :          case std::ios_base::end:
     213             :             newoff = static_cast<std::streamoff>(m_length);
     214             :          break;
     215             :          case std::ios_base::cur:
     216             :             newoff = in ? static_cast<std::streamoff>(this->gptr() - this->eback())
     217             :                         : static_cast<std::streamoff>(this->pptr() - this->pbase());
     218             :          break;
     219             :          default:
     220             :             return pos_type(off_type(-1));
     221             :       }
     222             : 
     223             :       off += newoff;
     224             : 
     225             :       if(in) {
     226             :          std::ptrdiff_t n = this->egptr() - this->eback();
     227             : 
     228             :          if(off < 0 || off > n)
     229             :             return pos_type(off_type(-1));
     230             :          else
     231             :             this->setg(this->eback(), this->eback() + off, this->eback() + n);
     232             :       }
     233             : 
     234             :       if(out) {
     235             :          std::ptrdiff_t n = this->epptr() - this->pbase();
     236             : 
     237             :          if(off < 0 || off > n)
     238             :             return pos_type(off_type(-1));
     239             :          else {
     240             :             this->setp(this->pbase(), this->pbase() + n);
     241             :             this->pbump(static_cast<int>(off));
     242             :          }
     243             :       }
     244             : 
     245             :       return pos_type(off);
     246             :    }
     247             : 
     248             :    virtual pos_type seekpos(pos_type pos, std::ios_base::openmode mode
     249             :                                  = std::ios_base::in | std::ios_base::out)
     250             :    {  return seekoff(pos - pos_type(off_type(0)), std::ios_base::beg, mode);  }
     251             : 
     252             :    private:
     253             :    std::ios_base::openmode m_mode;
     254             :    CharT *                 m_buffer;
     255             :    std::size_t             m_length;
     256             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     257             : };
     258             : 
     259             : //!A basic_istream class that uses a fixed size character buffer
     260             : //!as its formatting buffer.
     261             : template <class CharT, class CharTraits>
     262             : class basic_ibufferstream :
     263             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     264             :    private basic_bufferbuf<CharT, CharTraits>,
     265             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     266             :    public std::basic_istream<CharT, CharTraits>
     267             : {
     268             :    public:                         // Typedefs
     269             :    typedef typename std::basic_ios
     270             :       <CharT, CharTraits>::char_type          char_type;
     271             :    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
     272             :    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
     273             :    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
     274             :    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
     275             : 
     276             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     277             :    private:
     278             :    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
     279             :    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
     280             :    typedef std::basic_istream<char_type, CharTraits>  basic_streambuf_t;
     281             :    bufferbuf_t &       get_buf()      {  return *this;  }
     282             :    const bufferbuf_t & get_buf() const{  return *this;  }
     283             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     284             : 
     285             :    public:
     286             :    //!Constructor.
     287             :    //!Does not throw.
     288             :    basic_ibufferstream(std::ios_base::openmode mode = std::ios_base::in)
     289             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     290             :          //virtual base of basic_istream. The class will be initialized when
     291             :          //basic_istream is constructed calling basic_ios_t::init().
     292             :          //As bufferbuf_t's constructor does not throw there is no risk of
     293             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     294             :         bufferbuf_t(mode | std::ios_base::in)
     295             :       , basic_streambuf_t(this)
     296             :       {}
     297             : 
     298             :    //!Constructor. Assigns formatting buffer.
     299             :    //!Does not throw.
     300             :    basic_ibufferstream(const CharT *buf, std::size_t length,
     301             :                        std::ios_base::openmode mode = std::ios_base::in)
     302             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     303             :          //virtual base of basic_istream. The class will be initialized when
     304             :          //basic_istream is constructed calling basic_ios_t::init().
     305             :          //As bufferbuf_t's constructor does not throw there is no risk of
     306             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     307             :         bufferbuf_t(const_cast<CharT*>(buf), length, mode | std::ios_base::in)
     308             :       , basic_streambuf_t(this)
     309             :       {}
     310             : 
     311             :    ~basic_ibufferstream(){}
     312             : 
     313             :    public:
     314             :    //!Returns the address of the stored
     315             :    //!stream buffer.
     316             :    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
     317             :       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
     318             : 
     319             :    //!Returns the pointer and size of the internal buffer.
     320             :    //!Does not throw.
     321             :    std::pair<const CharT *, std::size_t> buffer() const
     322             :       { return get_buf().buffer(); }
     323             : 
     324             :    //!Sets the underlying buffer to a new value. Resets
     325             :    //!stream position. Does not throw.
     326             :    void buffer(const CharT *buf, std::size_t length)
     327             :       {  get_buf().buffer(const_cast<CharT*>(buf), length);  }
     328             : };
     329             : 
     330             : //!A basic_ostream class that uses a fixed size character buffer
     331             : //!as its formatting buffer.
     332             : template <class CharT, class CharTraits>
     333             : class basic_obufferstream :
     334             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     335             :    private basic_bufferbuf<CharT, CharTraits>,
     336             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     337             :    public std::basic_ostream<CharT, CharTraits>
     338             : {
     339             :    public:
     340             :    typedef typename std::basic_ios
     341             :       <CharT, CharTraits>::char_type          char_type;
     342             :    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
     343             :    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
     344             :    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
     345             :    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
     346             : 
     347             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     348             :    private:
     349             :    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
     350             :    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
     351             :    typedef std::basic_ostream<char_type, CharTraits>  basic_ostream_t;
     352             :    bufferbuf_t &       get_buf()      {  return *this;  }
     353             :    const bufferbuf_t & get_buf() const{  return *this;  }
     354             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     355             : 
     356             :    public:
     357             :    //!Constructor.
     358             :    //!Does not throw.
     359             :    basic_obufferstream(std::ios_base::openmode mode = std::ios_base::out)
     360             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     361             :          //virtual base of basic_istream. The class will be initialized when
     362             :          //basic_istream is constructed calling basic_ios_t::init().
     363             :          //As bufferbuf_t's constructor does not throw there is no risk of
     364             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     365             :          bufferbuf_t(mode | std::ios_base::out)
     366             :       ,  basic_ostream_t(this)
     367             :       {}
     368             : 
     369             :    //!Constructor. Assigns formatting buffer.
     370             :    //!Does not throw.
     371             :    basic_obufferstream(CharT *buf, std::size_t length,
     372             :                        std::ios_base::openmode mode = std::ios_base::out)
     373             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     374             :          //virtual base of basic_istream. The class will be initialized when
     375             :          //basic_istream is constructed calling basic_ios_t::init().
     376             :          //As bufferbuf_t's constructor does not throw there is no risk of
     377             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     378             :          bufferbuf_t(buf, length, mode | std::ios_base::out)
     379             :       ,  basic_ostream_t(this)
     380             :       {}
     381             : 
     382             :    ~basic_obufferstream(){}
     383             : 
     384             :    public:
     385             :    //!Returns the address of the stored
     386             :    //!stream buffer.
     387             :    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
     388             :       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
     389             : 
     390             :    //!Returns the pointer and size of the internal buffer.
     391             :    //!Does not throw.
     392             :    std::pair<CharT *, std::size_t> buffer() const
     393             :       { return get_buf().buffer(); }
     394             : 
     395             :    //!Sets the underlying buffer to a new value. Resets
     396             :    //!stream position. Does not throw.
     397             :    void buffer(CharT *buf, std::size_t length)
     398             :       {  get_buf().buffer(buf, length);  }
     399             : };
     400             : 
     401             : 
     402             : //!A basic_iostream class that uses a fixed size character buffer
     403             : //!as its formatting buffer.
     404             : template <class CharT, class CharTraits>
     405             : class basic_bufferstream :
     406             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     407             :    private basic_bufferbuf<CharT, CharTraits>,
     408             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     409             :    public std::basic_iostream<CharT, CharTraits>
     410             : {
     411             :    public:                         // Typedefs
     412             :    typedef typename std::basic_ios
     413             :       <CharT, CharTraits>::char_type          char_type;
     414             :    typedef typename std::basic_ios<char_type, CharTraits>::int_type     int_type;
     415             :    typedef typename std::basic_ios<char_type, CharTraits>::pos_type     pos_type;
     416             :    typedef typename std::basic_ios<char_type, CharTraits>::off_type     off_type;
     417             :    typedef typename std::basic_ios<char_type, CharTraits>::traits_type  traits_type;
     418             : 
     419             :    #if !defined(BOOST_INTERPROCESS_DOXYGEN_INVOKED)
     420             :    private:
     421             :    typedef basic_bufferbuf<CharT, CharTraits>         bufferbuf_t;
     422             :    typedef std::basic_ios<char_type, CharTraits>      basic_ios_t;
     423             :    typedef std::basic_iostream<char_type, CharTraits> basic_iostream_t;
     424             :    bufferbuf_t &       get_buf()      {  return *this;  }
     425             :    const bufferbuf_t & get_buf() const{  return *this;  }
     426             :    #endif   //#ifndef BOOST_INTERPROCESS_DOXYGEN_INVOKED
     427             : 
     428             :    public:
     429             :    //!Constructor.
     430             :    //!Does not throw.
     431             :    basic_bufferstream(std::ios_base::openmode mode
     432             :                       = std::ios_base::in | std::ios_base::out)
     433             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     434             :          //virtual base of basic_istream. The class will be initialized when
     435             :          //basic_istream is constructed calling basic_ios_t::init().
     436             :          //As bufferbuf_t's constructor does not throw there is no risk of
     437             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     438             :          bufferbuf_t(mode)
     439             :       ,  basic_iostream_t(this)
     440             :       {}
     441             : 
     442             :    //!Constructor. Assigns formatting buffer.
     443             :    //!Does not throw.
     444             :    basic_bufferstream(CharT *buf, std::size_t length,
     445             :                       std::ios_base::openmode mode
     446             :                         = std::ios_base::in | std::ios_base::out)
     447             :       :  //basic_ios_t() is called first (lefting it uninitialized) as it's a
     448             :          //virtual base of basic_istream. The class will be initialized when
     449             :          //basic_istream is constructed calling basic_ios_t::init().
     450             :          //As bufferbuf_t's constructor does not throw there is no risk of
     451             :          //calling the basic_ios_t's destructor without calling basic_ios_t::init()
     452             :          bufferbuf_t(buf, length, mode)
     453             :       ,  basic_iostream_t(this)
     454             :       {}
     455             : 
     456             :    ~basic_bufferstream(){}
     457             : 
     458             :    public:
     459             :    //!Returns the address of the stored
     460             :    //!stream buffer.
     461             :    basic_bufferbuf<CharT, CharTraits>* rdbuf() const
     462             :       { return const_cast<basic_bufferbuf<CharT, CharTraits>*>(&get_buf()); }
     463             : 
     464             :    //!Returns the pointer and size of the internal buffer.
     465             :    //!Does not throw.
     466             :    std::pair<CharT *, std::size_t> buffer() const
     467             :       { return get_buf().buffer(); }
     468             : 
     469             :    //!Sets the underlying buffer to a new value. Resets
     470             :    //!stream position. Does not throw.
     471             :    void buffer(CharT *buf, std::size_t length)
     472             :       {  get_buf().buffer(buf, length);  }
     473             : };
     474             : 
     475             : //Some typedefs to simplify usage
     476             : typedef basic_bufferbuf<char>        bufferbuf;
     477             : typedef basic_bufferstream<char>     bufferstream;
     478             : typedef basic_ibufferstream<char>    ibufferstream;
     479             : typedef basic_obufferstream<char>    obufferstream;
     480             : 
     481             : typedef basic_bufferbuf<wchar_t>     wbufferbuf;
     482             : typedef basic_bufferstream<wchar_t>  wbufferstream;
     483             : typedef basic_ibufferstream<wchar_t> wibufferstream;
     484             : typedef basic_obufferstream<wchar_t> wobufferstream;
     485             : 
     486             : 
     487             : }} //namespace boost {  namespace interprocess {
     488             : 
     489             : #include <boost/interprocess/detail/config_end.hpp>
     490             : 
     491             : #endif /* BOOST_INTERPROCESS_BUFFERSTREAM_HPP */

Generated by: LCOV version 1.14