#include "io_util.hh" #include "Evt.hh" #include "evt/Det.hh" #include "evt/Table.hh" #include "TDataType.h" #include "TBaseClass.h" #include "TMethod.h" #include "TList.h" #include "TTimeStamp.h" #include "stringutil.hh" string call_print( TClass* c, void* obj_ptr ) { TMethodCall tmc = TMethodCall( c, "print", "" ); TFunction* method = tmc.GetMethod(); if (!method) { fatal("class has no method print "); } std::ostringstream ss; const void* args[] = { &ss }; tmc.Execute( obj_ptr , args, 1, nullptr ); return ss.str(); } string call__str__( TClass* c, void* obj_ptr ) { TMethodCall tmc = TMethodCall( c, "__str__", "" ); TFunction* method = tmc.GetMethod(); if (!method) { fatal("class has no method __str__() "); } string rtype = method->GetReturnTypeName (); if ( rtype == "const char*") { long ret; tmc.Execute( obj_ptr , ret ); const char* s = (const char*) ret; return string(s); } if ( rtype == "string") { long ret; tmc.Execute( obj_ptr , ret ); return *((string*) ret); } fatal ("unknown return type for ", tmc.GetName() , rtype ); } /*! helper function to print container in dump() function */ template string stl_to_str( const T& container ) { return str(container.size()) + " entries"; } vector< vector< string > > get_datamembers( TClass* c, void* obj_ptr ) { vector < vector > r; for ( auto i : * (c->GetListOfDataMembers() ) ) { auto dmem = (TDataMember*) i; string name = dmem->GetName(); string typ = dmem->GetTypeName(); string desc = dmem->GetTitle(); desc = replace_all( desc, "dox:", ""); string value = "-"; bool is_static = (dmem->Property() & kIsStatic ) > 0; auto addr = ((char*) obj_ptr) + dmem->GetOffset(); auto dc = getclass_of_datamember( dmem ); if ( typ == "atomic" ) continue; if ( dmem->IsaPointer() ) { typ += "*"; value = str( addr ); } else if ( is_static ) { value = "[static]"; } else if ( dmem->IsBasic() ) { value = dmem->GetDataType()->AsString( (void*) addr ); } else if ( typ == "string" ) { value = *(string*) addr; } else if ( dc && dc->GetMethod("print", "") ) { value = call_print( dc, addr ); } else if ( typ == "TTimeStamp" ) { value = ((TTimeStamp*)addr)->AsString("s"); } else if ( dmem->IsSTLContainer() ) { if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "vector" ) value = stl_to_str( * (std::vector*) addr ); if ( typ == "map") value = stl_to_str( * (std::map*) addr ); if ( typ == "map") value = stl_to_str( * (std::map*) addr ); } else { value = "[cannot print]"; } r.push_back( { typ, name, value, desc } ); } return r; } vector< vector< string > > get_all_datamembers( TClass* c, void* obj_ptr ) { vector< vector< string > > r; for (auto i : *c->GetListOfBases() ) { auto base_tclass = ((TBaseClass*) i) -> GetClassPointer(); if ( base_tclass->GetName() == string("TObject") ) continue; //int offset C->GetBaseClassOffset( base_tclass ); const auto& v = get_datamembers( base_tclass, obj_ptr ); r.insert( r.end(), v.begin(), v.end() ); } const auto& v = get_datamembers( c, obj_ptr ); r.insert( r.end(), v.begin(), v.end() ); return r; } void xdump_( const std::type_info& t, void* obj_ptr ) { TClass* c = TClass::GetClass( t ); if (!c) { string typ = demangle( t.name() ); cout << " ROOT does not know about type " << typ << endl; return; } xdump_(c, obj_ptr ); } void xdump_( TClass* c, void* obj_ptr ) { const auto& vv = get_all_datamembers( c, obj_ptr ); Table T("type", "name", "value", "description"); for ( auto v : vv ) { T << v[0] << v[1] << v[2] << v[3]; } cout << T.__str__() << endl; //return T.__str__(); }