#ifndef _BYTEBUFFER_H #define _BYTEBUFFER_H #include <msgpack.hpp> typedef unsigned char uint8; /* Unsigned 8 bit quantity */ typedef signed char int8; /* Signed 8 bit quantity */ typedef unsigned short uint16; /* Unsigned 16 bit quantity */ typedef signed short int16; /* Signed 16 bit quantity */ typedef unsigned int uint32; /* Unsigned 32 bit quantity */ typedef signed int int32; /* Signed 32 bit quantity */ typedef signed long int64; typedef unsigned long uint64; class ByteBuffer { public: const static size_t DEFAULT_SIZE = 0x1000; ByteBuffer(): _rpos(0), _wpos(0) { _storage.reserve(DEFAULT_SIZE); } ByteBuffer(size_t res): _rpos(0), _wpos(0) { _storage.reserve(res); } ByteBuffer(const ByteBuffer &buf): _rpos(buf._rpos), _wpos(buf._wpos), _storage(buf._storage) { } virtual ~ByteBuffer() {} void clear() { _storage.clear(); _rpos = _wpos = 0; } 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)); } ByteBuffer &operator<<(bool value) { append<char>((char)value); return *this; } // unsigned ByteBuffer &operator<<(uint8 value) { append<uint8>(value); return *this; } ByteBuffer &operator<<(uint16 value) { append<uint16>(value); return *this; } ByteBuffer &operator<<(uint32 value) { append<uint32>(value); return *this; } ByteBuffer &operator<<(uint64 value) { append<uint64>(value); return *this; } // signed as in 2e complement ByteBuffer &operator<<(int8 value) { append<int8>(value); return *this; } ByteBuffer &operator<<(int16 value) { append<int16>(value); return *this; } ByteBuffer &operator<<(int32 value) { append<int32>(value); return *this; } ByteBuffer &operator<<(int64 value) { append<int64>(value); return *this; } ByteBuffer &operator<<(float value) { append<float>(value); return *this; } ByteBuffer &operator<<(double value) { append<double>(value); return *this; } /* ByteBuffer &operator<<(const std::string &value) { append((uint8 *)value.c_str(), value.length()); append((uint8)0); return *this; } ByteBuffer &operator<<(const char *str) { append((uint8 *)str, strlen(str)); append((uint8)0); return *this; }*/ ByteBuffer &operator<<(const std::string &value) { *this << (uint16)value.length(); append((uint8 *)value.c_str(), value.length()); return *this; } ByteBuffer &operator<<(const char *str) { uint16 len = strlen(str); *this << len; append((uint8 *)str, len); return *this; } // stream like operators for reading data ByteBuffer &operator>>(bool &value) { value = read<char>() > 0 ? true : false; return *this; } //unsigned ByteBuffer &operator>>(uint8 &value) { value = read<uint8>(); return *this; } ByteBuffer &operator>>(uint16 &value) { value = read<uint16>(); return *this; } ByteBuffer &operator>>(uint32 &value) { value = read<uint32>(); return *this; } ByteBuffer &operator>>(uint64 &value) { value = read<uint64>(); return *this; } //signed as in 2e complement ByteBuffer &operator>>(int8 &value) { value = read<int8>(); return *this; } ByteBuffer &operator>>(int16 &value) { value = read<int16>(); return *this; } ByteBuffer &operator>>(int32 &value) { value = read<int32>(); return *this; } ByteBuffer &operator>>(int64 &value) { value = read<int64>(); return *this; } ByteBuffer &operator>>(float &value) { value = read<float>(); return *this; } ByteBuffer &operator>>(double &value) { value = read<double>(); return *this; } /* ByteBuffer &operator>>(std::string& value) { value.clear(); while (true) { char c=read<char>(); if (c==0) break; value+=c; } return *this; }*/ ByteBuffer &operator>>(std::string& value) { uint16 len; *this >> len; if(len > 0) { value.resize(len); read((uint8*)value.c_str(), len); } else { value.clear(); } return *this; } uint8 operator[](size_t pos) { return read<uint8>(pos); } size_t rpos() { return _rpos; }; size_t rpos(size_t rpos) { _rpos = rpos; return _rpos; }; size_t wpos() { return _wpos; } size_t wpos(size_t wpos) { _wpos = wpos; return _wpos; } template <typename T> T read() { T r=read<T>(_rpos); _rpos += sizeof(T); return r; }; template <typename T> T read(size_t pos) const { //ASSERT(pos + sizeof(T) <= size()); if(pos + sizeof(T) > size()) { return (T)0; } else { return *((T*)&_storage[pos]); } } void read(uint8 *dest, size_t len) { if (_rpos + len <= size()) { memcpy(dest, &_storage[_rpos], len); } else { //throw error(); memset(dest, 0, len); } _rpos += len; } const uint8 *contents() const { return &_storage[0]; }; size_t size() const { return _storage.size(); }; void resize(size_t newsize) { _storage.resize(newsize); _rpos = 0; _wpos = size(); }; void reserve(size_t ressize) { if (ressize > size()) _storage.reserve(ressize); }; void append(const char *src, size_t cnt) { return append((const uint8 *)src, cnt); } void append(const uint8 *src, size_t cnt) { if (!cnt) return; if (_storage.size() < _wpos + cnt) _storage.resize(_wpos + cnt); memcpy(&_storage[_wpos], src, cnt); _wpos += cnt; } void append(const ByteBuffer& buffer) { if(buffer.size() > 0) append(buffer.contents(),buffer.size()); } void put(size_t pos, const uint8 *src, size_t cnt) { memcpy(&_storage[pos], src, cnt); } void hexlike() { uint32 j = 1, k = 1; printf("STORAGE_SIZE: %u ", (unsigned int)size() ); for(uint32 i = 0; i < size(); i++) { if ((i == (j*8)) && ((i != (k*16)))) { if (read<uint8>(i) < 0x0F) { printf("| 0%X ", read<uint8>(i) ); } else { printf("| %X ", read<uint8>(i) ); } j++; } else if (i == (k*16)) { rpos(rpos()-16); // move read pointer 16 places back printf(" | "); // write split char for (int x = 0; x < 16; x++) { printf("%c", read<uint8>(i-16 + x) ); } if (read<uint8>(i) < 0x0F) { printf(" 0%X ", read<uint8>(i) ); } else { printf(" %X ", read<uint8>(i) ); } k++; j++; } else { if (read<uint8>(i) < 0x0F) { printf("0%X ", read<uint8>(i) ); } else { printf("%X ", read<uint8>(i) ); } } } printf(" "); } protected: size_t _rpos, _wpos; std::vector<uint8> _storage; public: MSGPACK_DEFINE(_storage); }; #endif
#include <string> #include <iostream> #include <iomanip> #include <sstream> #include <cassert> //#include <msgpack.hpp> #include "ByteBuffer.h" void print(std::string const& buf) { for (std::string::const_iterator it = buf.begin(), end = buf.end(); it != end; ++it) { std::cout << std::setw(2) << std::hex << std::setfill('0') << (static_cast<int>(*it) & 0xff) << ' '; } std::cout << std::dec << std::endl; } int main() { { ByteBuffer A; int32 a = 1; int32 b = 2; A<<a; A<<b; std::stringstream ss; msgpack::pack(ss, A); print(ss.str()); // deal data ss.str() msgpack::object_handle oh = msgpack::unpack(ss.str().data(), ss.str().size()); msgpack::object obj = oh.get(); std::cout << obj << std::endl; ByteBuffer B; obj.convert(B); int32 c; int32 d; B>>c; B>>d; std::cout << c << " | " << d << std::endl; } system("pause"); return 0; }