bufferstream.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 445 行 · 第 1/2 页

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

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?