#include "TBranchElement.h"
#include "TBasket.h"
#include "TBranchObject.h"
#include "TBranchRef.h"
#include "TBrowser.h"
#include "TClass.h"
#include "TClassEdit.h"
#include "TClonesArray.h"
#include "TDataMember.h"
#include "TDataType.h"
#include "TError.h"
#include "TMath.h"
#include "TFile.h"
#include "TFolder.h"
#include "TLeafElement.h"
#include "TRealData.h"
#include "TStreamerElement.h"
#include "TStreamerInfo.h"
#include "TTree.h"
#include "TVirtualCollectionProxy.h"
#include "TVirtualCollectionIterators.h"
#include "TVirtualMutex.h"
#include "TVirtualPad.h"
#include "TBranchSTL.h"
#include "TVirtualArray.h"
#include "TBufferFile.h"
#include "TInterpreter.h"
#include "TROOT.h"
#include "TStreamerInfoActions.h"
#include "TSchemaRuleSet.h"
ClassImp(TBranchElement)
#if (__GNUC__ >= 3) || defined(__INTEL_COMPILER)
#if !defined(R__unlikely)
#define R__unlikely(expr) __builtin_expect(!!(expr), 0)
#endif
#if !defined(R__likely)
#define R__likely(expr) __builtin_expect(!!(expr), 1)
#endif
#else
#define R__unlikely(expr) expr
#define R__likely(expr) expr
#endif
namespace {
void RemovePrefix(TString& str, const char* prefix) {
if (str.Length() && prefix && strlen(prefix)) {
if (!str.Index(prefix)) {
str.Remove(0, strlen(prefix));
}
}
}
struct R__PushCache {
TBufferFile &fBuffer;
TVirtualArray *fOnfileObject;
R__PushCache(TBufferFile &b, TVirtualArray *in, UInt_t size) : fBuffer(b), fOnfileObject(in) {
if (fOnfileObject) {
fOnfileObject->SetSize(size);
fBuffer.PushDataCache( fOnfileObject );
}
}
~R__PushCache() {
if (fOnfileObject) fBuffer.PopDataCache();
}
};
}
void TBranchElement::SwitchContainer(TObjArray* branches) {
const Int_t nbranches = branches->GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* br = (TBranchElement*) branches->At(i);
switch (br->GetType()) {
case 31: br->SetType(41); break;
case 41: {
br->SetType(31);
br->fCollProxy = 0;
break;
}
}
br->SetReadLeavesPtr();
br->SetFillLeavesPtr();
SwitchContainer(br->GetListOfBranches());
}
}
namespace {
Bool_t CanSelfReference(TClass *cl) {
if (cl) {
if (cl->GetCollectionProxy()) {
TClass *inside = cl->GetCollectionProxy()->GetValueClass();
if (inside) {
return CanSelfReference(inside);
} else {
return kFALSE;
}
}
static TClassRef stringClass("std::string");
if (cl == stringClass || cl == TString::Class()) {
return kFALSE;
}
return kTRUE;
}
return kFALSE;
}
}
TBranchElement::TBranchElement()
: TBranch()
, fClassName()
, fParentName()
, fClonesName()
, fCollProxy(0)
, fCheckSum(0)
, fClassVersion(0)
, fID(0)
, fType(0)
, fStreamerType(-1)
, fMaximum(0)
, fSTLtype(TClassEdit::kNotSTL)
, fNdata(1)
, fBranchCount(0)
, fBranchCount2(0)
, fInfo(0)
, fObject(0)
, fOnfileObject(0)
, fInit(kFALSE)
, fInitOffsets(kFALSE)
, fTargetClass()
, fCurrentClass()
, fParentClass()
, fBranchClass()
, fClonesClass()
, fBranchOffset(0)
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
fNleaves = 0;
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesImpl;
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesImpl;
}
TBranchElement::TBranchElement(TTree *tree, const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
: TBranch()
, fClassName(sinfo->GetName())
, fParentName()
, fClonesName()
, fCollProxy(0)
, fCheckSum(sinfo->GetCheckSum())
, fClassVersion(sinfo->GetClass()->GetClassVersion())
, fID(id)
, fType(0)
, fStreamerType(-1)
, fMaximum(0)
, fSTLtype(TClassEdit::kNotSTL)
, fNdata(1)
, fBranchCount(0)
, fBranchCount2(0)
, fInfo(sinfo)
, fObject(0)
, fOnfileObject(0)
, fInit(kTRUE)
, fInitOffsets(kFALSE)
, fTargetClass(fClassName)
, fCurrentClass()
, fParentClass()
, fBranchClass(sinfo->GetClass())
, fClonesClass()
, fBranchOffset(0)
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(tree, 0, bname,sinfo,id,pointer,basketsize,splitlevel,btype);
}
TBranchElement::TBranchElement(TBranch *parent, const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
: TBranch()
, fClassName(sinfo->GetName())
, fParentName()
, fClonesName()
, fCollProxy(0)
, fCheckSum(sinfo->GetCheckSum())
, fClassVersion(sinfo->GetClass()->GetClassVersion())
, fID(id)
, fType(0)
, fStreamerType(-1)
, fMaximum(0)
, fSTLtype(TClassEdit::kNotSTL)
, fNdata(1)
, fBranchCount(0)
, fBranchCount2(0)
, fInfo(sinfo)
, fObject(0)
, fOnfileObject(0)
, fInit(kTRUE)
, fInitOffsets(kFALSE)
, fTargetClass( fClassName )
, fCurrentClass()
, fParentClass()
, fBranchClass(sinfo->GetClass())
, fClonesClass()
, fBranchOffset(0)
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(parent ? parent->GetTree() : 0, parent, bname,sinfo,id,pointer,basketsize,splitlevel,btype);
}
void TBranchElement::Init(TTree *tree, TBranch *parent,const char* bname, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize, Int_t splitlevel, Int_t btype)
{
TString name(bname);
SetName(name);
SetTitle(name);
fSplitLevel = splitlevel;
fTree = tree;
if (fTree == 0) return;
fMother = parent ? parent->GetMother() : this;
fParent = parent;
fDirectory = fTree->GetDirectory();
fFileName = "";
SetAutoDelete(kFALSE);
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesImpl;
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesImpl;
Int_t splitSTLP = splitlevel - (splitlevel%TTree::kSplitCollectionOfPointers);
splitlevel %= TTree::kSplitCollectionOfPointers;
fCompress = -1;
if (fTree->GetDirectory()) {
TFile* bfile = fTree->GetDirectory()->GetFile();
if (bfile) {
fCompress = bfile->GetCompressionSettings();
}
}
if (id > -1) {
TStreamerElement* element = sinfo->GetElement(id);
fStreamerType = element->GetType();
}
fEntryOffsetLen = 0;
if (btype || (fStreamerType <= TVirtualStreamerInfo::kBase) || (fStreamerType == TVirtualStreamerInfo::kCharStar) || (fStreamerType == TVirtualStreamerInfo::kBits) || (fStreamerType > TVirtualStreamerInfo::kFloat16)) {
fEntryOffsetLen = fTree->GetDefaultEntryOffsetLen();
}
if (basketsize < (100 + fEntryOffsetLen)) {
basketsize = 100 + fEntryOffsetLen;
}
fBasketSize = basketsize;
fBasketBytes = new Int_t[fMaxBaskets];
fBasketEntry = new Long64_t[fMaxBaskets];
fBasketSeek = new Long64_t[fMaxBaskets];
for (Int_t i = 0; i < fMaxBaskets; ++i) {
fBasketBytes[i] = 0;
fBasketEntry[i] = 0;
fBasketSeek[i] = 0;
}
TBranchElement* brOfCounter = 0;
if (id < 0) {
if (fBranchClass.GetClass()) {
Bool_t hasCustomStreamer = kFALSE;
Bool_t canSelfReference = CanSelfReference(fBranchClass);
if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
if (canSelfReference) SetBit(kBranchObject);
hasCustomStreamer = (!fBranchClass.GetClass()->GetCollectionProxy() && (gCint->ClassInfo_RootFlag(fBranchClass.GetClass()->GetClassInfo()) & 1));
} else {
if (canSelfReference) SetBit(kBranchAny);
hasCustomStreamer = !fBranchClass.GetClass()->GetCollectionProxy() && (fBranchClass.GetClass()->GetStreamer() != 0 || (gCint->ClassInfo_RootFlag(fBranchClass.GetClass()->GetClassInfo()) & 1));
}
if (hasCustomStreamer) {
fType = -1;
}
}
} else {
TStreamerElement* element = sinfo->GetElement(id);
if ((fStreamerType == TVirtualStreamerInfo::kObject) || (fStreamerType == TVirtualStreamerInfo::kBase) || (fStreamerType == TVirtualStreamerInfo::kTNamed) || (fStreamerType == TVirtualStreamerInfo::kTObject) || (fStreamerType == TVirtualStreamerInfo::kObjectp) || (fStreamerType == TVirtualStreamerInfo::kObjectP)) {
if (CanSelfReference(fBranchClass)) {
if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
SetBit(kBranchObject);
} else {
SetBit(kBranchAny);
}
}
}
if (element->IsA() == TStreamerBasicPointer::Class()) {
TStreamerBasicPointer *bp = (TStreamerBasicPointer *)element;
TString countname;
countname = bname;
Ssiz_t dot = countname.Last('.');
if (dot>=0) {
countname.Remove(dot+1);
} else {
countname = "";
}
countname += bp->GetCountName();
brOfCounter = (TBranchElement *)fTree->GetBranch(countname);
countname.Form("%s[%s]",name.Data(),bp->GetCountName());
SetTitle(countname);
} else if (element->IsA() == TStreamerLoop::Class()) {
TStreamerLoop *bp = (TStreamerLoop *)element;
TString countname;
countname = bname;
Ssiz_t dot = countname.Last('.');
if (dot>=0) {
countname.Remove(dot+1);
} else {
countname = "";
}
countname += bp->GetCountName();
brOfCounter = (TBranchElement *)fTree->GetBranch(countname);
countname.Form("%s[%s]",name.Data(),bp->GetCountName());
SetTitle(countname);
}
if (splitlevel > 0) {
const char* elem_type = element->GetTypeName();
fSTLtype = TMath::Abs(TClassEdit::IsSTLCont(elem_type));
if (element->CannotSplit()) {
fSplitLevel = 0;
} else if (element->IsA() == TStreamerBase::Class()) {
fType = 1;
TClass* clOfElement = TClass::GetClass(element->GetName());
Int_t nbranches = fBranches.GetEntriesFast();
if (!strcmp(name, clOfElement->GetName())) {
Unroll("", fBranchClass.GetClass(), clOfElement, pointer, basketsize, splitlevel+splitSTLP, 0);
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
Unroll(name, clOfElement, clOfElement, pointer, basketsize, splitlevel+splitSTLP, 0);
if (strchr(bname, '.')) {
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
if (nbranches == fBranches.GetEntriesFast()) {
if (strlen(bname)) {
name.Form("%s.%s", bname, clOfElement->GetName());
} else {
name.Form("%s", clOfElement->GetName());
}
SetName(name);
SetTitle(name);
}
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
} else if (element->GetClassPointer() == TClonesArray::Class()) {
Bool_t ispointer = element->IsaPointer();
TClonesArray *clones;
if (ispointer) {
char **ppointer = (char**)(pointer);
clones = (TClonesArray*)(*ppointer);
} else {
clones = (TClonesArray*)pointer;
}
fEntryOffsetLen = 0;
TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
if (!clones) {
SetFillLeavesPtr();
return;
}
TClass* clOfClones = clones->GetClass();
if (!clOfClones) {
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
fType = 3;
fClonesName = clOfClones->GetName();
fClonesClass = clOfClones;
TString aname;
aname.Form(" (%s)", clOfClones->GetName());
TString atitle = element->GetTitle();
if (!atitle.Contains(aname)) {
atitle += aname;
element->SetTitle(atitle.Data());
}
TString branchname( name );
branchname += "_";
SetTitle(branchname);
leaf->SetName(branchname);
leaf->SetTitle(branchname);
Unroll(name, clOfClones, clOfClones, pointer, basketsize, splitlevel+splitSTLP, 31);
BuildTitle(name);
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
} else if (((fSTLtype >= TClassEdit::kVector) && (fSTLtype < TClassEdit::kEnd)) || ((fSTLtype > -TClassEdit::kEnd) && (fSTLtype <= -TClassEdit::kVector))) {
TClass* contCl = TClass::GetClass(elem_type);
fCollProxy = contCl->GetCollectionProxy()->Generate();
TClass* valueClass = GetCollectionProxy()->GetValueClass();
Bool_t cansplit = kTRUE;
if (!valueClass) {
cansplit = kFALSE;
} else if ((valueClass == TString::Class()) || (valueClass == TClass::GetClass("string"))) {
cansplit = kFALSE;
} else if (GetCollectionProxy()->HasPointers() && !splitSTLP ) {
cansplit = kFALSE;
} else if (!valueClass->CanSplit() && !(GetCollectionProxy()->HasPointers() && splitSTLP)) {
cansplit = kFALSE;
} else if (valueClass->GetCollectionProxy()) {
cansplit = kFALSE;
}
if (cansplit) {
fType = 4;
TLeaf *leaf = new TLeafElement(this, name, fID, fStreamerType);
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
fClonesName = valueClass->GetName();
fClonesClass = valueClass;
TString aname;
aname.Form(" (%s)", valueClass->GetName());
TString atitle = element->GetTitle();
if (!atitle.Contains(aname)) {
atitle += aname;
element->SetTitle(atitle.Data());
}
TString branchname (name);
branchname += "_";
SetTitle(branchname);
leaf->SetName(branchname);
leaf->SetTitle(branchname);
Unroll(name, valueClass, valueClass, pointer, basketsize, splitlevel+splitSTLP, 41);
BuildTitle(name);
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
} else if (!strchr(elem_type, '*') && ((fStreamerType == TVirtualStreamerInfo::kObject) || (fStreamerType == TVirtualStreamerInfo::kAny))) {
fType = 2;
TClass* clm = TClass::GetClass(elem_type);
Int_t err = Unroll(name, clm, clm, pointer, basketsize, splitlevel+splitSTLP, 0);
if (err >= 0) {
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
}
}
}
TLeaf* leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
leaf->SetTitle(GetTitle());
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
if (brOfCounter) {
SetBranchCount(brOfCounter);
}
SetReadLeavesPtr();
SetFillLeavesPtr();
}
TBranchElement::TBranchElement(TTree *tree, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
, fClassName("TClonesArray")
, fParentName()
, fInfo((TStreamerInfo*)TClonesArray::Class()->GetStreamerInfo())
, fTargetClass( fClassName )
, fCurrentClass()
, fParentClass()
, fBranchClass(TClonesArray::Class())
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(tree, 0, bname, clones, basketsize, splitlevel, compress);
}
TBranchElement::TBranchElement(TBranch *parent, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
, fClassName("TClonesArray")
, fParentName()
, fInfo((TStreamerInfo*)TClonesArray::Class()->GetStreamerInfo())
, fTargetClass( fClassName )
, fCurrentClass()
, fParentClass()
, fBranchClass(TClonesArray::Class())
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(parent ? parent->GetTree() : 0, parent, bname, clones, basketsize, splitlevel, compress);
}
void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TClonesArray* clones, Int_t basketsize, Int_t splitlevel, Int_t compress)
{
fCollProxy = 0;
fSplitLevel = splitlevel;
fID = 0;
fInit = kTRUE;
fStreamerType = -1;
fType = 0;
fClassVersion = TClonesArray::Class()->GetClassVersion();
fCheckSum = fInfo->GetCheckSum();
fBranchCount = 0;
fBranchCount2 = 0;
fObject = 0;
fOnfileObject = 0;
fMaximum = 0;
fBranchOffset = 0;
fSTLtype = TClassEdit::kNotSTL;
fInitOffsets = kFALSE;
fTree = tree;
fMother = parent ? parent->GetMother() : this;
fParent = parent;
fDirectory = fTree->GetDirectory();
fFileName = "";
SetName(bname);
const char* name = GetName();
SetTitle(name);
fCompress = compress;
if (compress == -1 && fTree->GetDirectory()) {
TFile *bfile = fTree->GetDirectory()->GetFile();
if (bfile) fCompress = bfile->GetCompressionSettings();
}
if (basketsize < 100) basketsize = 100;
fBasketSize = basketsize;
fBasketBytes = new Int_t[fMaxBaskets];
fBasketEntry = new Long64_t[fMaxBaskets];
fBasketSeek = new Long64_t[fMaxBaskets];
for (Int_t i=0;i<fMaxBaskets;i++) {
fBasketBytes[i] = 0;
fBasketEntry[i] = 0;
fBasketSeek[i] = 0;
}
SetAutoDelete(kFALSE);
if (splitlevel%TTree::kSplitCollectionOfPointers > 0) {
TClass* clonesClass = clones->GetClass();
if (!clonesClass) {
Error("Init","Missing class object of the TClonesArray %s\n",clones->GetName());
return;
}
fType = 3;
TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
fClonesName = clonesClass->GetName();
fClonesClass = clonesClass;
std::string branchname = name + std::string("_");
SetTitle(branchname.c_str());
leaf->SetName(branchname.c_str());
leaf->SetTitle(branchname.c_str());
Unroll(name, clonesClass, clonesClass, 0, basketsize, splitlevel, 31);
BuildTitle(name);
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
if (!clones->GetClass() || CanSelfReference(clones->GetClass())) {
SetBit(kBranchObject);
}
TLeaf *leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
leaf->SetTitle(GetTitle());
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
SetReadLeavesPtr();
SetFillLeavesPtr();
}
TBranchElement::TBranchElement(TTree *tree, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
, fClassName(cont->GetCollectionClass()->GetName())
, fParentName()
, fTargetClass( fClassName )
, fCurrentClass()
, fParentClass()
, fBranchClass(cont->GetCollectionClass())
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(tree, 0, bname, cont, basketsize, splitlevel, compress);
}
TBranchElement::TBranchElement(TBranch *parent, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
: TBranch()
, fClassName(cont->GetCollectionClass()->GetName())
, fParentName()
, fTargetClass( fClassName )
, fCurrentClass()
, fParentClass()
, fBranchClass(cont->GetCollectionClass())
, fBranchID(-1)
, fReadActionSequence(0)
, fFillActionSequence(0)
, fIterators(0)
, fWriteIterators(0)
, fPtrIterators(0)
{
Init(parent ? parent->GetTree() : 0, parent, bname, cont, basketsize, splitlevel, compress);
}
void TBranchElement::Init(TTree *tree, TBranch *parent, const char* bname, TVirtualCollectionProxy* cont, Int_t basketsize, Int_t splitlevel, Int_t compress)
{
fCollProxy = cont->Generate();
TString name( bname );
if (name[name.Length()-1]=='.') {
name.Remove(name.Length()-1);
}
fInitOffsets = kFALSE;
fSplitLevel = splitlevel;
fInfo = 0;
fID = -1;
fInit = kTRUE;
fStreamerType = -1;
fType = 0;
fClassVersion = cont->GetCollectionClass()->GetClassVersion();
fCheckSum = cont->GetCollectionClass()->GetCheckSum();
fBranchCount = 0;
fBranchCount2 = 0;
fObject = 0;
fOnfileObject = 0;
fMaximum = 0;
fBranchOffset = 0;
fSTLtype = cont->GetCollectionType();
if (fSTLtype < 0) {
fSTLtype = -fSTLtype;
}
fTree = tree;
fMother = parent ? parent->GetMother() : this;
fParent = parent;
fDirectory = fTree->GetDirectory();
fFileName = "";
SetName(name);
SetTitle(name);
fCompress = compress;
if ((compress == -1) && fTree->GetDirectory()) {
TFile* bfile = fTree->GetDirectory()->GetFile();
if (bfile) {
fCompress = bfile->GetCompressionSettings();
}
}
if (basketsize < 100) {
basketsize = 100;
}
fBasketSize = basketsize;
fBasketBytes = new Int_t[fMaxBaskets];
fBasketEntry = new Long64_t[fMaxBaskets];
fBasketSeek = new Long64_t[fMaxBaskets];
for (Int_t i = 0; i < fMaxBaskets; ++i) {
fBasketBytes[i] = 0;
fBasketEntry[i] = 0;
fBasketSeek[i] = 0;
}
SetAutoDelete(kFALSE);
if ( (splitlevel%TTree::kSplitCollectionOfPointers > 0 && fBranchClass.GetClass() && fBranchClass.GetClass()->CanSplit()) ||
(cont->HasPointers() && splitlevel > TTree::kSplitCollectionOfPointers && cont->GetValueClass() && cont->GetValueClass()->CanSplit() ) )
{
fType = 4;
TLeaf* leaf = new TLeafElement(this, name, fID, fStreamerType);
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
TClass* valueClass = cont->GetValueClass();
if (!valueClass) {
return;
}
fClonesName = valueClass->GetName();
fClonesClass = valueClass;
TString branchname( name );
branchname += "_";
SetTitle(branchname);
leaf->SetName(branchname);
leaf->SetTitle(branchname);
Unroll(name, valueClass, valueClass, 0, basketsize, splitlevel, 41);
BuildTitle(name);
SetReadLeavesPtr();
SetFillLeavesPtr();
return;
}
TLeaf *leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
leaf->SetTitle(GetTitle());
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
SetReadLeavesPtr();
SetFillLeavesPtr();
}
TBranchElement::~TBranchElement()
{
if (fOnfileObject && TestBit(kOwnOnfileObj)) {
delete fOnfileObject;
fOnfileObject = 0;
}
ResetAddress();
delete[] fBranchOffset;
fBranchOffset = 0;
fInfo = 0;
fBranchCount2 = 0;
fBranchCount = 0;
if (fType == 4 || fType == 0) {
delete fCollProxy;
}
fCollProxy = 0;
delete fReadActionSequence;
delete fFillActionSequence;
delete fIterators;
delete fWriteIterators;
delete fPtrIterators;
}
inline TStreamerInfo* TBranchElement::GetInfoImp() const
{
if (!fInfo || (fInfo && (!fInit || !fInfo->IsCompiled()))) {
const_cast<TBranchElement*>(this)->InitInfo();
}
return fInfo;
}
TStreamerInfo* TBranchElement::GetInfo() const
{
return GetInfoImp();
}
void TBranchElement::Browse(TBrowser* b)
{
Int_t nbranches = fBranches.GetEntriesFast();
if (nbranches > 0) {
TList persistentBranches;
TBranch* branch=0;
TIter iB(&fBranches);
while((branch=(TBranch*)iB())) {
if (branch->IsFolder()) persistentBranches.Add(branch);
else {
TClass* cl=0;
if (strlen(GetClonesName()))
cl=fClonesClass;
else {
cl=TClass::GetClass(GetClassName());
TStreamerElement *element=0;
TClass* clsub=0;
if (fID>=0 && GetInfoImp()
&& GetInfoImp()->IsCompiled()
&& ((element=GetInfoImp()->GetElement(fID)))
&& ((clsub=element->GetClassPointer())))
cl=clsub;
}
if (cl) {
TString strMember=branch->GetName();
Size_t mempos=strMember.Last('.');
if (mempos!=kNPOS)
strMember.Remove(0, (Int_t)mempos+1);
mempos=strMember.First('[');
if (mempos!=kNPOS)
strMember.Remove((Int_t)mempos);
TDataMember* m=cl->GetDataMember(strMember);
if (!m || m->IsPersistent()) persistentBranches.Add(branch);
} else persistentBranches.Add(branch);
}
}
persistentBranches.Browse(b);
if (GetBrowsables() && GetBrowsables()->GetSize())
GetBrowsables()->Browse(b);
} else {
if (GetBrowsables() && GetBrowsables()->GetSize()) {
GetBrowsables()->Browse(b);
return;
}
TString slash("/");
TString escapedSlash("\\/");
TString name = GetName();
Int_t pos = name.First('[');
if (pos != kNPOS) {
name.Remove(pos);
}
TString mothername;
if (GetMother()) {
mothername = GetMother()->GetName();
pos = mothername.First('[');
if (pos != kNPOS) {
mothername.Remove(pos);
}
Int_t len = mothername.Length();
if (len) {
if (mothername(len-1) != '.') {
TString doublename = mothername;
doublename.Append(".");
Int_t isthere = (name.Index(doublename) == 0);
if (!isthere) {
name.Prepend(doublename);
} else {
if (GetMother()->FindBranch(mothername)) {
doublename.Append(mothername);
isthere = (name.Index(doublename) == 0);
if (!isthere) {
mothername.Append(".");
name.Prepend(mothername);
}
} else {
}
}
} else {
if (name.Index(mothername) == kNPOS) {
name.Prepend(mothername);
}
}
}
}
name.ReplaceAll(slash, escapedSlash);
GetTree()->Draw(name, "", b ? b->GetDrawOption() : "");
if (gPad) {
gPad->Update();
}
}
}
void TBranchElement::BuildTitle(const char* name)
{
TString branchname;
Int_t nbranches = fBranches.GetEntries();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* bre = (TBranchElement*) fBranches.At(i);
if (fType == 3) {
bre->SetType(31);
} else if (fType == 4) {
bre->SetType(41);
} else {
Error("BuildTitle", "This cannot happen, fType of parent is not 3 or 4!");
}
bre->fCollProxy = GetCollectionProxy();
bre->BuildTitle(name);
const char* fin = strrchr(bre->GetTitle(), '.');
if (fin == 0) {
continue;
}
bre->SetBranchCount(this);
TLeafElement* lf = (TLeafElement*) bre->GetListOfLeaves()->At(0);
branchname = fin+1;
Ssiz_t dim = branchname.First('[');
if (dim>=0) {
branchname.Remove(dim);
}
branchname += TString::Format("[%s_]",name);
bre->SetTitle(branchname);
if (lf) {
lf->SetTitle(branchname);
}
Int_t stype = bre->GetStreamerType();
if ((stype > 40) && (stype < 61)) {
TString name2 (bre->GetName());
Ssiz_t bn = name2.Last('.');
if (bn<0) {
continue;
}
TStreamerBasicPointer *el = (TStreamerBasicPointer*)bre->GetInfoImp()->GetElements()->FindObject(name2.Data()+bn+1);
name2.Remove(bn+1);
if (el) name2 += el->GetCountName();
TBranchElement *bc2 = (TBranchElement*)fBranches.FindObject(name2);
bre->SetBranchCount2(bc2);
}
bre->SetReadLeavesPtr();
bre->SetFillLeavesPtr();
}
}
Int_t TBranchElement::Fill()
{
Int_t nbytes = 0;
Int_t nwrite = 0;
Int_t nerror = 0;
Int_t nbranches = fBranches.GetEntriesFast();
ValidateAddress();
if (fID < 0) {
if (!fObject) {
Error("Fill", "attempt to fill branch %s while addresss is not set", GetName());
return 0;
}
}
if ((fType >= -1) && (fType < 10)) {
TBranchRef* bref = fTree->GetBranchRef();
if (bref) {
fBranchID = bref->SetParent(this, fBranchID);
}
}
if (!nbranches) {
if (!TestBit(kDoNotProcess)) {
nwrite = TBranch::Fill();
if (nwrite < 0) {
Error("Fill", "Failed filling branch:%s, nbytes=%d", GetName(), nwrite);
++nerror;
} else {
nbytes += nwrite;
}
}
} else {
if (fType == 3 || fType == 4) {
nwrite = TBranch::Fill();
if (nwrite < 0) {
Error("Fill", "Failed filling branch:%s, nbytes=%d", GetName(), nwrite);
++nerror;
} else {
nbytes += nwrite;
}
} else {
++fEntries;
}
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* branch = (TBranchElement*) fBranches[i];
if (!branch->TestBit(kDoNotProcess)) {
nwrite = branch->Fill();
if (nwrite < 0) {
Error("Fill", "Failed filling branch:%s.%s, nbytes=%d", GetName(), branch->GetName(), nwrite);
nerror++;
} else {
nbytes += nwrite;
}
}
}
}
if (fTree->Debug() > 0) {
Long64_t entry = fEntries;
if ((entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
printf("Fill: %lld, branch=%s, nbytes=%d\n", entry, GetName(), nbytes);
}
}
if (nerror != 0) {
return -1;
}
return nbytes;
}
void TBranchElement::FillLeavesMakeClass(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
if(fType ==3) {
TVirtualStreamerInfo* si = fClonesClass->GetStreamerInfo();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s' class '%s'", GetName(), fClonesClass->GetName());
return;
}
b.ForceWriteInfo(si,kFALSE);
Int_t* nptr = (Int_t*) fAddress;
b << *nptr;
} else if (fType == 31) {
if (!fAddress) {
return;
}
Int_t atype = fStreamerType;
if (atype > 54) {
return;
}
Int_t* nn = (Int_t*) fBranchCount->GetAddress();
if (!nn) {
Error("FillLeaves", "The branch counter address was zero!");
return;
}
Int_t n = *nn;
if (atype > 40) {
Error("FillLeaves", "Clonesa: %s, n=%d, sorry not supported yet", GetName(), n);
return;
}
if (atype > 20) {
atype -= 20;
TLeafElement* leaf = (TLeafElement*) fLeaves.UncheckedAt(0);
n = n * leaf->GetLenStatic();
}
switch (atype) {
case TVirtualStreamerInfo::kChar : { b.WriteFastArray((Char_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kShort : { b.WriteFastArray((Short_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kInt : { b.WriteFastArray((Int_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kLong : { b.WriteFastArray((Long_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kFloat : { b.WriteFastArray((Float_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kCounter : { b.WriteFastArray((Int_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kDouble : { b.WriteFastArray((Double_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kDouble32 : {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = si->GetElement(fID);
Double_t* xx = (Double_t*) fAddress;
for (Int_t ii = 0; ii < n; ++ii) {
b.WriteDouble32(&(xx[ii]),se);
}
break;
}
case TVirtualStreamerInfo::kFloat16 : {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
Float_t* xx = (Float_t*) fAddress;
for (Int_t ii = 0; ii < n; ++ii) {
b.WriteFloat16(&(xx[ii]),se);
}
break;
}
case TVirtualStreamerInfo::kUChar : { b.WriteFastArray((UChar_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kUShort : { b.WriteFastArray((UShort_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kUInt : { b.WriteFastArray((UInt_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kULong : { b.WriteFastArray((ULong_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kBits : { b.WriteFastArray((UInt_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kLong64 : { b.WriteFastArray((Long64_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kULong64 : { b.WriteFastArray((ULong64_t*) fAddress, n); break; }
case TVirtualStreamerInfo::kBool : { b.WriteFastArray((Bool_t*) fAddress, n); break; }
}
}
}
void TBranchElement::FillLeavesCollection(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TVirtualCollectionProxy* proxy = GetCollectionProxy();
Int_t n = 0;
TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
n = proxy->Size();
if (n > fMaximum) {
fMaximum = n;
}
b << n;
if(fSTLtype != TClassEdit::kVector && proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators->CreateIterators(fObject, proxy);
} else {
if (proxy->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fWriteIterators->CreateIterators(fObject, proxy);
} else {
fIterators->CreateIterators(fObject, proxy);
}
}
}
void TBranchElement::FillLeavesCollectionSplitVectorPtrMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
TVirtualCollectionIterators *iter = fBranchCount->fIterators;
R__ASSERT(0!=iter);
b.ApplySequenceVecPtr(*fFillActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::FillLeavesCollectionSplitPtrMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
TVirtualCollectionPtrIterators *iter = fBranchCount->fPtrIterators;
b.ApplySequence(*fFillActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::FillLeavesCollectionMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
TVirtualCollectionIterators *iter = fBranchCount->fIterators;
R__ASSERT(0!=iter);
b.ApplySequence(*fFillActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::FillLeavesAssociativeCollectionMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(), fObject);
TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
TVirtualCollectionIterators *iter = fBranchCount->fWriteIterators;
R__ASSERT(0!=iter);
b.ApplySequence(*fFillActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::FillLeavesClones(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TClonesArray* clones = (TClonesArray*) fObject;
Int_t n = clones->GetEntriesFast();
if (n > fMaximum) {
fMaximum = n;
}
b << n;
}
void TBranchElement::FillLeavesClonesMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TClonesArray* clones = (TClonesArray*) fObject;
Int_t n = clones->GetEntriesFast();
TStreamerInfo* si = (TStreamerInfo*)GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
char **arr = (char **)clones->GetObjectRef(0);
char **end = arr + n;
b.ApplySequenceVecPtr(*fFillActionSequence,arr,end);
}
void TBranchElement::FillLeavesCustomStreamer(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
if (TestBit(kBranchObject)) {
b.MapObject((TObject*) fObject);
} else if (TestBit(kBranchAny)) {
b.MapObject(fObject, fBranchClass);
}
fBranchClass->Streamer(fObject,b);
}
void TBranchElement::FillLeavesMemberBranchCount(TBuffer& b)
{
FillLeavesMember(b);
}
void TBranchElement::FillLeavesMemberCounter(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
TStreamerInfo* si = GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
b.ApplySequence(*fFillActionSequence, fObject);
Int_t n = *(Int_t*)(fObject + si->TStreamerInfo::GetElementOffset(fID));
if (n > fMaximum) {
fMaximum = n;
}
}
void TBranchElement::FillLeavesMember(TBuffer& b)
{
ValidateAddress();
if (!fObject) {
return;
}
if (TestBit(kBranchObject)) {
b.MapObject((TObject*) fObject);
} else if (TestBit(kBranchAny)) {
b.MapObject(fObject, fBranchClass);
}
TStreamerInfo* si = GetInfoImp();
if (!si) {
Error("FillLeaves", "Cannot get streamer info for branch '%s'", GetName());
return;
}
b.ApplySequence(*fFillActionSequence, fObject);
}
static void R__CleanName(std::string &name)
{
if (name[name.length()-1]==']') {
std::size_t dim = name.find_first_of("[");
if (dim != std::string::npos) {
name.erase(dim);
}
}
if (name[name.size()-1] != '.') {
name += '.';
}
}
TBranch* TBranchElement::FindBranch(const char *name)
{
if (fID >= 0) {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = si->GetElement(fID);
if (se && se->IsBase()) {
UInt_t len = strlen(name);
std::string longnm;
longnm.reserve(fName.Length()+len+3);
longnm = fName.Data();
R__CleanName(longnm);
longnm += name;
std::string longnm_parent;
longnm_parent.reserve(fName.Length()+len+3);
longnm_parent = (GetMother()->GetSubBranch(this)->GetName());
R__CleanName(longnm_parent);
longnm_parent += name;
UInt_t namelen = strlen(name);
TBranch* branch = 0;
Int_t nbranches = fBranches.GetEntries();
for(Int_t i = 0; i < nbranches; ++i) {
branch = (TBranch*) fBranches.UncheckedAt(i);
const char *brname = branch->GetName();
UInt_t brlen = strlen(brname);
if (brname[brlen-1]==']') {
const char *dim = strchr(brname,'[');
if (dim) {
brlen = dim - brname;
}
}
if (namelen == brlen
&& strncmp(name,brname,brlen) == 0) {
return branch;
}
if (brlen == longnm.length()
&& strncmp(longnm.c_str(),brname,brlen) == 0) {
return branch;
}
if (brlen == longnm_parent.length()
&& strncmp(longnm_parent.c_str(),brname,brlen) == 0) {
return branch;
}
if (namelen>brlen && name[brlen]=='.' && strncmp(name,brname,brlen)==0) {
return branch->FindBranch(name+brlen+1);
}
}
}
}
TBranch *result = TBranch::FindBranch(name);
if (!result) {
Int_t nbranches = fBranches.GetEntries();
for(Int_t i = 0; i < nbranches; ++i) {
TObject *obj = fBranches.UncheckedAt(i);
if(obj->IsA() != TBranchElement :: Class() )
continue;
TBranchElement *br = (TBranchElement*)obj;
TVirtualStreamerInfo* si = br->GetInfoImp();
if (si && br->GetID() >= 0) {
TStreamerElement* se = si->GetElement(br->GetID());
if (se && se->IsBase()) {
result = br->FindBranch(name);
}
}
}
}
return result;
}
TLeaf* TBranchElement::FindLeaf(const char *name)
{
TLeaf *leaf = TBranch::FindLeaf(name);
if (leaf==0 && GetListOfLeaves()->GetEntries()==1) {
TBranch *br = GetMother()->GetSubBranch( this );
if( br->IsA() != TBranchElement::Class() )
return 0;
TBranchElement *parent = (TBranchElement*)br;
if (parent==this || parent->GetID()<0 ) return 0;
TVirtualStreamerInfo* si = parent->GetInfoImp();
TStreamerElement* se = si->GetElement(parent->GetID());
if (! se->IsBase() ) return 0;
br = GetMother()->GetSubBranch( parent );
if( br->IsA() != TBranchElement::Class() )
return 0;
TBranchElement *grand_parent = (TBranchElement*)br;
std::string longname( grand_parent->GetName() );
R__CleanName(longname);
longname += name;
std::string leafname( GetListOfLeaves()->At(0)->GetName() );
if ( longname == leafname ) {
return (TLeaf*)GetListOfLeaves()->At(0);
}
}
return leaf;
}
char* TBranchElement::GetAddress() const
{
ValidateAddress();
return fAddress;
}
void TBranchElement::InitInfo()
{
if (!fInfo) {
TClass* cl = fBranchClass.GetClass();
TClass* targetClass = 0;
if( fTargetClass.GetClassName()[0] ) {
targetClass = fTargetClass;
if (!targetClass && GetCollectionProxy()) {
targetClass = fTargetClass;
}
if ( !targetClass ) {
Error( "InitInfo", "The target class dictionary is not present!" );
return;
}
} else {
targetClass = cl;
}
if (cl) {
{
if ( (cl->Property() & kIsAbstract) && cl == targetClass) {
TBranchElement *parent = (TBranchElement*)GetMother()->GetSubBranch(this);
if (parent && parent != this && !parent->GetClass()->IsLoaded() ) {
TString target = cl->GetName();
target += "@@emulated";
fTargetClass.SetName(target);
if (!fTargetClass) {
cl->GetStreamerInfoAbstractEmulated(fClassVersion);
}
targetClass = fTargetClass;
}
}
if( targetClass != cl ) {
fInfo = (TStreamerInfo*)targetClass->GetConversionStreamerInfo( cl, fClassVersion );
} else {
fInfo = (TStreamerInfo*)cl->GetStreamerInfo(fClassVersion);
}
}
R__LOCKGUARD(gCINTMutex);
if (fCheckSum && (cl->IsForeign() || (!cl->IsLoaded() && (fClassVersion == 1) && cl->GetStreamerInfos()->At(1) && (fCheckSum != ((TVirtualStreamerInfo*) cl->GetStreamerInfos()->At(1))->GetCheckSum())))) {
TStreamerInfo* info;
if( targetClass != cl )
info = (TStreamerInfo*)targetClass->GetConversionStreamerInfo( cl, fCheckSum );
else {
info = (TStreamerInfo*)cl->FindStreamerInfo( fCheckSum );
if (info) {
info = (TStreamerInfo*)cl->GetStreamerInfo(info->GetClassVersion());
}
}
if( info ) {
fInfo = info;
}
}
}
}
if (fInfo) {
if (!fInfo->IsCompiled()) {
Error("InitInfo","StreamerInfo is not compiled.");
}
if (!fInit) {
if (GetID() > -1) {
std::string s(GetName());
size_t pos = s.rfind('.');
if (pos != std::string::npos) {
s = s.substr(pos+1);
}
while ((pos = s.rfind('[')) != std::string::npos) {
s = s.substr(0, pos);
}
int offset = 0;
TStreamerElement* elt = fInfo->GetStreamerElement(s.c_str(), offset);
if (elt && offset!=TStreamerInfo::kMissing) {
size_t ndata = fInfo->GetNelement();
fIDs.clear();
for (size_t i = 0; i < ndata; ++i) {
if (fInfo->GetElement(i) == elt) {
if (elt->TestBit (TStreamerElement::kCache)
&& (i+1) < ndata
&& s == fInfo->GetElement(i)->GetName())
{
fID = i;
if (elt->TestBit(TStreamerElement::kRepeat)) {
fIDs.push_back(fID+1);
} else if (fInfo->GetElement(i+1)->TestBit(TStreamerElement::kWrite)) {
fIDs.push_back(fID+1);
}
} else {
fID = i;
}
if (elt->TestBit (TStreamerElement::kCache)) {
SetBit(TBranchElement::kCache);
}
break;
}
}
for (size_t i = fID+1+(fIDs.size()); i < ndata; ++i) {
TStreamerElement *nextel = fInfo->GetElement(i);
if (fType==31||fType==41) {
if (nextel->GetType() == TStreamerInfo::kObject
|| nextel->GetType() == TStreamerInfo::kAny) {
continue;
}
}
if (nextel->GetOffset() == TStreamerInfo::kMissing) {
continue;
}
if (nextel->IsA() != TStreamerArtificial::Class()
|| nextel->GetType() == TStreamerInfo::kCacheDelete ) {
break;
}
fIDs.push_back(i);
}
} else if (elt && offset==TStreamerInfo::kMissing) {
fIDs.clear();
size_t ndata = fInfo->GetNelement();
for (size_t i = 0; i < ndata; ++i) {
if (fInfo->GetElement(i) == elt) {
fID = i;
break;
}
}
} else {
}
if (fOnfileObject==0 && (fType==31 || fType==41 || (0 <= fType && fType <=2) ) && fInfo->GetNelement()
&& fInfo->GetElement(0)->GetType() == TStreamerInfo::kCacheNew)
{
Int_t arrlen = 1;
if (fType==31 || fType==41) {
TLeaf *leaf = (TLeaf*)fLeaves.At(0);
if (leaf) {
arrlen = leaf->GetMaximum();
}
}
fOnfileObject = new TVirtualArray( fInfo->GetElement(0)->GetClassPointer(), arrlen );
TObjArray *branches = GetMother()->GetSubBranch(this)->GetListOfBranches();
Int_t nbranches = branches->GetEntriesFast();
TBranchElement *lastbranch = this;
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* subbranch = (TBranchElement*)branches->At(i);
if (this!=subbranch && subbranch->fBranchClass == fBranchClass && subbranch->fCheckSum == fCheckSum) {
subbranch->fOnfileObject = fOnfileObject;
lastbranch = subbranch;
}
}
lastbranch->SetBit(kOwnOnfileObj);
}
}
fInit = kTRUE;
SetReadActionSequence();
SetFillActionSequence();
} else if (!fReadActionSequence) {
SetReadActionSequence();
SetFillActionSequence();
}
SetReadLeavesPtr();
SetFillLeavesPtr();
}
}
TVirtualCollectionProxy* TBranchElement::GetCollectionProxy()
{
if (fCollProxy) {
return fCollProxy;
}
TBranchElement* thiscast = const_cast<TBranchElement*>(this);
if (fType == 4) {
const char* className = 0;
if (fID < 0) {
if (fBranchClass.GetClass()) {
className = fBranchClass.GetClass()->GetName();
}
} else {
TVirtualStreamerInfo* si = thiscast->GetInfoImp();
TStreamerElement* se = si->GetElement(fID);
className = se->GetTypeName();
}
TClass* cl = TClass::GetClass(className);
if (!cl) {
if (fID < 0) {
cl = new TClass(fBranchClass.GetClassName(), fClassVersion, 0, 0, -1, -1);
cl->SetBit(TClass::kIsEmulation);
className = cl->GetName();
} else {
cl = new TClass(className, fClassVersion, 0, 0, -1, -1);
cl->SetBit(TClass::kIsEmulation);
}
}
TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
if (!proxy) {
TString equiv;
equiv.Form("vector<%s>",fClonesName.Data());
TClass *clequiv = TClass::GetClass(equiv);
proxy = clequiv->GetCollectionProxy();
if (!proxy) {
Fatal("GetCollectionProxy",
"Can not create a Collection Proxy of any kind for the class \"%s\" needed by the branch \"%s\" of the TTree \"%s\"!",
className, GetName(), GetTree()->GetName());
}
if (gDebug > 0) Info("GetCollectionProxy",
"Fixing the collection proxy of the class \"%s\" \n"
"\tneeded by the branch \"%s\" of the TTree \"%s\" to be similar to \"%s\".",
className, GetName(), GetTree()->GetName(),equiv.Data());
cl->CopyCollectionProxy( *proxy );
}
fCollProxy = proxy->Generate();
fSTLtype = className ? TClassEdit::IsSTLCont(className) : 0;
if (fSTLtype < 0) {
fSTLtype = -fSTLtype;
}
} else if (fType == 41) {
thiscast->fCollProxy = fBranchCount->GetCollectionProxy();
}
return fCollProxy;
}
TClass* TBranchElement::GetCurrentClass()
{
TClass* cl = fCurrentClass;
if (cl) {
return cl;
}
TStreamerInfo* brInfo = (TStreamerInfo*)GetInfoImp();
if (!brInfo) {
cl = TClass::GetClass(GetClassName());
R__ASSERT(cl && cl->GetCollectionProxy());
fCurrentClass = cl;
return cl;
}
TClass* motherCl = brInfo->GetClass();
if (motherCl->GetCollectionProxy()) {
cl = motherCl->GetCollectionProxy()->GetCollectionClass();
if (cl) {
fCurrentClass = cl;
}
return cl;
}
if (GetID() < 0 || GetID()>=brInfo->GetNelement()) {
return 0;
}
TStreamerElement* currentStreamerElement = brInfo->GetElement(GetID());
TDataMember* dm = (TDataMember*) motherCl->GetListOfDataMembers()->FindObject(currentStreamerElement->GetName());
TString newType;
if (!dm) {
if (!motherCl->IsLoaded()) {
TVirtualStreamerInfo* newInfo = motherCl->GetStreamerInfo();
if (newInfo != brInfo) {
TStreamerElement* newElems = (TStreamerElement*) newInfo->GetElements()->FindObject(currentStreamerElement->GetName());
if (newElems) {
newType = newElems->GetClassPointer()->GetName();
}
}
if (newType.Length()==0) {
newType = currentStreamerElement->GetClassPointer()->GetName();
}
}
} else {
newType = dm->GetTypeName();
}
cl = TClass::GetClass(newType);
if (cl) {
fCurrentClass = cl;
}
return cl;
}
Int_t TBranchElement::GetEntry(Long64_t entry, Int_t getall)
{
fReadEntry = entry;
TBranchRef* bref = fTree->GetBranchRef();
if (R__unlikely(bref)) {
fBranchID = bref->SetParent(this, fBranchID);
bref->SetRequestedEntry(entry);
}
Int_t nbytes = 0;
if (R__unlikely(IsAutoDelete())) {
SetBit(kDeleteObject);
SetAddress(fAddress);
} else {
if (R__unlikely(!fAddress && !fTree->GetMakeClass())) {
SetupAddressesImpl();
}
}
Int_t nbranches = fBranches.GetEntriesFast();
if (nbranches) {
if ((fType == 3) || (fType == 4)) {
Int_t nb = TBranch::GetEntry(entry, getall);
if (nb < 0) {
return nb;
}
nbytes += nb;
}
switch(fSTLtype) {
case TClassEdit::kSet:
case TClassEdit::kMultiSet:
case TClassEdit::kMap:
case TClassEdit::kMultiMap:
break;
default:
ValidateAddress();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* branch = (TBranch*) fBranches.UncheckedAt(i);
Int_t nb = branch->GetEntry(entry, getall);
if (nb < 0) {
return nb;
}
nbytes += nb;
}
break;
}
} else {
if (fBranchCount && (fBranchCount->GetReadEntry() != entry)) {
Int_t nb = fBranchCount->TBranch::GetEntry(entry, getall);
if (nb < 0) {
return nb;
}
nbytes += nb;
}
Int_t nb = TBranch::GetEntry(entry, getall);
if (nb < 0) {
return nb;
}
nbytes += nb;
}
if (R__unlikely(fTree->Debug() > 0)) {
if ((entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
Info("GetEntry", "%lld, branch=%s, nbytes=%d", entry, GetName(), nbytes);
}
}
return nbytes;
}
Int_t TBranchElement::GetExpectedType(TClass *&expectedClass,EDataType &expectedType)
{
expectedClass = 0;
expectedType = kOther_t;
Int_t type = GetStreamerType();
if ((type == -1) || (fID == -1)) {
expectedClass = fBranchClass;
} else {
TStreamerElement* element = GetInfoImp()->GetElement(fID);
if (element) {
expectedClass = element->GetClassPointer();
if (!expectedClass) {
TDataType* data = gROOT->GetType(element->GetTypeNameBasic());
if (!data) {
Error("GetExpectedType", "Did not find the type number for %s", element->GetTypeNameBasic());
return 1;
} else {
expectedType = (EDataType) data->GetType();
}
}
} else {
Error("GetExpectedType", "Did not find the type for %s",GetName());
return 2;
}
}
return 0;
}
const char* TBranchElement::GetIconName() const
{
if (IsFolder()) {
return "TBranchElement-folder";
} else {
return "TBranchElement-leaf";
}
}
Bool_t TBranchElement::GetMakeClass() const
{
return TestBit(kDecomposedObj);
}
Int_t TBranchElement::GetMaximum() const
{
if (fBranchCount) {
return fBranchCount->GetMaximum();
}
return fMaximum;
}
char* TBranchElement::GetObject() const
{
ValidateAddress();
return fObject;
}
TClass* TBranchElement::GetParentClass()
{
return fParentClass.GetClass();
}
const char* TBranchElement::GetTypeName() const
{
if (fType == 3 || fType == 4) {
return "Int_t";
}
if ((fStreamerType < 1) || (fStreamerType > 59)) {
if (fBranchClass.GetClass()) {
if (fID>=0) {
return GetInfoImp()->GetElement(fID)->GetTypeName();
} else {
return fBranchClass.GetClass()->GetName();
}
} else {
return 0;
}
}
const char *types[20] = {
"",
"Char_t",
"Short_t",
"Int_t",
"Long_t",
"Float_t",
"Int_t",
"char*",
"Double_t",
"Double32_t",
"",
"UChar_t",
"UShort_t",
"UInt_t",
"ULong_t",
"UInt_t",
"Long64_t",
"ULong64_t",
"Bool_t",
"Float16_t"
};
Int_t itype = fStreamerType % 20;
return types[itype];
}
template Double_t TBranchElement::GetTypedValue(Int_t j, Int_t len, Bool_t subarr) const;
template Long64_t TBranchElement::GetTypedValue(Int_t j, Int_t len, Bool_t subarr) const;
template LongDouble_t TBranchElement::GetTypedValue(Int_t j, Int_t len, Bool_t subarr) const;
template <typename T>
T TBranchElement::GetTypedValue(Int_t j, Int_t len, Bool_t subarr) const
{
ValidateAddress();
Int_t prID = fID;
char *object = fObject;
if (TestBit(kCache)) {
if (GetInfoImp()->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
prID = fID+1;
} else if (fOnfileObject) {
object = fOnfileObject->GetObjectAt(0);
}
}
if (!j && fBranchCount) {
Long64_t entry = fTree->GetReadEntry();
if (entry != fBranchCount->GetReadEntry()) {
fBranchCount->TBranch::GetEntry(entry);
}
if (fBranchCount2 && entry != fBranchCount2->GetReadEntry()) {
fBranchCount2->TBranch::GetEntry(entry);
}
}
if (fTree->GetMakeClass()) {
if (!fAddress) {
return 0;
}
if ((fType == 3) || (fType == 4)) {
return fNdata;
} else if ((fType == 31) || (fType == 41)) {
Int_t atype = fStreamerType;
if (atype < 20) {
atype += 20;
}
return GetInfoImp()->GetTypedValue<T>(fAddress, atype, j, 1);
} else if (fType <= 2) {
if ((fStreamerType > 40) && (fStreamerType < 55)) {
Int_t atype = fStreamerType - 20;
return GetInfoImp()->GetTypedValue<T>(fAddress, atype, j, 1);
} else {
return GetInfoImp()->GetTypedValue<T>(object, prID, j, -1);
}
}
}
if (object == 0)
{
return 0;
}
if (fType == 31) {
TClonesArray* clones = (TClonesArray*) object;
if (subarr) {
return GetInfoImp()->GetTypedValueClones<T>(clones, prID, j, len, fOffset);
}
return GetInfoImp()->GetTypedValueClones<T>(clones, prID, j/len, j%len, fOffset);
} else if (fType == 41) {
TVirtualCollectionProxy::TPushPop helper(((TBranchElement*) this)->GetCollectionProxy(), object);
if( fSplitLevel < TTree::kSplitCollectionOfPointers )
{
if (subarr)
return GetInfoImp()->GetTypedValueSTL<T>(((TBranchElement*) this)->GetCollectionProxy(), prID, j, len, fOffset);
return GetInfoImp()->GetTypedValueSTL<T>(((TBranchElement*) this)->GetCollectionProxy(), prID, j/len, j%len, fOffset);
}
else
{
if (subarr)
return GetInfoImp()->GetTypedValueSTLP<T>(((TBranchElement*) this)->GetCollectionProxy(), prID, j, len, fOffset);
return GetInfoImp()->GetTypedValueSTLP<T>(((TBranchElement*) this)->GetCollectionProxy(), prID, j/len, j%len, fOffset);
}
} else {
if (GetInfoImp()) {
return GetInfoImp()->GetTypedValue<T>(object, prID, j, -1);
}
return 0;
}
}
void* TBranchElement::GetValuePointer() const
{
ValidateAddress();
Int_t prID = fID;
char *object = fObject;
if (TestBit(kCache)) {
if (GetInfoImp()->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
prID = fID+1;
} else if (fOnfileObject) {
object = fOnfileObject->GetObjectAt(0);
}
}
if (fBranchCount) {
Long64_t entry = fTree->GetReadEntry();
fBranchCount->TBranch::GetEntry(entry);
if (fBranchCount2) fBranchCount2->TBranch::GetEntry(entry);
}
if (fTree->GetMakeClass()) {
if (!fAddress) {
return 0;
}
if (fType == 3) {
return 0;
} else if (fType == 4) {
return 0;
} else if (fType == 31) {
return 0;
} else if (fType == 41) {
return 0;
} else if (fType <= 2) {
if (fStreamerType > 40 && fStreamerType < 55) {
return 0;
} else {
return 0;
}
}
}
if (fType == 31) {
return 0;
} else if (fType == 41) {
return 0;
} else if (prID < 0) {
return object;
} else {
if (!GetInfoImp() || !object) return 0;
char **val = (char**)(object+GetInfoImp()->TStreamerInfo::GetElementOffset(prID));
return *val;
}
}
void TBranchElement::InitializeOffsets()
{
Int_t nbranches = fBranches.GetEntriesFast();
if (fID < 0) {
if (CanSelfReference(fBranchClass)) {
if (fBranchClass.GetClass()->InheritsFrom(TObject::Class())) {
SetBit(kBranchObject);
} else {
SetBit(kBranchAny);
}
}
}
if (nbranches) {
delete[] fBranchOffset;
fBranchOffset = 0;
fBranchOffset = new Int_t[nbranches];
if (!fBranchClass.GetClass()) {
Warning("InitializeOffsets", "No branch class set for branch: %s", GetName());
fInitOffsets = kTRUE;
return;
}
if (!GetInfoImp()) {
Warning("InitializeOffsets", "No streamer info available for branch: %s of class: %s", GetName(), fBranchClass.GetClass()->GetName());
fInitOffsets = kTRUE;
return;
}
TStreamerElement* branchElem = 0;
Int_t localOffset = 0;
TClass* branchClass = fBranchClass.GetClass();
Bool_t renamed = kFALSE;
if (fID > -1) {
TVirtualStreamerInfo* si = GetInfoImp();
if (!si->IsCompiled()) {
Warning("InitializeOffsets", "Streamer info for branch: %s has no elements array!", GetName());
fInitOffsets = kTRUE;
return;
}
branchElem = si->GetElement(fID);
if (!branchElem) {
Warning("InitializeOffsets", "Cannot get streamer element for branch: %s!", GetName());
fInitOffsets = kTRUE;
return;
} else if (branchElem->TestBit(TStreamerElement::kRepeat)) {
if (si->GetElement(fID+1)) {
branchElem = si->GetElement(fID+1);
}
}
localOffset = branchElem->GetOffset();
branchClass = branchElem->GetClassPointer();
if (localOffset == TStreamerInfo::kMissing) {
fObject = 0;
} else {
renamed = branchClass && branchElem->GetNewClass() && (branchClass != branchElem->GetNewClass());
}
} else {
renamed = fTargetClass != fBranchClass;
}
if (!branchClass) {
Error("InitializeOffsets", "Could not find class for branch: %s", GetName());
fInitOffsets = kTRUE;
return;
}
TString stlParentName;
Bool_t stlParentNameUpdated = kFALSE;
if( fType == 4 )
{
TBranch *br = GetMother()->GetSubBranch( this );
stlParentName = br->GetName();
stlParentName.Strip( TString::kTrailing, '.' );
}
for (Int_t subBranchIdx = 0; subBranchIdx < nbranches; ++subBranchIdx) {
bool alternateElement = false;
fBranchOffset[subBranchIdx] = 0;
TBranchElement* subBranch = dynamic_cast<TBranchElement*> (fBranches[subBranchIdx]);
if (subBranch == 0) {
continue;
}
if (renamed) {
if (subBranch->fBranchClass == branchClass) {
if (branchElem) subBranch->SetTargetClass(branchElem->GetNewClass()->GetName());
else subBranch->SetTargetClass(fTargetClass->GetName());
}
}
TVirtualStreamerInfo* sinfo = subBranch->GetInfoImp();
if (!sinfo) {
Warning("InitializeOffsets", "No streamer info for branch: %s subbranch: %s", GetName(), subBranch->GetName());
fInitOffsets = kTRUE;
return;
}
if (!sinfo->IsCompiled()) {
Warning("InitializeOffsets", "No elements array for branch: %s subbranch: %s", GetName(), subBranch->GetName());
fInitOffsets = kTRUE;
return;
}
TStreamerElement* subBranchElement = sinfo->GetElement(subBranch->fID);
if (!subBranchElement) {
Warning("InitializeOffsets", "No streamer element for branch: %s subbranch: %s", GetName(), subBranch->GetName());
fInitOffsets = kTRUE;
return;
} else if (subBranchElement->TestBit(TStreamerElement::kRepeat)) {
if (sinfo->GetElement(subBranch->fID+1)) {
subBranchElement = sinfo->GetElement(subBranch->fID+1);
}
} else if (subBranchElement->TestBit(TStreamerElement::kCache)) {
if (subBranch->fReadActionSequence && subBranch->fReadActionSequence->fActions.size() > 1) {
typedef TStreamerInfoActions::ActionContainer_t::iterator iterator;
iterator end = subBranch->fReadActionSequence->fActions.end();
for(iterator iter = subBranch->fReadActionSequence->fActions.begin();
iter != end; ++iter) {
TStreamerInfoActions::TConfiguration *config = iter->fConfiguration;
UInt_t id = config->fElemId;
TStreamerElement *e = (TStreamerElement*)config->fInfo->GetElements()->At(id);
if (e && !e->TestBit(TStreamerElement::kCache)) {
subBranchElement = e;
alternateElement = true;
break;
}
}
}
}
localOffset = subBranchElement->GetOffset();
if (localOffset == TStreamerInfo::kMissing) {
subBranch->fObject = 0;
}
{
Int_t streamerType = subBranchElement->GetType();
if (streamerType > TStreamerInfo::kObject
&& subBranch->GetListOfBranches()->GetEntries()==0
&& CanSelfReference(subBranchElement->GetClass()))
{
subBranch->SetBit(kBranchAny);
} else {
subBranch->ResetBit(kBranchAny);
}
}
if (subBranchElement->GetNewType()<0) {
subBranch->ResetBit(kBranchAny);
subBranch->ResetBit(kBranchObject);
}
TBranch* mother = GetMother();
if (!mother) {
Warning("InitializeOffsets", "Branch '%s' has no mother!", GetName());
fInitOffsets = kTRUE;
return;
}
TString motherName(mother->GetName());
Bool_t motherDot = kFALSE;
if (motherName.Length() && strchr(motherName.Data(), '.')) {
motherDot = kTRUE;
}
Bool_t motherDotAtEnd = kFALSE;
if (motherName.Length() && (motherName[motherName.Length()-1] == '.')) {
motherDotAtEnd = kTRUE;
}
Bool_t isBaseSubBranch = kFALSE;
if ((subBranch->fType == 1) || (subBranchElement && subBranchElement->IsBase())) {
isBaseSubBranch = kTRUE;
}
Bool_t isContDataMember = kFALSE;
if ((subBranch->fType == 31) || (subBranch->fType == 41)) {
isContDataMember = kTRUE;
}
TString dataName(subBranch->GetName());
if (motherDotAtEnd) {
dataName.Remove(0, motherName.Length());
if (!stlParentNameUpdated && stlParentName.Length()) {
stlParentName.Remove(0, motherName.Length());
stlParentNameUpdated = kTRUE;
}
} else if (motherDot) {
if ((fID < 0) && (subBranchElement->IsA() == TStreamerBase::Class())) {
if (dataName.Length() == motherName.Length()) {
dataName.Remove(0, motherName.Length());
if (!stlParentNameUpdated && stlParentName.Length()) {
stlParentName.Remove(0, motherName.Length());
}
}
} else {
if (dataName.Length() > motherName.Length()) {
dataName.Remove(0, motherName.Length() + 1);
if (!stlParentNameUpdated && stlParentName.Length()) {
stlParentName.Remove(0, motherName.Length());
}
}
}
}
stlParentNameUpdated = kTRUE;
if (isBaseSubBranch) {
TString pattern(subBranchElement->GetName());
if (pattern.Length() <= dataName.Length()) {
if (!strcmp(dataName.Data() + (dataName.Length() - pattern.Length()), pattern.Data())) {
dataName.Remove(dataName.Length() - pattern.Length());
}
}
if (dataName.Length()) {
if (dataName[0] == '.') {
dataName.Remove(0, 1);
}
}
}
TString parentName(GetName());
if (motherDotAtEnd) {
parentName.Remove(0, motherName.Length());
} else if (motherDot) {
if ((fID > -1) && (mother == mother->GetSubBranch(this)) && (branchElem->IsA() == TStreamerBase::Class())) {
if (parentName.Length() == motherName.Length()) {
parentName.Remove(0, motherName.Length());
}
} else {
if (parentName.Length() > motherName.Length()) {
parentName.Remove(0, motherName.Length() + 1);
}
}
}
if (fType == 1) {
if (mother != mother->GetSubBranch(this)) {
TString pattern(branchElem->GetName());
if (pattern.Length() <= parentName.Length()) {
if (!strcmp(parentName.Data() + (parentName.Length() - pattern.Length()), pattern.Data())) {
parentName.Remove(parentName.Length() - pattern.Length());
}
}
}
}
if (fID > -1) {
RemovePrefix(dataName, parentName);
}
if (dataName.Length()) {
if (dataName[0] == '.') {
dataName.Remove(0, 1);
}
}
if (dataName.Length()) {
if (dataName[dataName.Length()-1] == '.') {
dataName.Remove(dataName.Length() - 1, 1);
}
}
Int_t offset = 0;
if (dataName.Length()) {
TClass* pClass = 0;
TStreamerInfo *subInfo = subBranch->GetInfoImp();
if (subBranchElement->TestBit(TStreamerElement::kCache)) {
pClass = ((TStreamerElement*)subInfo->GetElements()->At(0))->GetClassPointer();
}
if (!pClass) {
if (fType == 1) {
pClass = branchElem->GetClassPointer();
if (pClass->Property() & kIsAbstract) {
TBranchElement *parent = (TBranchElement*)GetMother()->GetSubBranch(this);
if (parent && parent != this && !parent->GetClass()->IsLoaded() ) {
TString target = pClass->GetName();
target += "@@emulated";
pClass = TClass::GetClass(target);
}
}
} else {
pClass = subBranch->GetParentClass();
}
}
if (!pClass) {
if (GetClonesName() && strlen(GetClonesName())) {
pClass = fClonesClass;
if (!pClass) {
Warning("InitializeOffsets", "subBranch: '%s' has no parent class, and cannot get class for clones class: '%s'!", subBranch->GetName(), GetClonesName());
fInitOffsets = kTRUE;
return;
}
Warning("InitializeOffsets", "subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->GetName(), pClass->GetName());
}
if (fBranchCount && fBranchCount->fCollProxy && fBranchCount->fCollProxy->GetValueClass()) {
pClass = fBranchCount->fCollProxy->GetValueClass();
Warning("InitializeOffsets", "subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->GetName(), pClass ? pClass->GetName() : "unknowned class");
}
if (!pClass) {
pClass = branchClass;
}
}
if (renamed && pClass) {
if (pClass == branchClass) {
pClass = branchElem->GetNewClass();
} else if (fCollProxy && pClass == branchClass->GetCollectionProxy()->GetValueClass()) {
pClass = fCollProxy->GetValueClass();
}
}
if( dynamic_cast<TBranchSTL*>(fParent) && stlParentName.Length() )
{
if( !strncmp( stlParentName.Data(), dataName.Data(), stlParentName.Length()-1 )
&& dataName[ stlParentName.Length() ] == '.' )
dataName.Remove( 0, stlParentName.Length()+1 );
}
if (alternateElement) {
Ssiz_t dotpos = dataName.Last('.');
Ssiz_t endpos = dataName.Length();
if (dotpos != kNPOS) ++dotpos; else dotpos = 0;
dataName.Replace(dotpos,endpos-dotpos,subBranchElement->GetFullName());
}
TRealData* rd = pClass->GetRealData(dataName);
if (rd && (!rd->TestBit(TRealData::kTransient) || alternateElement)) {
offset = rd->GetThisOffset();
} else if (subBranchElement->TestBit(TStreamerElement::kWholeObject)) {
offset = 0;
} else {
if (fEntries == 0) {
if (pClass->GetListOfRealData()->GetEntries() == 0) {
Error("InitializeOffsets",
"Could not find the real data member '%s' when constructing the branch '%s' [Likely missing ShowMember].",
dataName.Data(),GetName());
} else if (subInfo && subInfo->GetClassVersion()!=subInfo->GetClass()->GetClassVersion()) {
Info("InitializeOffsets",
"TTree created with an older schema, some data might not be copied in 'slow-cloning' mode; fast-cloning should have the correct result. '%s' is missing when constructing the branch '%s'. ",
dataName.Data(),GetName());
} else {
Fatal("InitializeOffsets",
"Could not find the real data member '%s' when constructing the branch '%s' [Likely an internal error, please report to the developers].",
dataName.Data(),GetName());
}
}
localOffset = TStreamerInfo::kMissing;
}
} else {
if (isBaseSubBranch) {
} else {
Warning("InitializeOffsets", "Could not find the data member name for branch '%s' with parent branch '%s', assuming offset is zero!", subBranch->GetName(), GetName());
}
}
if (isContDataMember) {
if (subBranch->fObject == 0 && localOffset == TStreamerInfo::kMissing) {
subBranch->SetOffset(TStreamerInfo::kMissing);
fBranchOffset[subBranchIdx] = TStreamerInfo::kMissing;
} else {
if (isBaseSubBranch) {
subBranch->SetOffset(offset);
} else {
subBranch->SetOffset(offset - localOffset);
}
}
} else {
Int_t isSplit = 0 != subBranch->GetListOfBranches()->GetEntriesFast();
if (subBranch->fObject == 0 && localOffset == TStreamerInfo::kMissing) {
fBranchOffset[subBranchIdx] = TStreamerInfo::kMissing;
} else if (isSplit) {
if (isBaseSubBranch) {
fBranchOffset[subBranchIdx] = offset + localOffset;
} else {
fBranchOffset[subBranchIdx] = offset;
}
} else {
if (isBaseSubBranch) {
fBranchOffset[subBranchIdx] = offset;
} else {
fBranchOffset[subBranchIdx] = offset - localOffset;
}
}
}
}
}
else {
if (fID > -1) {
if (GetOffset() == TStreamerInfo::kMissing) {
fObject = 0;
}
}
}
fInitOffsets = kTRUE;
}
Bool_t TBranchElement::IsFolder() const
{
Int_t nbranches = fBranches.GetEntriesFast();
if (nbranches >= 1) {
return kTRUE;
}
TList* browsables = const_cast<TBranchElement*>(this)->GetBrowsables();
return browsables && browsables->GetSize();
}
Bool_t TBranchElement::IsMissingCollection() const
{
Bool_t ismissing = kFALSE;
TBasket* basket = (TBasket*) fBaskets.UncheckedAt(fReadBasket);
if (basket && fTree) {
Long64_t entry = fTree->GetReadEntry();
Long64_t first = fBasketEntry[fReadBasket];
Long64_t last;
if (fReadBasket == fWriteBasket) {
last = fEntryNumber - 1;
} else {
last = fBasketEntry[fReadBasket+1] - 1;
}
Int_t* entryOffset = basket->GetEntryOffset();
Int_t bufbegin;
Int_t bufnext;
if (entryOffset) {
bufbegin = entryOffset[entry-first];
if (entry < last) {
bufnext = entryOffset[entry+1-first];
} else {
bufnext = basket->GetLast();
}
if (bufnext == bufbegin) {
ismissing = kTRUE;
} else {
if (basket->GetNevBufSize() == 0) {
ismissing = kTRUE;
}
}
}
}
return ismissing;
}
void TBranchElement::Print(Option_t* option) const
{
Int_t nbranches = fBranches.GetEntriesFast();
if (strncmp(option,"debugAddress",strlen("debugAddress"))==0) {
if (strlen(option)==strlen("debugAddress")) {
Printf("%-24s %-16s %2s %4s %-16s %-16s %8s %8s %s\n",
"Branch Name", "Streamer Class", "ID", "Type", "Class", "Parent", "pOffset", "fOffset", "fObject");
}
if (strlen(GetName())>24) Printf("%-24s\n%-24s ", GetName(),"");
else Printf("%-24s ", GetName());
TBranchElement *parent = dynamic_cast<TBranchElement*>(GetMother()->GetSubBranch(this));
Int_t ind = parent ? parent->GetListOfBranches()->IndexOf(this) : -1;
TVirtualStreamerInfo *info = ((TBranchElement*)this)->GetInfoImp();
Printf("%-16s %2d %4d %-16s %-16s %8x %8x %s\n",
info ? info->GetName() : "StreamerInfo unvailable", GetID(), GetType(),
GetClassName(), GetParentName(),
(fBranchOffset&&parent && ind>=0) ? parent->fBranchOffset[ind] : 0,
GetOffset(), GetObject());
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
subbranch->Print("debugAddressSub");
}
return;
}
if (strncmp(option,"debugInfo",strlen("debugInfo"))==0) {
Printf("Branch %s uses:",GetName());
if (fID>=0) {
GetInfoImp()->GetElement(fID)->ls();
for(UInt_t i=0; i< fIDs.size(); ++i) {
GetInfoImp()->GetElement(fIDs[i])->ls();
}
Printf(" with read actions:");
if (fReadActionSequence) fReadActionSequence->Print(option);
Printf(" with write actions:");
if (fFillActionSequence) fFillActionSequence->Print(option);
}
TString suboption = "debugInfoSub";
suboption += (option+strlen("debugInfo"));
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* subbranch = (TBranchElement*)fBranches.At(i);
subbranch->Print(suboption);
}
Printf(" ");
return;
}
if (nbranches) {
if (fID == -2) {
if (strcmp(GetName(),GetTitle()) == 0) {
Printf("*Branch :%-66s *",GetName());
} else {
Printf("*Branch :%-9s : %-54s *",GetName(),GetTitle());
}
Printf("*Entries : %8d : BranchElement (see below) *",Int_t(fEntries));
Printf("*............................................................................*");
}
if (fType >= 2) {
TBranch::Print(option);
}
for (Int_t i=0;i<nbranches;i++) {
TBranch *branch = (TBranch*)fBranches.At(i);
branch->Print(option);
}
} else {
TBranch::Print(option);
}
}
void TBranchElement::PrintValue(Int_t lenmax) const
{
ValidateAddress();
TStreamerInfo *info = GetInfoImp();
Int_t prID = fID;
char *object = fObject;
if (TestBit(kCache)) {
if (info->GetElements()->At(fID)->TestBit(TStreamerElement::kRepeat)) {
prID = fID+1;
} else if (fOnfileObject) {
object = fOnfileObject->GetObjectAt(0);
}
}
if (fTree->GetMakeClass()) {
if (!fAddress) {
return;
}
if (fType == 3 || fType == 4) {
printf(" %-15s = %d\n", GetName(), fNdata);
return;
} else if (fType == 31 || fType == 41) {
Int_t n = TMath::Min(10, fNdata);
Int_t atype = fStreamerType + TVirtualStreamerInfo::kOffsetL;
if (fStreamerType == TVirtualStreamerInfo::kChar) {
atype = TVirtualStreamerInfo::kOffsetL + TVirtualStreamerInfo::kUChar;
}
if (atype > 54) {
printf(" %-15s = %d\n", GetName(), fNdata);
return;
}
if (fStreamerType > 20) {
atype -= 20;
TLeafElement* leaf = (TLeafElement*) fLeaves.UncheckedAt(0);
n = n * leaf->GetLenStatic();
}
if (GetInfoImp()) {
GetInfoImp()->PrintValue(GetName(), fAddress, atype, n, lenmax);
}
return;
} else if (fType <= 2) {
if ((fStreamerType > 40) && (fStreamerType < 55)) {
Int_t atype = fStreamerType - 20;
TBranchElement* counterElement = (TBranchElement*) fBranchCount;
Int_t n = (Int_t) counterElement->GetValue(0, 0);
if (GetInfoImp()) {
GetInfoImp()->PrintValue(GetName(), fAddress, atype, n, lenmax);
}
} else {
if (GetInfoImp()) {
GetInfoImp()->PrintValue(GetName(), object, prID, -1, lenmax);
}
}
return;
}
} else if (fType == 3) {
printf(" %-15s = %d\n", GetName(), fNdata);
} else if (fType == 31) {
TClonesArray* clones = (TClonesArray*) object;
if (GetInfoImp()) {
GetInfoImp()->PrintValueClones(GetName(), clones, prID, fOffset, lenmax);
}
} else if (fType == 41) {
TVirtualCollectionProxy::TPushPop helper(((TBranchElement*) this)->GetCollectionProxy(), object);
if (GetInfoImp()) {
GetInfoImp()->PrintValueSTL(GetName(), ((TBranchElement*) this)->GetCollectionProxy(), prID, fOffset, lenmax);
}
} else {
if (GetInfoImp()) {
GetInfoImp()->PrintValue(GetName(), object, prID, -1, lenmax);
}
}
}
void TBranchElement::ReadLeavesImpl(TBuffer&)
{
Fatal("ReadLeaves","The ReadLeaves function has not been configured for %s",GetName());
}
void TBranchElement::ReadLeavesMakeClass(TBuffer& b)
{
ValidateAddress();
if (fType == 3 || fType == 4) {
Int_t *n = (Int_t*) fAddress;
b >> n[0];
if ((n[0] < 0) || (n[0] > fMaximum)) {
if (IsMissingCollection()) {
n[0] = 0;
b.SetBufferOffset(b.Length() - sizeof(n));
} else {
Error("ReadLeaves", "Incorrect size read for the container in %s\nThe size read is %d when the maximum is %d\nThe size is reset to 0 for this entry (%lld)", GetName(), n[0], fMaximum, GetReadEntry());
n[0] = 0;
}
}
fNdata = n[0];
if (fType == 4) {
Int_t nbranches = fBranches.GetEntriesFast();
switch(fSTLtype) {
case TClassEdit::kSet:
case TClassEdit::kMultiSet:
case TClassEdit::kMap:
case TClassEdit::kMultiMap:
for (Int_t i=0; i<nbranches; i++) {
TBranch *branch = (TBranch*)fBranches[i];
Int_t nb = branch->GetEntry(GetReadEntry(), 1);
if (nb < 0) {
break;
}
}
break;
default:
break;
}
}
return;
} else if (fType == 31 || fType == 41) {
fNdata = fBranchCount->GetNdata();
Int_t atype = fStreamerType;
if (atype > 54) return;
if (!fAddress) {
return;
}
Int_t n = fNdata;
if (atype>40) {
atype -= 40;
if (!fBranchCount2) return;
const char *len_where = (char*)fBranchCount2->fAddress;
if (!len_where) return;
Int_t len_atype = fBranchCount2->fStreamerType;
Int_t length;
Int_t k;
Char_t isArray;
for( k=0; k<n; k++) {
char **where = &(((char**)fAddress)[k]);
delete [] *where;
*where = 0;
switch(len_atype) {
case 1: {length = ((Char_t*) len_where)[k]; break;}
case 2: {length = ((Short_t*) len_where)[k]; break;}
case 3: {length = ((Int_t*) len_where)[k]; break;}
case 4: {length = ((Long_t*) len_where)[k]; break;}
case 6: {length = ((Int_t*) len_where)[k]; break;}
case 11: {length = ((UChar_t*) len_where)[k]; break;}
case 12: {length = ((UShort_t*) len_where)[k]; break;}
case 13: {length = ((UInt_t*) len_where)[k]; break;}
case 14: {length = ((ULong_t*) len_where)[k]; break;}
case 15: {length = ((UInt_t*) len_where)[k]; break;}
case 16: {length = ((Long64_t*) len_where)[k]; break;}
case 17: {length = ((ULong64_t*)len_where)[k]; break;}
case 18: {length = ((Bool_t*) len_where)[k]; break;}
default: continue;
}
b >> isArray;
if (length <= 0) continue;
if (isArray == 0) continue;
switch (atype) {
case 1: {*where=new char[sizeof(Char_t)*length]; b.ReadFastArray((Char_t*) *where, length); break;}
case 2: {*where=new char[sizeof(Short_t)*length]; b.ReadFastArray((Short_t*) *where, length); break;}
case 3: {*where=new char[sizeof(Int_t)*length]; b.ReadFastArray((Int_t*) *where, length); break;}
case 4: {*where=new char[sizeof(Long_t)*length]; b.ReadFastArray((Long_t*) *where, length); break;}
case 5: {*where=new char[sizeof(Float_t)*length]; b.ReadFastArray((Float_t*) *where, length); break;}
case 6: {*where=new char[sizeof(Int_t)*length]; b.ReadFastArray((Int_t*) *where, length); break;}
case 8: {*where=new char[sizeof(Double_t)*length]; b.ReadFastArray((Double_t*)*where, length); break;}
case 11: {*where=new char[sizeof(UChar_t)*length]; b.ReadFastArray((UChar_t*) *where, length); break;}
case 12: {*where=new char[sizeof(UShort_t)*length]; b.ReadFastArray((UShort_t*)*where, length); break;}
case 13: {*where=new char[sizeof(UInt_t)*length]; b.ReadFastArray((UInt_t*) *where, length); break;}
case 14: {*where=new char[sizeof(ULong_t)*length]; b.ReadFastArray((ULong_t*) *where, length); break;}
case 15: {*where=new char[sizeof(UInt_t)*length]; b.ReadFastArray((UInt_t*) *where, length); break;}
case 16: {*where=new char[sizeof(Long64_t)*length]; b.ReadFastArray((Long64_t*) *where, length); break;}
case 17: {*where=new char[sizeof(ULong64_t)*length]; b.ReadFastArray((ULong64_t*)*where, length); break;}
case 18: {*where=new char[sizeof(Bool_t)*length]; b.ReadFastArray((Bool_t*) *where, length); break;}
}
}
return;
}
if (atype > 20) {
atype -= 20;
TLeafElement *leaf = (TLeafElement*)fLeaves.UncheckedAt(0);
n *= leaf->GetLenStatic();
}
switch (atype) {
case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
case 15: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
case 16: {b.ReadFastArray((Long64_t*)fAddress, n); break;}
case 17: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
case 18: {b.ReadFastArray((Bool_t*) fAddress, n); break;}
case 9: {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
Double_t *xx = (Double_t*) fAddress;
for (Int_t ii=0;ii<n;ii++) {
b.ReadDouble32(&(xx[ii]),se);
}
break;
}
case 19: {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
Float_t *xx = (Float_t*) fAddress;
for (Int_t ii=0;ii<n;ii++) {
b.ReadFloat16(&(xx[ii]),se);
}
break;
}
}
return;
} else if (fType <= 2) {
if (fStreamerType > 40 && fStreamerType < 55) {
Int_t atype = fStreamerType - 40;
Int_t n;
if (fBranchCount==0) {
TString countname( GetName() );
Ssiz_t dot = countname.Last('.');
if (dot>=0) {
countname.Remove(dot+1);
} else {
countname = "";
}
TString counter( GetTitle() );
Ssiz_t loc = counter.Last('[');
if (loc>=0) {
counter.Remove(0,loc+1);
}
loc = counter.Last(']');
if (loc>=0) {
counter.Remove(loc);
}
countname += counter;
SetBranchCount((TBranchElement *)fTree->GetBranch(countname));
}
if (fBranchCount) {
n = (Int_t)fBranchCount->GetValue(0,0);
} else {
Warning("ReadLeaves","Missing fBranchCount for %s. Data will not be read correctly by the MakeClass mode.",GetName());
n = 0;
}
fNdata = n;
Char_t isArray;
b >> isArray;
switch (atype) {
case 1: {b.ReadFastArray((Char_t*) fAddress, n); break;}
case 2: {b.ReadFastArray((Short_t*) fAddress, n); break;}
case 3: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 4: {b.ReadFastArray((Long_t*) fAddress, n); break;}
case 5: {b.ReadFastArray((Float_t*) fAddress, n); break;}
case 6: {b.ReadFastArray((Int_t*) fAddress, n); break;}
case 8: {b.ReadFastArray((Double_t*)fAddress, n); break;}
case 11: {b.ReadFastArray((UChar_t*) fAddress, n); break;}
case 12: {b.ReadFastArray((UShort_t*)fAddress, n); break;}
case 13: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
case 14: {b.ReadFastArray((ULong_t*) fAddress, n); break;}
case 15: {b.ReadFastArray((UInt_t*) fAddress, n); break;}
case 16: {b.ReadFastArray((Long64_t*) fAddress, n); break;}
case 17: {b.ReadFastArray((ULong64_t*)fAddress, n); break;}
case 18: {b.ReadFastArray((Bool_t*) fAddress, n); break;}
case 9: {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
Double_t *xx = (Double_t*) fAddress;
for (Int_t ii=0;ii<n;ii++) {
b.ReadDouble32(&(xx[ii]),se);
}
break;
}
case 19: {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
Float_t *xx = (Float_t*) fAddress;
for (Int_t ii=0;ii<n;ii++) {
b.ReadFloat16(&(xx[ii]),se);
}
break;
}
}
} else {
fNdata = 1;
if (fAddress) {
if (fType<0) {
fBranchClass->Streamer(fObject,b);
} else {
TStreamerInfo *info = GetInfoImp();
if (!info) {
return;
}
b.ApplySequence(*fReadActionSequence, fObject);
}
if (fStreamerType == TVirtualStreamerInfo::kCounter) {
fNdata = (Int_t) GetValue(0, 0);
}
} else {
fNdata = 0;
}
}
return;
}
}
void TBranchElement::ReadLeavesCollection(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
Int_t n;
b >> n;
if ((n < 0) || (n > fMaximum)) {
if (IsMissingCollection()) {
n = 0;
b.SetBufferOffset(b.Length()-sizeof(n));
} else {
Error("ReadLeaves", "Incorrect size read for the container in %s\n\tThe size read is %d while the maximum is %d\n\tThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
n = 0;
}
}
fNdata = n;
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,n);
TVirtualCollectionProxy* proxy = GetCollectionProxy();
TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
void* alternate = proxy->Allocate(fNdata, true);
if(fSTLtype != TClassEdit::kVector && proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators->CreateIterators(alternate, proxy);
} else {
fIterators->CreateIterators(alternate, proxy);
}
Int_t nbranches = fBranches.GetEntriesFast();
switch (fSTLtype) {
case TClassEdit::kSet:
case TClassEdit::kMultiSet:
case TClassEdit::kMap:
case TClassEdit::kMultiMap:
for (Int_t i = 0; i < nbranches; ++i) {
TBranch *branch = (TBranch*) fBranches[i];
Int_t nb = branch->GetEntry(GetReadEntry(), 1);
if (nb < 0) {
break;
}
}
break;
default:
break;
}
if( proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers )
{
TClass *elClass = proxy->GetValueClass();
Int_t i = 0;
if( !fNdata || *(void**)proxy->At( 0 ) != 0 )
i = fNdata;
for( ; i < fNdata; ++i )
{
void **el = (void**)proxy->At( i );
*el = elClass->New();
}
}
proxy->Commit(alternate);
}
void TBranchElement::ReadLeavesCollectionSplitPtrMember(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
fNdata = fBranchCount->GetNdata();
if (!fNdata) {
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,fNdata);
TStreamerInfo *info = GetInfoImp();
if (info == 0) return;
TVirtualCollectionProxy *proxy = GetCollectionProxy();
TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
TVirtualCollectionPtrIterators *iter = fBranchCount->fPtrIterators;
b.ApplySequence(*fReadActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::ReadLeavesCollectionSplitVectorPtrMember(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
fNdata = fBranchCount->GetNdata();
if (!fNdata) {
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,fNdata);
TStreamerInfo *info = GetInfoImp();
if (info == 0) return;
TVirtualCollectionProxy *proxy = GetCollectionProxy();
TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
TVirtualCollectionIterators *iter = fBranchCount->fIterators;
b.ApplySequenceVecPtr(*fReadActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::ReadLeavesCollectionMember(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
fNdata = fBranchCount->GetNdata();
if (!fNdata) {
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,fNdata);
TStreamerInfo *info = GetInfoImp();
if (info == 0) return;
TVirtualCollectionProxy *proxy = GetCollectionProxy();
TVirtualCollectionProxy::TPushPop helper(proxy, fObject);
TVirtualCollectionIterators *iter = fBranchCount->fIterators;
b.ApplySequence(*fReadActionSequence,iter->fBegin,iter->fEnd);
}
void TBranchElement::ReadLeavesClones(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
Int_t n;
b >> n;
if ((n < 0) || (n > fMaximum)) {
if (IsMissingCollection()) {
n = 0;
b.SetBufferOffset(b.Length()-sizeof(n));
} else {
Error("ReadLeaves", "Incorrect size read for the container in %s\n\tThe size read is %d while the maximum is %d\n\tThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
n = 0;
}
}
fNdata = n;
TClonesArray* clones = (TClonesArray*) fObject;
if (clones->IsZombie()) {
return;
}
clones->ExpandCreateFast(fNdata);
}
void TBranchElement::ReadLeavesClonesMember(TBuffer& b)
{
if (fObject == 0)
{
return;
}
fNdata = fBranchCount->GetNdata();
TClonesArray* clones = (TClonesArray*) fObject;
if (clones->IsZombie()) {
return;
}
TStreamerInfo *info = GetInfoImp();
if (info==0) return;
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,fNdata);
char **arr = (char **)clones->GetObjectRef();
char **end = arr + fNdata;
b.ApplySequenceVecPtr(*fReadActionSequence,arr,end);
}
void TBranchElement::ReadLeavesMember(TBuffer& b)
{
R__ASSERT(fBranchCount==0);
R__ASSERT(fStreamerType != TVirtualStreamerInfo::kCounter);
ValidateAddress();
if (fObject == 0)
{
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,1);
if (TestBit(kBranchObject)) {
b.MapObject((TObject*) fObject);
} else if (TestBit(kBranchAny)) {
b.MapObject(fObject, fBranchClass);
}
fNdata = 1;
TStreamerInfo *info = GetInfoImp();
if (!info) {
return;
}
b.ApplySequence(*fReadActionSequence, fObject);
}
void TBranchElement::ReadLeavesMemberBranchCount(TBuffer& b)
{
R__ASSERT(fStreamerType != TVirtualStreamerInfo::kCounter);
ValidateAddress();
if (fObject == 0)
{
return;
}
if (TestBit(kBranchObject)) {
b.MapObject((TObject*) fObject);
} else if (TestBit(kBranchAny)) {
b.MapObject(fObject, fBranchClass);
}
fNdata = (Int_t) fBranchCount->GetValue(0, 0);
TStreamerInfo *info = GetInfoImp();
if (!info) {
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,1);
b.ApplySequence(*fReadActionSequence, fObject);
}
void TBranchElement::ReadLeavesMemberCounter(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
if (TestBit(kBranchObject)) {
b.MapObject((TObject*) fObject);
} else if (TestBit(kBranchAny)) {
b.MapObject(fObject, fBranchClass);
}
TStreamerInfo *info = GetInfoImp();
if (!info) {
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,1);
b.ApplySequence(*fReadActionSequence, fObject);
fNdata = (Int_t) GetValue(0, 0);
}
void TBranchElement::ReadLeavesCustomStreamer(TBuffer& b)
{
ValidateAddress();
if (fObject == 0)
{
return;
}
R__PushCache onfileObject(((TBufferFile&)b),fOnfileObject,1);
fBranchClass->Streamer(fObject,b);
}
void TBranchElement::FillLeavesImpl(TBuffer&)
{
Fatal("FillLeaves","The FillLeaves function has not been configured for %s",GetName());
}
void TBranchElement::ReleaseObject()
{
if (fObject && TestBit(kDeleteObject)) {
if (IsAutoDelete() && fAddress != (char*)&fObject) {
*((char**) fAddress) = 0;
}
ResetBit(kDeleteObject);
if (fType == 3) {
TClonesArray::Class()->Destructor(fObject);
fObject = 0;
if ((fStreamerType == TVirtualStreamerInfo::kObjectp) ||
(fStreamerType == TVirtualStreamerInfo::kObjectP)) {
*((char**) fAddress) = 0;
}
} else if (fType == 4) {
TVirtualCollectionProxy* proxy = GetCollectionProxy();
if (!proxy) {
Warning("ReleaseObject", "Cannot delete allocated STL container because I do not have a proxy! branch: %s", GetName());
fObject = 0;
} else {
Bool_t needDelete = proxy->GetProperties()&TVirtualCollectionProxy::kNeedDelete;
if (needDelete && fID >= 0) {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = (TStreamerElement*) si->GetElement(fID);
needDelete = !se->TestBit(TStreamerElement::kDoNotDelete);
}
if (needDelete) {
TVirtualCollectionProxy::TPushPop helper(proxy,fObject);
proxy->Clear("force");
}
proxy->Destructor(fObject);
fObject = 0;
}
if (fStreamerType == TVirtualStreamerInfo::kSTLp) {
*((char**) fAddress) = 0;
}
} else {
TClass* cl = fBranchClass.GetClass();
if (!cl) {
Warning("ReleaseObject", "Cannot delete allocated object because I cannot instantiate a TClass object for its class! branch: '%s' class: '%s'", GetName(), fBranchClass.GetClassName());
fObject = 0;
} else {
TVirtualCollectionProxy* proxy = cl->GetCollectionProxy();
if (proxy) {
if (fID >= 0) {
TVirtualStreamerInfo* si = GetInfoImp();
TStreamerElement* se = si->GetElement(fID);
if (!se->TestBit(TStreamerElement::kDoNotDelete) && proxy->GetProperties()&TVirtualCollectionProxy::kNeedDelete) {
TVirtualCollectionProxy::TPushPop helper(proxy,fObject);
proxy->Clear("force");
}
} else if (proxy->GetProperties()&TVirtualCollectionProxy::kNeedDelete) {
TVirtualCollectionProxy::TPushPop helper(proxy,fObject);
proxy->Clear("force");
}
}
cl->Destructor(fObject);
fObject = 0;
}
}
}
}
void TBranchElement::Reset(Option_t* option)
{
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* branch = (TBranch*) fBranches[i];
branch->Reset(option);
}
fBranchID = -1;
TBranch::Reset(option);
}
void TBranchElement::ResetAfterMerge(TFileMergeInfo *info)
{
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* branch = (TBranch*) fBranches[i];
branch->ResetAfterMerge(info);
}
TBranch::ResetAfterMerge(info);
}
void TBranchElement::ResetAddress()
{
for (Int_t i = 0; i < fNleaves; ++i) {
TLeaf* leaf = (TLeaf*) fLeaves.UncheckedAt(i);
leaf->SetAddress(0);
}
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* br = (TBranch*) fBranches[i];
if (br) br->ResetAddress();
}
ReleaseObject();
ResetBit(kAddressSet);
fAddress = 0;
fObject = 0;
}
void TBranchElement::ResetDeleteObject()
{
ResetBit(kDeleteObject);
Int_t nb = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nb; ++i) {
TBranch* br = (TBranch*) fBranches[i];
if (br->InheritsFrom(TBranchElement::Class())) {
((TBranchElement*) br)->ResetDeleteObject();
}
}
}
void TBranchElement::SetAddress(void* addr)
{
if (TestBit(kDoNotProcess)) {
return;
}
if (fType < -1) {
return;
}
if (Long_t(addr) == -1) {
fAddress = (char*) -1;
fObject = (char*) -1;
ResetBit(kDeleteObject);
return;
}
fReadEntry = -1;
TClass* clOfBranch = fBranchClass.GetClass();
if( fTargetClass.GetClassName()[0] ) {
clOfBranch = fTargetClass;
}
TStreamerInfo *info = GetInfoImp();
if (fObject && TestBit(kDeleteObject)){
ReleaseObject();
}
fAddress = (char*) addr;
if (fAddress != (char*)(&fObject)) {
fObject = 0;
}
ResetBit(kDeleteObject);
if (fTree->GetMakeClass()) {
if (fID > -1) {
if (!info) {
fObject = fAddress;
} else {
fObject = fAddress - info->TStreamerInfo::GetElementOffset(fID);
}
return;
}
}
if (fType == 3) {
TClass* clm = fClonesClass;
if (clm) {
clm->BuildRealData();
clm->GetStreamerInfo();
}
TClass* newType = GetCurrentClass();
if (newType && (newType != TClonesArray::Class())) {
Bool_t matched = kFALSE;
if (newType->GetCollectionProxy()) {
TClass *content = newType->GetCollectionProxy()->GetValueClass();
if (clm == content) {
matched = kTRUE;
} else {
Warning("SetAddress", "The type of %s was changed from TClonesArray to %s but the content do not match (was %s)!", GetName(), newType->GetName(), GetClonesName());
}
} else {
Warning("SetAddress", "The type of the %s was changed from TClonesArray to %s but we do not have a TVirtualCollectionProxy for that container type!", GetName(), newType->GetName());
}
if (matched) {
SetType(4);
fSTLtype = TMath::Abs(TClassEdit::IsSTLCont(newType->GetName()));
fCollProxy = newType->GetCollectionProxy()->Generate();
SwitchContainer(GetListOfBranches());
SetReadLeavesPtr();
SetFillLeavesPtr();
if(fSTLtype != TClassEdit::kVector && fCollProxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators = new TVirtualCollectionPtrIterators(fCollProxy);
} else if (fCollProxy->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fWriteIterators = new TVirtualCollectionIterators(fCollProxy,kFALSE);
fIterators = new TVirtualCollectionIterators(fCollProxy);
} else {
fIterators = new TVirtualCollectionIterators(fCollProxy);
}
} else {
fAddress = 0;
}
}
} else if (fType == 4) {
TClass* newType = GetCurrentClass();
if (newType && (newType != GetCollectionProxy()->GetCollectionClass())) {
TVirtualCollectionProxy* newProxy = newType->GetCollectionProxy();
TVirtualCollectionProxy* oldProxy = GetCollectionProxy();
if (newProxy && (oldProxy->GetValueClass() == newProxy->GetValueClass()) && ((!oldProxy->GetValueClass() && (oldProxy->GetType() == newProxy->GetType())) || (oldProxy->GetValueClass() && (oldProxy->HasPointers() == newProxy->HasPointers())))) {
delete fCollProxy;
Int_t nbranches = GetListOfBranches()->GetEntries();
fCollProxy = newType->GetCollectionProxy()->Generate();
fSTLtype = fCollProxy->GetCollectionType();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* br = (TBranchElement*) GetListOfBranches()->UncheckedAt(i);
br->fCollProxy = 0;
if (br->fReadActionSequence) {
br->SetReadActionSequence();
}
if (br->fFillActionSequence) {
br->SetFillActionSequence();
}
}
SetReadActionSequence();
SetFillActionSequence();
SetReadLeavesPtr();
SetFillLeavesPtr();
delete fIterators;
delete fPtrIterators;
if(fSTLtype != TClassEdit::kVector && fCollProxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators = new TVirtualCollectionPtrIterators(fCollProxy);
} else if (fCollProxy->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fWriteIterators = new TVirtualCollectionIterators(fCollProxy,kFALSE);
fIterators = new TVirtualCollectionIterators(fCollProxy);
} else {
fIterators = new TVirtualCollectionIterators(fCollProxy);
}
}
else if (newProxy && (oldProxy->HasPointers() == newProxy->HasPointers()) && (oldProxy->GetValueClass()!=0) && (newProxy->GetValueClass()!=0)) {
if (newType->GetSchemaRules()->HasRuleWithSourceClass( oldProxy->GetCollectionClass()->GetName())) {
TClass *oldValueClass = oldProxy->GetValueClass();
delete fCollProxy;
Int_t nbranches = GetListOfBranches()->GetEntries();
fCollProxy = newType->GetCollectionProxy()->Generate();
fSTLtype = fCollProxy->GetCollectionType();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* br = (TBranchElement*) GetListOfBranches()->UncheckedAt(i);
br->fCollProxy = 0;
if (br->fBranchClass == oldValueClass) {
br->SetTargetClass(fCollProxy->GetValueClass()->GetName());
}
if (br->fReadActionSequence) {
br->SetReadActionSequence();
}
if (br->fFillActionSequence) {
br->SetFillActionSequence();
}
}
SetReadActionSequence();
SetFillActionSequence();
SetReadLeavesPtr();
SetFillLeavesPtr();
delete fIterators;
delete fPtrIterators;
if(fSTLtype != TClassEdit::kVector && fCollProxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators = new TVirtualCollectionPtrIterators(fCollProxy);
} else if (fCollProxy->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fWriteIterators = new TVirtualCollectionIterators(fCollProxy,kFALSE);
fIterators = new TVirtualCollectionIterators(fCollProxy);
} else {
fIterators = new TVirtualCollectionIterators(fCollProxy);
}
} else {
Error("SetAddress","For %s, we can not convert %s into %s\n",
GetName(),oldProxy->GetCollectionClass()->GetName(),newType->GetName());
fAddress = 0;
fObject = 0;
return;
}
}
else if ((newType == TClonesArray::Class()) && (oldProxy->GetValueClass() && !oldProxy->HasPointers() && oldProxy->GetValueClass()->InheritsFrom(TObject::Class())))
{
SetType(3);
fSTLtype = kNone;
switch(fStreamerType) {
case TVirtualStreamerInfo::kAny:
case TVirtualStreamerInfo::kSTL:
fStreamerType = TVirtualStreamerInfo::kObject;
break;
case TVirtualStreamerInfo::kAnyp:
case TVirtualStreamerInfo::kSTLp:
fStreamerType = TVirtualStreamerInfo::kObjectp;
break;
case TVirtualStreamerInfo::kAnyP:
fStreamerType = TVirtualStreamerInfo::kObjectP;
break;
}
fClonesClass = oldProxy->GetValueClass();
fClonesName = fClonesClass->GetName();
delete fCollProxy;
fCollProxy = 0;
TClass* clm = fClonesClass;
if (clm) {
clm->BuildRealData();
clm->GetStreamerInfo();
}
SwitchContainer(GetListOfBranches());
SetReadLeavesPtr();
SetFillLeavesPtr();
delete fIterators;
fIterators = 0;
delete fPtrIterators;
fPtrIterators =0;
} else {
Error("SetAddress","For %s can not convert %s into %s\n",GetName(),GetCurrentClass()->GetName(),newType->GetName());
fAddress = 0;
return;
}
} else {
if (!fIterators && !fPtrIterators) {
if(fSTLtype != TClassEdit::kVector && GetCollectionProxy()->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
fPtrIterators = new TVirtualCollectionPtrIterators(GetCollectionProxy());
} else if (fCollProxy->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fWriteIterators = new TVirtualCollectionIterators(fCollProxy,kFALSE);
fIterators = new TVirtualCollectionIterators(fCollProxy);
} else {
fIterators = new TVirtualCollectionIterators(GetCollectionProxy());
}
}
}
}
if (fType == 3) {
if (fAddress) {
if (fStreamerType == TVirtualStreamerInfo::kObject) {
fObject = fAddress;
TClonesArray* clones = (TClonesArray*) fObject;
if (!clones->GetClass()) {
new(fObject) TClonesArray(fClonesClass);
}
} else {
if ((fStreamerType != -1) &&
(fStreamerType != TVirtualStreamerInfo::kObjectp) &&
(fStreamerType != TVirtualStreamerInfo::kObjectP)) {
Error("SetAddress", "TClonesArray with fStreamerType: %d", fStreamerType);
} else if (fStreamerType == -1) {
TClonesArray** pp = (TClonesArray**) fAddress;
if (!*pp) {
*pp = new TClonesArray(fClonesClass);
}
fObject = (char*) *pp;
} else {
TClonesArray** pp = (TClonesArray**) fAddress;
if (!*pp) {
*pp = new TClonesArray(fClonesClass);
}
fObject = (char*) *pp;
}
}
} else {
if (fStreamerType == TVirtualStreamerInfo::kObject) {
Error("SetAddress", "Embedded TClonesArray given a zero address for branch '%s'", GetName());
} else {
if ((fStreamerType != -1) &&
(fStreamerType != TVirtualStreamerInfo::kObjectp) &&
(fStreamerType != TVirtualStreamerInfo::kObjectP)) {
Error("SetAddress", "TClonesArray with fStreamerType: %d", fStreamerType);
} else if (fStreamerType == -1) {
SetBit(kDeleteObject);
fObject = (char*) new TClonesArray(fClonesClass);
fAddress = (char*) &fObject;
} else {
Error("SetAddress", "Embedded pointer to a TClonesArray given a zero address for branch '%s'", GetName());
}
}
}
} else if (fType == 4) {
TVirtualCollectionProxy* proxy = GetCollectionProxy();
if (fAddress) {
if ((fStreamerType == TVirtualStreamerInfo::kObject) ||
(fStreamerType == TVirtualStreamerInfo::kAny) ||
(fStreamerType == TVirtualStreamerInfo::kSTL)) {
fObject = fAddress;
} else {
if ((fStreamerType != -1) && (fStreamerType != TVirtualStreamerInfo::kSTLp)) {
Error("SetAddress", "STL container with fStreamerType: %d", fStreamerType);
} else if (fStreamerType == -1) {
void** pp = (void**) fAddress;
if (!*pp) {
*pp = proxy->New();
if (!(*pp)) {
Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
fAddress = 0;
}
}
fObject = (char*) *pp;
} else {
void** pp = (void**) fAddress;
if (!*pp) {
*pp = proxy->New();
if (!(*pp)) {
Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
fAddress = 0;
}
}
fObject = (char*) *pp;
}
}
} else {
if ((fStreamerType == TVirtualStreamerInfo::kObject) ||
(fStreamerType == TVirtualStreamerInfo::kAny) ||
(fStreamerType == TVirtualStreamerInfo::kSTL)) {
Error("SetAddress", "Embedded STL container given a zero address for branch '%s'", GetName());
} else {
if ((fStreamerType != -1) && (fStreamerType != TVirtualStreamerInfo::kSTLp)) {
Error("SetAddress", "STL container with fStreamerType: %d", fStreamerType);
} else if (fStreamerType == -1) {
SetBit(kDeleteObject);
fObject = (char*) proxy->New();
if (fObject) {
fAddress = (char*) &fObject;
} else {
Error("SetAddress", "Failed to allocate STL container for branch '%s'", GetName());
fAddress = 0;
}
} else {
Error("SetAddress", "Embedded pointer to an STL container given a zero address for branch '%s'", GetName());
}
}
}
} else if (fType == 41) {
GetCollectionProxy();
fObject = fAddress;
} else if (fID < 0) {
char** pp = (char**) fAddress;
if (pp && *pp) {
fObject = *pp;
} else {
if (clOfBranch) {
if (!pp) {
SetBit(kDeleteObject);
}
fObject = (char*) clOfBranch->New();
if (pp) {
*pp = fObject;
} else {
fAddress = (char*) &fObject;
}
} else {
Error("SetAddress", "I have no TClass for branch %s, so I cannot allocate an I/O buffer!", GetName());
if (pp) {
fObject = 0;
*pp = 0;
}
}
}
} else {
fObject = fAddress;
}
if (!info) {
return;
}
if (!fInitOffsets) {
InitializeOffsets();
}
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* abranch = (TBranch*) fBranches.UncheckedAt(i);
if (fBranchOffset[i] != TStreamerInfo::kMissing) {
abranch->SetAddress(fObject + fBranchOffset[i]);
abranch->SetBit(kAddressSet);
} else {
abranch->SetBit(kAddressSet);
}
}
}
void TBranchElement::SetBasketSize(Int_t buffsize)
{
TBranch::SetBasketSize(buffsize);
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranch* branch = (TBranch*) fBranches[i];
branch->SetBasketSize(fBasketSize);
}
}
void TBranchElement::SetBranchCount(TBranchElement* brOfCounter)
{
fBranchCount = brOfCounter;
if (fBranchCount==0) return;
TLeafElement* leafOfCounter = (TLeafElement*) brOfCounter->GetListOfLeaves()->At(0);
TLeafElement* leaf = (TLeafElement*) GetListOfLeaves()->At(0);
if (leafOfCounter && leaf) {
leaf->SetLeafCount(leafOfCounter);
} else {
if (!leafOfCounter) {
Warning("SetBranchCount", "Counter branch %s for branch %s has no leaves!", brOfCounter->GetName(), GetName());
}
if (!leaf) {
Warning("SetBranchCount", "Branch %s has no leaves!", GetName());
}
}
}
Bool_t TBranchElement::SetMakeClass(Bool_t decomposeObj)
{
if (decomposeObj)
SetBit(kDecomposedObj);
else
ResetBit(kDecomposedObj);
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement* branch = (TBranchElement*) fBranches[i];
branch->SetMakeClass(decomposeObj);
}
SetReadLeavesPtr();
SetFillLeavesPtr();
return kTRUE;
}
void TBranchElement::SetObject(void* obj)
{
if (TestBit(kDoNotProcess)) {
return;
}
fObject = (char*)obj;
SetAddress( &fObject );
}
void TBranchElement::SetOffset(Int_t offset)
{
if (fReadActionSequence) {
fReadActionSequence->AddToOffset(offset - fOffset);
}
if (fFillActionSequence) {
fFillActionSequence->AddToOffset(offset - fOffset);
}
fOffset = offset;
}
void TBranchElement::SetReadActionSequence()
{
if (fInfo == 0) {
return;
}
TStreamerInfoActions::TActionSequence *original = 0;
TStreamerInfoActions::TActionSequence *transient = 0;
if (fType == 41) {
if( fSplitLevel >= TTree::kSplitCollectionOfPointers && fBranchCount->fSTLtype == TClassEdit::kVector) {
original = fInfo->GetReadMemberWiseActions(kTRUE);
} else {
TVirtualStreamerInfo *info = GetInfoImp();
if (GetParentClass() == info->GetClass()) {
if( fTargetClass.GetClassName()[0] && fBranchClass != fTargetClass ) {
original = GetCollectionProxy()->GetConversionReadMemberWiseActions(fBranchClass.GetClass(), fClassVersion);
} else {
original = GetCollectionProxy()->GetReadMemberWiseActions(fClassVersion);
}
} else if (GetCollectionProxy()) {
transient = TStreamerInfoActions::TActionSequence::CreateReadMemberWiseActions(info,*GetCollectionProxy());
original = transient;
}
}
} else if (fType == 31) {
original = fInfo->GetReadMemberWiseActions(kTRUE);
} else if (0<=fType && fType<=2) {
original = fInfo->GetReadMemberWiseActions(kFALSE);
}
if (original) {
fIDs.insert(fIDs.begin(),fID);
if (fReadActionSequence) delete fReadActionSequence;
fReadActionSequence = original->CreateSubSequence(fIDs,fOffset);
fIDs.erase(fIDs.begin());
}
delete transient;
}
void TBranchElement::SetReadLeavesPtr()
{
if (TestBit(kDecomposedObj)) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMakeClass;
} else if (fType == 4) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollection;
} else if (fType == 41) {
if( fSplitLevel >= TTree::kSplitCollectionOfPointers ) {
if (fBranchCount->fSTLtype == TClassEdit::kVector) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionSplitVectorPtrMember;
} else {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionSplitPtrMember;
}
} else {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCollectionMember;
}
} else if (fType == 3) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesClones;
} else if (fType == 31) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesClonesMember;
} else if (fType < 0) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesCustomStreamer;
} else if (fType <=2) {
if (fBranchCount) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMemberBranchCount;
} else if (fStreamerType == TVirtualStreamerInfo::kCounter) {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMemberCounter;
} else {
fReadLeaves = (ReadLeaves_t)&TBranchElement::ReadLeavesMember;
}
} else {
Fatal("SetReadLeavePtr","Unexpected branch type %d for %s",fType,GetName());
}
SetReadActionSequence();
}
void TBranchElement::SetFillActionSequence()
{
if (fInfo == 0) {
return;
}
TStreamerInfoActions::TActionSequence *original = 0;
TStreamerInfoActions::TActionSequence *transient = 0;
if (fType == 41) {
if( fSplitLevel >= TTree::kSplitCollectionOfPointers && fBranchCount->fSTLtype == TClassEdit::kVector) {
original = fInfo->GetWriteMemberWiseActions(kTRUE);
} else {
TVirtualStreamerInfo *info = GetInfoImp();
if (GetParentClass() == info->GetClass()) {
original = GetCollectionProxy()->GetWriteMemberWiseActions();
} else if (GetCollectionProxy()) {
transient = TStreamerInfoActions::TActionSequence::CreateWriteMemberWiseActions(info,*GetCollectionProxy());
original = transient;
}
}
} else if (fType == 31) {
original = fInfo->GetWriteMemberWiseActions(kTRUE);
} else if (0<=fType && fType<=2) {
original = fInfo->GetWriteMemberWiseActions(kFALSE);
}
if (original) {
fIDs.insert(fIDs.begin(),fID);
if (fFillActionSequence) delete fFillActionSequence;
fFillActionSequence = original->CreateSubSequence(fIDs,fOffset);
fIDs.erase(fIDs.begin());
}
delete transient;
}
void TBranchElement::SetFillLeavesPtr()
{
if (fTree->GetMakeClass() && ((fType==3)||(fType==31))) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesMakeClass;
} else if (fType == 4) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesCollection;
} else if (fType == 41) {
if( fSplitLevel >= TTree::kSplitCollectionOfPointers ) {
if (fBranchCount->fSTLtype == TClassEdit::kVector) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesCollectionSplitVectorPtrMember;
} else {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesCollectionSplitPtrMember;
}
} else if (GetCollectionProxy()->GetProperties() & TVirtualCollectionProxy::kIsAssociative) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesAssociativeCollectionMember;
} else {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesCollectionMember;
}
} else if (fType == 3) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesClones;
} else if (fType == 31) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesClonesMember;
} else if (fType < 0) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesCustomStreamer;
} else if (fType <=2) {
if (fBranchCount) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesMemberBranchCount;
} else if (fStreamerType == TVirtualStreamerInfo::kCounter) {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesMemberCounter;
} else {
fFillLeaves = (FillLeaves_t)&TBranchElement::FillLeavesMember;
}
} else {
Fatal("SetFillLeavePtr","Unexpected branch type %d for %s",fType,GetName());
}
SetFillActionSequence();
}
void TBranchElement::SetTargetClass(const char *name)
{
if (name == 0) return;
if (strcmp(fTargetClass.GetClassName(),name) != 0 )
{
fInfo = 0;
fInit = kFALSE;
fInitOffsets = kFALSE;
delete fReadActionSequence;
fReadActionSequence = 0;
delete fFillActionSequence;
fFillActionSequence = 0;
Int_t nbranches = fBranches.GetEntriesFast();
for (Int_t i = 0; i < nbranches; ++i) {
TBranchElement *sub = (TBranchElement*) fBranches[i];
if (sub->fTargetClass == fTargetClass ) {
sub->SetTargetClass(name);
}
if (sub->fParentClass == fTargetClass ) {
sub->SetParentClass(TClass::GetClass(name));
}
}
fTargetClass = name;
}
}
void TBranchElement::SetupAddresses()
{
ValidateAddress();
if (fAddress || fTree->GetMakeClass()) {
return;
}
SetupAddressesImpl();
}
void TBranchElement::SetupAddressesImpl()
{
if (TestBit(kDoNotProcess|kAddressSet)) {
return;
}
if( fType == 41 && fSplitLevel >= TTree::kSplitCollectionOfPointers )
{
TBranchElement *parent = (TBranchElement *)GetMother()->GetSubBranch( this );
GetInfoImp();
if( !parent->GetAddress() )
parent->SetAddress( 0 );
return;
}
TBranchElement* mother = (TBranchElement*) GetMother();
if (!mother) {
return;
}
TClass* cl = TClass::GetClass(mother->GetClassName());
GetInfoImp();
if (!cl) {
return;
}
if (!mother->GetAddress()) {
Bool_t motherStatus = mother->TestBit(kDoNotProcess);
mother->ResetBit(kDoNotProcess);
mother->SetAddress(0);
mother->SetBit(kDoNotProcess, motherStatus);
}
}
void TBranchElement::Streamer(TBuffer& R__b)
{
if (R__b.IsReading()) {
R__b.ReadClassBuffer(TBranchElement::Class(), this);
fParentClass.SetName(fParentName);
fBranchClass.SetName(fClassName);
fTargetClass.SetName(fClassName);
fClonesClass.SetName(fClonesName);
ResetBit(kDeleteObject|kCache|kOwnOnfileObj|kAddressSet);
if ((fType == 0) && (fLeaves.GetEntriesFast() == 0)) {
TLeaf* leaf = new TLeafElement(this, GetTitle(), fID, fStreamerType);
leaf->SetTitle(GetTitle());
fNleaves = 1;
fLeaves.Add(leaf);
fTree->GetListOfLeaves()->Add(leaf);
}
}
else {
TDirectory* dirsav = fDirectory;
fDirectory = 0;
{
Int_t classVersion = fClassVersion;
if (fClassVersion < 0) {
fClassVersion = -fClassVersion;
}
R__b.WriteClassBuffer(TBranchElement::Class(), this);
fClassVersion = classVersion;
}
{
R__b.ForceWriteInfo(GetInfoImp(), kTRUE);
}
if (fType == 3) {
TClass* cl = fClonesClass;
if (cl) {
R__b.ForceWriteInfo(cl->GetStreamerInfo(), kTRUE);
}
}
else if (fType == 4) {
TVirtualCollectionProxy* cp = GetCollectionProxy();
if (cp) {
TClass* cl = cp->GetValueClass();
if (cl) {
R__b.ForceWriteInfo(cl->GetStreamerInfo(), kTRUE);
}
}
}
if (!dirsav) {
return;
}
if (!dirsav->IsWritable()) {
fDirectory = dirsav;
return;
}
TDirectory* pdirectory = fTree->GetDirectory();
if (!pdirectory) {
fDirectory = dirsav;
return;
}
const char* treeFileName = pdirectory->GetFile()->GetName();
TBranch* mother = GetMother();
const char* motherFileName = treeFileName;
if (mother && (mother != this)) {
motherFileName = mother->GetFileName();
}
if ((fFileName.Length() > 0) && strcmp(motherFileName, fFileName.Data())) {
dirsav->WriteTObject(this);
}
fDirectory = dirsav;
}
}
Int_t TBranchElement::Unroll(const char* name, TClass* clParent, TClass* cl, char* ptr, Int_t basketsize, Int_t splitlevel, Int_t btype)
{
Int_t splitSTLP = splitlevel - (splitlevel%TTree::kSplitCollectionOfPointers);
splitlevel %= TTree::kSplitCollectionOfPointers;
TString branchname;
if ((cl == TObject::Class()) && clParent->CanIgnoreTObjectStreamer()) {
return 0;
}
TStreamerInfo* sinfo = fTree->BuildStreamerInfo(cl);
if (!sinfo) {
return 0;
}
Int_t ndata = sinfo->GetNelement();
if ((ndata == 1) && cl->GetCollectionProxy() && !strcmp(sinfo->GetElement(0)->GetName(), "This")) {
return 1;
}
for (Int_t elemID = 0; elemID < ndata; ++elemID) {
TStreamerElement* elem = sinfo->GetElement(elemID);
if (elem->IsA() == TStreamerArtificial::Class()) {
continue;
}
if (elem->TestBit(TStreamerElement::kRepeat)) {
continue;
}
if (elem->TestBit(TStreamerElement::kCache) && !elem->TestBit(TStreamerElement::kWrite)) {
continue;
}
Int_t offset = elem->GetOffset();
if (elem->IsA() == TStreamerBase::Class()) {
TClass* clOfBase = TClass::GetClass(elem->GetName());
if ((clOfBase->Property() & kIsAbstract) && cl->InheritsFrom(TCollection::Class())) {
return -1;
}
if ((btype == 31) || (btype == 41)) {
Int_t unroll = -1;
if (!elem->CannotSplit() || clOfBase == TObject::Class()) {
unroll = Unroll(name, clParent, clOfBase, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
}
if (unroll < 0) {
if (strlen(name)) {
branchname.Form("%s.%s", name, elem->GetFullName());
} else {
branchname.Form("%s", elem->GetFullName());
}
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, 0, basketsize, 0, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
}
} else if (clOfBase->GetListOfRealData()->GetSize()) {
if (strlen(name)) {
branchname.Form("%s.%s", name, elem->GetFullName());
TBranchElement* branch = new TBranchElement(this, name, sinfo, elemID, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
branch->SetName(branchname);
branch->SetTitle(branchname);
branch->SetParentClass(clParent);
fBranches.Add(branch);
} else {
branchname.Form("%s", elem->GetFullName());
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, splitlevel+splitSTLP, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
}
}
} else {
if (strlen(name)) {
branchname.Form("%s.%s", name, elem->GetFullName());
} else {
branchname.Form("%s", elem->GetFullName());
}
if ((splitlevel > 1) && ((elem->IsA() == TStreamerObject::Class()) || (elem->IsA() == TStreamerObjectAny::Class()))) {
TClass* elemClass = TClass::GetClass(elem->GetTypeName());
if (elemClass->Property() & kIsAbstract) {
return -1;
}
if (elem->CannotSplit()) {
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, 0, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
} else if (elemClass->InheritsFrom(TClonesArray::Class())) {
Int_t subSplitlevel = splitlevel-1;
if (btype == 31 || btype == 41 || elem->CannotSplit()) {
subSplitlevel = 0;
}
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, subSplitlevel, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
} else {
Int_t unroll = Unroll(branchname, clParent, elemClass, ptr + offset, basketsize, splitlevel-1+splitSTLP, btype);
if (unroll < 0) {
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, 0, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
}
}
}
else if( elem->GetClassPointer() &&
elem->GetClassPointer()->GetCollectionProxy() &&
elem->GetClassPointer()->GetCollectionProxy()->HasPointers() &&
splitSTLP && fType != 4 )
{
TBranchSTL* branch = new TBranchSTL( this, branchname,
elem->GetClassPointer()->GetCollectionProxy(),
basketsize, splitlevel - 1+splitSTLP, sinfo, elemID );
branch->SetAddress( ptr+offset );
fBranches.Add( branch );
}
else if ((elem->IsA() == TStreamerSTL::Class()) && !elem->IsaPointer()) {
Int_t subSplitlevel = splitlevel - 1;
if ((btype == 31) || (btype == 41) || elem->CannotSplit()) {
subSplitlevel = 0;
}
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, subSplitlevel+splitSTLP, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
} else if (((btype != 31) && (btype != 41)) && ptr && ((elem->GetClassPointer() == TClonesArray::Class()) || ((elem->IsA() == TStreamerSTL::Class()) && !elem->CannotSplit()))) {
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, ptr + offset, basketsize, splitlevel-1+splitSTLP, btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
} else {
TBranchElement* branch = new TBranchElement(this, branchname, sinfo, elemID, 0, basketsize, splitSTLP, btype);
branch->SetType(btype);
branch->SetParentClass(clParent);
fBranches.Add(branch);
}
}
}
return 1;
}
void TBranchElement::UpdateFile()
{
TBranch::UpdateFile();
}