41 const char* branchname ,
44 fHaveStaticClassOffsets(0),
45 fReadStatus(kReadNothingYet),
46 fBranchName(branchname),
57 fHaveLeaf(rhs.fHaveLeaf),
58 fHaveStaticClassOffsets(rhs.fHaveStaticClassOffsets),
59 fReadStatus(rhs.fReadStatus),
60 fSetupStatus(rhs.fSetupStatus),
61 fBranchName(rhs.fBranchName),
62 fLeafName(rhs.fLeafName),
63 fTreeReader(rhs.fTreeReader),
67 fStaticClassOffsets(rhs.fStaticClassOffsets)
84 fTreeReader->DeregisterValueReader(
this);
86 RegisterWithTreeReader();
103 if (fTreeReader) fTreeReader->DeregisterValueReader(
this);
104 R__ASSERT((fLeafName.Length() == 0 ) == !fHaveLeaf
105 &&
"leafness disagreement");
106 R__ASSERT(fStaticClassOffsets.empty() == !fHaveStaticClassOffsets
107 &&
"static class offset disagreement");
115 if (!fTreeReader->RegisterValueReader(
this)) {
116 fTreeReader =
nullptr;
127 if (!fProxy)
return kReadNothingYet;
128 if (fProxy->Read()) {
129 fReadStatus = kReadSuccess;
131 fReadStatus = kReadError;
141 std::string ret = buf;
156 fReadStatus = kReadError;
157 Error(
"TTreeReaderValueBase::GetLeaf()",
"Unable to get the branch from the tree");
161 fLeaf = myBranch->
GetLeaf(fLeafName);
163 Error(
"TTreeReaderValueBase::GetLeaf()",
"Failed to get the leaf from the branch");
171 if (ProxyRead() != kReadSuccess)
return 0;
175 return fLeaf->GetValuePointer();
178 fReadStatus = kReadError;
179 Error(
"TTreeReaderValueBase::GetAddress()",
"Unable to get the leaf");
183 if (fHaveStaticClassOffsets){
186 for (
unsigned int i = 0; i < fStaticClassOffsets.size() - 1; ++i){
187 address = *(
Byte_t**)(address + fStaticClassOffsets[i]);
190 return address + fStaticClassOffsets.back();
192 return (
Byte_t*)fProxy->GetWhere();
203 fSetupStatus = kSetupInternalError;
205 Error(
"TTreeReaderValueBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
207 fSetupStatus = kSetupTreeDestructed;
212 const char* brDataType =
"{UNDETERMINED}";
215 brDataType = GetBranchDataType(br, brDictUnused);
217 Error(
"TTreeReaderValueBase::CreateProxy()",
"The template argument type T of %s accessing branch %s (which contains data of type %s) is not known to ROOT. You will need to create a dictionary for it.",
218 GetDerivedTypeName(), fBranchName.Data(), brDataType);
219 fSetupStatus = kSetupMissingDictionary;
228 if (namedProxy && namedProxy->
GetDict() == fDict) {
230 fSetupStatus = kSetupMatch;
235 TLeaf *myLeaf = NULL;
239 if (fBranchName.Contains(
".")){
240 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
241 TString leafName (fBranchName(leafNameExpression));
245 std::vector<TString> nameStack;
246 nameStack.push_back(
TString());
251 branch = fTreeReader->GetTree()->GetBranch(
branchName);
252 if (!branch) branch = fTreeReader->GetTree()->GetBranch(
branchName +
".");
258 branch = fTreeReader->GetTree()->GetBranch(
branchName);
259 if (!branch) branch = fTreeReader->GetTree()->GetBranch(
branchName +
".");
266 TString traversingBranch = nameStack.back();
267 nameStack.pop_back();
273 std::vector<Long64_t> offsets;
280 while (nameStack.size() && found){
283 for (
int i = 0; i < myObjArray->
GetEntries(); ++i){
287 if (!strcmp(tempStreamerElement->
GetName(), traversingBranch.
Data())){
290 traversingBranch = nameStack.back();
291 nameStack.pop_back();
293 elementClass = tempStreamerElement->
GetClass();
301 if (!finalDataType) {
310 offsets.push_back(offset);
320 offsets.push_back(offset);
323 fStaticClassOffsets = offsets;
324 fHaveStaticClassOffsets = 1;
326 if (fDict != finalDataType && fDict != elementClass){
327 Error(
"TTreeReaderValueBase::CreateProxy",
"Wrong data type %s", finalDataType ? finalDataType->
GetName() : elementClass ? elementClass->
GetName() :
"UNKNOWN");
328 fSetupStatus = kSetupMismatch;
336 if (!fHaveStaticClassOffsets) {
337 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
338 fSetupStatus = kSetupMissingBranch;
344 myLeaf = branch->GetLeaf(
TString(leafName(1, leafName.
Length())));
346 Error(
"TTreeReaderValueBase::CreateProxy()",
347 "The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
348 fSetupStatus = kSetupMissingBranch;
356 branchActualType = fDict;
359 fLeafName = leafName(1, leafName.
Length());
360 fHaveLeaf = fLeafName.
Length() > 0;
361 fSetupStatus = kSetupMatchLeaf;
364 Error(
"TTreeReaderValueBase::CreateProxy()",
365 "Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
366 fSetupStatus = kSetupMismatch;
372 Error(
"TTreeReaderValueBase::CreateProxy()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
378 if (!myLeaf && !fHaveStaticClassOffsets) {
379 const char* branchActualTypeName = GetBranchDataType(branch, branchActualType);
381 if (!branchActualType) {
382 Error(
"TTreeReaderValueBase::CreateProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
383 fBranchName.Data(), branchActualTypeName ? branchActualTypeName :
"{UNDETERMINED TYPE}");
388 if (fDict != branchActualType) {
391 bool complainAboutMismatch =
true;
392 if (dictdt && actualdt) {
395 complainAboutMismatch =
false;
400 complainAboutMismatch =
false;
403 if (complainAboutMismatch) {
404 Error(
"TTreeReaderValueBase::CreateProxy()",
405 "The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderValue<%s>",
406 fBranchName.Data(), branchActualType->
GetName(),
415 if (namedProxy && !namedProxy->
GetDict()) {
419 fSetupStatus = kSetupMatch;
430 bool isTopLevel = branch->
GetMother() == branch;
432 membername = strrchr(branch->
GetName(),
'.');
433 if (membername.
IsNull()) {
434 membername = branch->
GetName();
438 fTreeReader->GetProxies()->Add(namedProxy);
441 fSetupStatus = kSetupMatch;
443 fSetupStatus = kSetupMismatch;
507 return "TClonesArray";
508 }
else if (brElement->
GetType() == 31
509 || brElement->
GetType() == 41) {
511 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Must use TTreeReaderArray to access a member of an object that is stored in a collection.");
517 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"Unknown type and class combination: %i, %s", brElement->
GetType(), brElement->
GetClassName());
528 if ((!dataTypeName || !dataTypeName[0])
541 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderArray:", branch->
GetName());
544 while ((leaf = (
TLeaf*) iLeaves())) {
545 Error(
"TTreeReaderValueBase::GetBranchDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
553 return "TClonesArray";
556 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
559 Error(
"TTreeReaderValueBase::GetBranchDataType()",
"The branch %s is of type %s - something that is not handled yet.", branch->
GetName(), branch->IsA()->
GetName());
Describe Streamer information for one class version
virtual const char * GetName() const
Returns name of object.
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
A TLeaf describes individual elements of a TBranch See TBranch structure in TTree.
static TDataType * GetDataType(EDataType type)
Given a EDataType type, get the TDataType* that represents it.
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
virtual const char * GetTypeName() const
int fHaveStaticClassOffsets
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist...
virtual ~TTreeReaderValueBase()
Unregister from tree reader, cleanup.
Regular expression class.
static TDictionary * GetDictionary(const char *name)
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
std::vector< Long64_t > fStaticClassOffsets
Type GetType(const std::string &Name)
TObject * At(Int_t idx) const
const Detail::TBranchProxy * GetProxy() const
TDictionary * GetDict() const
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
std::string ResolveTypedef(const char *tname, bool resolveAll=false)
ESetupStatus fSetupStatus
char * DemangleTypeIdName(const std::type_info &ti, int &errorCode)
Demangle in a portable way the type id name.
TTreeReaderValueBase & operator=(const TTreeReaderValueBase &)
Copy-assign.
virtual TBranch * GetBranch(const char *name)
Return pointer to the branch with the given name in this tree or its friends.
virtual const char * GetTypeName() const
Return type name of element in the branch.
void SetDict(TDictionary *dict)
void RegisterWithTreeReader()
Register with tree reader.
virtual TObject * FindObject(const char *name) const
Must be redefined in derived classes.
TTreeReader * fTreeReader
TTreeReaderValueBase(TTreeReader *reader, const char *branchname, TDictionary *dict)
Construct a tree value reader and register it with the reader object.
Basic data type descriptor (datatype information is obtained from CINT).
This class defines an abstract interface that must be implemented by all classes that contain diction...
virtual void CreateProxy()
Create the proxy object for our branch.
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
TSubString Strip(EStripType s=kTrailing, char c=' ') const
Return a substring of self stripped at beginning and/or end.
void * GetAddress()
Returns the memory address of the object being read.
The ROOT global object gROOT contains a list of all defined classes.
A Branch for the case of an object.
static std::string GetElementTypeName(const std::type_info &ti)
Stringify the template argument.
virtual TObjArray * GetElements() const =0
virtual Bool_t IsaPointer() const
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
TObjArray * GetListOfLeaves()
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
TObjArray * GetElements() const
const char * GetTypeName() const
Detail::TBranchProxy * fProxy
void NotifyNewTree(TTree *newTree)
The TTreeReader has switched to a new TTree. Update the leaf.
Int_t GetEntries() const
Return the number of objects in array (i.e.
A TTree object has a header with a name and a title.
A TTree is a list of TBranches.
Abstract Interface class describing Streamer information for one class.
const char * GetBranchDataType(TBranch *branch, TDictionary *&dict) const
Retrieve the type of data stored by branch; put its dictionary into dict, return its type name...
TBranch * GetMother() const
Get our top-level parent branch in the tree.
virtual Int_t GetElementOffset(Int_t id) const =0
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
TClass * GetClass() const
const char * Data() const