MACE  1.0.0
 All Classes Namespaces Files Functions Variables Enumerations Defines
libs/rpc/include/mace/rpc/datastream.hpp
00001 #ifndef _MACE_RPC_DATASTREAM_HPP_
00002 #define _MACE_RPC_DATASTREAM_HPP_
00003 #include <boost/type_traits/is_fundamental.hpp>
00004 #include <boost/static_assert.hpp>
00005 #include <stdint.h>
00006 
00007 namespace mace { namespace rpc {
00008 
00016 template<typename T>
00017 struct datastream {
00018   datastream( T start, uint32_t s )
00019   :m_start(start),m_pos(start),m_end(start+s){};
00020 
00021   template<typename DATA>
00022   inline datastream& operator<<(const DATA& d) {
00023     BOOST_STATIC_ASSERT( boost::is_fundamental<DATA>::value );
00024     write( (const char*)&d, sizeof(d) );
00025     return *this;
00026   }
00027 
00028   template<typename DATA>
00029   inline datastream& operator>>(DATA& d) {
00030     BOOST_STATIC_ASSERT( boost::is_fundamental<DATA>::value );
00031     read((char*)&d, sizeof(d) );
00032     return *this;
00033   }
00034   
00035   inline void skip( uint32_t s ){ m_pos += s; }
00036   inline bool read( char* d, uint32_t s ) {
00037     if( m_end - m_pos >= (int32_t)s ) {
00038       memcpy( d, m_pos, s );
00039       m_pos += s;
00040       return true;
00041     }
00042     return false;
00043   }
00044 
00045   inline bool write( const char* d, uint32_t s ) {
00046     if( m_end - m_pos >= (int32_t)s ) {
00047       memcpy( m_pos, d, s );
00048       m_pos += s;
00049       return true;
00050     }
00051     return false;
00052   }
00053 
00054   inline bool   put(char c) { 
00055     if( m_pos < m_end ) {
00056       *m_pos = c; 
00057       ++m_pos; 
00058       return true;
00059     }
00060     return  false;
00061   }
00062 
00063   inline bool   get( unsigned char& c ) { return get( *(char*)&c ); }
00064   inline bool   get( char& c ) {
00065     if( m_pos < m_end ) {
00066       c = *m_pos;
00067       ++m_pos; 
00068       return true;
00069     }
00070     ++m_pos; 
00071     return  false;
00072   }
00073 
00074   T               pos()const        { return m_pos;                               }
00075   inline bool     valid()const      { return m_pos <= m_end && m_pos >= m_start;  }
00076   inline bool     seekp(uint32_t p) { m_pos = m_start + p; return m_pos <= m_end; }
00077   inline uint32_t tellp()const      { return m_pos - m_start;                     }
00078   inline uint32_t remaining()const  { return m_end - m_pos;                       }
00079 private:
00080   T m_start;
00081   T m_pos;
00082   T m_end;
00083 };
00084 
00085 template<>
00086 struct datastream<size_t> {
00087   datastream( size_t init_size = 0):m_size(init_size){};
00088   template<typename DATA>
00089   inline datastream& operator<<(const DATA& d) {
00090     BOOST_STATIC_ASSERT( boost::is_fundamental<DATA>::value );
00091     m_size += sizeof(d);
00092     return *this;
00093   }
00094   inline bool skip( uint32_t s ) {
00095     m_size += s;
00096     return true;
00097   }
00098   inline bool write( const char* d, uint32_t s ) {
00099     m_size += s;
00100     return true;
00101   }
00102   inline bool   put(char c)    { 
00103     ++m_size;
00104     return  true;
00105   }
00106   inline bool     valid()const      { return true;              }
00107   inline bool     seekp(uint32_t p) { m_size = p;  return true; }
00108   inline uint32_t tellp()const      { return m_size;            }
00109   inline uint32_t remaining()const  { return 0;                 }
00110 private:
00111   uint32_t m_size;
00112 };
00113 
00114 
00115 } } // namespace boost::rpc
00116 
00117 #endif