Logo ROOT   6.16/01
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
13Hold the processed information about a TClass used in a TBranch while
14TTreeProxyGenerator is parsing the TTree information.
15Also contains the routine use to generate the appropriate code
16fragment in the result of MakeProxy.
17*/
18
21
22#include "TClass.h"
23#include "TClassEdit.h"
24#include "TError.h"
27
29
30namespace ROOT {
31namespace 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) :
65 fIsClones(isclones),
66 fContainerName(containerName),
67 fIsLeafList(false),
68 fSplitLevel(splitlevel),
69 fBranchName(branchname),
70 fSubBranchPrefix(branchname),
71 fInfo(info),
72 fMaxDatamemberType(3)
73 {
74 // Constructor.
75
76 R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
79 }
80
82 TNamed(branchname,branchname),
83 fIsClones(kOut),
84 fContainerName(),
85 fIsLeafList(true),
86 fSplitLevel(0),
87 fBranchName(branchname),
88 fSubBranchPrefix(branchname),
89 fInfo(0),
90 fMaxDatamemberType(3)
91 {
92 // Constructor for a branch constructed from a leaf list.
93
96 }
97
99 const char *branchname,
100 const char *branchPrefix, ELocation isclones,
101 UInt_t splitlevel,
102 const TString &containerName) :
104 fIsClones(isclones),
105 fContainerName(containerName),
106 fIsLeafList(true),
107 fSplitLevel(splitlevel),
108 fBranchName(branchname),
109 fSubBranchPrefix(branchPrefix),
110 fInfo(info),
111 fMaxDatamemberType(3)
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;
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) {
198 } else {
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.
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
260 fprintf(hf,"%-*s : ", offset," ");
261
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
283
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 ) {
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
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
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
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:363
#define R__ASSERT(e)
Definition: TError.h:96
int type
Definition: TGX11.cxx:120
TBranchProxyClassDescriptor(const TBranchProxyClassDescriptor &b)
void AddDescriptor(TBranchProxyDescriptor *desc, Bool_t isBase)
virtual Bool_t IsEquivalent(const TBranchProxyClassDescriptor *other)
void OutputDecl(FILE *hf, int offset, UInt_t maxVarname)
void OutputInit(FILE *hf, int offset, UInt_t maxVarname, const char *prefix)
Bool_t IsEquivalent(const TBranchProxyDescriptor *other, Bool_t inClass=kFALSE)
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:75
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:4309
Bool_t IsLoaded() const
Return true if the shared library of this class is currently in the a process's memory.
Definition: TClass.cxx:5674
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
Definition: TClass.cxx:2814
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
virtual Int_t GetSize() const
Return the capacity of the collection, i.e.
Definition: TCollection.h:182
void Reset()
Definition: TCollection.h:252
virtual void Add(TObject *obj)
Definition: TList.h:87
virtual TObject * At(Int_t idx) const
Returns the object at position idx. Returns 0 if idx is out of range.
Definition: TList.cxx:354
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
const char * Data() const
Definition: TString.h:364
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:687
TString & Prepend(const char *cs)
Definition: TString.h:656
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
virtual TClass * GetValueClass() const =0
Abstract Interface class describing Streamer information for one class.
int main(int argc, char **argv)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
std::string ShortType(const char *typeDesc, int mode)
Return the absolute type of typeDesc.