buffer类的设计
来源:互联网 发布:人工智能就业 知乎 编辑:程序博客网 时间:2024/06/13 18:26
这个Buffer类被作为muduo的TcpConnection的buffer。
WSABUF和WSARecv 可以实现 iovec和readv一样的功能
#pragma once#include<vector>#include<string>#include<algorithm>#include<assert.h>class Buffer{public: static const size_t kPrependSize = 8; static const size_t kInitialSize = 1024;private: static const char CRLF[]; std::vector<char> buffer_; size_t readIndex_; size_t writeIndex_;public: Buffer(size_t initial_size = kInitialSize); ~Buffer(); void swap(Buffer & buf); size_t prependableBytes() const { return readIndex_; } size_t readableBytes() const { return writeIndex_ - readIndex_; } size_t writeableBytes() const { return buffer_.size() - writeIndex_; } const char* peek() const { return begin() + readIndex_; } char* beginWrite() { return begin() + writeIndex_; } const char* beginWrite()const { return begin() + writeIndex_; } //write void ensureWriteable(size_t len) { if (writeableBytes() < len) { makeSpace(len); } assert(writeableBytes() > len); } void hasWritten(size_t len) { writeIndex_ += len; } void append(const std::string& str) { append(str.c_str(), str.size()); } void append(const char* data, size_t len)// this function is internal impl { ensureWriteable(len); std::copy(data, data + len, beginWrite()); hasWritten(len); } void append(const void* data, size_t len) { append(static_cast<const char*>(data), len); } void prepend(const void* data, size_t len) { assert(len < prependableBytes()); readIndex_ -= len; const char* d = static_cast<const char*>(data); std::copy(d, d + len, begin() + readIndex_); } //read void retrieve(size_t len)// this function is internal impl { assert(len <= readableBytes()); if (len < readableBytes()) readIndex_ += len; else retrieveAll(); } void retrieveUntil(const char* end) { size_t len = end - peek(); retrieve(len); } void retrieveAll() { readIndex_ = kPrependSize; writeIndex_ = kPrependSize; } std::string retrieveAllAsString() { printf("retrieveAllAsString() of Buffer size=%d\n", readableBytes()); return retrieveAsString(readableBytes()); } std::string retrieveAsString(size_t len) { assert(len <= readableBytes()); std::string ret(peek(), len); printf("retrieveAllAsString string=%s\n", ret.c_str()); retrieve(len); return ret; } //find const char* findCRLF() const { const char *ret = std::search(peek(), beginWrite(), CRLF, CRLF + 2); return ret == beginWrite() ? NULL : ret; } const char* findCRLF(const char* start) const { assert(peek() < start); assert(start < beginWrite()); const char *ret = std::search(start, beginWrite(), CRLF, CRLF + 2); return ret == beginWrite() ? NULL : ret; } const char* findEOL() const { const void *ret = memchr(peek(), '\n', readableBytes()); return static_cast<const char*>(ret); } const char* findEOL(const char* start) const { assert(peek() < start); assert(start < beginWrite()); const void *ret = memchr(peek(), '\n', beginWrite() - start); return static_cast<const char*>(ret); } //other void shrink() { buffer_.shrink_to_fit(); } intptr_t readFd(int fd, int* savedErrno);private: char* begin() { return &*buffer_.begin(); } const char* begin() const { return &*buffer_.begin(); } void makeSpace(size_t len) { if (len + kPrependSize > writeableBytes() + prependableBytes())//确实需要扩充 { buffer_.resize(len + kPrependSize); } else//prepend有足够空间 { assert(readIndex_ > kPrependSize); size_t read_able = readableBytes(); std::copy(begin() + readIndex_, begin() + writeIndex_, begin() + kPrependSize); readIndex_ = kPrependSize; writeIndex_ = readIndex_ + read_able; assert(read_able == readableBytes()); } }};
#include<WinSock2.h>#include <muduo_five\net\Buffer.h>#include<iostream>using std::cout; using std::cin; using std::endl;const char Buffer::CRLF[] = "\r\n";Buffer::Buffer(size_t initial_size) : buffer_(kPrependSize + initial_size), readIndex_(kPrependSize), writeIndex_(kPrependSize){ assert(prependableBytes() == kPrependSize); assert(readableBytes() == 0); assert(writeableBytes() == kInitialSize);}Buffer::~Buffer(){}void Buffer::swap(Buffer & buf){ buffer_.swap(buf.buffer_); std::swap(readIndex_, buf.readIndex_); std::swap(writeIndex_, buf.writeIndex_);}//WSABUF like linux iovec, WSARecv like readv.intptr_t Buffer::readFd(int fd, int* savedErrno){ cout << "readFd() of Buffer " << endl; char extrabuf[65536]; WSABUF vec[2]; const size_t writable = writeableBytes(); vec[0].buf = begin() + writeIndex_; vec[0].len = writable; vec[1].buf = extrabuf; vec[1].len = sizeof extrabuf; // when there is enough space in this buffer, don't read into extrabuf. // when extrabuf is used, we read 128k-1 bytes at most. const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1; DWORD n = 0;//count of received DWORD flag = 0; WSARecv(fd, vec, iovcnt, &n, &flag, NULL, NULL); if (n < 0) { *savedErrno = errno; } else if (n <= DWORD(writable)) { writeIndex_ += n; } else { writeIndex_ = buffer_.size(); append(extrabuf, n - writable); } return n;}
阅读全文
0 0
- buffer类的设计
- Muduo 设计与实现之一:Buffer 类的设计
- Muduo 设计与实现之一:Buffer 类的设计
- Muduo 设计与实现之一:Buffer 类的设计
- muduo中buffer的设计
- buffer设计
- Buffer类的详解
- Buffer类的详解
- Buffer类的详解
- nodeJs的buffer类
- Buffer类的详解
- Buffer类的详解
- Buffer类的详解
- 环形buffer的两种设计方式
- zfs的双buffer设计问题
- 一个特殊需求的环形Buffer设计
- muduo网络库中buffer的设计
- muduo网络库中buffer的设计
- hdu-6156 CaoHaha's staff
- Hive的行级acid事务处理
- poj 1860
- seekbar设置thumb后在真机出现黑边(不透明区域)
- How to run thing locally
- buffer类的设计
- odoo开发所遇到问题集合
- MySQL大表优化方案
- 用aardio给python写个图形界面
- Java:集合框架(四)Map详解及代码示例
- js中cookie的用法
- iOS_Runtime2_方法交换
- 介绍几种java中网络通信的方式
- 集合的几种遍历方式