// @(#)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.                                  //
//////////////////////////////////////////////////////////////////////////


#ifndef ROOT_TBranch
#include "TBranch.h"
#endif

#ifndef ROOT_TClassRef
#include "TClassRef.h"
#endif

#ifndef ROOT_TTree
#include "TTree.h"
#endif

#ifndef ROOT_TError
#include "TError.h"
#endif

#include <vector>

class TFolder;
class TStreamerInfo;
class TVirtualCollectionProxy;
class TVirtualCollectionIterators;
class TVirtualCollectionPtrIterators;
class TVirtualArray;

namespace TStreamerInfoActions { class TActionSequence; }


class TBranchElement : public TBranch {

// Friends
   friend class TTreeCloner;

// Types
protected:
   enum {
      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.
   };

// 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;     //! collection interface (if any)
   UInt_t                   fCheckSum;      //  CheckSum of class
   Version_t                fClassVersion;  //  Version number of class
   Int_t                    fID;            //  element serial number in fInfo
   Int_t                    fType;          //  branch type
   Int_t                    fStreamerType;  //  branch streamer type
   Int_t                    fMaximum;       //  Maximum entries for a TClonesArray or variable array
   Int_t                    fSTLtype;       //! STL container type
   Int_t                    fNdata;         //! Number of data in this branch
   TBranchElement          *fBranchCount;   //  pointer to primary branchcount branch
   TBranchElement          *fBranchCount2;  //  pointer to secondary branchcount branch
   TStreamerInfo           *fInfo;          //! Pointer to StreamerInfo
   char                    *fObject;        //! Pointer to object at *fAddress
   TVirtualArray           *fOnfileObject;  //! Place holder for the onfile representation of data members.
   Bool_t                   fInit;          //! Initialization flag for branch assignment
   Bool_t                   fInitOffsets;   //! Initialization flag to not endlessly recalculate offsets
   TClassRef                fTargetClass;   //! Reference to the target in-memory class
   TClassRef                fCurrentClass;  //! Reference to current (transient) class definition
   TClassRef                fParentClass;   //! Reference to class definition in fParentName
   TClassRef                fBranchClass;   //! Reference to class definition in fClassName
   TClassRef                fClonesClass;   //! Reference to class definition in fClonesName
   Int_t                   *fBranchOffset;  //! Sub-Branch offsets with respect to current transient class
   Int_t                    fBranchID;      //! ID number assigned by a TRefTable.
   std::vector<Int_t>       fIDs;           //! List of the serial number of all the StreamerInfo to be used.
   TStreamerInfoActions::TActionSequence *fReadActionSequence;  //! Set of actions to be executed to extract the data from the basket.
   TStreamerInfoActions::TActionSequence *fFillActionSequence; //! Set of actions to be executed to write the data to the basket.
   TVirtualCollectionIterators           *fIterators;     //! holds the iterators when the branch is of fType==4.
   TVirtualCollectionIterators           *fWriteIterators;//! holds the read (non-staging) iterators when the branch is of fType==4 and associative containers.
   TVirtualCollectionPtrIterators        *fPtrIterators;  //! holds the iterators when the branch is of fType==4 and it is a split collection of pointers.

// Not implemented
private:
   TBranchElement(const TBranchElement&);            // not implemented
   TBranchElement& operator=(const TBranchElement&); // not implemented

   static void SwitchContainer(TObjArray *);

// Implementation use only functions.
protected:
   void                     BuildTitle(const char* name);
   virtual void             InitializeOffsets();
   virtual void             InitInfo();
   Bool_t                   IsMissingCollection() const;
   TClass                  *GetParentClass(); // Class referenced by fParentName
   TStreamerInfo           *GetInfoImp() const;
   void                     ReleaseObject();
   void                     SetBranchCount(TBranchElement* bre);
   void                     SetBranchCount2(TBranchElement* bre) { fBranchCount2 = bre; }
   Int_t                    Unroll(const char* name, TClass* cltop, TClass* cl, char* ptr, Int_t basketsize, Int_t splitlevel, Int_t btype);
   inline void              ValidateAddress() const;

   void Init(TTree *tree, TBranch *parent, const char* name, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t btype = 0);
   void Init(TTree *tree, TBranch *parent, const char* name, TClonesArray* clones, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);
   void Init(TTree *tree, TBranch *parent, const char* name, TVirtualCollectionProxy* cont, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);

