Hall A ROOT/C++ Analyzer (podd)
Loading...
Searching...
No Matches
THaRTTI.cxx
Go to the documentation of this file.
1//*-- Author : Ole Hansen 28/01/02
2
4//
5// THaRTTI
6//
7// RTTI information for a member variable of a ROOT class.
8// This is a utility class used internally by THaVarList.
9//
11
12#include "THaRTTI.h"
13#include "THaVar.h"
14#include "THaArrayString.h"
15#include "TROOT.h"
16#include "TClass.h"
17#include "TClassEdit.h"
18#include "TDataMember.h"
19#include "TDataType.h"
20#include "TRealData.h"
21#include <iostream>
22#include <cassert>
23
24using namespace std;
25
26static TObject* FindRealDataVar( TList* lrd, const TString& var );
27
28//_____________________________________________________________________________
30 const void* const prototype )
31{
32 // Get RTTI info for member variable 'var' of ROOT class 'cl'
33 // 'prototype' is a pointer to an object of class 'cl' and must
34 // be specified if the class does not have a default constructor.
35
36 if( !cl )
37 return -1;
38
39 // Get the object's list TRealData. Unlike the list of TDataMembers,
40 // this list handles inheritance (i.e. it includes base class data
41 // members), and TRealData allows us to get any variable's offset.
42 // The main limitation is that data members have to be persistent.
43
44 TList* lrd = cl->GetListOfRealData();
45 if( !lrd ) {
46 // FIXME: Check if const_cast is appropriate here
47 // - prototype must not be modified
48 cl->BuildRealData( const_cast<void*>(prototype) );
49 lrd = cl->GetListOfRealData();
50 if( !lrd )
51 return -1;
52 }
53
54 // Parse possible array subscript
55 THaArrayString avar(var);
56 if( avar.IsError() )
57 return -1;
58 Int_t element_requested = -1;
59
60 // Variable names in TRealData are stored along with pointer prefixes (*)
61 // and array subscripts, so we have to use a customized search function:
62 auto* rd = dynamic_cast<TRealData*>( FindRealDataVar(lrd, avar ) );
63 if( !rd )
64 return -1;
65
66 // Get the TDataMember, which holds the really useful information
67 TDataMember* m = rd->GetDataMember();
68 if( !m )
69 return -1;
70
71 VarType type;
72 TClass* elemClass = nullptr;
73 if( m->IsBasic() || m->IsEnum() ) {
74 TString typnam( m->GetTypeName() );
75 if( m->IsEnum() || typnam == "Int_t" || typnam == "int" )
76 // Enumeration types are all treated as integers
77 type = kInt;
78 else if( typnam == "Double_t" || typnam == "double" )
79 type = kDouble;
80 else if( typnam == "Float_t" || typnam == "float" || typnam == "Real_t" )
81 type = kFloat;
82 else if( typnam == "UInt_t" || typnam == "unsigned int" )
83 type = kUInt;
84 else if( typnam == "Short_t" || typnam == "short" )
85 type = kShort;
86 else if( typnam == "UShort_t" || typnam == "unsigned short" )
87 type = kUShort;
88 else if( typnam == "Long_t" || typnam == "long" )
89 type = kLong;
90 else if( typnam == "ULong_t" || typnam == "unsigned long" )
91 type = kULong;
92 else if( typnam == "Char_t" || typnam == "Text_t" || typnam == "char" )
93 type = kChar;
94 else if( typnam == "Byte_t" || typnam == "UChar_t" ||
95 typnam == "Bool_t" || typnam == "bool" || typnam == "unsigned char" )
96 type = kByte;
97 else
98 return -1;
99 // Pointers are flagged as pointer types. The way THaVar works, this means:
100 // - Simple pointers will be dereferenced when reading the variable.
101 // This avoids dangling pointers.
102 // - For pointers to pointers, the value of the base pointer will be
103 // memorized. Therefore, if the base pointer changes, the variable
104 // will become invalid.
105 if( m->IsaPointer() )
106 // Simple, but depends on the definition order in VarType.h
107 type = (VarType)(type + kDoubleP);
108
109 } else if( m->IsSTLContainer() ) {
110 // STL containers: only std::vector supported
111 if( m->IsSTLContainer() != TClassEdit::kVector )
112 return -1;
113 // Get the vector element type name
114 TString typnam( m->GetTypeName() );
115 Ssiz_t lbrk = typnam.Index( "<" );
116 Ssiz_t rbrk = typnam.Index( ">" );
117 if( lbrk == kNPOS || rbrk == kNPOS || lbrk+1 >= rbrk )
118 return -1;
119 typnam = typnam(lbrk+1,rbrk-lbrk-1);
120 if( typnam == "Int_t" || typnam == "int" )
121 type = kIntV;
122 else if( typnam == "UInt_t" || typnam == "unsigned int" )
123 type = kUIntV;
124 else if( typnam == "Float_t" || typnam == "float" || typnam == "Real_t" )
125 type = kFloatV;
126 else if( typnam == "Double_t" || typnam == "double" )
127 type = kDoubleV;
128 else {
129 // Check for vector of defined object class or vector of pointers
130 // to such objects
131 Int_t nstar = 0;
132 while( nstar < 2 && typnam.EndsWith("*") ) {
133 typnam.Chop();
134 ++nstar;
135 }
136 if( nstar > 1 )
137 return -1; // Vector of pointer-to-pointers not supported
138 elemClass = gROOT->GetClass( typnam );
139 if( !elemClass )
140 return -1;
141 type = ( nstar == 0 ) ? kObjectV : kObjectPV;
142 }
143
144 } else {
145 type = (m->IsaPointer()) ? kObjectP : kObject;
146 }
147
148 // Check for arrays
149 Int_t array_dim = m->GetArrayDim();
150 const char* array_index = m->GetArrayIndex();
151 Long_t count_offset = -1;
152
153 TString subscript( rd->GetName() );
154 EArrayType atype = kScalar;
155
156 // May only request an element of a matching explicitly-dimensioned array
157 if( avar.IsArray() && array_dim != avar.GetNdim() )
158 return -1;
159
160 // If variable is explicitly dimensioned, ignore any "array index"
161 // in the comment.
162 if( array_dim > 0 ) {
163 // Explicitly dimensioned arrays must not be pointers
164 if( m->IsaPointer() )
165 return -1;
166 if( avar.IsArray() ) {
167 // If a specific element was requested, treat the variable as a scalar.
168 // Calculate the linear index of the requested element.
169 element_requested = avar[0];
170 for( Int_t idim = 0; idim < array_dim; ++idim ) {
171 if( avar[idim] >= m->GetMaxIndex(idim) ) // Out of bounds
172 return -1;
173 if( idim > 0 ) {
174 element_requested *= m->GetMaxIndex(idim);
175 element_requested += avar[idim];
176 }
177 }
178 } else {
179 // Otherwise it's a fixed-size array
180 Ssiz_t i = subscript.Index( "[" );
181 if( i == kNPOS )
182 return -1;
183 subscript = subscript(i,subscript.Length()-i);
184 atype = kFixed;
185 }
186
187 } else if( array_index && *array_index && m->IsaPointer() ) {
188 // If no explicit dimensions given, but the variable is a pointer
189 // and there is an array subscript given in the comment ( // [fN] ),
190 // then we have a variable-size array. The subscript variable in the
191 // comment MUST be an Int_t. I guess that is a standard ROOT
192 // convention anyway.
193
194 // Must be an array of a basic type
195 if( !m->GetDataType() )
196 return -1;
197
198 // See if the subscript variable exists and is an Int_t
199 TString index(array_index);
200 THaRTTI rtti;
201 rtti.Find( cl, index, prototype );
202 if( rtti.IsValid() && rtti.GetType() == kInt ) {
203 // Looking good. Let's get the offset
204 count_offset = rtti.GetOffset();
205 }
206 atype = kVariable;
207
208 } else if( m->IsSTLContainer() ) {
209 assert( m->IsSTLContainer() == TClassEdit::kVector );
210 atype = kVector;
211 }
212
213 // Build the RTTI object
214
215 fOffset = rd->GetThisOffset();
216 fType = type;
217 fArrayType = atype;
218 fDataMember = m;
219 fRealData = rd;
220 fElemClass = elemClass;
221
222 switch( atype ) {
223 case kScalar:
224 if( element_requested >= 0 )
225 fOffset += element_requested * m->GetUnitSize();
226 break;
227 case kFixed:
228 fSubscript = subscript;
229 break;
230 case kVariable:
231 fCountOffset = count_offset;
232 break;
233 case kVector:
234 break;
235 }
236
237 return 0;
238}
239
240//_____________________________________________________________________________
241static
243{
244 // Search list of TRealData 'lrd' for a variable named 'var',
245 // stripping pointer prefixes "*" and array subscripts.
246 // Return corresponding TRealData entry if found, else 0.
247 // Local function used by Find().
248
249 TObjLink* lnk = lrd->FirstLink();
250 while (lnk) {
251 TObject* obj = lnk->GetObject();
252 TString name( obj->GetName() );
253 name = name.Strip( TString::kLeading, '*' );
254 Ssiz_t i = name.Index( "[" );
255 if( i != kNPOS )
256 name = name(0,i);
257 if( name == var )
258 return obj;
259 lnk = lnk->Next();
260 }
261 return nullptr;
262}
263
264//_____________________________________________________________________________
266{
267 // If this is an object, get its class
268
269 if( IsObject() && fDataMember )
270 return gROOT->GetClass( fDataMember->GetTypeName() );
271 if( IsObjVector() )
272 return fElemClass;
273
274 return nullptr;
275}
276
277//_____________________________________________________________________________
279{
280 return fDataMember != nullptr && fDataMember->IsaPointer();
281}
282
283//_____________________________________________________________________________
285{
286 // Print RTTI information
287
288 cout << "Offset: " << fOffset;
289 if( fOffset == -1 )
290 cout << " (not initialized)";
291 cout << endl;
292 if( fOffset == -1 )
293 return;
294 cout << "Type: ";
295 if( !IsObject() && !(fType == kObjectV || fType == kObjectPV) )
296 cout << Vars::GetTypeName( fType );
297 else if( fDataMember )
298 cout << fDataMember->GetFullTypeName();
299 cout << endl;
300 if( IsArray() ) {
301 cout << "Array type: ";
302 switch( fArrayType ) {
303 case kFixed:
304 cout << "fixed" << endl;
305 cout << "Dimension: " << fSubscript.Data() << endl;
306 break;
307 case kVariable:
308 cout << "variable" << endl;
309 cout << "Count offset: " << fCountOffset << endl;
310 break;
311 case kVector:
312 cout << "vector" << endl;
313 break;
314 case kScalar:
315 assert(false); // not reached
316 break;
317 }
318 }
319}
320//_____________________________________________________________________________
int Int_t
long Long_t
bool Bool_t
const Ssiz_t kNPOS
int Ssiz_t
const char Option_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
char name[80]
static TObject * FindRealDataVar(TList *lrd, const TString &var)
Definition THaRTTI.cxx:242
#define gROOT
void BuildRealData(void *pointer=nullptr, Bool_t isTransient=kFALSE)
TList * GetListOfRealData() const
Bool_t IsaPointer() const
const char * GetTypeName() const
const char * GetFullTypeName() const
Bool_t IsArray() const
Bool_t IsError() const
Int_t GetNdim() const
TDataMember * fDataMember
Definition THaRTTI.h:60
EArrayType fArrayType
Definition THaRTTI.h:57
TRealData * fRealData
Definition THaRTTI.h:61
Bool_t IsObjVector() const
Definition THaRTTI.h:43
VarType GetType() const
Definition THaRTTI.h:38
TString fSubscript
Definition THaRTTI.h:58
EArrayType
Definition THaRTTI.h:21
@ kScalar
Definition THaRTTI.h:21
@ kVariable
Definition THaRTTI.h:21
@ kFixed
Definition THaRTTI.h:21
@ kVector
Definition THaRTTI.h:21
void Print(Option_t *opt="") const
Definition THaRTTI.cxx:284
Bool_t IsPointer() const
Definition THaRTTI.cxx:278
Bool_t IsArray() const
Definition THaRTTI.h:39
Bool_t IsObject() const
Definition THaRTTI.h:40
Long_t fCountOffset
Definition THaRTTI.h:59
TClass * fElemClass
Definition THaRTTI.h:62
Long_t fOffset
Definition THaRTTI.h:55
VarType fType
Definition THaRTTI.h:56
Long_t GetOffset() const
Definition THaRTTI.h:35
TClass * GetClass() const
Definition THaRTTI.cxx:265
Bool_t IsValid() const
Definition THaRTTI.h:46
Int_t Find(TClass *cl, const TString &var, const void *p=nullptr)
Definition THaRTTI.cxx:29
virtual TObjLink * FirstLink() const
virtual const char * GetName() const
Ssiz_t Length() const
Bool_t EndsWith(const char *pat, ECaseCompare cmp=kExact) const
const char * Data() const
TString & Chop()
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
STL namespace.
TMarker m
ClassImp(TPyArg)