/* * Copyright (c) 2015 Cryptonomex, Inc., and contributors. * * The MIT License * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace graphene::chain; namespace detail_ns { string remove_tail_if( const string& str, char c, const string& match ) { auto last = str.find_last_of( c ); if( last != std::string::npos ) if( str.substr( last + 1 ) == match ) return str.substr( 0, last ); return str; } string remove_namespace_if( const string& str, const string& match ) { auto last = str.find( match ); if( last != std::string::npos ) return str.substr( match.size()+2 ); return str; } string remove_namespace( string str ) { str = remove_tail_if( str, '_', "operation" ); str = remove_tail_if( str, '_', "t" ); str = remove_tail_if( str, '_', "object" ); str = remove_tail_if( str, '_', "type" ); str = remove_namespace_if( str, "graphene::chain" ); str = remove_namespace_if( str, "graphene::db" ); str = remove_namespace_if( str, "std" ); str = remove_namespace_if( str, "fc" ); auto pos = str.find( ":" ); if( pos != str.npos ) str.replace( pos, 2, "_" ); return str; } template void generate_serializer(); template void register_serializer(); map st; vector> serializers; bool register_serializer( const string& name, std::function sr ) { if( st.find(name) == st.end() ) { serializers.push_back( sr ); st[name] = serializers.size() - 1; return true; } return false; } template struct js_name { static std::string name(){ return remove_namespace(fc::get_typename::name()); }; }; template struct js_name> { static std::string name(){ return "fixed_array "+ fc::to_string(N) + ", " + remove_namespace(fc::get_typename::name()); }; }; template struct js_name> { static std::string name(){ return "bytes "+ fc::to_string(N); }; }; template struct js_name> { static std::string name(){ return "bytes "+ fc::to_string(N); }; }; template struct js_name< fc::optional > { static std::string name(){ return "optional " + js_name::name(); } }; template struct js_name< fc::smart_ref > { static std::string name(){ return js_name::name(); } }; template<> struct js_name< object_id_type > { static std::string name(){ return "object_id_type"; } }; template struct js_name< fc::flat_set > { static std::string name(){ return "set " + js_name::name(); } }; template struct js_name< std::vector > { static std::string name(){ return "array " + js_name::name(); } }; template struct js_name< fc::safe > { static std::string name(){ return js_name::name(); } }; template<> struct js_name< std::vector > { static std::string name(){ return "bytes()"; } }; template<> struct js_name { static std::string name(){ return "bytes 20"; } }; template<> struct js_name { static std::string name(){ return "bytes 28"; } }; template<> struct js_name { static std::string name(){ return "bytes 32"; } }; template<> struct js_name { static std::string name(){ return "varuint32"; } }; template<> struct js_name { static std::string name(){ return "varint32"; } }; template<> struct js_name< vote_id_type > { static std::string name(){ return "vote_id"; } }; template<> struct js_name< time_point_sec > { static std::string name(){ return "time_point_sec"; } }; template struct js_name > { static std::string name(){ return "protocol_id_type \"" + remove_namespace(fc::get_typename::name()) + "\""; }; }; template struct js_name< std::set > { static std::string name(){ return "set " + js_name::name(); } }; template struct js_name< std::map > { static std::string name(){ return "map (" + js_name::name() + "), (" + js_name::name() +")"; } }; template struct js_name< fc::flat_map > { static std::string name(){ return "map (" + js_name::name() + "), (" + js_name::name() +")"; } }; template struct js_sv_name; template struct js_sv_name { static std::string name(){ return "\n " + js_name::name(); } }; template struct js_sv_name { static std::string name(){ return "\n " + js_name::name() +" " + js_sv_name::name(); } }; template struct js_name< fc::static_variant > { static std::string name( std::string n = ""){ static const std::string name = n; if( name == "" ) return "static_variant [" + js_sv_name::name() + "\n]"; else return name; } }; template<> struct js_name< fc::static_variant<> > { static std::string name( std::string n = ""){ static const std::string name = n; if( name == "" ) return "static_variant []"; else return name; } }; template::is_defined::value> struct serializer; struct register_type_visitor { typedef void result_type; template result_type operator()( const Type& op )const { serializer::init(); } }; class register_member_visitor; struct serialize_type_visitor { typedef void result_type; int t = 0; serialize_type_visitor(int _t ):t(_t){} template result_type operator()( const Type& op )const { std::cout << " " <::name() ) <<": "< void operator()( const char* name )const { std::cout << " " << name <<": " << js_name::name() <<"\n"; } }; template struct serializer { static_assert( fc::reflector::is_defined::value == false, "invalid template arguments" ); static void init() {} static void generate() {} }; template struct serializer,false> { static void init() { serializer::init(); } static void generate() {} }; template struct serializer,false> { static void init() { serializer::init(); } static void generate() {} }; template struct serializer,false> { static void init() { serializer::init(); } static void generate() {} }; template<> struct serializer,false> { static void init() { } static void generate() {} }; template<> struct serializer { static void init() {} static void generate() {} }; template<> struct serializer { static void init() {} static void generate() {} }; template<> struct serializer { static void init() {} static void generate() {} }; #ifdef __APPLE__ // on mac, size_t is a distinct type from uint64_t or uint32_t and needs a separate specialization template<> struct serializer { static void init() {} static void generate() {} }; #endif template<> struct serializer { static void init() {} static void generate() {} }; template<> struct serializer { static void init() {} static void generate() {} }; template struct serializer,false> { static void init() { serializer::init(); } static void generate(){} }; template struct serializer< graphene::db::object_id ,true> { static void init() {} static void generate() {} }; template struct serializer< fc::static_variant, false > { static void init() { static bool init = false; if( !init ) { init = true; fc::static_variant var; for( int i = 0; i < var.count(); ++i ) { var.set_which(i); var.visit( register_type_visitor() ); } register_serializer( js_name>::name(), [=](){ generate(); } ); } } static void generate() { std::cout << js_name>::name() << " = static_variant [" + js_sv_name::name() + "\n]\n\n"; } }; template<> struct serializer< fc::static_variant<>, false > { static void init() { static bool init = false; if( !init ) { init = true; fc::static_variant<> var; register_serializer( js_name>::name(), [=](){ generate(); } ); } } static void generate() { std::cout << js_name>::name() << " = static_variant []\n\n"; } }; class register_member_visitor { public: template void operator()( const char* name )const { serializer::init(); } }; template struct serializer_init_helper { static void init() { auto name = js_name::name(); if( st.find(name) == st.end() ) { fc::reflector::visit( register_member_visitor() ); register_serializer( name, [=](){ generate(); } ); } } static void generate() { auto name = remove_namespace( js_name::name() ); if( name == "int64" ) return; std::cout << "" << name << " = new Serializer( \n" << " \"" + name + "\"\n"; fc::reflector::visit( serialize_member_visitor() ); std::cout <<")\n\n"; } }; template struct serializer_init_helper { static void init() { } }; template struct serializer { static_assert( fc::reflector::is_defined::value == reflected, "invalid template arguments" ); static void init() { serializer_init_helper< T, typename fc::reflector::is_enum >::init(); } }; } // namespace detail_ns int main( int argc, char** argv ) { try { operation op; std::cout << "ChainTypes.operations=\n"; for( int i = 0; i < op.count(); ++i ) { op.set_which(i); op.visit( detail_ns::serialize_type_visitor(i) ); } std::cout << "\n"; detail_ns::js_name::name("fee_parameters"); detail_ns::js_name::name("operation"); detail_ns::js_name::name("operation_result"); detail_ns::js_name::name("future_extensions"); detail_ns::js_name::name("worker_initializer"); detail_ns::js_name::name("predicate"); detail_ns::js_name::name("vesting_policy_initializer"); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); detail_ns::serializer::init(); for( const auto& gen : detail_ns::serializers ) gen(); } catch ( const fc::exception& e ){ edump((e.to_detail_string())); } return 0; }