#include "TBranchProxyDescriptor.h"
#include "TBranchProxyClassDescriptor.h"
#include "TClass.h"
#include "TClassEdit.h"
#include "TError.h"
#include "TVirtualStreamerInfo.h"
#include "TVirtualCollectionProxy.h"
ClassImp(ROOT::TBranchProxyClassDescriptor);
namespace ROOT {
   void TBranchProxyClassDescriptor::NameToSymbol() {
      
      
      fRawSymbol = TClassEdit::ShortType(GetName(),2); 
      fRawSymbol.ReplaceAll(":","_");
      fRawSymbol.ReplaceAll("<","_");
      fRawSymbol.ReplaceAll(">","_");
      fRawSymbol.ReplaceAll(" ","");
      fRawSymbol.ReplaceAll("*","st");
      fRawSymbol.ReplaceAll("&","rf");
      if (IsClones())
         fRawSymbol.Prepend("TClaPx_");
      else if (IsSTL()) 
         fRawSymbol.Prepend("TStlPx_");
      else
         fRawSymbol.Prepend("TPx_");
      if (fRawSymbol.Length() && fRawSymbol[fRawSymbol.Length()-1]=='.')
         fRawSymbol.Remove(fRawSymbol.Length()-1);
      SetName(fRawSymbol);
   }
   TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *type,
                                                            TVirtualStreamerInfo *info,
                                                            const char *branchname,
                                                            ELocation isclones,
                                                            UInt_t splitlevel,
                                                            const TString &containerName) :
      TNamed(type,type),
      fIsClones(isclones),
      fContainerName(containerName),
      fIsLeafList(false),
      fSplitLevel(splitlevel),
      fBranchName(branchname),
      fSubBranchPrefix(branchname),
      fInfo(info),
      fMaxDatamemberType(3)
   {
      
      R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
      NameToSymbol();
      if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
   }
   TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *branchname) :
      TNamed(branchname,branchname),
      fIsClones(kOut),
      fContainerName(),
      fIsLeafList(true),
      fSplitLevel(0),
      fBranchName(branchname),
      fSubBranchPrefix(branchname),
      fInfo(0),
      fMaxDatamemberType(3)
   {
      
      NameToSymbol();
      if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
   }
   TBranchProxyClassDescriptor::TBranchProxyClassDescriptor(const char *type, TVirtualStreamerInfo *info,
                                                            const char *branchname,
                                                            const char *branchPrefix, ELocation isclones,
                                                            UInt_t splitlevel,
                                                            const TString &containerName) :
      TNamed(type,type),
      fIsClones(isclones),
      fContainerName(containerName),
      fIsLeafList(true),
      fSplitLevel(splitlevel),
      fBranchName(branchname),
      fSubBranchPrefix(branchPrefix),
      fInfo(info),
      fMaxDatamemberType(3)
   {
      
      R__ASSERT( strcmp(fInfo->GetName(), type)==0 );
      NameToSymbol();
      if (fSubBranchPrefix.Length() && fSubBranchPrefix[fSubBranchPrefix.Length()-1]=='.') fSubBranchPrefix.Remove(fSubBranchPrefix.Length()-1);
   }
   const char* TBranchProxyClassDescriptor::GetBranchName() const
   {
      
      return fBranchName.Data();
   }
   const char* TBranchProxyClassDescriptor::GetSubBranchPrefix() const
   {
      
      return fSubBranchPrefix.Data();
   }
   const char* TBranchProxyClassDescriptor::GetRawSymbol() const
   {
      
      return fRawSymbol;
   }
   UInt_t TBranchProxyClassDescriptor::GetSplitLevel() const {
      
      return fSplitLevel;
   }
   Bool_t TBranchProxyClassDescriptor::IsEquivalent(const TBranchProxyClassDescriptor* other)
   {
      
      if ( !other ) return kFALSE;
      
      if ( strcmp(GetTitle(),other->GetTitle()) ) return kFALSE;
      
      
      if (fIsClones != other->fIsClones) return kFALSE;
      if (fIsClones != kOut) {
         if (fContainerName != other->fContainerName) return kFALSE;
      }
      TBranchProxyDescriptor *desc;
      TBranchProxyDescriptor *othdesc;
      if ( fListOfBaseProxies.GetSize() != other->fListOfBaseProxies.GetSize() ) return kFALSE;
      TIter next(&fListOfBaseProxies);
      TIter othnext(&other->fListOfBaseProxies);
      while ( (desc=(TBranchProxyDescriptor*)next()) ) {
         othdesc=(TBranchProxyDescriptor*)othnext();
         if (!desc->IsEquivalent(othdesc,kTRUE) ) return kFALSE;
      }
      if ( fListOfSubProxies.GetSize() != other->fListOfSubProxies.GetSize() ) return kFALSE;
      next = &fListOfSubProxies;
      othnext = &(other->fListOfSubProxies);
      while ( (desc=(TBranchProxyDescriptor*)next()) ) {
         othdesc=(TBranchProxyDescriptor*)othnext();
         if (!desc->IsEquivalent(othdesc,kTRUE)) return kFALSE;
         if (desc->IsSplit()) {
            TString leftname (  desc->GetBranchName() );
            TString rightname(  othdesc->GetBranchName() );
            if (leftname.Index(GetBranchName())==0) leftname.Remove( 0,strlen(GetBranchName()));
            if (leftname.Length() && leftname[0]=='.') leftname.Remove(0,1);
            if (rightname.Index(other->GetBranchName())==0) rightname.Remove(0,strlen(other->GetBranchName()));
            if (rightname.Length() && rightname[0]=='.') rightname.Remove(0,1);
            if (leftname != rightname ) return kFALSE;
         }
      }
      return true;
   }
   void TBranchProxyClassDescriptor::AddDescriptor(TBranchProxyDescriptor *desc, Bool_t isBase)
   {
      
      if (desc) {
         if (isBase) {
            fListOfBaseProxies.Add(desc);
         } else {
            fListOfSubProxies.Add(desc);
            UInt_t len = strlen(desc->GetTypeName());
            if ((len+2)>fMaxDatamemberType) fMaxDatamemberType = len+2;
         }
      }
   }
   Bool_t TBranchProxyClassDescriptor::IsLoaded() const
   {
      
      return IsLoaded(GetTitle());
   }
      
   Bool_t TBranchProxyClassDescriptor::IsLoaded(const char *classname)
   {
      
      TClass *cl = TClass::GetClass(classname);
      while (cl) {
         if (cl->IsLoaded()) return kTRUE;
         if (!cl->GetCollectionProxy()) return kFALSE;
         if (!cl->GetCollectionProxy()->GetValueClass()) return kTRUE; 
         cl = cl->GetCollectionProxy()->GetValueClass();
      }
      return kFALSE;
   }
   Bool_t TBranchProxyClassDescriptor::IsClones() const
   {
      
      return fIsClones==kClones || fIsClones==kInsideClones;
   }
   Bool_t TBranchProxyClassDescriptor::IsSTL() const
   {
      
      return fIsClones==kSTL || fIsClones==kInsideSTL;
   }
   TBranchProxyClassDescriptor::ELocation TBranchProxyClassDescriptor::GetIsClones() const
   {
      
      return fIsClones;
   }
   TString TBranchProxyClassDescriptor::GetContainerName() const
   {
      
      return fContainerName;
   }
   void TBranchProxyClassDescriptor::OutputDecl(FILE *hf, int offset, UInt_t )
   {
      
      TBranchProxyDescriptor *desc;
      
      fprintf(hf,"%-*sstruct %s\n", offset," ", GetName() );
      if (fListOfBaseProxies.GetSize()) {
         fprintf(hf,"%-*s   : ", offset," ");
         TIter next(&fListOfBaseProxies);
         desc = (TBranchProxyDescriptor*)next();
         fprintf(hf,"public %s", desc->GetTypeName());
         while ( (desc = (TBranchProxyDescriptor*)next()) ) {
            fprintf(hf,",\n%-*spublic %s", offset+5," ", desc->GetTypeName());
         }
         fprintf(hf,"\n");
      }
      fprintf(hf,"%-*s{\n", offset," ");
      
      fprintf(hf,"%-*s   %s(TBranchProxyDirector* director,const char *top,const char *mid=0) :",
              offset," ", GetName());
      Bool_t wroteFirst = kFALSE;
      if (fListOfBaseProxies.GetSize()) {
         TIter next(&fListOfBaseProxies);
         desc = (TBranchProxyDescriptor*)next();
         fprintf(hf,"\n%-*s%-*s(director, top, mid)",  offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
         wroteFirst = true;
         while ( (desc = (TBranchProxyDescriptor*)next()) ) {
            fprintf(hf,",\n%-*s%-*s(director, top, mid)",  offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
         }
      }
      fprintf(hf,"%s\n%-*s      %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
      wroteFirst = true;
      TString objInit = "top, mid";
      if ( GetIsClones() == kInsideClones || GetIsClones() == kInsideSTL ) {
         if (fListOfSubProxies.GetSize()) {
            desc = (TBranchProxyDescriptor*)fListOfSubProxies.At(0);
            if (desc && desc->IsSplit()) {
               
               
               
               TString main = GetBranchName();
               TString sub = desc->GetBranchName();
               sub.Remove(0,main.Length()+1);
               objInit  = "ffPrefix, ";
               objInit += "\"";
               objInit += sub;
               objInit += "\"";
               objInit = "top, \"\", mid";
            }
         }
      }
      fprintf(hf,"%s\n%-*s      %-*s(director, %s)",
              wroteFirst?",":"",offset," ",fMaxDatamemberType,"obj",objInit.Data());
      wroteFirst = true;
      TIter next(&fListOfSubProxies);
      while ( (desc = (TBranchProxyDescriptor*)next()) ) {
         if (wroteFirst) fprintf(hf,",");
         desc->OutputInit(hf,offset,fMaxDatamemberType,GetSubBranchPrefix());
         wroteFirst = true;
      }
      fprintf(hf,"\n%-*s   {};\n",offset," ");
      
      fprintf(hf,"%-*s   %s(TBranchProxyDirector* director, TBranchProxy *parent, const char *membername, const char *top=0, const char *mid=0) :",
              offset," ", GetName());
      wroteFirst = kFALSE;
      if (fListOfBaseProxies.GetSize()) {
         TIter next(&fListOfBaseProxies);
         desc = (TBranchProxyDescriptor*)next();
         fprintf(hf,"\n%-*s%-*s(director, parent, membername)",  offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
         wroteFirst = true;
         while ( (desc = (TBranchProxyDescriptor*)next()) ) {
            fprintf(hf,",\n%-*s%-*s(director, parent, membername)",  offset+6, " ", fMaxDatamemberType,desc->GetTypeName());
         }
      }
      fprintf(hf,"%s\n%-*s      %-*s(top,mid)",wroteFirst?",":"",offset," ",fMaxDatamemberType,"ffPrefix");
      wroteFirst = true;
      if ( true ||  IsLoaded() || IsClones() || IsSTL() ) {
         fprintf(hf,"%s\n%-*s      %-*s(director, parent, membername)",
                 wroteFirst?",":"",offset," ",fMaxDatamemberType,"obj");
         wroteFirst = true;
      }
      next = &fListOfSubProxies;
      while ( (desc = (TBranchProxyDescriptor*)next()) ) {
         if (wroteFirst) fprintf(hf,",");
         desc->OutputInit(hf,offset,fMaxDatamemberType,GetSubBranchPrefix());
         wroteFirst = true;
      }
      fprintf(hf,"\n%-*s   {};\n",offset," ");
      
      fprintf(hf,"%-*s%-*s %s;\n",  offset+3," ",  fMaxDatamemberType, "TBranchProxyHelper", "ffPrefix");
      
      if (IsLoaded()) {
         const char *type = GetTitle(); 
         fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
         
         if ( IsClones() ) {
            fprintf(hf,"%-*sconst %s* operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
            fprintf(hf,"%-*sconst %s* operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
            fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
            fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
            fprintf(hf,"%-*sTClaObjProxy<%s > obj;\n", offset+3, " ", type);
         } else if ( IsSTL() ) {
            if (fContainerName.Length() && IsLoaded(fContainerName)) {
               fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return obj.GetPtr()->at(i); }\n", offset+3," ",type);
               fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return obj.GetPtr()->at(i); }\n", offset+3," ",type);
               fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetPtr()->size(); }\n",offset+3," ");
               fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
               fprintf(hf,"%-*soperator %s*() { return obj.GetPtr(); }\n", offset+3," ",fContainerName.Data());
               fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", fContainerName.Data());
            } else {
               fprintf(hf,"%-*sconst %s& operator[](Int_t i) { return obj.At(i); }\n", offset+3," ",type);
               fprintf(hf,"%-*sconst %s& operator[](UInt_t i) { return obj.At(i); }\n", offset+3," ",type);
               fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
               fprintf(hf,"%-*sTStlObjProxy<%s > obj;\n", offset+3, " ", type);
            }
         } else {
            fprintf(hf,"%-*sconst %s* operator->() { return obj.GetPtr(); }\n", offset+3," ",type);
            fprintf(hf,"%-*sTObjProxy<%s > obj;\n", offset+3, " ", type);
         }
      } else if ( IsClones()) {
         fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
         fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
         fprintf(hf,"%-*sconst TClonesArray* operator->() { return obj.GetPtr(); }\n", offset+3," ");
         fprintf(hf,"%-*sTClaProxy obj;\n", offset+3," ");
      } else if ( IsSTL()) {
         fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
         fprintf(hf,"%-*sInt_t GetEntries() { return obj.GetEntries(); }\n",offset+3," ");
         
         fprintf(hf,"%-*sTStlProxy obj;\n", offset+3," ");
      } else {
         fprintf(hf,"%-*sInjecTBranchProxyInterface();\n", offset+3," ");
         fprintf(hf,"%-*sTBranchProxy obj;\n", offset+3," ");
      }
      fprintf(hf,"\n");
      next.Reset();
      while( (desc = ( TBranchProxyDescriptor *)next()) ) {
         desc->OutputDecl(hf,offset+3,fMaxDatamemberType);
      }
      fprintf(hf,"%-*s};\n",offset," ");
      
   }
}
Last update: Thu Jan 17 08:43:02 2008
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.