基于socket的通信必然会操作字节流,一直用netty(mina)的buf,挺方便的,前段时间写cocos2dx,就自己封装了一个c++版本 :
#ifndef __CCNET_BYTEBUF_H__ #define __CCNET_BYTEBUF_H__ #include <stdlib.h> #include <vector> 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<char> cache_data; ///待释放的字符串 vector<char*> 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] << 8) & 0xff00); addr |= ((cache_data[_readIndex + 1] << 16) & 0xff0000); addr |= ((cache_data[_readIndex] << 24) & 0xff000000); _readIndex += 4; return addr; return 0; } short ByteBuf::readShort() { checkRead(2); short addr = cache_data[_readIndex + 1] & 0xff; addr |= ((cache_data[_readIndex] << 8) & 0xff00); _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 < 0 ? 0 : _size; } void ByteBuf::checkRead(int length) { if (_writeIndex<length) { throw std::exception("_writeIndex less can read length!"); } }