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" 
   50   TVirtualCollectionProxy* fProxy;
 
   51   TPushPopSafe (TVirtualCollectionProxy* 
proxy, 
void* objectstart);
 
   52   inline ~TPushPopSafe();
 
   66 inline TPushPopSafe::TPushPopSafe (TVirtualCollectionProxy* 
proxy,
 
   71     fProxy->PushProxy (objectstart);
 
   81 inline TPushPopSafe::~TPushPopSafe()
 
   96 void RemovePrefix(TString& 
str, 
const char* 
prefix)
 
  113 std::string BasenameOfBranch (
const std::string& fullname)
 
  115   std::string 
s = fullname;
 
  116   size_t pos = 
s.rfind(
'.');
 
  117   if (
pos != std::string::npos) {
 
  120   while ((
pos = 
s.rfind(
'[')) != std::string::npos) {
 
  136 TStreamerInfo* GetStreamerInfoFromFile (
const TClass* 
cl, 
const TBranch* 
br)
 
  140   TDirectory* 
dir = 
br->GetDirectory();
 
  141   if (!
dir) 
return nullptr;
 
  143   if (!
file) 
return nullptr;
 
  144   if (
file->GetSeekInfo() == 0) 
return nullptr;
 
  147   const TList* silist = 
file->GetStreamerInfoCache();
 
  148   TListIter li (silist);
 
  150   while ((
info = 
dynamic_cast<TStreamerInfo*
> (li.Next())) != 
nullptr) {
 
  151     if (strcmp (
info->GetName(), 
cl->GetName()) == 0)
 
  167 bool DoesClassNeedConv (
const TClass* 
cl, 
const TBranch* 
br)
 
  169   if (!
cl) 
return false;
 
  170   TStreamerInfo* 
info = GetStreamerInfoFromFile (
cl, 
br);
 
  171   if (!
info) 
return false;
 
  175                                                     info->GetCheckSum()))
 
  179   TObjArray* elems = 
info->GetElements();
 
  180   int ndata = elems->GetEntriesFast();
 
  181   for (
int i = 0; 
i < ndata; ++
i) {
 
  182     TStreamerElement* elt =
 
  183       reinterpret_cast<TStreamerElement*
> (elems->At (
i));
 
  184     TClass* bcl = elt->GetClass();
 
  189     if (bcl && bcl != 
cl && DoesClassNeedConv (bcl, 
br))
 
  206 bool BaseHasField1 (TStreamerBase* elt,
 
  211   TClass* 
cl = elt->GetClassPointer();
 
  212   if (!
cl) 
return false;
 
  213   TStreamerInfo* 
info = GetStreamerInfoFromFile (
cl, 
br);
 
  214   if (!
info) 
return false;
 
  218   TObjArray* elems = 
info->GetElements();
 
  219   size_t ndata = elems->GetEntriesFast();
 
  220   for (
size_t ielt = 0; ielt < ndata; ielt++) {
 
  221     TStreamerElement* selt =
 
  222       reinterpret_cast<TStreamerElement*
> (elems->At(ielt));
 
  223     if (TStreamerBase* belt = 
dynamic_cast<TStreamerBase*
> (selt)) {
 
  224       if (BaseHasField1 (belt, 
name, 
br))
 
  228       if (
name == selt->GetName())
 
  248 bool BaseHasField (TStreamerBase* elt,
 
  250                    const TString& namedot,
 
  253   if (!elt) 
return false;
 
  254   RemovePrefix (bname, namedot.Data());
 
  255   Ssiz_t 
i = bname.Index (
"[");
 
  258   i = bname.Index (
".");
 
  261   return BaseHasField1 (elt, bname, 
br);
 
  265    struct R__PushCache {
 
  266       TBufferFile &fBuffer;
 
  267       TVirtualArray *fOnfileObject;
 
  269       R__PushCache(TBufferFile &
b, TVirtualArray *in, UInt_t 
size) : fBuffer(
b), fOnfileObject(in) {
 
  271             fOnfileObject->SetSize(
size);
 
  272             fBuffer.PushDataCache( fOnfileObject );
 
  276          if (fOnfileObject) fBuffer.PopDataCache();
 
  289 , fConvClass(nullptr)
 
  290 , fConvObject(nullptr)
 
  291 , fConvOrigBranches(nullptr)
 
  293 , fConvContainerFlag(false)
 
  294 , fConvDontReset(false)
 
  313     Int_t nbranches = fBranches.GetEntriesFast();
 
  314     for (Int_t 
i = 0; 
i < nbranches; 
i++) {
 
  386   TClass* topclass = 
nullptr;
 
  388     topclass = gROOT->GetClass (GetClassName());
 
  390     std::string 
s = BasenameOfBranch (GetName());
 
  392     TStreamerElement* elt = fInfo->GetStreamerElement(
s.c_str(), 
offset);
 
  394       topclass = elt->GetClass();
 
  396   if (!topclass) 
return;
 
  422   std::vector<TBranch*> conv_dummies;
 
  423   std::vector<TBranch*> noconv_branches;
 
  427   Int_t nbranches = fBranches.GetEntriesFast();
 
  429   for (Int_t 
i=0; 
i < nbranches; 
i++) {
 
  430     TBranch* 
b = 
dynamic_cast<TBranchElement*
> (fBranches[
i]);
 
  438   TStreamerInfo* 
info = GetStreamerInfoFromFile (topclass, 
this);
 
  439   if (!
info && fType == 4) {
 
  440     TVirtualCollectionProxy* 
proxy = topclass->GetCollectionProxy();
 
  442     topclass = 
proxy->GetValueClass();
 
  443     if (!topclass) 
return;
 
  444     info = GetStreamerInfoFromFile (topclass, 
this);
 
  446   else if (fType == 3) {
 
  447     topclass = gROOT->GetClass (fClonesName);
 
  448     if (!topclass) 
return;
 
  449     info = GetStreamerInfoFromFile (topclass, 
this);
 
  454   TObjArray* elems = 
info->GetElements();
 
  455   size_t ndata = elems->GetEntriesFast();
 
  456   for (
size_t ielt = 0; ielt < ndata; ++ielt) {
 
  458     TStreamerElement* elt =
 
  459       reinterpret_cast<TStreamerElement*
> (elems->At(ielt));
 
  465       TBranchElement* 
b = 
dynamic_cast<TBranchElement*
>(
branches[
i]);
 
  468       if (
b && gROOT->GetClass (
b->GetClassName()) == topclass) {
 
  469         if (
dynamic_cast<TStreamerBase*
> (elt) != 0 && 
b->GetType() == 1) {
 
  475           std::string 
s = BasenameOfBranch (
b->GetName());
 
  476           if (
s == elt->GetName())
 
  484           noconv_branches.push_back (
b);
 
  497       TClass* 
cl = elt->GetClass();
 
  498       if (
cl && DoesClassNeedConv (
cl, 
this)) {
 
  500         TClass* clparent = gROOT->GetClass (
info->GetName());
 
  505           name = elt->GetName();
 
  509             Ssiz_t 
i = 
name.Length()-1;
 
  510             while (
i >= 0 && 
name[
i] != 
'.')
 
  516           name += elt->GetName();
 
  519         dum->SetTitle (
name);
 
  520         TString namedot = 
name + 
".";
 
  521         dum->SetParentClass (clparent);
 
  522         dum->SetClassName (
info->GetName());
 
  523         dum->fCheckSum = 
info->GetCheckSum();
 
  524         dum->fClassVersion = topclass->GetClassVersion();
 
  526         dum->fTree = this->fTree;
 
  527         dum->fDirectory = this->fDirectory;
 
  528         dum->fBranchClass = topclass;
 
  529         if (
dynamic_cast<TStreamerBase*
> (elt) != 
nullptr) {
 
  531           Ssiz_t 
i = namedot.Length()-2;
 
  532           while (
i >= 0 && namedot[
i] != 
'.')
 
  534           namedot.Remove (
i+1);
 
  540         conv_dummies.push_back (dum);
 
  546           if (bname.Index (namedot) == 0 &&
 
  548                BaseHasField (
dynamic_cast<TStreamerBase*
>(elt),
 
  553             dum->GetListOfBranches()->Add (
branches[
i]);
 
  557               be->fParentClass = 
cl;
 
  574   if (conv_dummies.size() > 0) {
 
  584     for (
unsigned int i=0; 
i < conv_dummies.size(); 
i++)
 
  585       fBranches.Add (conv_dummies[
i]);
 
  586     for (
unsigned int i=0; 
i < noconv_branches.size(); 
i++)
 
  587       fBranches.Add (noconv_branches[
i]);
 
  605   const char* classname = 0;
 
  610     classname = GetClassName();
 
  611     checksum = fCheckSum;
 
  615     std::string 
s = BasenameOfBranch (GetName());
 
  617     TStreamerElement* elt = fInfo->GetStreamerElement(
s.c_str(), 
offset);
 
  619       TClass* 
cl = elt->GetClass();
 
  621         classname = 
cl->GetName();
 
  622         TStreamerInfo* 
info = GetStreamerInfoFromFile (
cl, 
this);
 
  624           checksum = 
info->GetCheckSum();
 
  637     if (!
conv && (fType == 4 || fType == 3)) {
 
  639       TClass* contclass = gROOT->GetClass (fClonesName.Data());
 
  641         TStreamerInfo* 
info = GetStreamerInfoFromFile (contclass, 
this);
 
  647                                                           info->GetCheckSum());
 
  651           if (
conv || DoesClassNeedConv (contclass, 
this)) {
 
  660       TClass* convclass = 
conv->GetPersClass();
 
  677       TClass* convclass = 
conv->GetPersClass();
 
  683         Bool_t optim = TStreamerInfo::CanOptimize();
 
  684         TStreamerInfo::Optimize(kFALSE);
 
  685         TStreamerInfo* 
info =
 
  686           dynamic_cast<TStreamerInfo*
> (convclass->GetStreamerInfo (0));
 
  689         TStreamerInfo::Optimize(optim);
 
  690         fParentClass = convclass;
 
  709   TBranchElement::InitInfo();
 
  717     TBranchElement::InitInfo();
 
  740   Int_t nbranches = fBranches.GetEntriesFast();
 
  741   for (Int_t 
i=0; 
i < nbranches; 
i++) {
 
  745       if (
b->fType == 41 || 
b->fType == 31) {
 
  746         b->fConvOrigType = 
b->fType;
 
  856   TBranchRef* bref = fTree->GetBranchRef();
 
  858     bref->SetParent(
this, fBranchID);
 
  859     bref->SetRequestedEntry(
entry);
 
  866   Int_t nbranches = fBranches.GetEntriesFast();
 
  872     if ((fType == 3) || (fType == 4)) {
 
  873       Int_t 
nb = TBranch::GetEntry(
entry, getall);
 
  888     case TClassEdit::kSet:
 
  889     case TClassEdit::kMultiSet:
 
  890     case TClassEdit::kMap:
 
  891     case TClassEdit::kMultiMap:
 
  907     if (fBranchCount && (fBranchCount->GetReadEntry() != 
entry)) {
 
  908       Int_t 
nb = fBranchCount->TBranch::GetEntry(
entry, getall);
 
  923       TBasket* basket = (TBasket*)GetBasket(GetReadBasket());
 
  924       TBuffer* 
buffer = basket->GetBufferRef();
 
  925       Int_t bufbegin = 
buffer->Length();
 
  928 #if __GNUC__ >= 11 && __GNUC__ <= 14 
  929 # pragma GCC diagnostic push 
  930 # pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 
  932       (this->*fReadLeaves) (*
buffer);
 
  933 #if __GNUC__ >= 11 && __GNUC__ <= 14 
  934 # pragma GCC diagnostic pop 
  940       nb = TBranch::GetEntry (
entry, getall);
 
  949   if (fTree->Debug() > 0) {
 
  950     if ((
entry >= fTree->GetDebugMin()) && (entry <= fTree->GetDebugMax())) {
 
  951       Info(
"GetEntry", 
"%lld, branch=%s, nbytes=%d", 
entry, GetName(), nbytes);
 
  978    if ((
n < 0) || (
n > fMaximum)) {
 
  979       if (IsMissingCollection()) {
 
  981          b.SetBufferOffset(
b.Length()-
sizeof(
n));
 
  983          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());
 
  989    R__PushCache onfileObject((
static_cast<TBufferFile&
>(
b)),fOnfileObject,
n);
 
 1001    TVirtualCollectionProxy* 
proxy = GetCollectionProxy();
 
 1002    TVirtualCollectionProxy::TPushPop 
helper(
proxy, fObject);
 
 1004    if(fSTLtype != TClassEdit::kVector && 
proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers ) {
 
 1012       case TClassEdit::kSet:
 
 1013       case TClassEdit::kMultiSet:
 
 1014       case TClassEdit::kMap:
 
 1015       case TClassEdit::kMultiMap:
 
 1030    if( 
proxy->HasPointers() && fSplitLevel > TTree::kSplitCollectionOfPointers )
 
 1032       TClass *elClass = 
proxy->GetValueClass();
 
 1039       if( !fNdata || *(
void**)
proxy->At( 0 ) != 0 )
 
 1042       for( ; 
i < fNdata; ++
i )
 
 1044          void **
el = (
void**)
proxy->At( 
i );
 
 1046          *
el = elClass->New();
 
 1060    assert(fStreamerType != TVirtualStreamerInfo::kCounter);
 
 1070    R__PushCache onfileObject((
static_cast<TBufferFile&
>(
b)),fOnfileObject,1);
 
 1075    if (TestBit(kBranchObject)) {
 
 1077       b.MapObject((TObject*) fObject);
 
 1078    } 
else if (TestBit(kBranchAny)) {
 
 1080       b.MapObject(fObject, fBranchClass);
 
 1083    fNdata = (Int_t) fBranchCount->GetValue(0, 0);
 
 1084    TStreamerInfo *
info = GetInfo();
 
 1115   Int_t nbranches = fBranches.GetEntriesFast();
 
 1124       UInt_t save_ndata = fNdata;
 
 1128       TVirtualCollectionProxy* 
proxy = 0;
 
 1129       TClonesArray* clones = 0;
 
 1131         proxy = GetCollectionProxy();
 
 1132       else if (fType == 3)
 
 1133         clones = (TClonesArray*)fObject;
 
 1145       std::vector<char*> last_addrs (nbranches, (
char*)0);
 
 1148       for (UInt_t j = 0; j < save_ndata; j++) {
 
 1154           addr = (
char*)(
proxy->At(j));
 
 1156           if (!clones) std::abort();
 
 1157           addr = (
char*)((*clones)[j]);
 
 1168         for (Int_t 
i = 0; 
i < nbranches; ++
i) {
 
 1169           TBranch* 
branch = (TBranch*) fBranches[
i];
 
 1177               be->fConvDontReset = 
true;
 
 1181           char* this_addr = 
obj + fBranchOffset[
i];
 
 1184           if (this_addr != last_addrs[
i]) {
 
 1185             last_addrs[
i] = this_addr;
 
 1207       fNdata = save_ndata;
 
 1214     for (Int_t 
i = 0; 
i < nbranches; ++
i) {
 
 1215       TBranch* 
branch = (TBranch*) fBranches[
i];
 
 1222         be->fConvDontReset = 
true;
 
 1256   Int_t type_save = 0;
 
 1258   if (!R__b.IsReading()) {
 
 1270   TBranchElement::Streamer (R__b);
 
 1272   if (!R__b.IsReading()) {
 
 1302   TStreamerElement* branchElem = 0;
 
 1303   TClass* cl_orig = 0;
 
 1305     TStreamerInfo* si = GetInfo();
 
 1306     branchElem = si->GetElem(fID);
 
 1308       if (branchElem && branchElem->IsBase()) {
 
 1309         cl_orig = branchElem->GetClassPointer();
 
 1318     Int_t nbranches = fBranches.GetEntriesFast();
 
 1319     for (Int_t subBranchIdx = 0; subBranchIdx < nbranches; ++subBranchIdx) {
 
 1328   TBranchElement::InitializeOffsets();
 
 1345    TBranchElement::SetAddress (
add);
 
 1347      Int_t nbranches = fBranches.GetEntriesFast();
 
 1348      for (Int_t 
i = 0; 
i < nbranches; ++
i) {
 
 1349        TBranch* abranch = (TBranch*) fBranches[
i];
 
 1375   char* 
object = fObject;
 
 1377   TBranchElement::ResetAddress();
 
 1386       if (fAddress && (*((
char**) fAddress) != fObject)) {
 
 1389         if (TestBit(kDeleteObject)) {
 
 1390           Warning(
"ReleaseObject", 
"branch: %s, You have overwritten the pointer to an object which I owned!", GetName());
 
 1391           Warning(
"ReleaseObject", 
"This is a memory leak.  Please use SetAddress() to change the pointer instead.");
 
 1392           ResetBit(kDeleteObject);
 
 1399     if (fAddress && fObject && TestBit(kDeleteObject)) {
 
 1400       ResetBit(kDeleteObject);
 
 1403         TClonesArray::Class()->Destructor(fObject);
 
 1405         if ((fStreamerType == TVirtualStreamerInfo::kObjectp) ||
 
 1406             (fStreamerType == TVirtualStreamerInfo::kObjectP)) {
 
 1409           *((
char**) fAddress) = 0;
 
 1411       } 
else if (fType == 4) {
 
 1413         TVirtualCollectionProxy* 
proxy = GetCollectionProxy();
 
 1415           Warning(
"ResetAddress", 
"Cannot delete allocated STL container because I do not have a proxy!  branch: %s", GetName());
 
 1418           proxy->Destructor(fObject);
 
 1421         if (fStreamerType == TVirtualStreamerInfo::kSTLp) {
 
 1424           *((
char**) fAddress) = 0;
 
 1428         TClass* 
cl = fBranchClass.GetClass();
 
 1430           Warning(
"ResetAddress", 
"Cannot delete allocated object because I cannot instantiate a TClass object for its class!  branch: '%s' class: '%s'", GetName(), fBranchClass.GetClassName());
 
 1433           cl->Destructor(fObject);