// @(#)root/tree:$Id$ // Author: Rene Brun 14/01/2001 /************************************************************************* * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * * All rights reserved. * * * * For the licensing terms see $ROOTSYS/LICENSE. * * For the list of contributors see $ROOTSYS/README/CREDITS. * *************************************************************************/ #ifndef ROOT_TBranchElement #define ROOT_TBranchElement ////////////////////////////////////////////////////////////////////////// // // // TBranchElement // // // // A Branch for the case of an object. // ////////////////////////////////////////////////////////////////////////// #include "TBranch.h" #include "TClassRef.h" #include "TTree.h" #include "TError.h" class TFolder; class TStreamerInfo; class TVirtualCollectionProxy; class TVirtualCollectionIterators; class TVirtualCollectionPtrIterators; class TVirtualArray; #include "TStreamerInfoActions.h" class TBranchElement : public TBranch { // Friends friend class TTreeCloner; friend class TLeafElement; // Types protected: enum EStatusBits { kBranchFolder = BIT(14), kDeleteObject = BIT(16), ///< We are the owner of fObject. kCache = BIT(18), ///< Need to pushd/pop fOnfileObject. kOwnOnfileObj = BIT(19), ///< We are the owner of fOnfileObject. kAddressSet = BIT(20), ///< The addressing set have been called for this branch kMakeClass = BIT(21), ///< This branch has been switched to using the MakeClass Mode kDecomposedObj = BIT(21) ///< More explicit alias for kMakeClass. }; // Note on fType values: // -1 unsplit object with custom streamer at time of writing // 0 unsplit object with default streamer at time of writing // OR simple data member of split object (fID==-1 for the former) // 1 base class of a split object. // 2 class typed data member of a split object // 3 branch count of a split TClonesArray // 31 data member of the content of a split TClonesArray // 4 branch count of a split STL Collection. // 41 data member of the content of a split STL collection // Data Members protected: TString fClassName; ///< Class name of referenced object TString fParentName; ///< Name of parent class TString fClonesName; ///< Name of class in TClonesArray (if any) TVirtualCollectionProxy *fCollProxy; ///(i, len, subarr); } template T GetTypedValue(Int_t i, Int_t len, Bool_t subarr = kFALSE) const; virtual void *GetValuePointer() const; Int_t GetClassVersion() { return fClassVersion; } Bool_t IsBranchFolder() const { return TestBit(kBranchFolder); } Bool_t IsFolder() const; virtual Bool_t IsObjectOwner() const { return TestBit(kDeleteObject); } virtual Bool_t Notify() { if (fAddress) { ResetAddress(); } return 1; } virtual void Print(Option_t* option = "") const; void PrintValue(Int_t i) const; virtual void Reset(Option_t* option = ""); virtual void ResetAfterMerge(TFileMergeInfo *); virtual void ResetAddress(); virtual void ResetDeleteObject(); virtual void ResetInitInfo(bool recurse); virtual void SetAddress(void* addobj); virtual Bool_t SetMakeClass(Bool_t decomposeObj = kTRUE); virtual void SetObject(void *objadd); virtual void SetBasketSize(Int_t buffsize); virtual void SetBranchFolder() { SetBit(kBranchFolder); } virtual void SetClassName(const char* name) { fClassName = name; } virtual void SetOffset(Int_t offset); virtual void SetMissing(); inline void SetParentClass(TClass* clparent); virtual void SetParentName(const char* name) { fParentName = name; } virtual void SetTargetClass(const char *name); virtual void SetupAddresses(); virtual void SetType(Int_t btype) { fType = btype; } virtual void UpdateFile(); void Unroll(const char *name, TClass *cl, TStreamerInfo *sinfo, char* objptr, Int_t bufsize, Int_t splitlevel); enum EBranchElementType { kLeafNode = 0, kBaseClassNode = 1, // -- We are a base class element. // Note: This does not include an STL container class which is // being used as a base class because the streamer element // in that case is not the base streamer element it is the // STL streamer element. kObjectNode = 2, kClonesNode = 3, kSTLNode = 4, kClonesMemberNode = 31, kSTLMemberNode = 41 }; private: virtual Int_t FillImpl(ROOT::Internal::TBranchIMTHelper *); ClassDef(TBranchElement,10) // Branch in case of an object }; inline void TBranchElement::SetParentClass(TClass* clparent) { fParentClass = clparent; fParentName = clparent ? clparent->GetName() : ""; } inline void TBranchElement::ValidateAddress() const { // Check to see if the user changed the object pointer without telling us. if (fID < 0) { // We are a top-level branch. if (!fTree->GetMakeClass() && fAddress && (*((char**) fAddress) != fObject)) { // The semantics of fAddress and fObject are violated. // Assume the user changed the pointer on us. // Note: The cast is here because we want to be able to // be called from the constant get functions. // FIXME: Disable the check/warning TTree until we add a missing interface. if (TestBit(kDeleteObject)) { // This should never happen! Error("ValidateAddress", "We owned an object whose address changed! our ptr: %p new ptr: %p", (void*)fObject, (void*)*((char**) fAddress)); const_cast(this)->ResetBit(kDeleteObject); } const_cast(this)->SetAddress(fAddress); } } } #endif // ROOT_TBranchElement