   void ReadLeavesImpl(TBuffer& b);
   void ReadLeavesMakeClass(TBuffer& b);
   void ReadLeavesCollection(TBuffer& b);
   void ReadLeavesCollectionSplitPtrMember(TBuffer& b);
   void ReadLeavesCollectionSplitVectorPtrMember(TBuffer& b);
   void ReadLeavesCollectionMember(TBuffer& b);
   void ReadLeavesClones(TBuffer& b);
   void ReadLeavesClonesMember(TBuffer& b);
   void ReadLeavesCustomStreamer(TBuffer& b);
   void ReadLeavesMember(TBuffer& b);
   void ReadLeavesMemberBranchCount(TBuffer& b);
   void ReadLeavesMemberCounter(TBuffer& b);
   void SetReadLeavesPtr();
   void SetReadActionSequence();
   void SetupAddressesImpl();

   void FillLeavesImpl(TBuffer& b);
   void FillLeavesMakeClass(TBuffer& b);
   void FillLeavesCollection(TBuffer& b);
   void FillLeavesCollectionSplitVectorPtrMember(TBuffer& b);
   void FillLeavesCollectionSplitPtrMember(TBuffer& b);
   void FillLeavesCollectionMember(TBuffer& b);
   void FillLeavesAssociativeCollectionMember(TBuffer& b);
   void FillLeavesClones(TBuffer& b);
   void FillLeavesClonesMember(TBuffer& b);
   void FillLeavesCustomStreamer(TBuffer& b);
   void FillLeavesMemberBranchCount(TBuffer& b);
   void FillLeavesMemberCounter(TBuffer& b);
   void FillLeavesMember(TBuffer& b);
   void SetFillLeavesPtr();
   void SetFillActionSequence();
// Public Interface.
public:
   TBranchElement();
   TBranchElement(TTree *tree, const char* name, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t btype = 0);
   TBranchElement(TTree *tree, const char* name, TClonesArray* clones, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);
   TBranchElement(TTree *tree, const char* name, TVirtualCollectionProxy* cont, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);
   TBranchElement(TBranch *parent, const char* name, TStreamerInfo* sinfo, Int_t id, char* pointer, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t btype = 0);
   TBranchElement(TBranch *parent, const char* name, TClonesArray* clones, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);
   TBranchElement(TBranch *parent, const char* name, TVirtualCollectionProxy* cont, Int_t basketsize = 32000, Int_t splitlevel = 0, Int_t compress = -1);

   virtual                  ~TBranchElement();

   virtual void             Browse(TBrowser* b);
   virtual Int_t            Fill();
   virtual TBranch         *FindBranch(const char *name);
   virtual TLeaf           *FindLeaf(const char *name);
   virtual char            *GetAddress() const;
           TBranchElement  *GetBranchCount() const { return fBranchCount; }
           TBranchElement  *GetBranchCount2() const { return fBranchCount2; }
           Int_t           *GetBranchOffset() const { return fBranchOffset; }
           UInt_t           GetCheckSum() { return fCheckSum; }
   virtual const char      *GetClassName() const { return fClassName.Data(); }
   virtual TClass          *GetClass() const { return fBranchClass; }
   virtual const char      *GetClonesName() const { return fClonesName.Data(); }
   TVirtualCollectionProxy *GetCollectionProxy();
   TClass                  *GetCurrentClass(); // Class referenced by transient description
   virtual Int_t            GetEntry(Long64_t entry = 0, Int_t getall = 0);
   virtual Int_t            GetExpectedType(TClass *&clptr,EDataType &type);
           const char      *GetIconName() const;
           Int_t            GetID() const { return fID; }
           TStreamerInfo   *GetInfo() const;
           Bool_t           GetMakeClass() const;
           char            *GetObject() const;
   virtual const char      *GetParentName() const { return fParentName.Data(); }
   virtual Int_t            GetMaximum() const;
           Int_t            GetNdata() const { return fNdata; }
           Int_t            GetType() const { return fType; }
           Int_t            GetStreamerType() const { return fStreamerType; }
   virtual TClass          *GetTargetClass() { return fTargetClass; }
   virtual const char      *GetTypeName() const;
           Double_t         GetValue(Int_t i, Int_t len, Bool_t subarr = kFALSE) const { return GetTypedValue<Double_t>(i, len, subarr); }
   template<typename T > 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             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);
   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();

   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
   };

   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<TBranchElement*>(this)->ResetBit(kDeleteObject);
         }
         const_cast<TBranchElement*>(this)->SetAddress(fAddress);
      }
   }
}

