00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "TBranchProxyDescriptor.h"
00024 #include "TBranchProxyClassDescriptor.h"
00025
00026 #include "TClass.h"
00027 #include "TClassEdit.h"
00028 #include "TError.h"
00029 #include "TVirtualStreamerInfo.h"
00030 #include "TVirtualCollectionProxy.h"
00031
00032 ClassImp(ROOT::TBranchProxyClassDescriptor);
00033
00034 namespace ROOT {
00035
00036 void TBranchProxyClassDescriptor::NameToSymbol() {
00037
00038
00039
00040
00041 fRawSymbol = TClassEdit::ShortType(GetName(),2);
00042 fRawSymbol.ReplaceAll(":","_");
00043 fRawSymbol.ReplaceAll("<","_");
00044 fRawSymbol.ReplaceAll(">","_");
00045 fRawSymbol.ReplaceAll(",","Cm");
00046 fRawSymbol.ReplaceAll(" ","");
00047 fRawSymbol.ReplaceAll("*","st");
00048 fRawSymbol.ReplaceAll("&","rf");
00049 if (IsClones())
00050 fRawSymbol.Prepend("TClaPx_");
00051 else if (IsSTL())
00052 fRawSymbol.Prepend("TStlPx_");
00053 else
00054 fRawSymbol.Prepend("TPx_");
00055 if (fRawSymbol.Length() && fRawSymbol[fRawSymbol.Length()-1]=='.')
00056 fRawSymbol.Remove(fRawSymbol.Length()-1);
00057
00058 SetName(fRawSymbol);
00059 }
00060
00061 TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *type,
00062 TVirtualStreamerInfo *info,
00063 const char *branchname,
00064 ELocation isclones,
00065 UInt_t splitlevel,
00066 const TString &containerName) :
00067 TNamed(type,type),
00068 fIsClones(isclones),
00069 fContainerName(containerName),
00070 fIsLeafList(false),
00071 fSplitLevel(splitlevel),
00072 fBranchName(branchname),
00073 fSubBranchPrefix(branchname),
00074 fInfo(info),
00075 fMaxDatamemberType(3)
00076 {
00077
00078
00079 R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
00080 NameToSymbol();
00081 if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
00082 }
00083
00084 TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *branchname) :
00085 TNamed(branchname,branchname),
00086 fIsClones(kOut),
00087 fContainerName(),
00088 fIsLeafList(true),
00089 fSplitLevel(0),
00090 fBranchName(branchname),
00091 fSubBranchPrefix(branchname),
00092 fInfo(0),
00093 fMaxDatamemberType(3)
00094 {
00095
00096
00097 NameToSymbol();
00098 if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
00099 }
00100
00101 TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *type, TVirtualStreamerInfo *info,
00102 const char *branchname,
00103 const char *branchPrefix, ELocation isclones,
00104 UInt_t splitlevel,
00105 const TString &containerName) :
00106 TNamed(type,type),
00107 fIsClones(isclones),
00108 fContainerName(containerName),
00109 fIsLeafList(true),
00110 fSplitLevel(splitlevel),
00111 fBranchName(branchname),
00112 fSubBranchPrefix(branchPrefix),
00113 fInfo(info),
00114 fMaxDatamemberType(3)
00115 {
00116
00117
00118 R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
00119 NameToSymbol();
00120 if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
00121 }
00122
00123 const char* TBranchProxyClassDescriptor::GetBranchName() const
00124 {
00125
00126 return fBranchName.Data();
00127 }
00128
00129 const char* TBranchProxyClassDescriptor::GetSubBranchPrefix() const
00130 {
00131
00132 return fSubBranchPrefix.Data();
00133 }
00134
00135 const char* TBranchProxyClassDescriptor::GetRawSymbol() const
00136 {
00137
00138
00139 return fRawSymbol;
00140 }
00141
00142 UInt_t TBranchProxyClassDescriptor::GetSplitLevel() const {
00143
00144 return fSplitLevel;
00145 }
00146
00147 Bool_t TBranchProxyClassDescriptor::IsEquivalent(const TBranchProxyClassDescriptor* other)
00148 {
00149
00150
00151 if ( !other ) return kFALSE;
00152
00153 if ( strcmp(GetTitle(),other->GetTitle()) ) return kFALSE;
00154
00155
00156
00157 if (fIsClones != other->fIsClones) return kFALSE;
00158 if (fIsClones != kOut) {
00159 if (fContainerName != other->fContainerName) return kFALSE;
00160 }
00161
00162 TBranchProxyDescriptor *desc;
00163 TBranchProxyDescriptor *othdesc;
00164
00165 if ( fListOfBaseProxies.GetSize() != other->fListOfBaseProxies.GetSize() ) return kFALSE;
00166 TIter next(&fListOfBaseProxies);
00167 TIter othnext(&other->fListOfBaseProxies);
00168 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
00169 othdesc=(TBranchProxyDescriptor*)othnext();
00170 if (!desc->IsEquivalent(othdesc,kTRUE) ) return kFALSE;
00171 }
00172
00173 if ( fListOfSubProxies.GetSize() != other->fListOfSubProxies.GetSize() ) return kFALSE;
00174 next = &fListOfSubProxies;
00175 othnext = &(other->fListOfSubProxies);
00176
00177 while ( (desc=(TBranchProxyDescriptor*)next()) ) {
00178 othdesc=(TBranchProxyDescriptor*)othnext();
00179 if (!desc->IsEquivalent(othdesc,kTRUE)) return kFALSE;
00180 if (desc->IsSplit()) {
00181 TString leftname ( desc->GetBranchName() );
00182 TString rightname( othdesc->GetBranchName() );
00183
00184 if (leftname.Index(GetBranchName())==0) leftname.Remove( 0,strlen(GetBranchName()));
00185 if (leftname.Length() && leftname[0]=='.') leftname.Remove(0,1);
00186 if (rightname.Index(other->GetBranchName())==0) rightname.Remove(0,strlen(other->GetBranchName()));
00187 if (rightname.Length() && rightname[0]=='.') rightname.Remove(0,1);
00188 if (leftname != rightname ) return kFALSE;
00189 }
00190 }
00191 return true;
00192 }
00193
00194 void TBranchProxyClassDescriptor::AddDescriptor(TBranchProxyDescriptor *desc, Bool_t isBase)
00195 {
00196
00197
00198 if (desc) {
00199 if (isBase) {
00200 fListOfBaseProxies.Add(desc);
00201 } else {
00202 fListOfSubProxies.Add(desc);
00203 UInt_t len = strlen(desc->GetTypeName());
00204 if ((len+2)>fMaxDatamemberType) fMaxDatamemberType = len+2;
00205 }
00206 }
00207 }
00208
00209 Bool_t TBranchProxyClassDescriptor::IsLoaded() const
00210 {
00211
00212 return IsLoaded(GetTitle());
00213 }
00214
00215 Bool_t TBranchProxyClassDescriptor::IsLoaded(const char *classname)
00216 {
00217
00218 TClass *cl = TClass::GetClass(classname);
00219 while (cl) {
00220 if (cl->IsLoaded()) return kTRUE;
00221 if (!cl->GetCollectionProxy()) return kFALSE;
00222 if (!cl->GetCollectionProxy()->GetValueClass()) return kTRUE;
00223 cl = cl->GetCollectionProxy()->GetValueClass();
00224 }
00225 return kFALSE;
00226 }
00227
00228 Bool_t TBranchProxyClassDescriptor::IsClones() const
00229 {
00230
00231 return fIsClones==kClones || fIsClones==kInsideClones;
00232 }
00233
00234 Bool_t TBranchProxyClassDescriptor::IsSTL() const
00235 {
00236
00237 return fIsClones==kSTL || fIsClones==kInsideSTL;
00238 }
00239
00240 TBranchProxyClassDescriptor::ELocation TBranchProxyClassDescriptor::GetIsClones() const
00241 {
00242
00243 return fIsClones;
00244 }
00245
00246 TString TBranchProxyClassDescriptor::GetContainerName() const
00247 {
00248
00249 return fContainerName;
00250 }
00251
00252 void TBranchProxyClassDescriptor::OutputDecl(FILE *hf, int offset, UInt_t )
00253 {
00254
00255
00256 TBranchProxyDescriptor *desc;
00257
00258
00259
00260 fprintf(hf,"%-*sstruct %s\n", offset," ", GetName() );
00261
00262 if (fListOfBaseProxies.GetSize()) {
00263 fprintf(hf,"%-*s : ", offset," ");
00264
00265 TIter next(&fListOfBaseProxies);
00266
00267 desc = (TBranchProxyDescriptor*)next();
00268 fprintf(hf,"public %s", desc->GetTypeName());
00269
00270 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
00271 fprintf(hf,",\n%-*spublic %s", offset+5," ", desc->GetTypeName());
00272 }
00273
00274 fprintf(hf,"\n");
00275 }
00276 fprintf(hf,"%-*s{\n", offset," ");
00277
00278
00279
00280 fprintf(hf,"%-*s %s(TBranchProxyDirector* director,const char *top,const char *mid=0) :",
00281 offset," ", GetName());
00282
00283 Bool_t wroteFirst = kFALSE;
00284
00285 if (fListOfBaseProxies.GetSize()) {
00286
00287 TIter next(&fListOfBaseProxies);
00288
00289 desc = (TBranchProxyDescriptor*)next();
00290 fprintf(hf,"\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
00291 wroteFirst = true;
00292
00293 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
00294 fprintf(hf,",\n%-*s%-*s(director, top, mid)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
00295 }
00296
00297 }
00298 fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
00299 wroteFirst = true;
00300
00301 TString objInit = "top, mid";
00302 if ( GetIsClones() == kInsideClones || GetIsClones() == kInsideSTL ) {
00303 if (fListOfSubProxies.GetSize()) {
00304 desc = (TBranchProxyDescriptor*)fListOfSubProxies.At(0);
00305 if (desc && desc->IsSplit()) {
00306
00307
00308
00309
00310
00311 TString main = GetBranchName();
00312 TString sub = desc->GetBranchName();
00313 sub.Remove(0,main.Length()+1);
00314
00315 objInit = "ffPrefix, ";
00316 objInit += "\"";
00317 objInit += sub;
00318 objInit += "\"";
00319
00320 objInit = "top, \"\", mid";
00321 }
00322 }
00323 }
00324
00325 fprintf(hf,"%s\n%-*s %-*s(director, %s)",
00326 ",",offset," ",fMaxDatamemberType,"obj",objInit.Data());
00327
00328 TIter next(&fListOfSubProxies);
00329 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
00330 fprintf(hf,",");
00331 desc->OutputInit(hf,offset,fMaxDatamemberType,GetSubBranchPrefix());
00332 }
00333 fprintf(hf,"\n%-*s {};\n",offset," ");
00334
00335
00336
00337 fprintf(hf,"%-*s %s(TBranchProxyDirector* director, TBranchProxy *parent, const char *membername, const char *top=0, const char *mid=0) :",
00338 offset," ", GetName());
00339
00340 wroteFirst = kFALSE;
00341
00342 if (fListOfBaseProxies.GetSize()) {
00343
00344 TIter nextbase(&fListOfBaseProxies);
00345
00346
00347 desc = (TBranchProxyDescriptor*)nextbase();
00348 fprintf(hf,"\n%-*s%-*s(director, parent, membername)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
00349 wroteFirst = true;
00350
00351 while ( (desc = (TBranchProxyDescriptor*)nextbase()) ) {
00352 fprintf(hf,",\n%-*s%-*s(director, parent, membername)", offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
00353 }
00354
00355 }
00356 fprintf(hf,"%s\n%-*s %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
00357 wroteFirst = true;
00358
00359 if ( true || IsLoaded() || IsClones() || IsSTL() ) {
00360 fprintf(hf,"%s\n%-*s %-*s(director, parent, membername)",
00361 ",",offset," ",fMaxDatamemberType,"obj");
00362 }
00363
00364 next.Reset();
00365 while ( (desc = (TBranchProxyDescriptor*)next()) ) {
00366 fprintf(hf,",");
00367 desc->OutputInit(hf,offset,fMaxDatamemberType,GetSubBranchPrefix());
00368 }
00369 fprintf(hf,"\n%-*s {};\n",offset," ");
00370
00371
00372
00373 fprintf(hf,"%-*s%-*s %s;\n", offset+3," ", fMaxDatamemberType, "TBranchProxyHelper", "ffPrefix");
00374
00375
00376 if (IsLoaded()) {
00377
00378 const char *type = GetTitle();
00379 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
00380
00381 if ( IsClones() ) {
00382 fprintf(hf,"%-*sconst %s* operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
00383 fprintf(hf,"%-*sconst %s* operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
00384 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
00385 fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
00386 fprintf(hf,"%-*sTClaObjProxy<%s > obj;\n", offset+3, " ", type);
00387 } else if ( IsSTL() ) {
00388 if (fContainerName.Length() && IsLoaded(fContainerName)) {
00389 fprintf(hf,"%-*sconst %s& At(UInt_t i) {\n",offset+3," ",type);
00390 TClass *stlCl = TClass::GetClass(fContainerName);
00391 TClass *cl = TClass::GetClass(GetTitle());
00392 if (cl->GetMethodWithPrototype(cl->GetName(),"TRootIOCtor*")) {
00393 fprintf(hf,"%-*s static %s default_val((TRootIOCtor*)0);\n",offset+3," ",type);
00394 } else {
00395 fprintf(hf,"%-*s static %s default_val;\n",offset+3," ",type);
00396 }
00397 fprintf(hf,"%-*s if (!obj.Read()) return default_val;\n",offset+3," ");
00398 if (stlCl->GetCollectionProxy()->GetValueClass() == cl) {
00399 fprintf(hf,"%-*s %s *temp = & obj.GetPtr()->at(i);\n",offset+3," ",type);
00400 } else {
00401 fprintf(hf,"%-*s %s *temp = (%s *)( obj.GetProxy()->GetStlStart(i) );\n",offset+3," ",type,type);
00402 }
00403
00404
00405 fprintf(hf,"%-*s if (temp) return *temp; else return default_val;\n",offset+3," ");
00406 fprintf(hf,"%-*s}\n",offset+3," ");
00407
00408 fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return At(i); }\n", offset+3," ",type);
00409 fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return At(i); }\n", offset+3," ",type);
00410 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetPtr()->size(); }\n",offset+3," ");
00411 fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
00412 fprintf(hf,"%-*soperator %s*() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
00413 fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", fContainerName.Data());
00414 } else {
00415 fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
00416 fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
00417 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
00418 fprintf(hf,"%-*sTStlObjProxy<%s > obj;\n", offset+3, " ", type);
00419 }
00420 } else {
00421 fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",type);
00422 fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", type);
00423 }
00424
00425 } else if ( IsClones()) {
00426
00427 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
00428 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
00429 fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
00430 fprintf(hf,"%-*sTClaProxy obj;\n", offset+3," ");
00431
00432 } else if ( IsSTL()) {
00433
00434 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
00435 fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
00436
00437 fprintf(hf,"%-*sTStlProxy obj;\n", offset+3," ");
00438
00439 } else {
00440
00441 fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
00442 fprintf(hf,"%-*sTBranchProxy obj;\n", offset+3," ");
00443
00444 }
00445
00446 fprintf(hf,"\n");
00447
00448 next.Reset();
00449 while( (desc = ( TBranchProxyDescriptor *)next()) ) {
00450 desc->OutputDecl(hf,offset+3,fMaxDatamemberType);
00451 }
00452 fprintf(hf,"%-*s};\n",offset," ");
00453
00454
00455 }
00456
00457 }