25 #include "TClassEdit.h" 56 void RemovePrefix(
TString& str,
const char* prefix) {
58 if (str.
Length() && prefix && strlen(prefix)) {
59 if (!str.
Index(prefix)) {
60 str.
Remove(0, strlen(prefix));
85 for (
Int_t i = 0; i < nbranches; ++i) {
88 case 31: br->
SetType(41);
break;
110 return CanSelfReference(inside);
115 const static TClassRef stringClass(
"std::string");
143 , fSTLtype(
ROOT::kNotSTL)
159 , fReadActionSequence(0)
160 , fFillActionSequence(0)
209 Init(tree, 0, bname,sinfo,
id,pointer,basketsize,splitlevel,btype);
251 Init(parent ? parent->
GetTree() : 0, parent, bname,sinfo,id,pointer,basketsize,splitlevel,btype);
270 if (
fTree == 0)
return;
362 if (hasCustomStreamer) {
415 if (splitlevel > 0) {
436 if (!strcmp(name, clOfElement->
GetName())) {
463 Unroll(name, clOfElement, clOfElement, pointer, basketsize, splitlevel+splitSTLP, 0);
464 if (strchr(bname,
'.')) {
497 char **ppointer = (
char**)(pointer);
538 Unroll(name, clOfClones, clOfClones, pointer, basketsize, splitlevel+splitSTLP, 31);
545 TClass* contCl = elementClass;
590 Unroll(name, valueClass, valueClass, pointer, basketsize, splitlevel+splitSTLP, 41);
603 TClass* clm = elementClass;
604 Int_t err =
Unroll(name, clm, clm, pointer, basketsize, splitlevel+splitSTLP, 0);
660 Init(tree, 0, bname, clones, basketsize, splitlevel, compress);
684 Init(parent ? parent->
GetTree() : 0, parent, bname, clones, basketsize, splitlevel, compress);
727 if (basketsize < 100) basketsize = 100;
747 Error(
"Init",
"Missing class object of the TClonesArray %s\n",clones->
GetName());
759 std::string branchname = name + std::string(
"_");
761 leaf->
SetName(branchname.c_str());
763 Unroll(name, clonesClass, clonesClass, 0, basketsize, splitlevel, 31);
803 Init(tree, 0, bname, cont, basketsize, splitlevel, compress);
826 Init(parent ? parent->
GetTree() : 0, parent, bname, cont, basketsize, splitlevel, compress);
838 if (name[name.
Length()-1]==
'.') {
880 if (basketsize < 100) {
921 Unroll(name, valueClass, valueClass, 0, basketsize, splitlevel, 41);
1000 if (nbranches > 0) {
1001 TList persistentBranches;
1004 while((branch=(
TBranch*)iB())) {
1005 if (branch->
IsFolder()) persistentBranches.
Add(branch);
1031 mempos=strMember.
First(
'[');
1036 }
else persistentBranches.
Add(branch);
1039 persistentBranches.
Browse(b);
1060 pos = mothername.
First(
'[');
1066 if (mothername(len-1) !=
'.') {
1071 TString doublename = mothername;
1073 Int_t isthere = (name.
Index(doublename) == 0);
1078 doublename.
Append(mothername);
1079 isthere = (name.
Index(doublename) == 0);
1115 for (
Int_t i = 0; i < nbranches; ++i) {
1119 }
else if (
fType == 4) {
1122 Error(
"BuildTitle",
"This cannot happen, fType of parent is not 3 or 4!");
1126 const char* fin = strrchr(bre->
GetTitle(),
'.');
1159 if ((stype > 40) && (stype < 61)) {
1201 Error(
"Fill",
"attempt to fill branch %s while addresss is not set",
GetName());
1224 Error(
"Fill",
"Failed filling branch:%s, nbytes=%d",
GetName(), nwrite);
1236 Error(
"Fill",
"Failed filling branch:%s, nbytes=%d",
GetName(), nwrite);
1244 for (
Int_t i = 0; i < nbranches; ++i) {
1247 nwrite = branch->
FillImpl(imtHelper);
1249 Error(
"Fill",
"Failed filling branch:%s.%s, nbytes=%d",
GetName(), branch->
GetName(), nwrite);
1262 printf(
"Fill: %lld, branch=%s, nbytes=%d\n", entry,
GetName(), nbytes);
1300 }
else if (
fType == 31) {
1321 Error(
"FillLeaves",
"The branch counter address was zero!");
1327 Error(
"FillLeaves",
"Clonesa: %s, n=%d, sorry not supported yet",
GetName(), n);
1350 for (
Int_t ii = 0; ii <
n; ++ii) {
1360 for (
Int_t ii = 0; ii <
n; ++ii) {
1443 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1474 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1504 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1535 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1590 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1595 char **end = arr +
n;
1672 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1716 Error(
"FillLeaves",
"Cannot get streamer info for branch '%s'",
GetName());
1730 if (name[name.length()-1]==
']') {
1731 std::size_t dim = name.find_first_of(
"[");
1732 if (dim != std::string::npos) {
1736 if (name[name.size()-1] !=
'.') {
1755 if (se && se->
IsBase()) {
1757 UInt_t len = strlen(name);
1763 std::string longnm_parent;
1767 longnm_parent +=
name;
1769 UInt_t namelen = strlen(name);
1773 for(
Int_t i = 0; i < nbranches; ++i) {
1776 const char *brname = branch->
GetName();
1777 UInt_t brlen = strlen(brname);
1778 if (brname[brlen-1]==
']') {
1779 const char *dim = strchr(brname,
'[');
1781 brlen = dim - brname;
1784 if (namelen == brlen
1785 && strncmp(name,brname,brlen) == 0) {
1788 if (brlen == longnm.length()
1789 && strncmp(longnm.c_str(),brname,brlen) == 0) {
1793 if (brlen == longnm_parent.length()
1794 && strncmp(longnm_parent.c_str(),brname,brlen) == 0) {
1798 if (namelen>brlen && name[brlen]==
'.' && strncmp(name,brname,brlen)==0) {
1809 for(
Int_t i = 0; i < nbranches; ++i) {
1815 if (si && br->
GetID() >= 0) {
1817 if (se && se->
IsBase()) {
1839 if (parent==
this || parent->
GetID()<0 )
return 0;
1844 if (! se->
IsBase() )
return 0;
1852 std::string longname( grand_parent->
GetName() );
1858 if ( longname == leafname ) {
1910 if ( !targetClass ) {
1911 Error(
"InitInfo",
"The target class dictionary is not present!" );
1929 target +=
"@@emulated";
1938 if( targetClass != cl ) {
1955 if( targetClass != cl )
1985 Error(
"InitInfo",
"StreamerInfo is not compiled.");
1996 size_t pos = s.rfind(
'.');
1997 if (pos != std::string::npos) {
1998 s = s.substr(pos+1);
2000 while ((pos = s.rfind(
'[')) != std::string::npos) {
2001 s = s.substr(0, pos);
2008 for (
size_t i = 0; i <
ndata; ++i) {
2066 for (
size_t i = 0; i <
ndata; ++i) {
2093 for (
Int_t i = 0; i < nbranches; ++i) {
2097 lastbranch = subbranch;
2129 const char* className = 0;
2166 Fatal(
"GetCollectionProxy",
2167 "Can not create a Collection Proxy of any kind for the class \"%s\" needed by the branch \"%s\" of the TTree \"%s\"!",
2171 "Fixing the collection proxy of the class \"%s\" \n" 2172 "\tneeded by the branch \"%s\" of the TTree \"%s\" to be similar to \"%s\".",
2178 }
else if (
fType == 41) {
2221 if (newInfo != brInfo) {
2230 if (newType.
Length()==0) {
2303 case ROOT::kSTLmultiset:
2304 case ROOT::kSTLunorderedset:
2305 case ROOT::kSTLunorderedmultiset:
2307 case ROOT::kSTLmultimap:
2308 case ROOT::kSTLunorderedmap:
2309 case ROOT::kSTLunorderedmultimap:
2313 for (
Int_t i = 0; i < nbranches; ++i) {
2341 Info(
"GetEntry",
"%lld, branch=%s, nbytes=%d", entry,
GetName(), nbytes);
2359 if ((type == -1) || (
fID == -1)) {
2368 if (!expectedClass) {
2378 Error(
"GetExpectedType",
"Did not find the type for %s",
GetName());
2391 return "TBranchElement-folder";
2393 return "TBranchElement-leaf";
2454 const char *types[20] = {
2477 return types[itype];
2486 template <
typename T>
2506 }
else if (fOnfileObject) {
2537 }
else if (
fType <= 2) {
2562 }
else if (
fType == 41) {
2598 }
else if (fOnfileObject) {
2615 }
else if (
fType == 4) {
2618 }
else if (
fType == 31) {
2623 }
else if (
fType == 41) {
2628 }
else if (
fType <= 2) {
2643 }
else if (
fType == 41) {
2645 }
else if (prID < 0) {
2650 char **val = (
char**)(
object+
GetInfoImp()->TStreamerInfo::GetElementOffset(prID));
2693 Warning(
"InitializeOffsets",
"No branch class set for branch: %s",
GetName());
2710 Int_t localOffset = 0;
2723 Warning(
"InitializeOffsets",
"Streamer info for branch: %s has no elements array!",
GetName());
2730 Warning(
"InitializeOffsets",
"Cannot get streamer element for branch: %s!",
GetName());
2751 Error(
"InitializeOffsets",
"Could not find class for branch: %s",
GetName());
2765 stlParentName = br->
GetName();
2774 for (
Int_t subBranchIdx = 0; subBranchIdx < nbranches; ++subBranchIdx) {
2775 bool alternateElement =
false;
2779 if (subBranch == 0) {
2793 Warning(
"InitializeOffsets",
"No streamer info for branch: %s subbranch: %s",
GetName(), subBranch->
GetName());
2798 Warning(
"InitializeOffsets",
"No elements array for branch: %s subbranch: %s",
GetName(), subBranch->
GetName());
2804 if (!subBranchElement) {
2805 Warning(
"InitializeOffsets",
"No streamer element for branch: %s subbranch: %s",
GetName(), subBranch->
GetName());
2819 typedef TStreamerInfoActions::ActionContainer_t::iterator iterator;
2822 iter != end; ++iter) {
2827 subBranchElement =
e;
2828 alternateElement =
true;
2835 localOffset = subBranchElement->
GetOffset();
2844 && CanSelfReference(subBranchElement->
GetClass()))
2860 Warning(
"InitializeOffsets",
"Branch '%s' has no mother!",
GetName());
2866 if (motherName.Length() && strchr(motherName.Data(),
'.')) {
2870 if (motherName.Length() && (motherName[motherName.Length()-1] ==
'.')) {
2871 motherDotAtEnd =
kTRUE;
2875 if ((subBranch->
fType == 1) || (subBranchElement && subBranchElement->
IsBase())) {
2883 isBaseSubBranch =
kTRUE;
2887 if ((subBranch->
fType == 31) || (subBranch->
fType == 41)) {
2889 isContDataMember =
kTRUE;
2914 if (motherDotAtEnd) {
2916 dataName.
Remove(0, motherName.Length());
2918 if (!stlParentNameUpdated && stlParentName.
Length()) {
2919 stlParentName.
Remove(0, motherName.Length());
2920 stlParentNameUpdated =
kTRUE;
2922 }
else if (motherDot) {
2936 if (dataName.Length() == motherName.Length()) {
2937 dataName.Remove(0, motherName.Length());
2939 if (!stlParentNameUpdated && stlParentName.
Length()) {
2940 stlParentName.
Remove(0, motherName.Length());
2945 if (dataName.Length() > motherName.Length()) {
2946 dataName.
Remove(0, motherName.Length() + 1);
2947 if (!stlParentNameUpdated && stlParentName.
Length()) {
2948 stlParentName.
Remove(0, motherName.Length());
2953 stlParentNameUpdated =
kTRUE;
2954 if (isBaseSubBranch) {
2958 if (pattern.Length() <= dataName.Length()) {
2959 if (!strcmp(dataName.Data() + (dataName.Length() - pattern.Length()), pattern.Data())) {
2963 dataName.
Remove(dataName.Length() - pattern.Length());
2967 if (dataName.Length()) {
2968 if (dataName[0] ==
'.') {
2978 if (motherDotAtEnd) {
2980 parentName.
Remove(0, motherName.Length());
2981 }
else if (motherDot) {
2995 if (parentName.
Length() == motherName.Length()) {
2996 parentName.
Remove(0, motherName.Length());
3000 if (parentName.
Length() > motherName.Length()) {
3001 parentName.
Remove(0, motherName.Length() + 1);
3014 if (pattern.Length() <= parentName.
Length()) {
3015 if (!strcmp(parentName.
Data() + (parentName.
Length() - pattern.Length()), pattern.Data())) {
3019 parentName.
Remove(parentName.
Length() - pattern.Length());
3031 RemovePrefix(dataName, parentName);
3035 if (dataName.Length()) {
3036 if (dataName[0] ==
'.') {
3037 dataName.Remove(0, 1);
3042 if (dataName.Length()) {
3043 if (dataName[dataName.Length()-1] ==
'.') {
3044 dataName.Remove(dataName.Length() - 1, 1);
3060 if (dataName.Length()) {
3085 target +=
"@@emulated";
3103 Warning(
"InitializeOffsets",
"subBranch: '%s' has no parent class, and cannot get class for clones class: '%s'!", subBranch->
GetName(),
GetClonesName());
3107 Warning(
"InitializeOffsets",
"subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->
GetName(), pClass->
GetName());
3111 Warning(
"InitializeOffsets",
"subBranch: '%s' has no parent class! Assuming parent class is: '%s'.", subBranch->
GetName(), pClass ? pClass->
GetName() :
"unknowned class");
3116 pClass = branchClass;
3121 if (renamed && pClass) {
3122 if (pClass == branchClass) {
3134 if( dynamic_cast<TBranchSTL*>(
fParent) && stlParentName.
Length() )
3136 if( !strncmp( stlParentName.
Data(), dataName.Data(), stlParentName.
Length()-1 )
3137 && dataName[ stlParentName.
Length() ] ==
'.' )
3138 dataName.Remove( 0, stlParentName.
Length()+1 );
3145 if (alternateElement) {
3146 Ssiz_t dotpos = dataName.Last(
'.');
3147 Ssiz_t endpos = dataName.Length();
3148 if (dotpos !=
kNPOS) ++dotpos;
else dotpos = 0;
3149 dataName.Replace(dotpos,endpos-dotpos,subBranchElement->
GetFullName());
3170 Error(
"InitializeOffsets",
3171 "Could not find the real data member '%s' when constructing the branch '%s' [Likely missing ShowMember].",
3176 Info(
"InitializeOffsets",
3177 "TTree created with an older schema, some data might not be copied in 'slow-cloning' mode; fast-cloning should have the correct result. '%s' is missing when constructing the branch '%s'. ",
3181 Fatal(
"InitializeOffsets",
3182 "Could not find the real data member '%s' when constructing the branch '%s' [Likely an internal error, please report to the developers].",
3190 if (isBaseSubBranch) {
3193 Warning(
"InitializeOffsets",
"Could not find the data member name for branch '%s' with parent branch '%s', assuming offset is zero!", subBranch->
GetName(),
GetName());
3201 if (isContDataMember) {
3215 if (isBaseSubBranch) {
3222 subBranch->
SetOffset(offset - localOffset);
3232 }
else if (isSplit) {
3233 if (isBaseSubBranch) {
3244 if (isBaseSubBranch) {
3275 if (nbranches >= 1) {
3279 return browsables && browsables->
GetSize();
3294 if (basket &&
fTree) {
3307 bufbegin = entryOffset[entry-first];
3310 bufnext = entryOffset[entry+1-first];
3314 if (bufnext == bufbegin) {
3333 if (strncmp(option,
"debugAddress",strlen(
"debugAddress"))==0) {
3334 if (strlen(option)==strlen(
"debugAddress")) {
3335 Printf(
"%-24s %-16s %2s %4s %-16s %-16s %8s %8s %s\n",
3336 "Branch Name",
"Streamer Class",
"ID",
"Type",
"Class",
"Parent",
"pOffset",
"fOffset",
"fObject");
3345 Printf(
"%-16s %2d %4d %-16s %-16s %8x %8x %s\n",
3350 for (
Int_t i = 0; i < nbranches; ++i) {
3352 subbranch->
Print(
"debugAddressSub");
3356 if (strncmp(option,
"debugInfo",strlen(
"debugInfo"))==0) {
3363 Printf(
" with read actions:");
3365 Printf(
" with write actions:");
3368 TString suboption =
"debugInfoSub";
3369 suboption += (option+strlen(
"debugInfo"));
3370 for (
Int_t i = 0; i < nbranches; ++i) {
3372 subbranch->
Print(suboption);
3385 Printf(
"*............................................................................*");
3390 for (
Int_t i=0;i<nbranches;i++) {
3392 branch->
Print(option);
3412 }
else if (fOnfileObject) {
3449 }
else if (
fType <= 2) {
3466 }
else if (
fType == 3) {
3468 }
else if (
fType == 31) {
3473 }
else if (
fType == 41) {
3490 Fatal(
"ReadLeaves",
"The ReadLeaves function has not been configured for %s",
GetName());
3505 if ((n[0] < 0) || (n[0] >
fMaximum)) {
3510 Error(
"ReadLeaves",
"Incorrect size read for the container in %s\nThe size read is %d when the maximum is %d\nThe size is reset to 0 for this entry (%lld)",
GetName(), n[0],
fMaximum,
GetReadEntry());
3519 case ROOT::kSTLmultiset:
3521 case ROOT::kSTLmultimap:
3522 for (
Int_t i=0; i<nbranches; i++) {
3539 if (atype > 54)
return;
3548 if (!len_where)
return;
3553 for( k=0; k<
n; k++) {
3554 char **where = &(((
char**)
fAddress)[k]);
3558 case 1: {length = ((
Char_t*) len_where)[k];
break;}
3559 case 2: {length = ((
Short_t*) len_where)[k];
break;}
3560 case 3: {length = ((
Int_t*) len_where)[k];
break;}
3561 case 4: {length = ((
Long_t*) len_where)[k];
break;}
3563 case 6: {length = ((
Int_t*) len_where)[k];
break;}
3565 case 11: {length = ((
UChar_t*) len_where)[k];
break;}
3566 case 12: {length = ((
UShort_t*) len_where)[k];
break;}
3567 case 13: {length = ((
UInt_t*) len_where)[k];
break;}
3568 case 14: {length = ((
ULong_t*) len_where)[k];
break;}
3569 case 15: {length = ((
UInt_t*) len_where)[k];
break;}
3570 case 16: {length = ((
Long64_t*) len_where)[k];
break;}
3571 case 17: {length = ((
ULong64_t*)len_where)[k];
break;}
3572 case 18: {length = ((
Bool_t*) len_where)[k];
break;}
3576 if (length <= 0)
continue;
3577 if (isArray == 0)
continue;
3623 for (
Int_t ii=0;ii<
n;ii++) {
3632 for (
Int_t ii=0;ii<
n;ii++) {
3639 }
else if (
fType <= 2) {
3659 loc = counter.
Last(
']');
3663 countname += counter;
3669 Warning(
"ReadLeaves",
"Missing fBranchCount for %s. Data will not be read correctly by the MakeClass mode.",
GetName());
3695 for (
Int_t ii=0;ii<
n;ii++) {
3704 for (
Int_t ii=0;ii<
n;ii++) {
3759 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());
3765 R__PushCache onfileObject(((
TBufferFile&)b),fOnfileObject,n);
3786 case ROOT::kSTLunorderedset:
3787 case ROOT::kSTLunorderedmultiset:
3788 case ROOT::kSTLmultiset:
3790 case ROOT::kSTLmultimap:
3791 case ROOT::kSTLunorderedmap:
3792 case ROOT::kSTLunorderedmultimap:
3793 for (
Int_t i = 0; i < nbranches; ++i) {
3821 if( !
fNdata || *(
void**)proxy->
At( 0 ) != 0 )
3826 void **el = (
void**)proxy->
At( i );
3828 *el = elClass->
New();
3832 proxy->
Commit(alternate);
3858 if (info == 0)
return;
3899 if (info == 0)
return;
3930 if (info == 0)
return;
3963 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());
4002 if (info==0)
return;
4010 char **end = arr +
fNdata;
4032 R__PushCache onfileObject(((
TBufferFile&)b),fOnfileObject,1);
4084 R__PushCache onfileObject(((
TBufferFile&)b),fOnfileObject,1);
4119 R__PushCache onfileObject(((
TBufferFile&)b),fOnfileObject,1);
4140 R__PushCache onfileObject(((
TBufferFile&)b),fOnfileObject,1);
4149 Fatal(
"FillLeaves",
"The FillLeaves function has not been configured for %s",
GetName());
4172 }
else if (
fType == 4) {
4177 Warning(
"ReleaseObject",
"Cannot delete allocated STL container because I do not have a proxy! branch: %s",
GetName());
4181 if (needDelete &&
fID >= 0) {
4188 proxy->
Clear(
"force");
4213 proxy->
Clear(
"force");
4217 proxy->
Clear(
"force");
4238 for (
Int_t i = 0; i < nbranches; ++i) {
4240 branch->
Reset(option);
4253 for (
Int_t i = 0; i < nbranches; ++i) {
4275 for (
Int_t i = 0; i < nbranches; ++i) {
4301 for (
Int_t i = 0; i < nb; ++i) {
4442 if (
Long_t(addr) == -1) {
4534 if (clm == content) {
4540 Warning(
"SetAddress",
"The type of the %s was changed from TClonesArray to %s but we do not have a TVirtualCollectionProxy for that container type!",
GetName(), newType->
GetName());
4566 }
else if (
fType == 4) {
4578 for (
Int_t i = 0; i < nbranches; ++i) {
4611 for (
Int_t i = 0; i < nbranches; ++i) {
4639 Error(
"SetAddress",
"For %s, we can not convert %s into %s\n",
4772 Error(
"SetAddress",
"Embedded TClonesArray given a zero address for branch '%s'",
GetName());
4788 Error(
"SetAddress",
"Embedded pointer to a TClonesArray given a zero address for branch '%s'",
GetName());
4792 }
else if (
fType == 4) {
4819 Error(
"SetAddress",
"Failed to allocate STL container for branch '%s'",
GetName());
4836 Error(
"SetAddress",
"Failed to allocate STL container for branch '%s'",
GetName());
4855 Error(
"SetAddress",
"Embedded STL container given a zero address for branch '%s'",
GetName());
4868 Error(
"SetAddress",
"Failed to allocate STL container for branch '%s'",
GetName());
4876 Error(
"SetAddress",
"Embedded pointer to an STL container given a zero address for branch '%s'",
GetName());
4880 }
else if (
fType == 41) {
4886 }
else if (
fID < 0) {
4906 Error(
"SetAddress",
"I have no TClass for branch %s, so I cannot allocate an I/O buffer!",
GetName());
4933 for (
Int_t i = 0; i < nbranches; ++i) {
4956 for (
Int_t i = 0; i < nbranches; ++i) {
4972 if (leafOfCounter && leaf) {
4975 if (!leafOfCounter) {
4976 Warning(
"SetBranchCount",
"Counter branch %s for branch %s has no leaves!", brOfCounter->
GetName(),
GetName());
4979 Warning(
"SetBranchCount",
"Branch %s has no leaves!",
GetName());
4998 for (
Int_t i = 0; i < nbranches; ++i) {
5066 original =
transient;
5069 }
else if (
fType == 31) {