Buf网络缓冲区
由于网络协议分包的需要,因此编写buf网络缓冲区,以便分包。
struct SBuf
{
char* _base=nullptr;
char* _b=nullptr;
char* _e=nullptr;
size_t _size=0;
SBuf(size_t size);
SBuf();
~SBuf();
char* data(){return _b;}
void append(char* b, int32_t l);
void consume(int32_t l);
void clear(){ _b = _e = _base; }
int32_t len(){return _e-_b;}
};
SBuf::SBuf(size_t size)
{
_size = size;
_b=_e=_base = new char[_size];
memset(_base,0,_size);
}
SBuf::SBuf()
{
_size = getpagesize()/2;
_b = _e = _base = new char[_size];
memset(_base, 0, _size);
}
SBuf::~SBuf(){
if (_base)(delete _base);
}
void SBuf::append(char* b, int32_t l)
{
//_e后面的空间可以容纳当前追加数据
if (_e + l < _base + _size){
memcpy(_e,b,l);
_e+=l;
}else if(_e-_b+l<=_size){ //当前空间可以容纳追加的数据
memcpy(_base,_b,_e-_b);
_e = _base+len();
_b=_base;
memcpy(_e,b,l);
_e+=l;
}else{//空间不足
char* newbuf = new char[(_size+l)*2];
memset(newbuf,0, l * 2);
_size = (_size + l) * 2;
int32_t len = _e - _b;
memcpy(newbuf, _b, len);
memcpy(newbuf + len, b, l);
delete _base;
_b=_base=newbuf;
_e = _b + len + l;
}
}
void SBuf::consume(int32_t l)
{
if (l >(_e-_b))
{
_b=_e=_base;
}else{
_b+=l;
}
}
测试用例
TEST(SBuf, append){
SBuf buf(512);
char b[5120] = {0};
buf.append(b,sizeof(b));
EXPECT_EQ(buf.len(),5120);
}
TEST(SBuf, append2){
SBuf buf(5);
char* b="123456";
buf.append(b, strlen(b)+1);
EXPECT_EQ(buf.len(), strlen(b) + 1);
EXPECT_STREQ(buf._b,b);
}
TEST(SBuf, consume){
SBuf buf(10);
char* b = "123456";
buf.append(b, strlen(b));
buf.consume(3);
string s;
s.append(buf.data(), buf.len());
EXPECT_EQ(buf.len(), strlen(b)-3);
EXPECT_STREQ(s.c_str(),"456");
buf.append(b, strlen(b));
s.clear();
s.append(buf.data(), buf.len());
printf("buf data %s\n", s.c_str());
buf.consume(8);
buf.append(b, strlen(b));
s.clear();
s.append(buf.data(), buf.len());
printf("buf data %s\n", s.c_str());
EXPECT_STREQ(buf.data(), "6123456");
}