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

/**//**
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; // 導入固定長度類型的數據到緩沖區
out.push(mydata, sizeof(mydata)); // 導入一個數組(緩沖區)到該緩沖區
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>(); // 跳過一個Uint32,比如我們不需要這個參數
in >> v >> vf >> vd >> vl >> vul;
in.pop(mydata, sizeof(mydata));
if (!in)
{
Error("error");
}
}
@endcode
*/


/**//// 緩沖區基類
class basic_buffer


{
public:

enum bufstate
{ _good = 0x0, _eof = 0x1, _fail = 0x2, _bad = 0x4/**//*嚴重錯誤*/};

protected:

void* _buf; /**//// 緩沖區首地址

size_t _bufSize; /**//// 緩沖區大小

size_t _pos; /**//// 當前操作位置

bufstate _state; /**//// 緩沖區當前操作的狀態

// 構造(析構)
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()
{ }

// 狀態相關(用于檢測操作的結果)
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:

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

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


/**//// 將當前位置向后移動指定的大小
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);
}


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

{
return _buf;
}


/**//// 獲取緩沖區當前位置的地址
void* current() const

{
return (char*)_buf + _pos;
}


/**//// 獲取緩沖區數據操作的當前位置偏移
size_t pos() const

{
return _pos;
}


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

{
return _bufSize;
}
};





/**//// 輸出緩沖(指各種數據導入到緩沖區中)
class obuffer : public basic_buffer


{
// 構造(析構)
protected:

obuffer() : basic_buffer()
{ }

public:

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


~obuffer()
{ }


// 方法
public:

/**//// 獲取緩沖區中數據的實際占用尺寸
size_t size() const

{
return pos();
}


/**//// 向緩沖區寫入各種具有固定長度的數據類型,包括簡單類型和復合類型(結構)
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編譯時,該段代碼可能要移植到buffer.cpp文件中分離編譯
#ifdef _MSC_VER


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

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

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

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


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

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


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

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

#endif


/**//// 跳過某種數據類型(不進行賦值,僅僅改變當前位置)
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);
}


/**//// 在當前位置導入一段緩沖
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字節對齊
char _data[_Buf_Size];

public:
FixOutBuffer()

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


~FixOutBuffer()
{ }
};





/**//// 輸入緩沖(指從緩沖區中導出各種數據)
class ibuffer : public basic_buffer


{
// 構造(析構)
protected:

ibuffer() : basic_buffer()
{ }

public:

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


~ibuffer()
{ }


// 方法
public:

/**//// 獲取緩沖區中數據的實際占用尺寸
size_t size() const

{
return _bufSize;
}


/**//// 從緩沖區導出各種具有固定長度的數據類型,包括簡單類型和復合類型(結構)
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編譯時,該段代碼可能要移植到buffer.cpp文件中分離編譯
#ifdef _MSC_VER

/**//// 對常字符串的特化處理
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結尾的字符串

{
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);
}


/**//// 對字符串的特化處理
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結尾

{
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);
}


/**//// 對常寬字符串的特化處理
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結尾

{
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);
}


/**//// 對寬字符串的特化處理
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結尾

{
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


/**//// 跳過某種數據類型(不進行賦值,僅僅改變當前位置)
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);
}


/**//// 在當前位置導出一段緩沖
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__