#endif // ROOT_TBranchElement
 TBranchElement.h:1
 TBranchElement.h:2
 TBranchElement.h:3
 TBranchElement.h:4
 TBranchElement.h:5
 TBranchElement.h:6
 TBranchElement.h:7
 TBranchElement.h:8
 TBranchElement.h:9
 TBranchElement.h:10
 TBranchElement.h:11
 TBranchElement.h:12
 TBranchElement.h:13
 TBranchElement.h:14
 TBranchElement.h:15
 TBranchElement.h:16
 TBranchElement.h:17
 TBranchElement.h:18
 TBranchElement.h:19
 TBranchElement.h:20
 TBranchElement.h:21
 TBranchElement.h:22
 TBranchElement.h:23
 TBranchElement.h:24
 TBranchElement.h:25
 TBranchElement.h:26
 TBranchElement.h:27
 TBranchElement.h:28
 TBranchElement.h:29
 TBranchElement.h:30
 TBranchElement.h:31
 TBranchElement.h:32
 TBranchElement.h:33
 TBranchElement.h:34
 TBranchElement.h:35
 TBranchElement.h:36
 TBranchElement.h:37
 TBranchElement.h:38
 TBranchElement.h:39
 TBranchElement.h:40
 TBranchElement.h:41
 TBranchElement.h:42
 TBranchElement.h:43
 TBranchElement.h:44
 TBranchElement.h:45
 TBranchElement.h:46
 TBranchElement.h:47
 TBranchElement.h:48
 TBranchElement.h:49
 TBranchElement.h:50
 TBranchElement.h:51
 TBranchElement.h:52
 TBranchElement.h:53
 TBranchElement.h:54
 TBranchElement.h:55
 TBranchElement.h:56
 TBranchElement.h:57
 TBranchElement.h:58
 TBranchElement.h:59
 TBranchElement.h:60
 TBranchElement.h:61
 TBranchElement.h:62
 TBranchElement.h:63
 TBranchElement.h:64
 TBranchElement.h:65
 TBranchElement.h:66
 TBranchElement.h:67
 TBranchElement.h:68
 TBranchElement.h:69
 TBranchElement.h:70
 TBranchElement.h:71
 TBranchElement.h:72
 TBranchElement.h:73
 TBranchElement.h:74
 TBranchElement.h:75
 TBranchElement.h:76
 TBranchElement.h:77
 TBranchElement.h:78
 TBranchElement.h:79
 TBranchElement.h:80
 TBranchElement.h:81
 TBranchElement.h:82
 TBranchElement.h:83
 TBranchElement.h:84
 TBranchElement.h:85
 TBranchElement.h:86
 TBranchElement.h:87
 TBranchElement.h:88
 TBranchElement.h:89
 TBranchElement.h:90
 TBranchElement.h:91
 TBranchElement.h:92
 TBranchElement.h:93
 TBranchElement.h:94
 TBranchElement.h:95
 TBranchElement.h:96
 TBranchElement.h:97
 TBranchElement.h:98
 TBranchElement.h:99
 TBranchElement.h:100
 TBranchElement.h:101
 TBranchElement.h:102
 TBranchElement.h:103
 TBranchElement.h:104
 TBranchElement.h:105
 TBranchElement.h:106
 TBranchElement.h:107
 TBranchElement.h:108
 TBranchElement.h:109
 TBranchElement.h:110
 TBranchElement.h:111
 TBranchElement.h:112
 TBranchElement.h:113
 TBranchElement.h:114
 TBranchElement.h:115
 TBranchElement.h:116
 TBranchElement.h:117
 TBranchElement.h:118
 TBranchElement.h:119
 TBranchElement.h:120
 TBranchElement.h:121
 TBranchElement.h:122
 TBranchElement.h:123
 TBranchElement.h:124
 TBranchElement.h:125
 TBranchElement.h:126
 TBranchElement.h:127
 TBranchElement.h:128
 TBranchElement.h:129
 TBranchElement.h:130
 TBranchElement.h:131
 TBranchElement.h:132
 TBranchElement.h:133
 TBranchElement.h:134
 TBranchElement.h:135
 TBranchElement.h:136
 TBranchElement.h:137
 TBranchElement.h:138
 TBranchElement.h:139
 TBranchElement.h:140
 TBranchElement.h:141
 TBranchElement.h:142
 TBranchElement.h:143
 TBranchElement.h:144
 TBranchElement.h:145
 TBranchElement.h:146
 TBranchElement.h:147
 TBranchElement.h:148
 TBranchElement.h:149
 TBranchElement.h:150
 TBranchElement.h:151
 TBranchElement.h:152
 TBranchElement.h:153
 TBranchElement.h:154
 TBranchElement.h:155
 TBranchElement.h:156
 TBranchElement.h:157
 TBranchElement.h:158
 TBranchElement.h:159
 TBranchElement.h:160
 TBranchElement.h:161
 TBranchElement.h:162
 TBranchElement.h:163
 TBranchElement.h:164
 TBranchElement.h:165
 TBranchElement.h:166
 TBranchElement.h:167
 TBranchElement.h:168
 TBranchElement.h:169
 TBranchElement.h:170
 TBranchElement.h:171
 TBranchElement.h:172
 TBranchElement.h:173
 TBranchElement.h:174
 TBranchElement.h:175
 TBranchElement.h:176
 TBranchElement.h:177
 TBranchElement.h:178
 TBranchElement.h:179
 TBranchElement.h:180
 TBranchElement.h:181
 TBranchElement.h:182
 TBranchElement.h:183
 TBranchElement.h:184
 TBranchElement.h:185
 TBranchElement.h:186
 TBranchElement.h:187
 TBranchElement.h:188
 TBranchElement.h:189
 TBranchElement.h:190
 TBranchElement.h:191
 TBranchElement.h:192
 TBranchElement.h:193
 TBranchElement.h:194
 TBranchElement.h:195
 TBranchElement.h:196
 TBranchElement.h:197
 TBranchElement.h:198
 TBranchElement.h:199
 TBranchElement.h:200
 TBranchElement.h:201
 TBranchElement.h:202
 TBranchElement.h:203
 TBranchElement.h:204
 TBranchElement.h:205
 TBranchElement.h:206
 TBranchElement.h:207
 TBranchElement.h:208
 TBranchElement.h:209
 TBranchElement.h:210
 TBranchElement.h:211
 TBranchElement.h:212
 TBranchElement.h:213
 TBranchElement.h:214
 TBranchElement.h:215
 TBranchElement.h:216
 TBranchElement.h:217
 TBranchElement.h:218
 TBranchElement.h:219
 TBranchElement.h:220
 TBranchElement.h:221
 TBranchElement.h:222
 TBranchElement.h:223
 TBranchElement.h:224
 TBranchElement.h:225
 TBranchElement.h:226
 TBranchElement.h:227
 TBranchElement.h:228
 TBranchElement.h:229
 TBranchElement.h:230
 TBranchElement.h:231
 TBranchElement.h:232
 TBranchElement.h:233
 TBranchElement.h:234
 TBranchElement.h:235
 TBranchElement.h:236
 TBranchElement.h:237
 TBranchElement.h:238
 TBranchElement.h:239
 TBranchElement.h:240
 TBranchElement.h:241
 TBranchElement.h:242
 TBranchElement.h:243
 TBranchElement.h:244
 TBranchElement.h:245
 TBranchElement.h:246
 TBranchElement.h:247
 TBranchElement.h:248
 TBranchElement.h:249
 TBranchElement.h:250
 TBranchElement.h:251
 TBranchElement.h:252
 TBranchElement.h:253
 TBranchElement.h:254
 TBranchElement.h:255
 TBranchElement.h:256
 TBranchElement.h:257
 TBranchElement.h:258
 TBranchElement.h:259
 TBranchElement.h:260
 TBranchElement.h:261
 TBranchElement.h:262
 TBranchElement.h:263
 TBranchElement.h:264
 TBranchElement.h:265
 TBranchElement.h:266
 TBranchElement.h:267
 TBranchElement.h:268
 TBranchElement.h:269
 TBranchElement.h:270
 TBranchElement.h:271
 TBranchElement.h:272
 TBranchElement.h:273
 TBranchElement.h:274
 TBranchElement.h:275