00001 #ifndef _BOOST_RPC_VARINT_HPP_
00002 #define _BOOST_RPC_VARINT_HPP_
00003 #include <boost/reflect/reflect.hpp>
00004 #include <boost/rpc/datastream.hpp>
00005
00006 namespace boost { namespace rpc {
00007
00008 struct unsigned_int
00009 {
00010 unsigned_int( uint32_t v = 0 ):value(v){}
00011
00012 operator uint32_t()const { return value; }
00013
00014 template<typename T>
00015 unsigned_int& operator=( const T& v ) { value = v; return *this; }
00016
00017 uint32_t value;
00018
00019 template<typename T>
00020 friend inline datastream<T>& operator<<( datastream<T>& ds, const unsigned_int& vi )
00021 {
00022 uint64_t v = vi.value;
00023 do
00024 {
00025 uint8_t b = uint8_t(v) & 0x7f;
00026 v >>= 7;
00027 b |= ((v > 0) << 7);
00028 ds.putc(b);
00029 }while( v );
00030 return ds;
00031 }
00032
00033 template<typename T>
00034 friend inline datastream<T>& operator>>( datastream<T>& ds, unsigned_int& vi )
00035 {
00036 uint64_t v = 0;
00037 char b = 0;
00038 uint8_t by = 0;
00039 do {
00040 ds.getc(b);
00041 v |= uint32_t(uint8_t(b) & 0x7f) << by;
00042 by += 7;
00043 } while( uint8_t(b) & 0x80 );
00044
00045 vi.value = v;
00046
00047 return ds;
00048 }
00049 };
00050
00051 struct signed_int
00052 {
00053 signed_int( int32_t v = 0 ):value(v){}
00054 operator int32_t()const { return value; }
00055 template<typename T>
00056 signed_int& operator=( const T& v ) { value = v; return *this; }
00057
00058 int32_t value;
00059
00060 template<typename T>
00061 friend inline datastream<T>& operator<<( datastream<T>& ds, const signed_int& vi )
00062 {
00063 uint32_t v = (vi.value<<1) ^ (vi.value>>31);
00064 do
00065 {
00066 uint8_t b = uint8_t(v) & 0x7f;
00067 v >>= 7;
00068 b |= ((v > 0) << 7);
00069 ds.putc(b);
00070 }
00071 while( v );
00072 return ds;
00073 }
00074
00075 template<typename T>
00076 friend inline datastream<T>& operator>>( datastream<T>& ds, signed_int& vi )
00077 {
00078 uint32_t v = 0;
00079 char b = 0;
00080 int by = 0;
00081 do {
00082 ds.getc(b);
00083 v |= uint32_t(uint8_t(b) & 0x7f) << by;
00084 by += 7;
00085 } while( uint8_t(b) & 0x80 );
00086
00087 vi.value = ((v>>1) ^ (v>>31)) + (v&0x01);
00088 vi.value = v&0x01 ? vi.value : -vi.value;
00089 vi.value = - vi.value;
00090
00091 return ds;
00092 }
00093 };
00094
00095 } }
00096
00097 BOOST_REFLECT_TYPEINFO( boost::rpc::unsigned_int )
00098 BOOST_REFLECT_TYPEINFO( boost::rpc::signed_int )
00099
00100 #endif