17#include "TClonesArray.h"
18#include "TStreamerElement.h"
21#include "TVirtualCollectionProxy.h"
22#include "TVirtualCollectionIterators.h"
23#include "TBranchRef.h"
24#include "TClassEdit.h"
27#include "TStreamerInfo.h"
28#include "TBufferFile.h"
29#include "TVirtualArray.h"
51 TVirtualCollectionProxy* fProxy;
52 TPushPopSafe (TVirtualCollectionProxy* proxy,
void* objectstart);
53 inline ~TPushPopSafe();
67inline TPushPopSafe::TPushPopSafe (TVirtualCollectionProxy* proxy,
72 fProxy->PushProxy (objectstart);
82inline TPushPopSafe::~TPushPopSafe()
97void RemovePrefix(TString& str,
const char* prefix)
99 if (
str.Length() && prefix && strlen(prefix)) {
100 if (!
str.Index(prefix)) {
101 str.Remove(0, strlen(prefix));
114std::string BasenameOfBranch (
const std::string& fullname)
116 std::string
s = fullname;
117 size_t pos =
s.rfind(
'.');
118 if (pos != std::string::npos) {
121 while ((pos =
s.rfind(
'[')) != std::string::npos) {
137TStreamerInfo* GetStreamerInfoFromFile (
const TClass* cl,
const TBranch* br)
141 TDirectory*
dir =
br->GetDirectory();
142 if (!dir)
return nullptr;
144 if (!
file)
return nullptr;
145 if (
file->GetSeekInfo() == 0)
return nullptr;
148 const TList* silist =
file->GetStreamerInfoCache();
149 TListIter li (silist);
151 while ((info =
dynamic_cast<TStreamerInfo*
> (li.Next())) !=
nullptr) {
152 if (strcmp (
info->GetName(),
cl->GetName()) == 0)
168bool DoesClassNeedConv (
const TClass* cl,
const TBranch* br)
170 if (!cl)
return false;
171 TStreamerInfo*
info = GetStreamerInfoFromFile (cl, br);
172 if (!info)
return false;
176 info->GetCheckSum()))
180 TObjArray* elems =
info->GetElements();
181 int ndata = elems->GetEntriesFast();
182 for (
int i = 0;
i < ndata; ++
i) {
183 TStreamerElement* elt =
184 reinterpret_cast<TStreamerElement*
> (elems->At (i));
185 TClass* bcl = elt->GetClass();
190 if (bcl && bcl != cl && DoesClassNeedConv (bcl, br))
207bool BaseHasField1 (TStreamerBase* elt,
212 TClass*
cl = elt->GetClassPointer();
213 if (!cl)
return false;
214 TStreamerInfo*
info = GetStreamerInfoFromFile (cl, br);
215 if (!info)
return false;
219 TObjArray* elems =
info->GetElements();
220 size_t ndata = elems->GetEntriesFast();
221 for (
size_t ielt = 0; ielt < ndata; ielt++) {
222 TStreamerElement* selt =
223 reinterpret_cast<TStreamerElement*
> (elems->At(ielt));
224 if (TStreamerBase* belt =
dynamic_cast<TStreamerBase*
> (selt)) {
225 if (BaseHasField1 (belt, name, br))
229 if (name == selt->GetName())
249bool BaseHasField (TStreamerBase* elt,
251 const TString& namedot,
254 if (!elt)
return false;
255 RemovePrefix (bname, namedot.Data());
256 Ssiz_t
i = bname.Index (
"[");
259 i = bname.Index (
".");
262 return BaseHasField1 (elt, bname, br);
266 struct R__PushCache {
267 TBufferFile &fBuffer;
268 TVirtualArray *fOnfileObject;
270 R__PushCache(TBufferFile &b, TVirtualArray *in, UInt_t
size) : fBuffer(
b), fOnfileObject(in) {
272 fOnfileObject->SetSize(
size);
273 fBuffer.PushDataCache( fOnfileObject );
277 if (fOnfileObject) fBuffer.PopDataCache();
314 Int_t nbranches = fBranches.GetEntriesFast();
315 for (Int_t i = 0; i < nbranches; i++) {
316 if (fBranches[i]->TestBit (
kIsDummy))
387 TClass* topclass =
nullptr;
389 topclass = gROOT->GetClass (GetClassName());
391 std::string s = BasenameOfBranch (GetName());
393 TStreamerElement* elt = fInfo->GetStreamerElement(s.c_str(), offset);
395 topclass = elt->GetClass();
397 if (!topclass)
return;
423 std::vector<TBranch*> conv_dummies;
424 std::vector<TBranch*> noconv_branches;
428 Int_t nbranches = fBranches.GetEntriesFast();
430 for (Int_t i=0;
i < nbranches;
i++) {
431 TBranch*
b =
dynamic_cast<TBranchElement*
> (fBranches[
i]);
439 TStreamerInfo*
info = GetStreamerInfoFromFile (topclass,
this);
440 if (!info && fType == 4) {
441 TVirtualCollectionProxy*
proxy = topclass->GetCollectionProxy();
443 topclass =
proxy->GetValueClass();
444 if (!topclass)
return;
445 info = GetStreamerInfoFromFile (topclass,
this);
447 else if (fType == 3) {
448 topclass = gROOT->GetClass (fClonesName);
449 if (!topclass)
return;
450 info = GetStreamerInfoFromFile (topclass,
this);
455 TObjArray* elems =
info->GetElements();
456 size_t ndata = elems->GetEntriesFast();
457 for (
size_t ielt = 0; ielt < ndata; ++ielt) {
459 TStreamerElement* elt =
460 reinterpret_cast<TStreamerElement*
> (elems->At(ielt));
465 for (
unsigned i=0;
i <
branches.size();
i++) {
466 TBranchElement*
b =
dynamic_cast<TBranchElement*
>(
branches[
i]);
469 if (b && gROOT->GetClass (
b->GetClassName()) == topclass) {
470 if (
dynamic_cast<TStreamerBase*
> (elt) != 0 &&
b->GetType() == 1) {
476 std::string
s = BasenameOfBranch (
b->GetName());
477 if (s == elt->GetName())
485 noconv_branches.push_back (b);
498 TClass*
cl = elt->GetClass();
499 if (cl && DoesClassNeedConv (cl,
this)) {
501 TClass* clparent = gROOT->GetClass (
info->GetName());
506 name = elt->GetName();
510 Ssiz_t
i =
name.Length()-1;
511 while (i >= 0 && name[i] !=
'.')
517 name += elt->GetName();
520 dum->SetTitle (name);
521 TString namedot =
name +
".";
522 dum->SetParentClass (clparent);
523 dum->SetClassName (
info->GetName());
524 dum->fCheckSum =
info->GetCheckSum();
525 dum->fClassVersion = topclass->GetClassVersion();
527 dum->fTree = this->fTree;
528 dum->fDirectory = this->fDirectory;
529 dum->fBranchClass = topclass;
530 if (
dynamic_cast<TStreamerBase*
> (elt) !=
nullptr) {
532 Ssiz_t
i = namedot.Length()-2;
533 while (i >= 0 && namedot[i] !=
'.')
535 namedot.Remove (i+1);
541 conv_dummies.push_back (dum);
545 for (
unsigned i=0;
i <
branches.size(); ) {
547 if (bname.Index (namedot) == 0 &&
549 BaseHasField (
dynamic_cast<TStreamerBase*
>(elt),
554 dum->GetListOfBranches()->Add (branches[i]);
558 be->fParentClass =
cl;
572 for (
unsigned int i=0;
i <
branches.size();
i++)
573 noconv_branches.push_back (branches[i]);
575 if (conv_dummies.size() > 0) {
585 for (
unsigned int i=0;
i < conv_dummies.size();
i++)
586 fBranches.Add (conv_dummies[i]);
587 for (
unsigned int i=0;
i < noconv_branches.size();
i++)
588 fBranches.Add (noconv_branches[i]);
606 const char* classname = 0;
611 classname = GetClassName();
612 checksum = fCheckSum;
616 std::string s = BasenameOfBranch (GetName());
618 TStreamerElement* elt = fInfo->GetStreamerElement(s.c_str(), offset);
620 TClass* cl = elt->GetClass();
622 classname = cl->GetName();
623 TStreamerInfo* info = GetStreamerInfoFromFile (cl,
this);
625 checksum = info->GetCheckSum();
638 if (!conv && (fType == 4 || fType == 3)) {
640 TClass* contclass = gROOT->GetClass (fClonesName.Data());
642 TStreamerInfo* info = GetStreamerInfoFromFile (contclass,
this);
648 info->GetCheckSum());
652 if (conv || DoesClassNeedConv (contclass,
this)) {
661 TClass* convclass = conv->GetPersClass();
678 TClass* convclass = conv->GetPersClass();
684 Bool_t optim = TStreamerInfo::CanOptimize();
685 TStreamerInfo::Optimize(kFALSE);
686 TStreamerInfo* info =
687 dynamic_cast<TStreamerInfo*
> (convclass->GetStreamerInfo (0));
690 TStreamerInfo::Optimize(optim);
691 fParentClass = convclass;
710 TBranchElement::InitInfo();
718 TBranchElement::InitInfo();
741 Int_t nbranches = fBranches.GetEntriesFast();
742 for (Int_t i=0; i < nbranches; i++) {
746 if (b->fType == 41 || b->fType == 31) {
747 b->fConvOrigType = b->fType;
857 TBranchRef* bref = fTree->GetBranchRef();
859 bref->SetParent(
this, fBranchID);
860 bref->SetRequestedEntry(entry);
867 Int_t nbranches = fBranches.GetEntriesFast();
873 if ((fType == 3) || (fType == 4)) {
874 Int_t
nb = TBranch::GetEntry(entry, getall);
890 case ROOT::kSTLmultiset:
892 case ROOT::kSTLmultimap:
908 if (fBranchCount && (fBranchCount->GetReadEntry() != entry)) {
909 Int_t
nb = fBranchCount->TBranch::GetEntry(entry, getall);
924 TBasket* basket = (TBasket*)GetBasket(GetReadBasket());
925 TBuffer*
buffer = basket->GetBufferRef();
926 Int_t bufbegin =
buffer->Length();
929#if __GNUC__ >= 11 && __GNUC__ <= 14
930# pragma GCC diagnostic push
931# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
933 (this->*fReadLeaves) (*buffer);
934#if __GNUC__ >= 11 && __GNUC__ <= 14
935# pragma GCC diagnostic pop
941 nb = TBranch::GetEntry (entry, getall);
950 if (fTree->Debug() > 0) {
951 if ((entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
952 Info(
"GetEntry",
"%lld, branch=%s, nbytes=%d", entry, GetName(), nbytes);
979 if ((n < 0) || (n > fMaximum)) {
980 if (IsMissingCollection()) {
982 b.SetBufferOffset(
b.Length()-
sizeof(n));
984 Error(
"ReadLeaves",
"Incorrect size read for the container in %s\n\tThe size read is %d while the maximum is %d\n\tThe size is reset to 0 for this entry (%lld)", GetName(), n, fMaximum, GetReadEntry());
990 R__PushCache onfileObject((
static_cast<TBufferFile&
>(b)),fOnfileObject,n);
1002 TVirtualCollectionProxy*
proxy = GetCollectionProxy();
1003 TVirtualCollectionProxy::TPushPop
helper(proxy, fObject);
1005 if(fSTLtype != ROOT::kSTLvector &&
proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
1006 fPtrIterators->CreateIterators(alternate, proxy);
1008 fIterators->CreateIterators(alternate, proxy);
1014 case ROOT::kSTLmultiset:
1016 case ROOT::kSTLmultimap:
1031 if(
proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers )
1033 TClass *elClass =
proxy->GetValueClass();
1040 if( !fNdata || *(
void**)
proxy->At( 0 ) != 0 )
1043 for( ;
i < fNdata; ++
i )
1045 void **
el = (
void**)
proxy->At( i );
1047 *
el = elClass->New();
1051 proxy->Commit(alternate);
1061 assert(fStreamerType != TVirtualStreamerInfo::kCounter);
1071 R__PushCache onfileObject((
static_cast<TBufferFile&
>(b)),fOnfileObject,1);
1076 if (TestBit(kBranchObject)) {
1078 b.MapObject((TObject*) fObject);
1079 }
else if (TestBit(kBranchAny)) {
1081 b.MapObject(fObject, fBranchClass);
1084 fNdata = (Int_t) fBranchCount->GetValue(0, 0);
1085 TStreamerInfo *
info = GetInfo();
1116 Int_t nbranches = fBranches.GetEntriesFast();
1125 UInt_t save_ndata = fNdata;
1129 TVirtualCollectionProxy*
proxy = 0;
1130 TClonesArray* clones = 0;
1132 proxy = GetCollectionProxy();
1133 else if (fType == 3)
1134 clones = (TClonesArray*)fObject;
1140 TPushPopSafe
helper (proxy,fObject);
1146 std::vector<char*> last_addrs (nbranches, (
char*)0);
1149 for (UInt_t j = 0;
j < save_ndata;
j++) {
1155 addr = (
char*)(
proxy->At(j));
1157 if (!clones) std::abort();
1158 addr = (
char*)((*clones)[j]);
1169 for (Int_t i = 0;
i < nbranches; ++
i) {
1170 TBranch* branch = (TBranch*) fBranches[i];
1178 be->fConvDontReset =
true;
1182 char* this_addr =
obj + fBranchOffset[
i];
1185 if (this_addr != last_addrs[i]) {
1186 last_addrs[
i] = this_addr;
1187 branch->SetAddress (obj + fBranchOffset[i]);
1191 Int_t
nb = branch->GetEntry(entry, getall);
1204 fConv->ConvertVoid (addr, obj);
1208 fNdata = save_ndata;
1215 for (Int_t i = 0;
i < nbranches; ++
i) {
1216 TBranch* branch = (TBranch*) fBranches[i];
1223 be->fConvDontReset =
true;
1227 Int_t
nb = branch->GetEntry(entry, getall);
1257 Int_t type_save = 0;
1259 if (!R__b.IsReading()) {
1271 TBranchElement::Streamer (R__b);
1273 if (!R__b.IsReading()) {
1303 TStreamerElement* branchElem = 0;
1304 TClass* cl_orig = 0;
1306 TStreamerInfo* si = GetInfo();
1307 branchElem = si->GetElem(fID);
1309 if (branchElem && branchElem->IsBase()) {
1310 cl_orig = branchElem->GetClassPointer();
1319 Int_t nbranches = fBranches.GetEntriesFast();
1320 for (Int_t subBranchIdx = 0; subBranchIdx < nbranches; ++subBranchIdx) {
1329 TBranchElement::InitializeOffsets();
1346 TBranchElement::SetAddress (
add);
1348 Int_t nbranches = fBranches.GetEntriesFast();
1349 for (Int_t i = 0;
i < nbranches; ++
i) {
1350 TBranch* abranch = (TBranch*) fBranches[i];
1351 abranch->SetAddress(
fConvObject + fBranchOffset[i]);
1376 char*
object = fObject;
1377 char* address = fAddress;
1378 TBranchElement::ResetAddress();
1387 if (fAddress && (*((
char**) fAddress) != fObject)) {
1390 if (TestBit(kDeleteObject)) {
1391 Warning(
"ReleaseObject",
"branch: %s, You have overwritten the pointer to an object which I owned!", GetName());
1392 Warning(
"ReleaseObject",
"This is a memory leak. Please use SetAddress() to change the pointer instead.");
1393 ResetBit(kDeleteObject);
1400 if (fAddress && fObject && TestBit(kDeleteObject)) {
1401 ResetBit(kDeleteObject);
1404 TClonesArray::Class()->Destructor(fObject);
1406 if ((fStreamerType == TVirtualStreamerInfo::kObjectp) ||
1407 (fStreamerType == TVirtualStreamerInfo::kObjectP)) {
1410 *((
char**) fAddress) = 0;
1412 }
else if (fType == 4) {
1414 TVirtualCollectionProxy*
proxy = GetCollectionProxy();
1416 Warning(
"ResetAddress",
"Cannot delete allocated STL container because I do not have a proxy! branch: %s", GetName());
1419 proxy->Destructor(fObject);
1422 if (fStreamerType == TVirtualStreamerInfo::kSTLp) {
1425 *((
char**) fAddress) = 0;
1429 TClass*
cl = fBranchClass.GetClass();
1431 Warning(
"ResetAddress",
"Cannot delete allocated object because I cannot instantiate a TClass object for its class! branch: '%s' class: '%s'", GetName(), fBranchClass.GetClassName());
1434 cl->Destructor(fObject);
size_t size() const
Number of registered mappings.
void TConvertingBranchElement_init()
Registry for Root converters.
A variant of TBranchElement that can call converters when reading objects in split mode.
Base class for Root converters.
static TConverterRegistry * Instance()
Return a pointer to the global registry instance.
TVirtualConverter * GetConverter(const char *name, int checksum) const
Look up a converter in the registry by name and checksum.
Int_t fConvOrigType
Saved branch list. If we change.
virtual void SetAddress(void *add)
Set the address of the object to use for I/O.
void ReadLeavesMemberBranchCountConverting(TBuffer &b)
TConvertingBranchElement()
Constructor.
TVirtualConverter * fConv
virtual void ResetAddress()
Reset branch addresses and maybe delete the object.
bool fConvDontReset
True if we're doing a container.
void ConvResetType()
Recursively reset the type field of containers in conversions.
bool fConvContainerFlag
Saved branch type. The original.
TClass * fConvClass
Conversion for this branch.
static void SetDoDel(bool flag)
Set the deletion flag.
static std::atomic< bool > fgDoDel
Flag that the next read should.
static void * new_TConvertingBranchElement(void *p)
new() method for this object.
static constexpr unsigned int kIsDummy
Flag used to mark dummy nodes created by BuildConvertedElisions.
char * fConvObject
Class for conversion.
virtual void InitializeOffsets()
Initialize data member offsets.
virtual Int_t GetEntry(Long64_t entry, Int_t getall)
Read all branches into the previously-declared object.
void ReadLeavesCollectionConverting(TBuffer &b)
Read leaves into I/O buffers for this branch.
virtual ~TConvertingBranchElement()
Destructor.
static void Initialize()
Set up to allow for conversions in split mode.
Int_t ReadSubBranches(Long64_t entry, Int_t getall, bool dont_reset)
@branch Read in the subbranches of this branch.
virtual void Streamer(TBuffer &R__b)
Read or write this object.
virtual void InitInfo()
Initialize the TStreamerInfo pointer.
void CheckForConversion()
Check to see if we need to worry about conversions for this branch.
void BuildConvertedElisions()
Add dummy nodes if needed to recover the correct tree structure.
TObjArray * fConvOrigBranches
Pointer to tmp obj used for conversion.
Base class for converters for Root schema evolution.
bool add(const std::string &hname, TKey *tobj)
Error
The different types of error that can be flagged in the L1TopoRDO.
float j(const xAOD::IParticle &, const xAOD::TrackMeasurementValidation &hit, const Eigen::Matrix3d &jab_inv)
alternate(gen, dictionary, weight_dict, p_nom)
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]