Bytemaster's Boost Libraries
/Users/dlarimer/dev/libs/rpc/include/boost/rpc/dynamic_raw.hpp
00001 #ifndef _BOOST_RPC_DYNAMIC_RAW_HPP_
00002 #define _BOOST_RPC_DYNAMIC_RAW_HPP_
00003 
00010 namespace boost { namespace rpc { namespace dynamic {
00011   namespace raw {
00012 
00013     template<typename T>
00014     class parser;
00015     class parser_base;
00016     class skip_parser;
00017 
00018     class description_database {
00019       public:
00020         boost::optional<boost::rpc::description> get_description( const std::string& type_name )const {
00021           type_description_map::const_iterator itr = m_type_db.find(type_name);
00022           if( itr != m_type_db.end() ) 
00023             return itr->second;
00024           return boost::optional<boost::rpc::description>();
00025         }
00026         void set( const std::string& name, const boost::rpc::description& d ) {
00027           m_type_db[name]=d;
00028         }
00029         
00030         template<typename T>
00031         parser<T>* get_parser();        
00032         
00033         skip_parser* get_skip_parser(const std::string& type);        
00034 
00035       private:
00036         typedef std::map<std::string, boost::rpc::description> type_description_map;
00037         typedef std::map<std::string, skip_parser*>            type_skipper_map;
00038         typedef std::map<std::string, parser_base*>            type_parser_map;
00039         type_description_map m_type_db;
00040         type_skipper_map     m_skipper_db;
00041         type_parser_map      m_parser_db;
00042     };
00043 
00044     template<typename Class>
00045     class member_parser_base {
00046       public:
00047         virtual member_parser_base(){}
00048         virtual void unpack( std::istream& s, Class& self )=0;
00049         virtual void pack( std::ostream& s, const Class& self )=0;
00050     };
00051 
00052     template<typename T, typename Class>
00053     class member_parser : public member_parser_base<Class> {
00054       public:
00055         member_parser( T (Class::*m ), description_database& db )
00056         :member(m) {
00057             member_parser = db.get_parser<T>();    
00058         }
00059 
00060         void unpack( std::istream& s, Class& self ) {
00061             member_parser->unpack( s, self.*member );
00062         }
00063         void pack( std::ostream& s, const Class& self ) {
00064             member_parser->pack( s, self.*member );
00065         }
00066 
00067         parser<T>* member_parser;
00068         T (Class::*member);
00069     };
00070 
00076     struct create_member_parser {
00077       create_member_parser( boost::rpc::description::field& f, description_database& db )
00078       :m_parser(NULL), m_db(db), m_field(f){}
00079 
00080       template<typename T>
00081       inline void operator()( T (Class::*p), const char* name )const {
00082         if( std::string(name) == m_field.name ) {
00083            if( m_field.type == boost::reflect::get_typename<T>() )
00084                m_parser = new member_parser<T,Class>(p,m_db); 
00085            else {
00086               // consider ignoring this as if it was not present...
00087               throw "fields with same name have different types";
00088            }
00089         }
00090       }
00091       parser_base* m_parser;
00092       boost::rpc::description_database& m_db;
00093       boost::rpc::description::field& m_field;
00094     };
00095 
00096     template<typename Class>
00097     class skip_member_parser : public member_parser_base<Class> {
00098       public:
00099         skip_member_parser( boost::rpc::description::field& f, boost::rpc::description_database& db ) {
00100           m_parser = db.get_skip_parser( f.type );
00101         }
00102         void unpack( std::istream& s, Class& ) { m_parser->skip( s ); }
00103         void pack( std::ostream& s, const Class& ) { m_parser->skip( s ); }
00104       private:
00105         skip_parser* m_parser;
00106     };
00107 
00108     class skip_parser {
00109       public:
00110         skip_parser( boost::rpc::description& d, description_database& db ) {
00111           for( uint32_t i = 0; i < d.fields.size(); ++i ) {
00112             m_fields.push_back( db.get_skip_parser( d.feilds[i].type ) );
00113           }
00114         }
00115 
00116         template<typename Stream>
00117         void skip( Stream& s ) {
00118           std::vector<skip_parser*>::iterator itr = m_fields.begin();
00119           while( itr != m_fields.end() ) {
00120             (*itr)->skip(s);
00121             ++itr;
00122           }
00123         }
00124         std::vector<skip_parser*> m_fields;
00125     };
00126     class public_base {
00127       public:
00128         virtual ~public_base(){};  
00129     };
00130 
00131     template<typename T>
00132     class parser : public parser_base { 
00133       public:
00134         parser( boost::rpc::description& d, description_database& db ) {
00135           for( uint32_t i = 0; i < d.fields.size(); ++i ) {
00136             create_member_parser<T> v( d.fields[i], db );
00137             boost::reflect::reflector<T>::visit( v );
00138             // add the field to the parse order or create a skip parser
00139             m_fields.push_back( v.get_parser() ? v.get_parser() : new skip_member_parser<T>( d.fields[i], db ) );
00140           }
00141         }
00142         virtual void unpack( std::istream& s, T& v ) {
00143           for( uint32_t i = 0; i < m_fields.size(); ++i ) {
00144             m_fields[i]->unpack( s, v );
00145           }
00146         }
00147         virtual void pack( std::ostream& s, const T& v ) {
00148           for( uint32_t i = 0; i < m_fields.size(); ++i ) {
00149             m_fields[i]->pack( s, v );
00150           }
00151         }
00152       private:
00153         std::vector<member_parser<T>*>  m_fields;     
00154     };
00155 
00156   } // namespace raw
00157 } } } // boost::rpc::dynamic
00158 
00159 #endif
 All Classes Namespaces Files Functions Variables Typedefs Defines