19 #include "TClassEdit.h" 41 Error(
"TClonesReader::GetCA()",
"Read error in TBranchProxy.");
70 Error(
"TSTLReader::GetCP()",
"Read error in TBranchProxy.");
74 Error(
"TSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
83 if (!myCollectionProxy)
return 0;
84 return myCollectionProxy->
Size();
89 if (!myCollectionProxy)
return 0;
91 return *(
void**)myCollectionProxy->
At(idx);
94 return myCollectionProxy->
At(idx);
106 if (!proxy->
Read()) {
108 Error(
"TCollectionLessSTLReader::GetCP()",
"Read error in TBranchProxy.");
112 Error(
"TCollectionLessSTLReader::GetCP()",
"Logic error, proxy object not set in TBranchProxy.");
116 return fLocalCollection;
121 if (!myCollectionProxy)
return 0;
123 return myCollectionProxy->
Size();
128 if (!myCollectionProxy)
return 0;
131 return *(
void**)myCollectionProxy->
At(idx);
133 return myCollectionProxy->
At(idx);
143 Int_t fBasicTypeSize;
145 TObjectArrayReader() : fBasicTypeSize(-1) { }
146 ~TObjectArrayReader() {}
150 Error(
"TObjectArrayReader::GetCP()",
"Read error in TBranchProxy.");
158 if (!myCollectionProxy)
return 0;
159 return myCollectionProxy->
Size();
162 if (!proxy->
Read())
return 0;
165 void *array = (
void*)proxy->
GetStart();
167 if (fBasicTypeSize == -1){
170 Error(
"TObjectArrayReader::At()",
"Cannot get class info from branch proxy.");
176 objectSize = fBasicTypeSize;
178 return (
void*)((
Byte_t*)array + (objectSize * idx));
181 void SetBasicTypeSize(
Int_t size){
182 fBasicTypeSize = size;
186 template <
class BASE>
187 class TUIntOrIntReader:
public BASE {
191 bool fIsUnsigned =
false;
200 template <
class...
ARGS>
201 TUIntOrIntReader(
TTreeReader *treeReader,
const char *leafName,
203 BASE(std::forward<ARGS>(args)...)
205 if (
TLeaf* sizeLeaf = treeReader->
GetTree()->FindLeaf(leafName)) {
206 fIsUnsigned = sizeLeaf->IsUnsigned();
217 return *GetSizeReader<UInt_t>();
218 return *GetSizeReader<Int_t>();
222 class TArrayParameterSizeReader:
public TUIntOrIntReader<TObjectArrayReader> {
225 TUIntOrIntReader<TObjectArrayReader>(treeReader,
branchName) {}
229 class TArrayFixedSizeReader :
public TObjectArrayReader {
234 TArrayFixedSizeReader(
Int_t sizeArg) : fSize(sizeArg) {}
241 ~TBasicTypeArrayReader() {}
246 Error(
"TBasicTypeArrayReader::GetCP()",
"Read error in TBranchProxy.");
255 if (!myCollectionProxy)
return 0;
256 return myCollectionProxy->
Size();
261 if (!myCollectionProxy)
return 0;
266 class TBasicTypeClonesReader :
public TClonesReader {
270 TBasicTypeClonesReader(
Int_t offsetArg) : fOffset(offsetArg) {}
274 if (!myClonesArray)
return 0;
275 return (
Byte_t*)myClonesArray->
At(idx) + fOffset;
284 TLeafReader(
TTreeReaderValueBase *valueReaderArg) : fValueReader(valueReaderArg), fElementSize(-1) {}
288 return myLeaf ? myLeaf->
GetLen() : 0;
294 if (fElementSize == -1){
296 if (!myLeaf)
return 0;
299 return (
Byte_t*)address + (fElementSize * idx);
308 class TLeafParameterSizeReader:
public TUIntOrIntReader<TLeafReader> {
310 TLeafParameterSizeReader(
TTreeReader *treeReader,
const char *leafName,
312 TUIntOrIntReader<TLeafReader>(treeReader, leafName, valueReaderArg) {}
316 return TUIntOrIntReader<TLeafReader>::GetSize(proxy);
337 fSetupStatus = kSetupInternalError;
339 Error(
"TTreeReaderArrayBase::CreateProxy()",
"TTreeReader object not set / available for branch %s!",
341 fSetupStatus = kSetupTreeDestructed;
346 const char* brDataType =
"{UNDETERMINED}";
349 brDataType = GetBranchDataType(br, dictUnused);
351 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.",
352 GetDerivedTypeName(), fBranchName.Data(), brDataType);
353 fSetupStatus = kSetupMissingDictionary;
364 TLeaf *myLeaf =
nullptr;
365 if (!GetBranchAndLeaf(branch, myLeaf, branchActualType))
369 Error(
"TTreeReaderArrayBase::CreateProxy()",
370 "No dictionary for branch %s.", fBranchName.Data());
377 fSetupStatus = kSetupMatch;
379 SetImpl(branch, myLeaf);
388 fSetupStatus = kSetupMatch;
390 Error(
"TTreeReaderArrayBase::CreateProxy()",
391 "Type ambiguity (want %s, have %s) for branch %s.",
398 bool isTopLevel = branch->
GetMother() == branch;
400 membername = strrchr(branch->
GetName(),
'.');
401 if (membername.IsNull()) {
402 membername = branch->
GetName();
405 namedProxy =
new TNamedBranchProxy(fTreeReader->fDirector, branch, fBranchName, membername);
406 fTreeReader->AddProxy(namedProxy);
409 fSetupStatus = kSetupMatch;
411 fSetupStatus = kSetupMismatch;
415 TString branchActualTypeName;
416 const char* nonCollTypeName = GetBranchContentDataType(branch, branchActualTypeName, branchActualType);
417 if (nonCollTypeName) {
418 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which should be accessed through a TTreeReaderValue< %s >.",
419 fBranchName.Data(), nonCollTypeName, nonCollTypeName);
420 if (fSetupStatus == kSetupInternalError)
421 fSetupStatus = kSetupNotACollection;
425 if (!branchActualType) {
426 if (branchActualTypeName.IsNull()) {
427 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"Cannot determine the type contained in the collection of branch %s. That's weird - please report!",
430 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s, which does not have a dictionary.",
431 fBranchName.Data(), branchActualTypeName.Data());
432 if (fSetupStatus == kSetupInternalError)
433 fSetupStatus = kSetupMissingDictionary;
439 if (fDict != branchActualType) {
440 Error(
"TTreeReaderArrayBase::CreateContentProxy()",
"The branch %s contains data of type %s. It cannot be accessed by a TTreeReaderArray<%s>",
441 fBranchName.Data(), branchActualType->
GetName(), fDict->GetName());
442 if (fSetupStatus == kSetupInternalError || fSetupStatus >= 0)
443 fSetupStatus = kSetupMismatch;
455 SetImpl(branch, myLeaf);
464 branch = fTreeReader->
GetTree()->GetBranch(fBranchName);
468 if (!fBranchName.Contains(
".")) {
469 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
470 fSetupStatus = kSetupMissingBranch;
475 TRegexp leafNameExpression (
"\\.[a-zA-Z0-9_]+$");
476 TString leafName (fBranchName(leafNameExpression));
477 TString
branchName = fBranchName(0, fBranchName.Length() - leafName.Length());
478 branch = fTreeReader->
GetTree()->GetBranch(branchName);
480 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"The tree does not have a branch called %s. You could check with TTree::Print() for available branches.", fBranchName.Data());
481 fSetupStatus = kSetupMissingBranch;
486 myLeaf = branch->GetLeaf(TString(leafName(1, leafName.Length())));
488 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());
489 fSetupStatus = kSetupMissingBranch;
496 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Failed to get the dictionary for %s.", myLeaf->
GetTypeName());
497 fSetupStatus = kSetupMissingDictionary;
504 branchActualType = fDict;
507 fLeafName = leafName(1, leafName.Length());
508 fSetupStatus = kSetupMatchLeaf;
511 Error(
"TTreeReaderArrayBase::GetBranchAndLeaf()",
"Leaf of type %s cannot be read by TTreeReaderValue<%s>.", myLeaf->
GetTypeName(), fDict->GetName());
513 fSetupStatus = kSetupMismatch;
539 fImpl =
new TLeafReader(
this);
545 fImpl =
new TLeafParameterSizeReader(fTreeReader, leafFullName.Data(),
this);
547 fSetupStatus = kSetupMatchLeaf;
561 if (fSetupStatus == kSetupInternalError)
562 fSetupStatus = kSetupMatch;
564 fImpl =
new TSTLReader();
570 fImpl =
new TClonesReader();
581 fImpl =
new TBasicTypeArrayReader();
584 fImpl =
new TBasicTypeClonesReader(element->
GetOffset());
588 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
593 ((TArrayParameterSizeReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
596 fImpl =
new TClonesReader();
598 Error(
"TTreeReaderArrayBase::SetImpl()",
599 "Cannot read branch %s: unhandled streamer element type %s",
600 fBranchName.Data(), element->IsA()->
GetName());
601 fSetupStatus = kSetupInternalError;
612 Error(
"TTreeReaderArrayBase::SetImpl",
"Failed to get the top leaf from the branch");
613 fSetupStatus = kSetupMissingBranch;
618 if (fSetupStatus == kSetupInternalError)
619 fSetupStatus = kSetupMatch;
621 fImpl =
new TArrayFixedSizeReader(size);
624 fImpl =
new TArrayParameterSizeReader(fTreeReader, sizeLeaf->
GetName());
626 ((TObjectArrayReader*)fImpl)->SetBasicTypeSize(((
TDataType*)fDict)->
Size());
628 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchClones not implemented");
629 fSetupStatus = kSetupInternalError;
631 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchObject not implemented");
632 fSetupStatus = kSetupInternalError;
634 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchSTL not implemented");
635 fImpl =
new TSTLReader();
636 fSetupStatus = kSetupInternalError;
638 Error(
"TTreeReaderArrayBase::SetImpl",
"Support for branches of type TBranchRef not implemented");
639 fSetupStatus = kSetupInternalError;
654 TString& contentTypeName,
658 contentTypeName =
"";
662 || brElement->
GetType() == 3) {
667 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Could not get value class.");
676 if (brElement->
GetType() == 3) {
682 TClassEdit::TSplitType splitType(brElement->
GetClassName());
683 int isSTLCont = splitType.IsSTLCont();
685 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Cannot determine STL collection type of %s stored in branch %s", brElement->
GetClassName(), branch->
GetName());
688 bool isMap = isSTLCont == ROOT::kSTLmap
689 || isSTLCont == ROOT::kSTLmultimap;
690 if (isMap) contentTypeName =
"std::pair< ";
691 contentTypeName += splitType.fElements[1];
693 contentTypeName += splitType.fElements[2];
694 contentTypeName +=
" >";
699 }
else if (brElement->
GetType() == 31
700 || brElement->
GetType() == 41) {
705 if (ExpectedTypeRet == 0) {
711 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains a data type %d for which the dictionary cannot be retrieved.",
712 branch->
GetName(), (int)dtData);
717 }
else if (ExpectedTypeRet == 1) {
718 int brID = brElement->
GetID();
721 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s contains data of type %s for which the dictionary does not exist. It's needed.",
736 return "{CANNOT DETERMINE TBranchElement DATA TYPE}";
748 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get class from branch element.");
752 if (!myCollectionProxy){
753 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get collection proxy from STL class");
761 Error(
"TTreeReaderArrayBase::GetBranchDataType()",
"Could not get valueClass from collectionProxy.");
764 contentTypeName = dict->
GetName();
768 if (!fProxy->Setup() || !fProxy->Read()){
769 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Failed to get type from proxy, unable to check type");
770 contentTypeName =
"UNKNOWN";
772 return contentTypeName;
776 contentTypeName = dict->
GetName();
790 contentTypeName =
"TClonesArray";
791 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
793 fSetupStatus = kSetupNoCheck;
800 if (dict) contentTypeName = dict->
GetName();
805 contentTypeName = dict->
GetName();
816 if ((!dataTypeName || !dataTypeName[0])
829 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());
832 while ((leaf = (
TLeaf*) iLeaves())) {
833 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
" %s.%s", branch->
GetName(), leaf->GetName());
839 Warning(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"Not able to check type correctness, ignoring check");
841 fSetupStatus = kSetupNoCheck;
847 return "TClonesArray";
850 Error(
"TTreeReaderArrayBase::GetBranchContentDataType()",
"The branch %s is a TBranchRef and cannot be represented as a C++ type.", branch->
GetName());
853 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...
Namespace for new ROOT classes and functions.
virtual TClass * GetValueClass() const =0
TStreamerElement * GetElement(Int_t id) const
virtual const char * GetTypeName() const
virtual TLeaf * GetLeafCounter(Int_t &countval) const
Return a pointer to the counter of this leaf.
Regular expression class.
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.
virtual Int_t GetLenType() const
TDictionary * GetContentDict() const
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.
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
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.
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
typedef void((*Func_t)())
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