#ifndef USER2_BYTEBUFFER_H_
#define USER2_BYTEBUFFER_H_
#include <string>
#include <vector>
#include <assert.h>
#include <string.h>
typedef signed char int8;
typedef unsigned char uint8;
typedef signed short int16;
typedef unsigned short uint16;
typedef signed int int32;
typedef unsigned int uint32;
typedef signed long long int64;
typedef unsigned long long uint64;
class Message;
typedef std::tr1::shared_ptr<Message> MessagePtr;
class Message
{
public:
const static size_t DEFAULT_SIZE = 0x10000;
Message() : readPos_(0) , writePos_(0)
{
buffer_.reserve(DEFAULT_SIZE);
}
Message(size_t size) : readPos_(0), writePos_(0)
{
buffer_.reserve(size);
}
Message(const unsigned char* p, size_t len) : readPos_(0) , writePos_(0)
{
buffer_.reserve(DEFAULT_SIZE);
append(p, len);
}
static MessagePtr New()
{
MessagePtr msgPtr(new Message());
return msgPtr;
}
static MessagePtr New(size_t size)
{
MessagePtr msgPtr(new Message(size));
return msgPtr;
}
static MessagePtr New(const unsigned char* p, size_t len)
{
MessagePtr msgPtr(new Message(p, len)); return msgPtr;
}
void writeBuffer(const unsigned char* p, size_t len) { append(p, len); }
unsigned char* get() { return (unsigned char*)(&buffer_[0]); }
unsigned int count() { return buffer_.size(); }
void clear() { buffer_.clear(); readPos_ = writePos_ = 0; }
Message& operator<< (bool value) { append<char>((char)value); return *this; }
Message& operator<< (char value) { append<char>((char)value); return *this; }
Message& operator<< (uint8 value) { append<uint8>(value); return *this; }
Message& operator<< (uint16 value) { append<uint16>(value); return *this; }
Message& operator<< (uint32 value) { append<uint32>(value); return *this; }
Message& operator<< (uint64 value) { append<uint64>(value); return *this; }
Message& operator<< (int8 value) { append<int8>(value); return *this; }
Message& operator<< (int16 value) { append<int16>(value); return *this; }
Message& operator<< (int32 value) { append<int32>(value); return *this; }
Message& operator<< (int64 value) { append<int64>(value); return *this; }
Message& operator<< (float value) { append<float>(value); return *this; }
Message& operator<< (double value) { append<double>(value); return *this;}
Message& operator<< (const std::string& value)
{
uint32 count = value.size();
append((const uint8*)(&count), sizeof(uint32));
append((const uint8*)value.c_str(), value.length());
return *this;
}
Message& operator<< (const std::wstring& value)
{
uint32 count = value.size()*2;
append((const uint8*)(&count), sizeof(uint32));
append((const uint8*)value.c_str(), count);
return *this;
}
template<typename T>
Message& operator<< (const std::vector<T>& vt)
{
uint32 count = vt.size();
append((const uint8*)(&count), sizeof(uint32));
for (uint32 i=0; i<count; i++) { *this << vt[i]; }
return *this;
}
Message& operator>> (bool& value) { value = read<char>() > 0 ? true : false; return *this; }
Message& operator>> (char& value) { value = read<char>(); return *this; }
Message& operator>> (uint8& value) { value = read<uint8>(); return *this; }
Message& operator>> (uint16& value) { value = read<uint16>(); return *this; }
Message& operator>> (uint32& value) { value = read<uint32>(); return *this; }
Message& operator>> (uint64& value) { value = read<uint64>(); return *this; }
Message& operator>> (int8& value) { value = read<int8>(); return *this; }
Message& operator>> (int16& value) { value = read<int16>(); return *this; }
Message& operator>> (int32& value) { value = read<int32>(); return *this; }
Message& operator>> (int64& value) { value = read<int64>(); return *this; }
Message& operator>> (float& value) { value = read<float>(); return *this; }
Message& operator>> (double& value) { value = read<double>(); return *this; }
Message& operator>> (std::string& value)
{
value.clear();
uint32 count = read<uint32>();
if (count > 0)
{
uint8 *p = NULL;
read(&p, count);
value.assign((char*)p, count);
}
return *this;
}
Message& operator>> (std::wstring& value)
{
value.clear();
uint32 count = read<uint32>();
if (count > 0)
{
uint8 *p = NULL;
read(&p, count);
value.assign((wchar_t*)p, count/2);
}
return *this;
}
template<typename T>
Message& operator>> (std::vector<T>& vt)
{
uint32 count = read<uint32>();
while (count--)
{
T t;
*this >> t;
vt.push_back(t);
}
return *this;
}
private:
template<typename T>
void append(T value) { append((uint8*)&value, sizeof(value)); }
template<typename T>
void put(size_t pos, T value) { put(pos, (uint8*)&value, sizeof(value)); }
uint8 operator[] (size_t pos) { return read<uint8>(pos); }
size_t rpos() const { return readPos_; }
size_t rpos(size_t pos) { readPos_ = pos; return readPos_; }
size_t wpos() const { return writePos_; }
size_t wpos(size_t pos) { writePos_ = pos; return writePos_; }
template<typename T>
T read()
{
T t = read<T>(readPos_);
readPos_ += sizeof(T);
return t;
}
template<typename T>
T read(size_t pos) const
{
assert(pos + sizeof(T) <= size());
return *((const T*)&buffer_[pos]);
}
void read(uint8** dst, size_t len)
{
assert(readPos_ + len <= size());
*dst = &buffer_[readPos_];
readPos_ += len;
}
void append(const std::string& str) { append((const uint8*)str.c_str(), str.size() + 1); }
void append(const char* str, size_t len) { append((const uint8*)str, len); }
void append(const uint8* src, size_t count)
{
if (buffer_.size() < writePos_ + count)
{
buffer_.resize(writePos_ + count);
}
memcpy(&buffer_[writePos_], src, count);
writePos_ += count;
}
void put(size_t pos, const uint8* src, size_t count)
{
assert(pos + count <= size());
memcpy(&buffer_[pos], src, count);
}
size_t size() const { return buffer_.size(); }
private:
size_t readPos_;
size_t writePos_;
std::vector<uint8> buffer_;
};
template<typename T>
Message& operator<<(MessagePtr msg, T &t) { return (*msg.get()) << t; }
template<typename T>
Message& operator>>(MessagePtr msg, T &t) { return (*msg.get()) >> t; }
#endif // USER2_BYTEBUFFER_H_