基于socket的通信必然会操作字节流,一直用netty(mina)的buf,挺方便的,前段时间写cocos2dx,就自己封装了一个c++版本 :
#ifndef __CCNET_BYTEBUF_H__
#define __CCNET_BYTEBUF_H__
#include
#include
using namespace std;
/************************************************************************/
/* 构建发送数据buffer,封装读/写 */
/************************************************************************/
class ByteBuf
{
public:
ByteBuf();
ByteBuf(int capacity);
~ByteBuf(void);
public:
void writeShort(short value);
void writeInt(int value);
void writeByte(char ch);
void wirteBytes(char *str);
void wirteBytes(char*str, int srcIndex, int length);
void wirteBytes(ByteBuf *buffer);
void wirteBytes(ByteBuf *buffer, int length);
void wirteBytes(ByteBuf *buffer, int srcIndex, int length);
///写入一个字符串,先写4字节长度,再写字符串
void writeString(const char* str);
//写入一个字符串
void writeString(const char*str,int length);
//
int writeIndex();
//返回写入的数据
char* flush();
//释放buffer
void release();
public:
///read a int 4
int readInt();
///read a short 2
short readShort();
///read a char 1
char readByte();
//don't deleted this point ,only last call release methed
char* readString();
//don't deleted this point ,only last call release methed
char* readString(int length);
char* readString(int srcIndex,int length);
//return writeindex-readindex
int readableBytes();
//
int readIndex();
private:
void checkRead(int length);
private:
///will be handed data
char* data;
//readIndex
int _readIndex;
// writeIndex
int _writeIndex;
///缓冲的待处理字节数
vector cache_data;
///待释放的字符串
vector release_and_delete;
};
#endif
#include "stdafx.h"
#include "ByteBuf.h"
//stream动态缓冲区的初始化大小
#define BYTE_BUFFER_SIZE 512
ByteBuf::~ByteBuf(){}
ByteBuf::ByteBuf(){
this->data = NULL;
this->_readIndex = 0;
this->_writeIndex = 0;
this->cache_data.reserve(BYTE_BUFFER_SIZE); // 预分配空间
}
ByteBuf::ByteBuf(int capacity)
{
this->data = NULL;
this->_readIndex = 0;
this->_writeIndex = 0;
this->cache_data.reserve(BYTE_BUFFER_SIZE);
}
char*ByteBuf::flush(){
int _size = this->readableBytes();
if (_size != 0)
{
int nIdx = 0;
this->data = new char[_size];
for(auto iter = cache_data.begin(); iter != cache_data.end(); iter++, nIdx++)
{
this->data[nIdx] = *iter;
}
return this->data; //this data will be dispatcher by logic, be careful at last you must be call release
}
return NULL;
}
void ByteBuf::release(){
if (data != NULL)
{
delete data;
}
data = nullptr;
this->_readIndex = 0;
this->_writeIndex = 0;
cache_data.clear();
if (!release_and_delete.empty())
{
for (auto iter = begin(release_and_delete); iter != end(release_and_delete); ++iter)
{
delete *iter;
*iter = nullptr;
}
}
release_and_delete.clear();
}
void ByteBuf::writeShort(short num)
{
this->cache_data.push_back( ((0xff00 & num) >> 8) );
this->cache_data.push_back( (0xff & num) );
_writeIndex += 0x2;
}
void ByteBuf::writeInt(int num)
{
this->cache_data.push_back( ((0xff000000 & num) >> 24) );
this->cache_data.push_back( ((0xff0000 & num) >> 16) );
this->cache_data.push_back( ((0xff00 & num) >> 8) );
this->cache_data.push_back( (0xff & num) );
_writeIndex += 0x4;
}
void ByteBuf::writeByte(char ch)
{
this->cache_data.push_back(ch);
_writeIndex += 0x1;
}
void ByteBuf::wirteBytes(char *str)
{
wirteBytes(str, 0, strlen(str));
}
void ByteBuf::wirteBytes(char*str, int srcIndex, int length)
{
for (int index = srcIndex; index != length;++index)
{
this->cache_data.push_back(str[index]);
}
_writeIndex += length;
}
void ByteBuf::wirteBytes(ByteBuf *buffer)
{
wirteBytes(buffer, buffer->_writeIndex);
buffer->release();
}
void ByteBuf::wirteBytes(ByteBuf *buffer, int length)
{
wirteBytes(buffer,0,buffer->_writeIndex);
buffer->release();
}
void ByteBuf::wirteBytes(ByteBuf *buffer, int srcIndex, int length)
{
for (int index = srcIndex; index != length;++index)
{
this->cache_data.push_back(buffer->cache_data[index]);
}
_writeIndex += length;
buffer->release();
}
void ByteBuf::writeString(const char* str)
{
auto _size = strlen(str);
for (int index = 0; index != _size; ++index){
this->cache_data.push_back(str[index]);
}
_writeIndex += _size;
}
void ByteBuf::writeString(const char*str, int length)
{
for (int index = 0; index != length; ++index){
this->cache_data.push_back(str[index]);
}
_writeIndex += length;
}
int ByteBuf::writeIndex(){
return this->_writeIndex;
}
int ByteBuf::readIndex()
{
return _readIndex;
}
int ByteBuf::readInt()
{
checkRead(4);
int addr = cache_data[_readIndex + 3] & 0xff;
addr |= ((cache_data[_readIndex + 2] <
addr |= ((cache_data[_readIndex + 1] <
addr |= ((cache_data[_readIndex] <
_readIndex += 4;
return addr;
return 0;
}
short ByteBuf::readShort()
{
checkRead(2);
short addr = cache_data[_readIndex + 1] & 0xff;
addr |= ((cache_data[_readIndex] <
_readIndex += 2;
return addr;
}
char ByteBuf::readByte()
{
checkRead(1);
char addr = cache_data[_readIndex];
_readIndex += 1;
return addr;
return 0;
}
char* ByteBuf::readString()
{
return readString(_writeIndex);
}
char* ByteBuf::readString(int length)
{
if (length <= 0)return nullptr;
char * temp = new char[length];
for (int index = 0; index != length; ++index)
{
temp[index] = this->cache_data[_readIndex];
++_readIndex;
}
release_and_delete.push_back(temp);
return temp;
}
char* ByteBuf::readString(int srcIndex, int length)
{
if (length <= 0)return nullptr;
char * temp = new char[length];
for (int index = 0; index != length ; ++index)
{
temp[index] = this->cache_data[srcIndex]; //指定位置开始读取数据
++srcIndex;
}
_readIndex += length;
release_and_delete.push_back(temp);
return temp;
}
int ByteBuf::readableBytes()
{
auto _size = _writeIndex - _readIndex;
return _size
}
void ByteBuf::checkRead(int length)
{
if (_writeIndex
{
throw std::exception("_writeIndex less can read length!");
}
}