void Buffer::ensureWritableBytes(size_t len) { if (writableBytes() < len) { makeSpace(len); } assert(writableBytes() >= len); }
ssize_t Buffer::readFd(int fd, int* savedErrno) { // saved an ioctl()/FIONREAD call to tell how much to read char extrabuf[65536]; 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; // 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; const ssize_t n = sockets::readv(fd, vec, iovcnt); if (n < 0) { *savedErrno = errno; } else if (implicit_cast<size_t>(n) <= writable) { writerIndex_ += n; } else { writerIndex_ = buffer_.size(); append(extrabuf, n - writable); } // if (n == writable + sizeof extrabuf) // { // goto line_30; // } return n; }
Buffer::Buffer() : readerIndex_(kCheapPrepend), writerIndex_(kCheapPrepend) { buffer_.assign(kInitialSize+kCheapPrepend,0); assert(readableBytes() == 0); assert(writableBytes() == kInitialSize); assert(prependableBytes() == kCheapPrepend); }
void Buffer::makeSpace(size_t len) { if (writableBytes() + prependableBytes() < len + kCheapPrepend) { // FIXME: move readable data buffer_.resize(writerIndex_+len+kCheapPrepend,0); } else { // move readable data to the front, make space inside buffer assert(kCheapPrepend < readerIndex_); size_t readable = readableBytes(); std::copy(begin()+readerIndex_, begin()+writerIndex_, begin()+kCheapPrepend); readerIndex_ = kCheapPrepend; writerIndex_ = readerIndex_ + readable; assert(readable == readableBytes()); } }