注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

gmd20的个人空间

// 编程和生活

 
 
 

日志

 
 

stl库中string stringbuf iostream三者的关系和转换, asio 网络库中的streambuf流的使用  

2012-02-08 23:52:29|  分类: 程序设计 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

stl库中string stringbuf  iostream三者的关系和转换

=================================================

 

iostream(streambuf)  构造函数    关联stringbuf  streambuf

iostream.rdbuf()  <----> stringbuf   streambuf   更新关联的

 

stringbuf.str()  <---------> string  更新string内容

stringstream.rdbuf()    <------------------>  stringbuf 

stringstream.str()    <------------------> string

 

 

详细参考这个网站

http://www.cplusplus.com/reference/iostream/iostream/

 

 

iostream 和 asio的 streambuf

===========================

basic_streambuf:public  std::streambuf.

 

typedef basic_streambuf streambuf;

http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/streambuf.html

 

iostream.rdbuf (std::streambuf)    设置关联的streambuf

 

http://www.cplusplus.com/reference/iostream/streambuf/

streambuf::setg   Set input sequence pointers (protected member function)

void setg ( char* gbeg, char* gnext, char* gend );

setp Set output sequence pointers (protected member function)

void setp ( char* pbeg, char* pend );

 

 

 

 

/// Automatically resizable buffer class based on std::streambuf.

template <typename Allocator = std::allocator<char> >

class basic_streambuf

  : public std::streambuf,

    private noncopyable

 

 

template<

    typename AsyncReadStream,

    typename Allocator,

    typename ReadHandler>

void async_read(

    AsyncReadStream & s,

    basic_streambuf< Allocator > & b,

    ReadHandler handler);

 

template<

    typename AsyncWriteStream,

    typename Allocator,

    typename WriteHandler>

void async_write(

    AsyncWriteStream & s,

    basic_streambuf< Allocator > & b,

    WriteHandler handler);

 

 

---------------------------------------------------------

boost::asio 的有一个 basic_streambuf 是 继承 streambuf而来

http://www.boost.org/doc/libs/1_48_0/doc/html/boost_asio/reference/streambuf.html

 

看说明和下面两个文件的代码的实现。看看 asio是如何利用 streambuf的

http://www.boost.org/doc/libs/1_48_0/boost/asio/basic_streambuf.hpp

http://www.boost.org/doc/libs/1_48_0/boost/asio/impl/write.hpp

http://www.boost.org/doc/libs/1_48_0/boost/asio/impl/read.hpp

 

----------------------------------

http://www.boost.org/doc/libs/1_48_0/boost/asio/impl/read.hpp

 

 

template <typename SyncReadStream, typename Allocator,

    typename CompletionCondition>

std::size_t read(SyncReadStream& s,

    boost::asio::basic_streambuf<Allocator>& b,

    CompletionCondition completion_condition, boost::system::error_code& ec)

{

  ec = boost::system::error_code();

  std::size_t total_transferred = 0;

  std::size_t max_size = detail::adapt_completion_condition_result(

        completion_condition(ec, total_transferred));

  std::size_t bytes_available = read_size_helper(b, max_size);

  while (bytes_available > 0)

  {

    std::size_t bytes_transferred = s.read_some(b.prepare(bytes_available), ec);

    b.commit(bytes_transferred);  ///////////asio接受数据的时候如何设置 streambuf的

    total_transferred += bytes_transferred;

    max_size = detail::adapt_completion_condition_result(

          completion_condition(ec, total_transferred));

    bytes_available = read_size_helper(b, max_size);

  }

  return total_transferred;

}

 

template <typename SyncReadStream, typename Allocator>

inline std::size_t read(SyncReadStream& s,

    boost::asio::basic_streambuf<Allocator>& b,

    boost::system::error_code& ec)

{

  return read(s, b, transfer_all(), ec);

}

 -------------------------------

template <typename SyncWriteStream, typename Allocator,

    typename CompletionCondition>

std::size_t write(SyncWriteStream& s,

    boost::asio::basic_streambuf<Allocator>& b,

    CompletionCondition completion_condition, boost::system::error_code& ec)

{

  std::size_t bytes_transferred = write(s, b.data(), completion_condition, ec);

  b.consume(bytes_transferred);  ////asio发送时如何里哟娜 streambuf的

  return bytes_transferred;

}

 

template <typename SyncWriteStream, typename Allocator>

