Logo ROOT   6.10/09
Reference Guide
TBranchProxyClassDescriptor.cxx
Go to the documentation of this file.
1 // @(#)root/treeplayer:$Id$
2 // Author: Philippe Canal 06/06/2004
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers and al. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /** \class TBranchProxyClassDescriptor
13 Hold the processed information about a TClass used in a TBranch while
14 TTreeProxyGenerator is parsing the TTree information.
15 Also contains the routine use to generate the appropriate code
16 fragment in the result of MakeProxy.
17 */
18 
19 #include "TBranchProxyDescriptor.h"
21 
22 #include "TClass.h"
23 #include "TClassEdit.h"
24 #include "TError.h"
25 #include "TVirtualStreamerInfo.h"
27 
29 
30 namespace ROOT {
31 namespace Internal {
32 
34 
35  // Make the typename a proper class name without having the really deal with
36  // namespace and templates.
37 
38  fRawSymbol = TClassEdit::ShortType(GetName(),2); // Drop default allocator from the name.
39  fRawSymbol.ReplaceAll(":","_");
40  fRawSymbol.ReplaceAll("<","_");
41  fRawSymbol.ReplaceAll(">","_");
42  fRawSymbol.ReplaceAll(",","Cm");
43  fRawSymbol.ReplaceAll(" ","");
44  fRawSymbol.ReplaceAll("*","st");
45  fRawSymbol.ReplaceAll("&","rf");
46  if (IsClones())
47  fRawSymbol.Prepend("TClaPx_");
48  else if (IsSTL())
49  fRawSymbol.Prepend("TStlPx_");
50  else
51  fRawSymbol.Prepend("TPx_");
52  if (fRawSymbol.Length() && fRawSymbol[fRawSymbol.Length()-1]=='.')
54 
56  }
57 
60  const char *branchname,
61  ELocation isclones,
62  UInt_t splitlevel,
63  const TString &containerName) :
64  TNamed(type,type),
65  fIsClones(isclones),
66  fContainerName(containerName),
67  fIsLeafList(false),
68  fSplitLevel(splitlevel),
69  fBranchName(branchname),
70  fSubBranchPrefix(branchname),
71  fInfo(info),
73  {
74  // Constructor.
75 
76  R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
77  NameToSymbol();
79  }
80 
82  TNamed(branchname,branchname),
83  fIsClones(kOut),
85  fIsLeafList(true),
86  fSplitLevel(0),
87  fBranchName(branchname),
88  fSubBranchPrefix(branchname),
89  fInfo(0),
91  {
92  // Constructor for a branch constructed from a leaf list.
93 
94  NameToSymbol();
96  }
97 
99  const char *branchname,
100  const char *branchPrefix, ELocation isclones,
101  UInt_t splitlevel,
102  const TString &containerName) :
103  TNamed(type,type),
104  fIsClones(isclones),
105  fContainerName(containerName),
106  fIsLeafList(true),
107  fSplitLevel(splitlevel),
108  fBranchName(branchname),
109  fSubBranchPrefix(branchPrefix),
110  fInfo(info),
112  {
113  // Constructor.
114 
115  R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
116  NameToSymbol();
118  }
119 
121  {
122  // Get the branch name
123  return fBranchName.Data();
124  }
125 
127  {
128  // Get the prefix from the branch name
129  return fSubBranchPrefix.Data();
130  }
131 
133  {
134  // Get the real symbol name
135 
136  return fRawSymbol;
137  }
138 
140  // Return the split level of the branch.
141  return fSplitLevel;
142  }
143 
145  {
146  // Return true if this description is the 'same' as the other decription.
147 
148  if ( !other ) return kFALSE;
149  // Purposely do not test on the name!
150  if ( strcmp(GetTitle(),other->GetTitle()) ) return kFALSE;
151  // if ( fBranchName != other->fBranchName ) return kFALSE;
152  // if ( fSubBranchPrefix != other->fSubBranchPrefix ) return kFALSE;
153 
154  if (fIsClones != other->fIsClones) return kFALSE;
155  if (fIsClones != kOut) {
156  if (fContainerName != other->fContainerName) return kFALSE;
157  }
158 
160  TBranchProxyDescriptor *othdesc;
161 
162  if ( fListOfBaseProxies.GetSize() != other->fListOfBaseProxies.GetSize() ) return kFALSE;
163  TIter next(&fListOfBaseProxies);
164  TIter othnext(&other->fListOfBaseProxies);
165  while ( (desc=(TBranchProxyDescriptor*)next()) ) {
166  othdesc=(TBranchProxyDescriptor*)othnext();
167  if (!desc->IsEquivalent(othdesc,kTRUE) ) return kFALSE;
168  }
169 
170  if ( fListOfSubProxies.GetSize() != other->fListOfSubProxies.GetSize() ) return kFALSE;
171  next = &fListOfSubProxies;
172  othnext = &(other->fListOfSubProxies);
173 
174  while ( (desc=(TBranchProxyDescriptor*)next()) ) {
175  othdesc=(TBranchProxyDescriptor*)othnext();
176  if (!desc->IsEquivalent(othdesc,kTRUE)) return kFALSE;
177  if (desc->IsSplit()) {
178  TString leftname ( desc->GetBranchName() );
179  TString rightname( othdesc->GetBranchName() );
180 
181  if (leftname.Index(GetBranchName())==0) leftname.Remove( 0,strlen(GetBranchName()));
182  if (leftname.Length() && leftname[0]=='.') leftname.Remove(0,1);
183  if (rightname.Index(other->GetBranchName())==0) rightname.Remove(0,strlen(other->GetBranchName()));
184  if (rightname.Length() && rightname[0]=='.') rightname.Remove(0,1);
185  if (leftname != rightname ) return kFALSE;
186  }
187  }
188  return true;
189  }
190 
192  {
193  // Add a descriptor to this proxy.
194 
195  if (desc) {
196  if (isBase) {
197  fListOfBaseProxies.Add(desc);
198  } else {
199  fListOfSubProxies.Add(desc);
200  UInt_t len = strlen(desc->GetTypeName());
201  if ((len+2)>fMaxDatamemberType) fMaxDatamemberType = len+2;
202  }
203  }
204  }
205 
207  {
208  // Return true if the class needed by the branch is loaded
209  return IsLoaded(GetTitle());
210  }
211 
213  {
214  // Return true if the class needed by the branch is loaded
215  TClass *cl = TClass::GetClass(classname);
216  while (cl) {
217  if (cl->IsLoaded()) return kTRUE;
218  if (!cl->GetCollectionProxy()) return kFALSE;
219  if (!cl->GetCollectionProxy()->GetValueClass()) return kTRUE; // stl container of simple type are always 'loaded'
220  cl = cl->GetCollectionProxy()->GetValueClass();
221  }
222  return kFALSE;
223  }
224 
226  {
227  // Return true if this proxy is for a TClonesArray.
229  }
230 
232  {
233  // Return true if this proxy is for a TClonesArray.
234  return fIsClones==kSTL || fIsClones==kInsideSTL;
235  }
236 
238  {
239  // Return whether the branch is inside, nested in or outside of a TClonesArray
240  return fIsClones;
241  }
242 
244  {
245  // Return the name of the container holding this class, if any.
246  return fContainerName;
247  }
248 
249  void TBranchProxyClassDescriptor::OutputDecl(FILE *hf, int offset, UInt_t /* maxVarname */)
250  {
251  // Output the declaration and implementation of this emulation class
252 
254 
255 
256  // Start the class declaration with the eventual list of base classes
257  fprintf(hf,"%-*sstruct %s\n", offset," ", GetName() );
258 
259  if (fListOfBaseProxies.GetSize()) {
260  fprintf(hf,"%-*s : ", offset," ");
261 
262  TIter next(&fListOfBaseProxies);
263 
264  desc = (TBranchProxyDescriptor*)next();
265  fprintf(hf,"public %s", desc->GetTypeName());
266 
267  while ( (desc = (TBranchProxyDescriptor*)next()) ) {
268  fprintf(hf,",\n%-*spublic %s", offset+5," ", desc->GetTypeName());
269  }
270 
271  fprintf(hf,"\n");
272  }
273  fprintf(hf,"%-*s{\n", offset," ");
274 
275 
276  // Write the constructor
277  fprintf(hf,"%-*s %s(TBranchProxyDirector* director,const char *top,const char *mid=0) :",
278  offset," ", GetName());
279 
280  Bool_t wroteFirst = kFALSE;
281 
282  if (fListOfBaseProxies.GetSize()) {
283 
284  TIter next(&fListOfBaseProxies);
285 
286  desc = (TBranchProxyDescriptor*)next();
287  fprintf(hf,"\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
288  wroteFirst = true;
289 
290  while ( (desc = (TBranchProxyDescriptor*)next()) ) {
291  fprintf(hf,",\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
292  }
293 
294  }
295  fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
296  wroteFirst = true;
297 
298  TString objInit = "top, mid";
299  if ( GetIsClones() == kInsideClones || GetIsClones() == kInsideSTL ) {
300  if (fListOfSubProxies.GetSize()) {
302  if (desc && desc->IsSplit()) {
303 
304  // In the case of a split sub object is TClonesArray, the
305  // object itself does not have its own branch, so we need to
306  // use its first (semantic) sub-branch as a proxy
307 
309  TString sub = desc->GetBranchName();
310  sub.Remove(0,main.Length()+1);
311 
312  objInit = "ffPrefix, ";
313  objInit += "\"";
314  objInit += sub;
315  objInit += "\"";
316 
317  objInit = "top, \"\", mid";
318  }
319  }
320  }
321 
322  fprintf(hf,"%s\n%-*s %-*s(director, %s)",
323  ",",offset," ",fMaxDatamemberType,"obj",objInit.Data());
324 
325  TIter next(&fListOfSubProxies);
326  while ( (desc = (TBranchProxyDescriptor*)next()) ) {
327  fprintf(hf,",");
329  }
330  fprintf(hf,"\n%-*s {};\n",offset," ");
331 
332 
333  // Write the 2nd constructor
334  fprintf(hf,"%-*s %s(TBranchProxyDirector* director, TBranchProxy *parent, const char *membername, const char *top=0, const char *mid=0) :",
335  offset," ", GetName());
336 
337  wroteFirst = kFALSE;
338 
339  if (fListOfBaseProxies.GetSize()) {
340 
341  TIter nextbase(&fListOfBaseProxies);
342 
343  // This is guarantee to return a non zero value due to the if (fListOfBaseProxies.GetSize())
344  desc = (TBranchProxyDescriptor*)nextbase();
345  fprintf(hf,"\n%-*s%-*s(director, parent, membername)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
346  wroteFirst = true;
347 
348  while ( (desc = (TBranchProxyDescriptor*)nextbase()) ) {
349  fprintf(hf,",\n%-*s%-*s(director, parent, membername)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
350  }
351 
352  }
353  fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
354  wroteFirst = true;
355 
356  if ( true || IsLoaded() || IsClones() || IsSTL() ) {
357  fprintf(hf,"%s\n%-*s %-*s(director, parent, membername)",
358  ",",offset," ",fMaxDatamemberType,"obj");
359  }
360 
361  next.Reset();
362  while ( (desc = (TBranchProxyDescriptor*)next()) ) {
363  fprintf(hf,",");
365  }
366  fprintf(hf,"\n%-*s {};\n",offset," ");
367 
368 
369  // Declare the data members.
370  fprintf(hf,"%-*s%-*s %s;\n", offset+3," ", fMaxDatamemberType, "ROOT::Internal::TBranchProxyHelper", "ffPrefix");
371 
372  // If the real class is available, make it available via the arrow operator:
373  if (IsLoaded()) {
374 
375  const char *type = GetTitle(); /* IsClones() ? "TClonesArray" : GetTitle(); */
376  fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
377  //Can the real type contain a leading 'const'? If so the following is incorrect.
378  if ( IsClones() ) {
379  fprintf(hf,"%-*sconst %s* operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
380  fprintf(hf,"%-*sconst %s* operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
381  fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
382  fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
383  fprintf(hf,"%-*sTClaObjProxy<%s > obj;\n", offset+3, " ", type);
384  } else if ( IsSTL() ) {
386  fprintf(hf,"%-*sconst %s& At(UInt_t i) {\n",offset+3," ",type);
389  if (cl->GetMethodWithPrototype(cl->GetName(),"TRootIOCtor*")) {
390  fprintf(hf,"%-*s static %s default_val((TRootIOCtor*)0);\n",offset+3," ",type);
391  } else {
392  fprintf(hf,"%-*s static %s default_val;\n",offset+3," ",type);
393  }
394  fprintf(hf,"%-*s if (!obj.Read()) return default_val;\n",offset+3," ");
395  if (stlCl->GetCollectionProxy()->GetValueClass() == cl) {
396  fprintf(hf,"%-*s %s *temp = & obj.GetPtr()->at(i);\n",offset+3," ",type);
397  } else {
398  fprintf(hf,"%-*s %s *temp = (%s *)( obj.GetProxy()->GetStlStart(i) );\n",offset+3," ",type,type);
399  }
400  //fprintf(hf,"%-*s %s *temp = (%s *)( obj.GetPtr()->at(i)) + obj.GetOffset() );\n",offset+3," ",type,type);
401  //fprintf(hf,"%-*s %s *temp = (%s *)(void*)(&obj.At(i));\n",offset+3," ",type,type);
402  fprintf(hf,"%-*s if (temp) return *temp; else return default_val;\n",offset+3," ");
403  fprintf(hf,"%-*s}\n",offset+3," ");
404 
405  fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return At(i); }\n", offset+3," ",type);
406  fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return At(i); }\n", offset+3," ",type);
407  fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetPtr()->size(); }\n",offset+3," ");
408  fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
409  fprintf(hf,"%-*soperator %s*() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
410  fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", fContainerName.Data());
411  } else {
412  fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
413  fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
414  fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
415  fprintf(hf,"%-*sTStlObjProxy<%s > obj;\n", offset+3, " ", type);
416  }
417  } else {
418  fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",type);
419  fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", type);
420  }
421 
422  } else if ( IsClones()) {
423 
424  fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
425  fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
426  fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
427  fprintf(hf,"%-*sTClaProxy obj;\n", offset+3," ");
428 
429  } else if ( IsSTL()) {
430 
431  fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
432  fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
433  // fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
434  fprintf(hf,"%-*sTStlProxy obj;\n", offset+3," ");
435 
436  } else {
437 
438  fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
439  fprintf(hf,"%-*sTBranchProxy obj;\n", offset+3," ");
440 
441  }
442 
443  fprintf(hf,"\n");
444 
445  next.Reset();
446  while( (desc = ( TBranchProxyDescriptor *)next()) ) {
447  desc->OutputDecl(hf,offset+3,fMaxDatamemberType);
448  }
449  fprintf(hf,"%-*s};\n",offset," ");
450 
451  //TBranchProxyDescriptor::OutputDecl(hf,offset,maxVarname);
452  }
453 
454 } // namespace Internal
455 } // namespace ROOT
virtual Bool_t IsEquivalent(const TBranchProxyClassDescriptor *other)
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
virtual TClass * GetValueClass() const =0
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:640
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:131
void OutputInit(FILE *hf, int offset, UInt_t maxVarname, const char *prefix)
#define R__ASSERT(e)
Definition: TError.h:96
Basic string class.
Definition: TString.h:129
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2814
bool Bool_t
Definition: RtypesCore.h:59
TString & Prepend(const char *cs)
Definition: TString.h:609
void AddDescriptor(TBranchProxyDescriptor *desc, Bool_t isBase)
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process&#39;s memory.
Definition: TClass.cxx:5549
void OutputDecl(FILE *hf, int offset, UInt_t maxVarname)
unsigned int UInt_t
Definition: RtypesCore.h:42
Ssiz_t Length() const
Definition: TString.h:388
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:315
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString & Remove(Ssiz_t pos)
Definition: TString.h:621
#define ClassImp(name)
Definition: Rtypes.h:336
Bool_t IsEquivalent(const TBranchProxyDescriptor *other, Bool_t inClass=kFALSE)
int type
Definition: TGX11.cxx:120
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2885
TBranchProxyClassDescriptor(const TBranchProxyClassDescriptor &b)
virtual void Add(TObject *obj)
Definition: TList.h:77
virtual Int_t GetSize() const
Definition: TCollection.h:89
Abstract Interface class describing Streamer information for one class.
TMethod * GetMethodWithPrototype(const char *method, const char *proto, Bool_t objectIsConst=kFALSE, ROOT::EFunctionMatchMode mode=ROOT::kConversionMatch)
Find the method with a given prototype.
Definition: TClass.cxx:4217
const Bool_t kTRUE
Definition: RtypesCore.h:91
int main(int argc, char **argv)
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
const char * Data() const
Definition: TString.h:347