前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缩略muduo库(7):Buffer 缓冲区

缩略muduo库(7):Buffer 缓冲区

作者头像
看、未来
发布2021-10-09 15:33:42
2870
发布2021-10-09 15:33:42
举报
代码语言:javascript
复制
#pragma once

/// A buffer class modeled after org.jboss.netty.buffer.ChannelBuffer
///
/// @code
/// +-------------------+------------------+------------------+
/// | prependable bytes |  readable bytes  |  writable bytes  |
/// |                   |     (CONTENT)    |                  |
/// +-------------------+------------------+------------------+
/// |                   |                  |                  |
/// 0      <=      readerIndex   <=   writerIndex    <=     size
/// @endcode


#include <vector>
#include <string>

class Buffer{
public:
    
    ~Buffer();

    static const size_t kCheapPrepend = 8;
    static const size_t kInittialSize = 8;

    explicit Buffer(size_t initialSzie = kInittialSize)
        :buffer_(kCheapPrepend = initialSzie),
        readerIndex_(kCheapPrepend),
        writerIndex_(kCheapPrepend),
    {
    }

    size_t readablebuffer() const{
        return writerIndex_ - readerIndex_;
    }

    size_t writeablebuffer() const{
        return buffer_.size() - readerIndex_;
    }

    size_t prependablebuffer() const {
        return readerIndex_;
    }

    const char* peek(){
        retrn begin() + readerIndex_;
    }

    //buffer类型转为string类型
    void retrieve(size_t len){
        if(len<readablebuffer()){
            readerIndex_ += len;
        }
        else{
            retrieve_all();
        }
    }

    void retrieve_all(){
        readerIndex_ = writerIndex_ = kCheapPrepend;
    }

    std::string retrieve_all_asString(){
        return  retrieve_asString(readableBytes()); //应用读取数据长度
    }

    std::string retrieve_asString(size_t len){
        std::string result(peek(),len); //读取出可读取数据
        retrieve(len);  //对缓冲区进行复位操作
        return result;
    }

    void ensurewriteablebytes(size_t len){
        if(writerIndex_ < len){
            makespace();
        }
    }

    void append(const char* data,size_t len){
        ensurewriteablebytes(len);
        std::copy(data,data+len,beginwrite());
        writeIndex_ += len;
    }

    char* beginwrite(){
        return begin() + writeIndex_;
    }

    ssize_t readFD(int fd,int* saveerrno);
    
private:
    char* begin(){
        
        return &*buffer_.begin();   //vector底层首元素地址
    }

    const char* begin()const{
        return &*buffer_.begin();
    }

    void makespace(){
        if(writeablebuffer() + prependablebuffer() < len + kCheapPrepend){
            buffer_.resize(writeIndex_ + len);
        }
        else{
            size_t readable = readableBytes();
            std::copy(begin()+readerIndex_,
                        begin()+writerIndex_,
                        begin()+kCheapPrepend);
            readerIndex_ = kCheapPrepend;
            writerIndex_ = readerIndex_ + readable;
        }
    }

    std::vector<char> buffer_;
    size_t readerIndex_;
    size_t writerIndex_;
};
代码语言:javascript
复制
#include "buffer.hpp"

#include <errno.h>
#include <sys/uio.h>

/*
    从fd上读取数据
    buffer有大小,但是流数据不知道大小
*/
ssize_t Buffer::readFD(int fd,int* saveerrno){
    char exreabuf[65536] = {0}; //栈上的空间

    struct iovec vec[2];
    const size_t writable = writableBytes();
    //  先往上面这个写
    vec[0].iov_base = begin()+writerIndex_;
    vec[0].iov_len = writable;
    
    //上面那个写完了再用这里的
    vec[1].iov_base = extrabuf;
    vec[1].iov_len = sizeof extrabuf;
 
    const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1;
    const ssize_t n = sockets::readv(fd, vec, iovcnt);
    
    if (n < 0){
        *savedErrno = errno;
    }
    else if (n <= writable){
        writerIndex_ += n;
    }
    else{
        writerIndex_ = buffer_.size();
        append(extrabuf, n - writable);
    }
  
    return n;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/09/06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档