inline std::size_t write(SyncWriteStream& s,

    boost::asio::basic_streambuf<Allocator>& b,

    boost::system::error_code& ec)

{

  return write(s, b, transfer_all(), ec);

}


--------------------------------

 

  /// Get a list of buffers that represents the input sequence.

  /**

   * @returns An object of type @c const_buffers_type that satisfies

   * ConstBufferSequence requirements, representing all character arrays in the

   * input sequence.

   *

   * @note The returned object is invalidated by any @c basic_streambuf member

   * function that modifies the input sequence or output sequence.

   */

  const_buffers_type data() const

  {

    return boost::asio::buffer(boost::asio::const_buffer(gptr(),

          (pptr() - gptr()) * sizeof(char_type)));

  }

 

 

 

-------------------------------------

Examples

 

Writing directly from an streambuf to a socket:

 

boost::asio::streambuf b;

std::ostream os(&b);

os << "Hello, World!\n";

 

// try sending some data in input sequence

size_t n = sock.send(b.data());

 

b.consume(n); // sent data is removed from input sequence

Reading from a socket directly into a streambuf:

 

boost::asio::streambuf b;

 

// reserve 512 bytes in output sequence

boost::asio::streambuf::mutable_buffers_type bufs = b.prepare(512);

 

size_t n = sock.receive(bufs);

 

// received data is "committed" from output sequence to input sequence

b.commit(n);

 

std::istream is(&b);

std::string s;

is >> s;

-------------------------------------------

 

 

 

 

如果实现有一个streambuf 想填充这个streambuf然后发送出去的过程应是这样的

=========================================================================

 

 

1. 如果需要修改 流关联的 streambuf 

iostream.rdbuf (streambuf)    设置关联的streambuf

 

2. 把input 和output 流动当前指针移到文件的最开始

 

iostream.seekg   

streambuf.pubseekpos  pubseekoff 

  默认的实现streambuf是不支持seek的 全部返回错误了,stringbuf才支持seek,看来这个想法不行了  2月9好补充

3. 

iostream.write

 

4.  表明可读的长度

streambuf.commit(n)

 

5. 使用发送函数发送streambuf应该就可以了。

async_write    

 

 

 


class mystreambuf: public streambuf {
private:
    typedef streambuf  _Mysb;
   
public:
mystreambuf():streambuf(){}
//这个seekoff 是stringbuf的实现,用作asio的streambuf应该也是合适的
virtual pos_type __CLR_OR_THIS_CALL seekoff(off_type _Off,
ios_base::seekdir _Way,
ios_base::openmode _Which = ios_base::in | ios_base::out)
{ // change position by _Off, according to _Way, _Mode
         char * _Seekhigh = _Mysb::epptr(); //用输出的结尾做为seek的尽头?  

if (_Mysb::pptr() != 0 && _Seekhigh < _Mysb::pptr())
_Seekhigh = _Mysb::pptr(); // update high-water pointer

if (_Which & ios_base::in && _Mysb::gptr() != 0)
{ // position within read buffer
if (_Way == ios_base::end)
_Off += (off_type)(_Seekhigh - _Mysb::eback());
else if (_Way == ios_base::cur
&& (_Which & ios_base::out) == 0)
_Off += (off_type)(_Mysb::gptr() - _Mysb::eback());
else if (_Way != ios_base::beg)
_Off = _BADOFF;

if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
{ // change read position
_Mysb::gbump((int)(_Mysb::eback() - _Mysb::gptr() + _Off));
if (_Which & ios_base::out && _Mysb::pptr() != 0)
_Mysb::setp(_Mysb::pbase(), _Mysb::gptr(),
_Mysb::epptr()); // change write position to match
}
else
_Off = _BADOFF;
}
else if (_Which & ios_base::out && _Mysb::pptr() != 0)
{ // position within write buffer
if (_Way == ios_base::end)
_Off += (off_type)(_Seekhigh - _Mysb::eback());
else if (_Way == ios_base::cur)
_Off += (off_type)(_Mysb::pptr() - _Mysb::eback());
else if (_Way != ios_base::beg)
_Off = _BADOFF;

if (0 <= _Off && _Off <= _Seekhigh - _Mysb::eback())
_Mysb::pbump((int)(_Mysb::eback()
- _Mysb::pptr() + _Off)); // change write position
else
_Off = _BADOFF;
}
else
_Off = _BADOFF; // neither read nor write buffer selected, fail
return (pos_type(_Off));
}

};
  评论这张
 
阅读(1780)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017