常常需要對(duì)緩沖區(qū)進(jìn)行操作,尤其在基于c/s的應(yīng)用中,需要將一些結(jié)構(gòu)或數(shù)據(jù)類型“填充”到緩沖區(qū)發(fā)給服務(wù)器(或客戶端),而另外一段則需要將緩沖區(qū)還原成結(jié)構(gòu)或其他數(shù)據(jù)類型,發(fā)現(xiàn)特別的不爽,所以寫(xiě)了這個(gè)iobuffer,他不同于stl的strstream或stringstream,我的這個(gè)iobuffer,不將其他數(shù)據(jù)類型轉(zhuǎn)換成字符串來(lái)進(jìn)行保存,這個(gè)iobuffer更像是一個(gè)buffer proxy,他自己不new出一個(gè)buffer,只是對(duì)已存在的buffer進(jìn)行操作,不管這個(gè)buffer是堆上的還是棧上的(注:這里實(shí)現(xiàn)了一個(gè)FixOutBuffer特殊點(diǎn),是自己帶一個(gè)固定大小的緩沖),對(duì)于小緩沖,用FixOutBuffer不錯(cuò),如obuffer256就相當(dāng)于定義了 char buffer[256];具體應(yīng)用大家可以看源代碼,代碼很短,容易明白。這里對(duì)字符串做個(gè)說(shuō)明:
當(dāng)進(jìn)行字符串導(dǎo)入時(shí):
obuffer << "some string"; // 實(shí)際是將該字符串拷貝到了緩沖區(qū)中
但當(dāng)對(duì)字符串導(dǎo)出時(shí):
const char* str;
ibuffer>>str; // 實(shí)際只是將緩沖區(qū)中該字符串的首地址賦值給str,這樣就不需要多一次沒(méi)有必要的字符串拷貝,用戶拿到str就可以直接用,緩沖區(qū)中為該字符串產(chǎn)生了'\0'結(jié)束標(biāo)志。
具體應(yīng)用可以參考代碼中包含的例子。

/**//**
Created 2007.6.7 by PeakGao
Email: peakgao163@163.com
*/

#ifndef __IOBUFFER_H__
#define __IOBUFFER_H__



/**//** 示例.
@code
struct SimpleStruct
{
Uint x,y;
};

void test()
{
SimpleStruct ss;
ss.x = 11111;
ss.y = 22222;
Uint8 v8 = 8;
Uint16 v16 = 16;
Uint32 v32 = 32;
Uint v = 123456789;
Float vf = 3.1415926f;
Double vd = 3.1415926535897932;
long vl = 0xffffffff;
unsigned long vul = 0xffffffff;
const char* name = "user name";
Uint8 mydata[12] = {0,1,2,3,4,5,6,7,8,9,10,11};

char data[256];
obuffer out(data, sizeof(data)); // 或者使用: FixOutBuffer<256> out;
out << ss << name << v8 << v16 << v32 << v << vf << vd << vl << vul; // 導(dǎo)入固定長(zhǎng)度類型的數(shù)據(jù)到緩沖區(qū)
out.push(mydata, sizeof(mydata)); // 導(dǎo)入一個(gè)數(shù)組(緩沖區(qū))到該緩沖區(qū)
if (!out)
{
Error("error\n");
}

ibuffer in(out.buffer(), out.size());
ss.x = ss.y = 0;
const char* nameptr = 0;
memset(mydata, 0, sizeof(mydata));
in >> ss >> nameptr >> v8 >> v16;
in.skip<Uint32>(); // 跳過(guò)一個(gè)Uint32,比如我們不需要這個(gè)參數(shù)
in >> v >> vf >> vd >> vl >> vul;
in.pop(mydata, sizeof(mydata));
if (!in)
{
Error("error");
}
}
@endcode
*/


/**//// 緩沖區(qū)基類
class basic_buffer


