forked from gaojingcome/WebServer
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f578366
commit e1bd71d
Showing
2 changed files
with
201 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/* | ||
* @Author : mark | ||
* @Date : 2020-06-26 | ||
* @copyleft GPL 2.0 | ||
*/ | ||
#include "buffer.h" | ||
|
||
Buffer::Buffer() : buffer_(INIT_BUFF_SIZE), readPos_(0), writePos_(0) {} | ||
|
||
size_t Buffer::ReadableBytes() const { | ||
return writePos_ - readPos_; | ||
} | ||
size_t Buffer::WritableBytes() const { | ||
return buffer_.size() - writePos_; | ||
} | ||
|
||
size_t Buffer::prependableBytes() const { | ||
return readPos_; | ||
} | ||
|
||
const char* Buffer::Peek() const { | ||
return BeginPtr_() + readPos_; | ||
} | ||
|
||
char* Buffer::Peek(){ | ||
return BeginPtr_() + readPos_; | ||
} | ||
|
||
void Buffer::Retrieve(size_t len) { | ||
assert(len <= ReadableBytes()); | ||
readPos_ += len; | ||
} | ||
|
||
void Buffer::RetrieveUntil(const char* end) { | ||
assert(Peek() <= end ); | ||
Retrieve(end - Peek()); | ||
} | ||
|
||
void Buffer::RetrieveAll() { | ||
readPos_ = 0; | ||
writePos_ = 0; | ||
} | ||
|
||
std::string Buffer::RetrieveAllToStr() { | ||
std::string str(Peek(), ReadableBytes()); | ||
RetrieveAll(); | ||
return str; | ||
} | ||
|
||
const char* Buffer::BeginWriteConst() const { | ||
return BeginPtr_() + writePos_; | ||
} | ||
|
||
char* Buffer::BeginWrite() { | ||
return BeginPtr_() + writePos_; | ||
} | ||
|
||
void Buffer::HasWritten(size_t len) { | ||
writePos_ += len; | ||
} | ||
|
||
void Buffer::Append(const std::string& str) { | ||
Append(str.data(), str.length()); | ||
} | ||
void Buffer::Append(const char* data, size_t len) { | ||
EnsureWriteable(len); | ||
std::copy(data, data + len, BeginWrite()); | ||
HasWritten(len); | ||
} | ||
|
||
void Buffer::Append(const void* data, size_t len) { | ||
Append(static_cast<const char*>(data), len); | ||
} | ||
|
||
void Buffer::Append(const Buffer& buff) { | ||
Append(buff.Peek(), buff.ReadableBytes()); | ||
} | ||
|
||
void Buffer::EnsureWriteable(size_t len) { | ||
if(WritableBytes() < len) { | ||
MakeSpace_(len); | ||
} | ||
assert(WritableBytes() >= len); | ||
} | ||
|
||
ssize_t Buffer::ReadFd(int fd, int* saveErrno) { | ||
char buff[MAX_BUFF_SIZE]; | ||
struct iovec iov[2]; | ||
const size_t writable = WritableBytes(); | ||
/* 分散读, 保证数据全部读完 */ | ||
iov[0].iov_base = BeginPtr_() + writePos_; | ||
iov[0].iov_len = writable; | ||
iov[1].iov_base = buff; | ||
iov[1].iov_len = sizeof(buff); | ||
|
||
const ssize_t len = readv(fd, iov, 2); | ||
if(len < 0) { | ||
*saveErrno = errno; | ||
} | ||
else if(static_cast<size_t>(len) <= writable) { | ||
writePos_ += len; | ||
} | ||
else { | ||
writePos_ = buffer_.size(); | ||
Append(buff, len - writePos_); | ||
} | ||
return len; | ||
} | ||
|
||
ssize_t Buffer::WriteFd(int fd, int* saveErrno) { | ||
size_t readSize = ReadableBytes(); | ||
ssize_t len = write(fd, Peek(), readSize); | ||
if(len < 0) { | ||
*saveErrno = errno; | ||
} | ||
readPos_ += len; | ||
return len; | ||
} | ||
|
||
char* Buffer::BeginPtr_() { | ||
return &*buffer_.begin(); | ||
} | ||
|
||
const char* Buffer::BeginPtr_() const { | ||
return &*buffer_.begin(); | ||
} | ||
|
||
void Buffer::MakeSpace_(size_t len) { | ||
if(WritableBytes() + prependableBytes() < len) { | ||
buffer_.resize(writePos_ + len); | ||
} | ||
else { | ||
size_t readable = ReadableBytes(); | ||
std::copy(BeginPtr_() + readPos_, BeginPtr_() + writePos_, BeginPtr_()); | ||
readPos_ = 0; | ||
writePos_ = readPos_ + readable; | ||
assert(readable == ReadableBytes()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
/* | ||
* @Author : mark | ||
* @Date : 2020-06-26 | ||
* @copyleft GPL 2.0 | ||
*/ | ||
|
||
#ifndef BUFFER_H | ||
#define BUFFER_H | ||
#include <cstring> //perror | ||
#include <iostream> | ||
#include <unistd.h> // write | ||
#include <sys/uio.h> //readv | ||
#include <vector> //readv | ||
#include <atomic> | ||
#include <assert.h> | ||
|
||
|
||
class Buffer { | ||
public: | ||
Buffer(); | ||
~Buffer() = default; | ||
|
||
size_t WritableBytes() const; | ||
size_t ReadableBytes() const ; | ||
size_t prependableBytes() const; | ||
|
||
const char* Peek() const; | ||
char* Peek(); | ||
void EnsureWriteable(size_t len); | ||
void HasWritten(size_t len); | ||
|
||
void Retrieve(size_t len); | ||
void RetrieveUntil(const char* end); | ||
|
||
void RetrieveAll() ; | ||
std::string RetrieveAllToStr(); | ||
|
||
const char* BeginWriteConst() const; | ||
char* BeginWrite(); | ||
|
||
void Append(const std::string& str); | ||
void Append(const char* data, size_t len); | ||
void Append(const void* data, size_t len); | ||
void Append(const Buffer& buff); | ||
|
||
ssize_t ReadFd(int fd, int* Errno); | ||
ssize_t WriteFd(int fd, int* Errno); | ||
|
||
private: | ||
const size_t MAX_BUFF_SIZE = 65536; | ||
const size_t INIT_BUFF_SIZE = 1024; | ||
|
||
char* BeginPtr_(); | ||
const char* BeginPtr_() const; | ||
void MakeSpace_(size_t len); | ||
|
||
std::vector<char> buffer_; | ||
std::atomic<std::size_t> readPos_; | ||
std::atomic<std::size_t> writePos_; | ||
}; | ||
|
||
#endif //BUFFER_H |