43 Error(
"TClonesReader::GetCA()",
"Read error in TBranchProxy.");
72 Error(
"TSTLReader::GetCP()",
"Read error in TBranchProxy.");
76 Error(
"TSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
85 if (!myCollectionProxy)
return 0;
86 return myCollectionProxy->
Size();
91 if (!myCollectionProxy)
return 0;
93 return *(
void**)myCollectionProxy->
At(idx);
96 return myCollectionProxy->
At(idx);
108 if (!proxy->
Read()) {
110 Error(
"TCollectionLessSTLReader::GetCP()",
"Read error in TBranchProxy.");
114 Error(
"TCollectionLessSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
118 return fLocalCollection;
123 if (!myCollectionProxy)
return 0;
128 return myCollectionProxy->
Size();
133 if (!myCollectionProxy)
return 0;
140 return *(
void**)myCollectionProxy->
At(idx);
142 return myCollectionProxy->
At(idx);
152 Int_t fBasicTypeSize;
154 TObjectArrayReader() : fBasicTypeSize(-1) { }
155 ~TObjectArrayReader() {}
159 Error(
"TObjectArrayReader::GetCP()",
"Read error in TBranchProxy.");
167 if (!myCollectionProxy)
return 0;
168 return myCollectionProxy->
Size();
171 if (!proxy->
Read())
return 0;
174 void *array = (
void*)proxy->
GetStart();
176 if (fBasicTypeSize == -1){
179 Error(
"TObjectArrayReader::At()",
"Cannot get class info from branch proxy.");
185 objectSize = fBasicTypeSize;
187 return (
void*)((
Byte_t*)array + (objectSize * idx));
190 void SetBasicTypeSize(
Int_t size){
191 fBasicTypeSize = size;
195 template <
class BASE>
196 class TUIntOrIntReader:
public BASE {
199 std::unique_ptr<TTreeReaderValueBase> fSizeReader;
200 bool fIsUnsigned =
false;
209 template <
class...
ARGS>
210 TUIntOrIntReader(
TTreeReader *treeReader,
const char *leafName,
212 BASE(std::forward<ARGS>(args)...)
214 if (
TLeaf* sizeLeaf = treeReader->
GetTree()->FindLeaf(leafName)) {
215 fIsUnsigned = sizeLeaf->IsUnsigned();
226 return *GetSizeReader<UInt_t>();
227 return *GetSizeReader<Int_t>();
231 class TArrayParameterSizeReader:
public TUIntOrIntReader<TObjectArrayReader> {
234 TUIntOrIntReader<TObjectArrayReader>(treeReader,
branchName) {}
238 class TArrayFixedSizeReader :
public TObjectArrayReader {
243 TArrayFixedSizeReader(
Int_t sizeArg) : fSize(sizeArg) {}
250 ~TBasicTypeArrayReader() {}
255 Error(
"TBasicTypeArrayReader::GetCP()",
"Read error in TBranchProxy.");
264 if (!myCollectionProxy)
return 0;
265 return myCollectionProxy->
Size();
270 if (!myCollectionProxy)
return 0;
275 class TBasicTypeClonesReader :
public TClonesReader {
279 TBasicTypeClonesReader(
Int_t offsetArg) : fOffset(offsetArg) {}
283 if (!myClonesArray)
return 0;
284 return (
Byte_t*)myClonesArray->
At(idx) + fOffset;
293 TLeafReader(
TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
297 return myLeaf ? myLeaf->
GetLen() : 0;
303 if (fElementSize == -1){
305 if (!myLeaf)
return 0;
308 return (
Byte_t*)address + (fElementSize * idx);
317 class TLeafParameterSizeReader:
public TUIntOrIntReader<TLeafReader> {
319 TLeafParameterSizeReader(
TTreeReader *treeReader,
const char *leafName,
321 TUIntOrIntReader<TLeafReader>(treeReader, leafName, valueReaderArg) {}
325 return TUIntOrIntReader<TLeafReader>::GetSize(proxy);
346 fSetupStatus = kSetupInternalError;
348 Error(
"TTreeReaderArrayBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
350 fSetupStatus = kSetupTreeDestructed;
355 const char* brDataType =
"{UNDETERMINED}";
358 brDataType = GetBranchDataType(br, dictUnused);
360 Error(
"TTreeReaderArrayBase::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.",
361 GetDerivedTypeName(), fBranchName.Data(), brDataType);
362 fSetupStatus = kSetupMissingDictionary;
373 TLeaf *myLeaf =
nullptr;
374 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
378 Error(
"TTreeReaderArrayBase::CreateProxy()",
379 "No dictionary for branch %s.", fBranchName.Data());
386 fSetupStatus = kSetupMatch;
388 SetImpl(branch, myLeaf);
397 fSetupStatus = kSetupMatch;
399 Error(
"TTreeReaderArrayBase::CreateProxy()",
400 "Type ambiguity (want %s, have %s) for branch %s.",
407 bool isTopLevel = branch->
GetMother() == branch;
409 membername = strrchr(branch->
GetName(),
'.');
410 if (membername.IsNull()) {
411 membername = branch->
GetName();
414 namedProxy =
new TNamedBranchProxy(fTreeReader->fDirector, branch, fBranchName, membername);
415 fTreeReader->AddProxy(namedProxy);
418 fSetupStatus = kSetupMatch;
420 fSetupStatus = kSetupMismatch;
424 TString branchActualTypeName;
425 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
426 if (nonCollTypeName) {
427 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
428 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
429 if (fSetupStatus == kSetupInternalError)
430 fSetupStatus = kSetupNotACollection;
434 if (!branchActualType) {
435 if (branchActualTypeName.IsNull()) {
436 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
439 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
440 fBranchName.Data(), branchActualTypeName.Data());
441 if (fSetupStatus == kSetupInternalError)
442 fSetupStatus = kSetupMissingDictionary;
448 if (fDict != branchActualType) {
449 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
450 fBranchName.Data(), branchActualType->
GetName(), fDict->GetName());
451 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
452 fSetupStatus = kSetupMismatch;
464 SetImpl(branch, myLeaf);
473 branch = fTreeReader->
GetTree()->GetBranch(fBranchName);
477 if (!fBranchName.Contains(
".")) {
478 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
479 fSetupStatus = kSetupMissingBranch;
484 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
485 TString leafName (fBranchName(leafNameExpression));
486 TString
branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
487 branch = fTreeReader->
GetTree()->GetBranch(branchName);
489 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
490 fSetupStatus = kSetupMissingBranch;
495 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
497 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch, nor a sub-branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
498 fSetupStatus = kSetupMissingBranch;
505 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Failed to get the dictionary for %s.", myLeaf->
GetTypeName());
506 fSetupStatus = kSetupMissingDictionary;
513 branchActualType = fDict;
516 fLeafName = leafName(1, leafName.Length());
517 fHaveLeaf = (fLeafName.Length() > 0);
518 fSetupStatus = kSetupMatchLeaf;
521 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
523 fSetupStatus = kSetupMismatch;
549 fImpl =
new TLeafReader(
this);
555 fImpl =
new TLeafParameterSizeReader(fTreeReader, leafFullName.Data(),
this);
557 fSetupStatus = kSetupMatchLeaf;
571 if (fSetupStatus == kSetupInternalError)
572 fSetupStatus = kSetupMatch;
574 fImpl =
new TSTLReader();
580 fImpl =
new TClonesReader();
591 fImpl =
new TBasicTypeArrayReader();
594 fImpl =
new TBasicTypeClonesReader(element->
GetOffset());
598 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
603 ((TArrayParameterSizeReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
606 fImpl =
new TClonesReader();
608 Error(
"TTreeReaderArrayBase::SetImpl()",
609 "Cannot read branch %s: unhandled streamer element type %s",
610 fBranchName.Data(), element->IsA()->
GetName());
611 fSetupStatus = kSetupInternalError;
622 Error(
"TTreeReaderArrayBase::SetImpl",
"Failed to get the top leaf from the branch");
623 fSetupStatus = kSetupMissingBranch;
628 if (fSetupStatus == kSetupInternalError)
629 fSetupStatus = kSetupMatch;
631 fImpl =
new TArrayFixedSizeReader(size);
634 fImpl =
new TArrayParameterSizeReader(fTreeReader, sizeLeaf->
GetName());
636 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
638 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchClones not implemented");
639 fSetupStatus = kSetupInternalError;
641 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchObject not implemented");
642 fSetupStatus = kSetupInternalError;
644 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchSTL not implemented");
645 fImpl =
new TSTLReader();
646 fSetupStatus = kSetupInternalError;
648 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchRef not implemented");
649 fSetupStatus = kSetupInternalError;
664 TString& contentTypeName,
668 contentTypeName =
"";
672 || brElement->
GetType() == 3) {
677 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Could not get value class.");
686 if (brElement->
GetType() == 3) {
695 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Cannot determine STL collection type of %s stored in branch %s", brElement->
GetClassName(), branch->
GetName());
700 if (isMap) contentTypeName =
"std::pair< ";
701 contentTypeName += splitType.fElements[1];
703 contentTypeName += splitType.fElements[2];
704 contentTypeName +=
" >";
709 }
else if (brElement->
GetType() == 31
710 || brElement->
GetType() == 41) {
715 if (ExpectedTypeRet == 0) {
721 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
722 branch->
GetName(), (int)dtData);
727 }
else if (ExpectedTypeRet == 1) {
728 int brID = brElement->
GetID();
731 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
746 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
758 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get class from branch element.");
762 if (!myCollectionProxy){
763 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get collection proxy from STL class");
771 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get valueClass from collectionProxy.");
774 contentTypeName = dict->
GetName();
778 if (!fProxy->Setup() || !fProxy->Read()){
779 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Failed to get type from proxy, unable to check type");
780 contentTypeName =
"UNKNOWN";
782 return contentTypeName;
786 contentTypeName = dict->
GetName();
800 contentTypeName =
"TClonesArray";
801 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
803 fSetupStatus = kSetupNoCheck;
810 if (dict) contentTypeName = dict->
GetName();
815 contentTypeName = dict->
GetName();
826 if ((!dataTypeName || !dataTypeName[0])
839 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"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());
842 while ((leaf = (
TLeaf*) iLeaves())) {
843 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
849 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
851 fSetupStatus = kSetupNoCheck;
857 return "TClonesArray";
860 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
863 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"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.
TVirtualCollectionProxy * GetCollectionProxy()
Return the collection proxy describing the branch content, if any.
const char * GetBranchContentDataType(TBranch *branch, TString &contentTypeName, TDictionary *&dict)
Access a branch's collection content (not the collection itself) through a proxy. ...
TString GetTypeName()
Get basic type of typedef, e,g.
Int_t GetSplitLevel() const
virtual Int_t GetExpectedType(TClass *&clptr, EDataType &type)
Fill expectedClass and expectedType with information on the data type of the object/values contained ...
TTreeReader is a simple, robust and fast interface to read values from a TTree, TChain or TNtuple...
virtual TClass * GetValueClass() const =0
TStreamerElement * GetElement(Int_t id) const
virtual void PushProxy(void *objectstart)=0
virtual const char * GetTypeName() const
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf (if any) or store the number of elements that the leaf c...
Regular expression class.
virtual void CreateProxy()
Create the proxy object for our branch.
static TDictionary * GetDictionary(const char *name)
TStreamerInfo * GetInfo() const
Get streamer info for the branch class.
TVirtualCollectionProxy * GetCollectionProxy() const
Return the proxy describing the collection (if any).
virtual void * GetStart(UInt_t=0)
Int_t GetArrayLength() const
EReadStatus ProxyRead()
Try to read the value from the TBranchProxy, returns the status of the read.
Type GetType(const std::string &Name)
TObject * At(Int_t idx) const
virtual EDataType GetType() const =0
void SetContentDict(TDictionary *dict)
TBranchElement * GetBranchCount() const
const Detail::TBranchProxy * GetProxy() const
virtual TLeaf * GetLeaf(const char *name) const
Return pointer to the 1st Leaf named name in thisBranch.
int IsSTLCont(int testAlloc=0) const
type : type name: vector<list<classA,allocator>,allocator> testAlloc: if true, we test allocator...
virtual Int_t GetLenType() const
TDictionary * GetContentDict() const
Extracts data from a TTree.
virtual const char * GetClonesName() const
TTreeReaderValueBase::EReadStatus fReadStatus
bool GetBranchAndLeaf(TBranch *&branch, TLeaf *&myLeaf, TDictionary *&branchActualType)
Determine the branch / leaf and its type; reset fProxy / fSetupStatus on error.
virtual Int_t GetLen() const
Return the number of effective elements of this leaf, for the current entry.
virtual const char * GetTypeName() const
Return type name of element in the branch.
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 Bool_t HasPointers() const =0
virtual TLeaf * GetLeafCount() const
If this leaf stores a variable-sized array or a multi-dimensional array whose last dimension has vari...
TClass * GetCurrentClass()
Return a pointer to the current type of the data member corresponding to branch element.
void * GetAddress()
Returns the memory address of the object being read.
The ROOT global object gROOT contains a list of all defined classes.
void Warning(const char *location, const char *msgfmt,...)
A Branch for the case of an object.
virtual void PopProxy()=0
TObject * UncheckedAt(Int_t i) const
TVirtualCollectionProxy * GetCollection()
virtual const char * GetClassName() const
Return the name of the user class whose content is stored in this branch, if any. ...
virtual void * At(UInt_t idx)=0
TObjArray * GetListOfLeaves()
TClass * GetClass() const
TLeaf * GetLeaf()
If we are reading a leaf, return the corresponding TLeaf.
Int_t GetClassSize() const
TObjArray * GetElements() const
virtual UInt_t Size() const =0
An array of clone (identical) objects.
const char * GetTypeName() const
virtual ~TVirtualCollectionReader()
virtual TClass * GetClass() const
Int_t GetEntries() const
Return the number of objects in array (i.e.
virtual void * At(Detail::TBranchProxy *, size_t)=0
Base class for all the proxy object.
TBranch * GetBranch() const
A TTree is a list of TBranches.
TBranch * GetMother() const
Get our top-level parent branch in the tree.
void Error(ErrorHandler_t func, int code, const char *va_(fmt),...)
Write error message and call a handler, if required.
TClass * GetClass() const
void SetImpl(TBranch *branch, TLeaf *myLeaf)
Create the TVirtualCollectionReader object for our branch.
virtual size_t GetSize(Detail::TBranchProxy *)=0