{
public:

enum bufstate
{ _good = 0x0, _eof = 0x1, _fail = 0x2, _bad = 0x4/**//*嚴(yán)重錯(cuò)誤*/};

protected:

void* _buf; /**//// 緩沖區(qū)首地址

size_t _bufSize; /**//// 緩沖區(qū)大小

size_t _pos; /**//// 當(dāng)前操作位置

bufstate _state; /**//// 緩沖區(qū)當(dāng)前操作的狀態(tài)

// 構(gòu)造(析構(gòu))
protected:

basic_buffer() : _buf(0), _bufSize(0), _pos(0), _state(_good)
{ }

public:
basic_buffer(void* buffer, size_t maxsize) : _buf(buffer), _bufSize(maxsize), _pos(0), _state(_good)

{
assert(buffer != 0 && maxsize > 0);
}


~basic_buffer()
{ }

// 狀態(tài)相關(guān)(用于檢測(cè)操作的結(jié)果)
public:
bool operator !() const

{
return (!good());
}

operator bool() const

{
return (good());
}

bufstate state() const

{
return _state;
}

void setstate(bufstate state_)

{
if (state_ != _good)
_state = (bufstate)((int)_state | (int)state_);
}

void setstate(int state_)

{
setstate((bufstate)state_);
}

bool good() const

{
return ((int)state() == (int)_good || (int)state() == (int)(_good | _eof));
}

bool eof() const

{
return ((int)state() & (int)_eof);
}

bool fail() const

{
return (((int)state() & ((int)_fail | (int)_bad)) != 0);
}

bool bad() const

{
return (((int)state() & (int)_bad) != 0);
}


// 屬性及操作
public:

/**//// 緩沖區(qū)清除操作
void clear()

{
memset(_buf, 0, _bufSize);
_pos = 0;
_state = _good;
}


/**//// 將當(dāng)前位置向后移動(dòng)指定的大小
void skipn(size_t bytes)

{
if (_pos + bytes <= _bufSize)

{
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else
setstate(basic_buffer::_eof|basic_buffer::_fail);
}


/**//// 獲取緩沖區(qū)地址
void* buffer() const

{
return _buf;
}


/**//// 獲取緩沖區(qū)當(dāng)前位置的地址
void* current() const

{
return (char*)_buf + _pos;
}


/**//// 獲取緩沖區(qū)數(shù)據(jù)操作的當(dāng)前位置偏移
size_t pos() const

{
return _pos;
}


/**//// 獲取緩沖區(qū)的容量(即緩沖區(qū)的大小)
size_t capacity() const

{
return _bufSize;
}
};





/**//// 輸出緩沖(指各種數(shù)據(jù)導(dǎo)入到緩沖區(qū)中)
class obuffer : public basic_buffer


{
// 構(gòu)造(析構(gòu))
protected:

obuffer() : basic_buffer()
{ }

public:

obuffer(void* buffer, size_t maxsize) : basic_buffer(buffer, maxsize)
{ }


~obuffer()
{ }


// 方法
public:

/**//// 獲取緩沖區(qū)中數(shù)據(jù)的實(shí)際占用尺寸
size_t size() const

{
return pos();
}


/**//// 向緩沖區(qū)寫(xiě)入各種具有固定長(zhǎng)度的數(shù)據(jù)類型,包括簡(jiǎn)單類型和復(fù)合類型(結(jié)構(gòu))
template <class T> obuffer& operator << (T value)

{
if (_pos + sizeof(T) <= _bufSize)

{
*(T*)((char*)_buf + _pos) = value;
_pos += sizeof(T);

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
}
return (*this);
}

//使用GCC編譯時(shí),該段代碼可能要移植到buffer.cpp文件中分離編譯
#ifdef _MSC_VER


/**//// 對(duì)常字符串的特化處理
template<> obuffer& operator << (const char* value)

{
return push((void*)value, strlen(value) + sizeof(char));
}

/**//// 對(duì)字符串的特化處理
template<> obuffer& operator << (char* value)

{
return push((void*)value, strlen(value) + sizeof(char));
}


/**//// 對(duì)常寬字符串的特化處理
template<> obuffer& operator << (const wchar_t* value)

{
return push((void*)value, (wcslen(value) + 1) * sizeof(wchar_t));
}


/**//// 對(duì)寬字符串的特化處理
template<> obuffer& operator << (wchar_t* value)

{
return push((void*)value, (wcslen(value) + 1) * sizeof(wchar_t));
}

#endif


/**//// 跳過(guò)某種數(shù)據(jù)類型(不進(jìn)行賦值,僅僅改變當(dāng)前位置)
template <class T> obuffer& skip()

{
if (_pos + sizeof(T) <= _bufSize)

{
_pos += sizeof(T);

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
}
return (*this);
}


/**//// 在當(dāng)前位置導(dǎo)入一段緩沖
obuffer& push(void* buffer, size_t bytes)

{
if (buffer == 0 || bytes == 0)

{
setstate(basic_buffer::_bad|basic_buffer::_fail);
return (*this);
}

if (_pos + bytes <= _bufSize)

{
memcpy((char*)_buf + _pos, buffer, bytes);
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
}
return (*this);
}
};



/**//// 固定大小的輸出緩沖
template <size_t _MaxBytes = 256>
class FixOutBuffer : public obuffer


{
protected:

enum
{_Buf_Size = _MaxBytes ? ((_MaxBytes + 7) & ~7) : 8}; // 8字節(jié)對(duì)齊
char _data[_Buf_Size];

public:
FixOutBuffer()

{
_buf = _data;
_bufSize = _Buf_Size;
_pos = 0;
_state = basic_buffer::_good;
}


~FixOutBuffer()
{ }
};





/**//// 輸入緩沖(指從緩沖區(qū)中導(dǎo)出各種數(shù)據(jù))
class ibuffer : public basic_buffer


{
// 構(gòu)造(析構(gòu))
protected:

ibuffer() : basic_buffer()
{ }

public:

ibuffer(void* buffer, size_t actualSize) : basic_buffer(buffer, actualSize)
{ }


~ibuffer()
{ }


// 方法
public:

/**//// 獲取緩沖區(qū)中數(shù)據(jù)的實(shí)際占用尺寸
size_t size() const

{
return _bufSize;
}


/**//// 從緩沖區(qū)導(dǎo)出各種具有固定長(zhǎng)度的數(shù)據(jù)類型,包括簡(jiǎn)單類型和復(fù)合類型(結(jié)構(gòu))
template <class T> ibuffer& operator >> (T& value)

{
if (_pos + sizeof(T) <= _bufSize)

{
value = *(T*)((char*)_buf + _pos);
_pos += sizeof(T);

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
}
return (*this);
}

//使用GCC編譯時(shí),該段代碼可能要移植到buffer.cpp文件中分離編譯
#ifdef _MSC_VER

/**//// 對(duì)常字符串的特化處理
template<> ibuffer& operator >> (const char*& value)

{
const char* str = (const char*)_buf + _pos;
while ((size_t)(str - (const char*)_buf) < _bufSize && *str++);
size_t bytes = (size_t)(str - (char*)_buf) - _pos;
if (bytes > 0 && _pos + bytes <= _bufSize)

{
if (*((char*)_buf + _pos + bytes - 1) != 0) // 不是0結(jié)尾的字符串

{
setstate(basic_buffer::_eof|basic_buffer::_bad);
return (*this);
}
value = (char*)_buf + _pos;
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
value = 0;
}

return (*this);
}


/**//// 對(duì)字符串的特化處理
template<> ibuffer& operator >> (char*& value)

{
const char* str = (const char*)_buf + _pos;
while ((size_t)(str - (const char*)_buf) < _bufSize && *str++);
size_t bytes = (size_t)(str - (char*)_buf) - _pos;
if (bytes > 0 && _pos + bytes <= _bufSize)

{
if (*((char*)_buf + _pos + bytes - 1) != 0) // 不是0結(jié)尾

{
setstate(basic_buffer::_eof|basic_buffer::_bad);
return (*this);
}
value = (char*)_buf + _pos;
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
value = 0;
}

return (*this);
}


/**//// 對(duì)常寬字符串的特化處理
template<> ibuffer& operator >> (const wchar_t*& value)

{
const wchar_t* str = (const wchar_t*)((Int8*)_buf + _pos);
while ((size_t)((Int8*)str - (Int8*)_buf) < _bufSize && *str++);
size_t bytes = (size_t)((Int8*)str - (Int8*)_buf) - _pos;
if (bytes > 0 && _pos + bytes <= _bufSize)

{
if (*(const wchar_t*)((Int8*)_buf + _pos + bytes - sizeof(wchar_t)) != 0) // 不是0結(jié)尾

{
setstate(basic_buffer::_eof|basic_buffer::_bad);
return (*this);
}
value = (const wchar_t*)((Int8*)_buf + _pos);
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
value = 0;
}

return (*this);
}


/**//// 對(duì)寬字符串的特化處理
template<> ibuffer& operator >> (wchar_t*& value)

{
const wchar_t* str = (const wchar_t*)((Int8*)_buf + _pos);
while ((size_t)((Int8*)str - (Int8*)_buf) < _bufSize && *str++);
size_t bytes = (size_t)((Int8*)str - (Int8*)_buf) - _pos;
if (bytes > 0 && _pos + bytes <= _bufSize)

{
if (*(const wchar_t*)((Int8*)_buf + _pos + bytes - sizeof(wchar_t)) != 0) // 不是0結(jié)尾

{
setstate(basic_buffer::_eof|basic_buffer::_bad);
return (*this);
}
value = (wchar_t*)((Int8*)_buf + _pos);
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
value = 0;
}

return (*this);
}
#endif


/**//// 跳過(guò)某種數(shù)據(jù)類型(不進(jìn)行賦值,僅僅改變當(dāng)前位置)
template <class T> ibuffer& skip()

{
if (_pos + sizeof(T) <= _bufSize)

{
_pos += sizeof(T);

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else
setstate(basic_buffer::_eof|basic_buffer::_fail);
return (*this);
}


/**//// 在當(dāng)前位置導(dǎo)出一段緩沖
ibuffer& pop(void* buffer, size_t bytes)

{
if (buffer == 0 || bytes == 0)

{
setstate(basic_buffer::_bad|basic_buffer::_fail);
return (*this);
}

if (_pos + bytes <= _bufSize)

{
memcpy(buffer, (char*)_buf + _pos, bytes);
_pos += bytes;

if (_pos == _bufSize)
setstate(basic_buffer::_eof);
}
else

{
setstate(basic_buffer::_eof|basic_buffer::_fail);
}
return (*this);
}
};


#ifndef FIXOUTBUFFER_TYPEDEF
# define FIXOUTBUFFER_TYPEDEF
typedef FixOutBuffer<32> obuffer32;
typedef FixOutBuffer<64> obuffer64;
typedef FixOutBuffer<256> obuffer256;
typedef FixOutBuffer<512> obuffer512;
typedef FixOutBuffer<1024> obuffer1024;
typedef FixOutBuffer<2048> obuffer2048;
typedef FixOutBuffer<4096> obuffer4096;
#endif



#endif // __BUFFER_H__
