void inspectDicts()
{
   // Supercluster energy
   TClass* sc = TClass::GetClass("SuperCluster");
   TDataMember* dm = sc->GetDataMember("energy2");
   if (dm)
      std::cout << "SuperCluster::energy2 type is " << dm->GetTypeName()
                << std::endl;
   dm = sc->GetDataMember("energy"); // should not
   if (dm)
      std::cout << "SuperCluster::energy type is " << dm->GetTypeName()
                << std::endl;

   // Particle vertex
   TClass* par = TClass::GetClass("Particle");
   dm = par->GetDataMember("vertex");
   if (dm)
      std::cout << "Particle::vertex type is " << dm->GetTypeName()
                << std::endl;
   dm = par->GetDataMember("vertex2"); // should not print
   if (dm)
      std::cout << "Particle::vertex2 type is " << dm->GetTypeName()
                << std::endl;
}
Beispiel #2
0
//_____________________________________________________________________________
Int_t THaRTTI::Find( TClass* cl, TString& var, 
		     const void* const prototype )
{
  // Get RTTI info for member variable 'var' of ROOT class 'cl'
  // 'prototype' is a pointer to an object of class 'cl' and must
  // be specified if the class does not have a default constructor.

  if( !cl )
    return -1;

  // Get the object's list TRealData.  Unlike the list of TDataMembers,
  // this list handles inheritance (i.e. it includes base class data
  // members), and TRealData allows us to get any variable's offset.
  // The main limitation is that data members have to be persistent.

  TList* lrd = cl->GetListOfRealData();
  if( !lrd ) {
    // FIXME: Check if const_cast is appropriate here 
    // - prototype must not be modified
    cl->BuildRealData( const_cast<void*>(prototype) );
    lrd = cl->GetListOfRealData();
    if( !lrd )
      return -1;
  }

  // Variable names in TRealData are stored along with pointer prefixes (*)
  // and array subscripts, so we have to use a customized search function:
  TRealData* rd = static_cast<TRealData*>( FindRealDataVar( lrd, var ) );
  if( !rd )
    return -1;

  // Get the TDataMember, which holds the really useful information
  TDataMember* m = rd->GetDataMember();
  if( !m )
    return -1;

  VarType type;
  if( m->IsBasic() || m->IsEnum() ) {
    TString typnam( m->GetTypeName() );
    if( typnam == "Double_t" )
      type = kDouble;
    else if( typnam == "Float_t" || typnam == "Real_t" )
      type = kFloat;
    else if( typnam == "Int_t" )
      type = kInt;
    else if( typnam == "UInt_t" )
      type = kUInt;
    else if( typnam == "Short_t" )
      type = kShort;
    else if( typnam == "UShort_t" )
      type = kUShort;
    else if( typnam == "Long_t" )
      type = kLong;
    else if( typnam == "ULong_t" )
      type = kULong;
    else if( typnam == "Char_t" || typnam == "Text_t" )
      type = kChar;
    else if( typnam == "Byte_t" || typnam == "UChar_t" ||
	     typnam == "Bool_t" )
      type = kByte;
    else if( m->IsEnum() )
      // Enumeration types are all treated as integers
      type = kInt;
    else
      return -1;
    // Pointers are flagged as pointer types. The way THaVar works, this means:
    // - Simple pointers will be dereferenced when reading the variable.
    //   This avoids dangling pointers.
    // - For pointers to pointers, the value of the base pointer will be
    //   memorized. Therefore, if the base pointer changes, the variable
    //   will become invalid.
    if( m->IsaPointer() )
      // Simple, but depends on the definition order in VarType.h
      type = (VarType)(type + kDoubleP);

  } else {
    type = (m->IsaPointer()) ? kObjectP : kObject;
  }

  // Check for arrays
  Int_t        array_dim    = m->GetArrayDim();
  const char*  array_index  = m->GetArrayIndex();
  Int_t        count_offset = -1;

  TString subscript( rd->GetName() );
  EArrayType atype = kScalar;

  // If variable is explicitly dimensioned, ignore any "array index"
  // in the comment.
  if( array_dim > 0 ) {
    // Explicitly dimensioned arrays must not be pointers
    if( m->IsaPointer() )
      return -1;
    Ssiz_t i = subscript.Index( '[' );
    if( i == kNPOS )
      return -1;
    subscript = subscript(i,subscript.Length()-i);
    atype = kFixed;

  } else if( array_index && *array_index && m->IsaPointer() ) {
    // If no explicit dimensions given, but the variable is a pointer
    // and there is an array subscript given in the comment ( // [fN] ), 
    // then we have a variable-size array.  The subscript variable in the
    // comment MUST be an Int_t. I guess that is a standard ROOT 
    // convention anyway.

    // See if the subscript variable exists and is an Int_t
    TString index(array_index);
    THaRTTI rtti;
    rtti.Find( cl, index, prototype );
    if( rtti.IsValid() && rtti.GetType() == kInt ) {
      // Looking good. Let's get the offset
      count_offset = rtti.GetOffset();
    }
    atype = kVariable;
  }

  // Build the RTTI object

  fOffset     = rd->GetThisOffset();
  fType       = type;
  fArrayType  = atype;
  fDataMember = m;
  fRealData   = rd;

  switch( atype ) {
  case kFixed:
    fSubscript = subscript;
    break;
  case kVariable:
    fCountOffset = count_offset;
    break;
  default:
    break;
  }

  return 0;
}