93 for(
Int_t ind = last-1; ind >= at; --ind) {
94 arr->
AddAt( arr->
At(ind), ind+1);
102 Int_t offset = objs.size();
105 for(
Int_t ind = last-1; ind >= at; --ind) {
106 arr->
AddAt( arr->
At(ind), ind+offset);
108 for(
size_t ins = 0; ins < objs.size(); ++ins) {
109 arr->
AddAt(objs[ins], at+ins);
118 while (at<last && arr->At(at) != oldobj) {
130 while (at<last && arr->At(at) != oldobj) {
245 struct TPreventRecursiveBuildGuard {
246 TPreventRecursiveBuildGuard(
TStreamerInfo* info): fInfo(info) {
250 ~TPreventRecursiveBuildGuard() {
281 TPreventRecursiveBuildGuard buildGuard(
this);
300 if (strncmp(
GetName(),
"ROOT::VecOps::RVec<", 19) == 0) {
301 Warning(
"Build",
"Due to some major, backward-incompatible improvements planned for ROOT::RVec, direct I/O of "
302 "ROOT::RVec objects will break between v6.24 and v6.26. Please use std::vectors instead. See "
303 "the release notes of v6.24 for more information.");
306 TStreamerElement::Class()->IgnoreTObjectStreamer();
314 ROOT::TSchemaRuleSet::TMatches rules;
340 Error(
"Build()",
"Cannot stream virtual base %s of class %s",
344 const char* bname = base->
GetName();
345 const char* btitle = base->
GetTitle();
347 if (!strcmp(bname,
"string")) {
356 Error(
"Build",
"The class \"%s\" is compiled and its base class \"%s\" is a collection and we do not have a dictionary for it, we will not be able to read or write this base class.",
GetName(),bname);
362 element =
new TStreamerBase(bname, btitle, offset, isTransient);
370 Warning(
"Build",
"%s: base class %s has no streamer or dictionary it will not be saved",
GetName(), clm->
GetName());
386 if (!isTransient && !clm->
IsLoaded() && !(isCollection || isString)) {
389 Warning(
"Build",
"%s: base class %s has no streamer or dictionary it will not be saved",
GetName(), clm->
GetName());
405 std::string typeNameBuf;
406 std::string trueTypeNameBuf;
427 const char* dmName = dm->
GetName();
428 const char* dmTitle = dm->
GetTitle();
434 std::array<Int_t, 5> maxIndices;
444 while(typeNameBuf.back() ==
'*') typeNameBuf.pop_back();
445 dmFull = trueTypeNameBuf.c_str();
446 dmType = typeNameBuf.c_str();
453 trueTypeNameBuf = typeNameBuf;
454 while(typeNameBuf.back() ==
'*') typeNameBuf.pop_back();
455 dmFull = dmType = typeNameBuf.c_str();
469 const char* rbracket = ::strchr(dmTitle,
']');
470 if (lbracket && rbracket) {
475 Error(
"Build",
"%s, discarding: %s %s, illegal %s\n",
GetName(), dmFull, dmName, dmTitle);
481 if (!dtCounter || !isInteger) {
483 Error(
"Build",
"%s, discarding: %s %s, illegal [%s] (must be Int_t)\n",
GetName(), dmFull, dmName, counterName);
492 Error(
"Build",
"%s, discarding: %s %s, illegal [%s] must be placed before \n",
GetName(), dmFull, dmName, counterName);
502 if (!dmCounter && (strstr(dmFull,
"char*") || strstr(dmFull,
"Char_t*"))) {
504 dsize =
sizeof(
char*);
508 Error(
"Build",
"%s, unknown type: %s %s",
GetName(), dmFull, dmName);
510 }
else if (dmIsPtr && (dtype !=
kCharStar)) {
515 if ((
fName ==
"TString") || (
fName ==
"TClass")) {
519 Error(
"Build",
"%s, discarding: %s %s, no [dimension]\n",
GetName(), dmFull, dmName);
524 if ((
fClass == TObject::Class()) && !strcmp(dmName,
"fBits")) {
533 static const char* full_string_name =
"basic_string<char,char_traits<char>,allocator<char> >";
534 if (!strcmp(dmType,
"string") || !strcmp(dmType,
"std::string") || !strcmp(dmType, full_string_name)) {
538 if (proxy) element =
new TStreamerSTL(dmName, dmTitle, offset, dmFull, *proxy, dmIsPtr);
539 else element =
new TStreamerSTL(dmName, dmTitle, offset, dmFull, dmFull, dmIsPtr);
542 auto printErrorMsg = [&](
const char* category)
545 Error(
"Build",
"The class \"%s\" is %s and for its data member \"%s\" we do not have a dictionary for the collection \"%s\". Because of this, we will not be able to read or write this data member.",
GetName(), category, dmName, dmType);
549 printErrorMsg(
"compiled");
555 printErrorMsg(
"interpreted");
565 Error(
"Build",
"%s, unknown type: %s %s\n",
GetName(), dmFull, dmName);
583 Error(
"Build",
"%s: %s has no streamer or dictionary, data member %s will not be saved",
590 }
else if ((clm == TString::Class()) && !dmIsPtr) {
595 Warning(
"Build",
"%s: %s has no streamer or dictionary, data member \"%s\" will not be saved",
608 for (
Int_t i = 0; i < ndim; ++i) {
610 if (isStdArray) maxIndex = maxIndices[i];
630 if ( !wasCompiled && (rules && rules.HasRuleWithSource( element->
GetName(),
kTRUE )) ) {
631 needAllocClass =
kTRUE;
640 && rules && !rules.HasRuleWithTarget( element->
GetName(),
kTRUE ) )
669 if (needAllocClass) {
744 Bool_t isstl = element && strcmp(
"This",element->
GetName())==0;
746 if (element->
GetTitle()[0] ==
'<') {
751 if (content[
c] ==
'<') ++level;
752 else if (content[
c] ==
'>') --level;
763 "Update the collection proxy of the class \"%s\" \n"
764 "\tto be similar to \"%s\".",
769 The class %s had a collection proxy when written but it is not an STL\n \
770 collection and we did not record the type of the content of the collection.\n \
771 We will claim the content is a bool (i.e. no data will be read).",
803 ::Warning(
"TClass::TClass",
"no dictionary for class %s is available",
GetName());
810 Bool_t isstl = element && strcmp(
"This",element->
GetName())==0;
812 if (element->
GetTitle()[0] ==
'<') {
817 if (content[
c] ==
'<') ++level;
818 else if (content[
c] ==
'>') --level;
829 "Update the collection proxy of the class \"%s\" \n"
830 "\tto be similar to \"%s\".",
835 The class %s had a collection proxy when written but it is not an STL\n \
836 collection and we did not record the type of the content of the collection.\n \
837 We will claim the content is a bool (i.e. no data will be read).",
859 searchOnChecksum =
kFALSE;
865 searchOnChecksum =
kTRUE;
872 searchOnChecksum =
kFALSE;
878 searchOnChecksum =
kTRUE;
888 searchOnChecksum =
kFALSE;
894 searchOnChecksum =
kTRUE;
905 if (!searchOnChecksum) {
911 for (
Int_t i = -1; i < ninfos; ++i) {
928 while ((slot < ninfos) && (array->
UncheckedAt(slot) != 0)) {
974#ifdef TEST_FOR_BACKWARD_COMPATIBILITY_ABSTRACT_CLASSES
1035 for (
Int_t i = 0; i < nel; ++i) {
1053 if (oldIsNonVersioned) {
1056 The class %s transitioned from not having a specified class version\n\
1057 to having a specified class version (the current class version is %d).\n\
1058 However too many different non-versioned layouts of the class have been\n\
1059 loaded so far. This prevent the proper reading of objects written with\n\
1060 the class layout version %d, in particular from the file:\n\
1062 To work around this issue, load fewer 'old' files in the same ROOT session.",
1066 The class %s transitioned from not having a specified class version\n\
1067 to having a specified class version (the current class version is %d).\n\
1068 However too many different non-versioned layouts of the class have been\n\
1069 loaded so far. This prevent the proper reading of objects written with\n\
1070 the class layout version %d.\n\
1071 To work around this issue, load fewer 'old' files in the same ROOT session.",
1078 The StreamerInfo for version %d of class %s read from the file %s\n\
1079 has a different checksum than the previously loaded StreamerInfo.\n\
1080 Reading objects of type %s from the file %s \n\
1081 (and potentially other files) might not work correctly.\n\
1082 Most likely the version number of the class was not properly\n\
1083 updated [See ClassDef(%s,%d)].",
1087 The StreamerInfo from %s does not match existing one (%s:%d)\n\
1088 The existing one has not been used yet and will be discarded.\n\
1089 Reading the file %s will work properly, however writing object of\n\
1090 type %s will not work properly. Most likely the version number\n\
1091 of the class was not properly updated [See ClassDef(%s,%d)].",
1097 The StreamerInfo for version %d of class %s\n\
1098 has a different checksum than the previously loaded StreamerInfo.\n\
1099 Reading objects of type %s\n\
1100 (and potentially other files) might not work correctly.\n\
1101 Most likely the version number of the class was not properly\n\
1102 updated [See ClassDef(%s,%d)].",
1106 The StreamerInfo from %s does not match existing one (%s:%d)\n\
1107 The existing one has not been used yet and will be discarded.\n\
1108 Reading should work properly, however writing object of\n\
1109 type %s will not work properly. Most likely the version number\n\
1110 of the class was not properly updated [See ClassDef(%s,%d)].",
1142#ifdef TEST_FOR_BACKWARD_COMPATIBILITY_ABSTRACT_CLASSES
1178 The StreamerInfo of class %s read from file %s\n\
1179 has the same version (=%d) as the active class but a different checksum.\n\
1180 You should update the version to ClassDef(%s,%d).\n\
1181 Do not try to write objects with the current class definition,\n\
1185 The StreamerInfo of class %s \n\
1186 has the same version (=%d) as the active class but a different checksum.\n\
1187 You should update the version to ClassDef(%s,%d).\n\
1188 Do not try to write objects with the current class definition,\n\
1196 Fatal(
"BuildCheck",
"\n\
1197 The StreamerInfo of unversioned class %s \n\
1198 has the same version (=%d) as the active class but an old checksum.\n\
1230 fNumber = maininfo->GetNumber();
1263 for (
Int_t i=0;i < ndata;i++) {
1265 if (!element)
break;
1272 if (ty <=
kULong)
continue;
1276 {
for (
int j=ndata-1;j>=i;j--) {elements->
AddAtAndExpand(elements->
At(j),j+1);}}
1277 elements->
AddAt(bt,i);
1299 Warning(
"BuildFor",
"The build of %s streamer info for %s has been requested, but no matching conversion rules were specified",
GetName(), in_memory_cl->
GetName() );
1317 if (oldClass == 0 || newClass == 0)
return kFALSE;
1322 const char *oldname = oldClass->
GetName();
1323 for (
UInt_t i = oldlen, done =
false, nest = 0; (i>0) && !done ; --i) {
1324 switch (oldClass->
GetName()[i-1]) {
1325 case '>' : ++nest;
break;
1326 case '<' :
if (nest==0)
return kFALSE;
1328 case ':' :
if (nest == 0) oldname= &(oldClass->
GetName()[i]); done =
kTRUE;
break;
1331 oldlen = strlen(oldname);
1332 if (!(strlen(newClass->
GetName()) > strlen(oldClass->
GetName()))) {
1336 const char* newEnd = & (newClass->
GetName()[newlen-oldlen]);
1338 if (0 != strcmp(newEnd, oldname)) {
1366 Error(
"ImportStreamerInfo",
"Unable to clone the StreamerInfo for %s.",(*next)->GetName());
1412 if (oldContent == newContent) {
1413 contentMatch =
kTRUE;
1414 }
else if (newContent) {
1417 if (oldFlatContent == newFlatContent) {
1418 contentMatch =
kTRUE;
1424 contentMatch = (newContent==0);
1428 if ((oldContent==0 && oldProxy->
GetType() == newProxy->
GetType())
1505 TClass *FindAlternate(
TClass *context,
const std::string &i_name, std::string& newName)
1511 std::string
name(i_name);
1513 if (
name.compare(0,6,
"const ")==0) {
1519 while(
name[
name.length()-nstars-1]==
'*') {
1524 name.erase(
name.length()-nstars,nstars);
1527 std::string alternate(context->
GetName());
1528 alternate.append(
"::");
1529 alternate.append(
name);
1533 newName.append(altcl->
GetName());
1534 newName.append(suffix);
1538 size_t ctxt_cursor = strlen(context->
GetName());
1539 for (
size_t level = 0; ctxt_cursor != 0; --ctxt_cursor) {
1540 switch (context->
GetName()[ctxt_cursor]) {
1541 case '<': --level;
break;
1542 case '>': ++level;
break;
1543 case ':':
if (level == 0) {
1547 alternate.append(context->
GetName(),ctxt_cursor+1);
1548 alternate.append(
name);
1551 newName.append(altcl->
GetName());
1552 newName.append(suffix);
1603 if ((firstNewCl && !firstOldCl) || (secondNewCl && !secondOldCl))
1605 std::vector<std::string> inside;
1609 TClass *firstAltCl = firstOldCl;
1610 TClass *secondAltCl = secondOldCl;
1611 std::string firstNewName;
1612 std::string secondNewName;
1613 if (!info && !firstOldCl) {
1616 if (!info && !secondOldCl) {
1619 if (firstNewCl && !firstOldCl) {
1620 firstAltCl = FindAlternate(context, inside[1], firstNewName);
1621 }
else if (firstAltCl) {
1622 firstNewName = firstAltCl->
GetName();
1624 firstNewName = inside[1];
1626 if (secondNewCl && !secondOldCl) {
1627 secondAltCl = FindAlternate(context, inside[2], secondNewName);
1628 }
else if (secondAltCl) {
1629 secondNewName = secondAltCl->
GetName();
1631 secondNewName = inside[2];
1633 if ((firstNewCl && firstAltCl != firstOldCl) ||
1634 (secondNewCl && secondAltCl != secondOldCl) ) {
1637 std::string alternate = inside[0];
1638 alternate.append(
"<");
1639 alternate.append(firstNewName);
1640 alternate.append(
",");
1641 alternate.append(secondNewName);
1645 if (alternate[alternate.length()-1]==
'>') {
1646 alternate.append(
" ");
1648 alternate.append(
">");
1661 std::vector<std::string> inside;
1666 std::string newName;
1667 TClass *altcl = FindAlternate(context, inside[1], newName);
1670 std::string alternate = inside[0];
1671 alternate.append(
"<");
1672 alternate.append(newName);
1676 if (alternate[alternate.length()-1]==
'>') {
1677 alternate.append(
" ");
1679 alternate.append(
">");
1687 struct TBuildOldGuard {
1713 TBuildOldGuard buildOldGuard(
this);
1716 printf(
"\n====>Rebuilding TStreamerInfo for class: %s, version: %d\n",
GetName(),
fClassVersion);
1760 constexpr size_t kSizeOfPtr =
sizeof(
void*);
1787 ROOT::TSchemaRuleSet::TMatches rules;
1793 Int_t virtualInfoLocAlloc = 0;
1799 if (element->IsA()==TStreamerArtificial::Class()
1816 if (element->IsA() == TStreamerBase::Class()) {
1818#if defined(PROPER_IMPLEMEMANTION_OF_BASE_CLASS_RENAMING)
1841 Error(
"BuildOld",
"Could not find base class: %s for %s and could not find any matching rename rule\n", base->
GetName(),
GetName());
1851 Error(
"BuildOld",
"Could not find base class: %s for %s, renaming rule was found but is malformed\n", base->
GetName(),
GetName());
1861 else if( !baseclass ) {
1864 Warning(
"BuildOld",
"Missing base class: %s skipped", base->
GetName());
1866 baseclass =
new TClass(element->
GetName(), 1, 0, 0, -1, -1);
1867 element->
Update(0, baseclass);
1877 if (baseOffset < 0) {
1889 if (!baserule.empty()) {
1900 element->
Init(
this);
1912 if (infobase) baseclass = infobase->
GetClass();
1918 if (infobase && infobase->
fComp == 0) {
1940 if (baseOffset < 0) {
1945 offset += baseclass->
Size();
1952 Int_t baseOffset = -1;
1960 if (strchr(bc->
GetName(),
'<') || !strcmp(bc->
GetName(),
"string")) {
1963 if (bcName == elName) {
1978 Error(
"BuildOld",
"The class \"%s\" is compiled and its base class \"%s\" is a collection and we do not have a dictionary for it, we will not be able to read or write this base class.",
GetName(),bc->
GetName());
1991 if (newInfo ==
this) {
1992 baseOffset = offset;
1994 }
else if (newInfo) {
1998 const char *newElName = newElement->
GetName();
1999 if (newElement->
IsBase() && (strchr(newElName,
'<') || !strcmp(newElName,
"string")) ) {
2002 if (bcName == elName) {
2008 Error(
"BuildOld",
"Could not find STL base class: %s for %s\n", element->
GetName(),
GetName());
2012 asize = newElement->
GetSize();
2015 if (baseOffset == -1) {
2026 if (baseOffset < 0) {
2032 element->
Init(
this);
2047 std::string typeNameBuf;
2048 const char* dmType =
nullptr;
2052 std::array<Int_t, 5> maxIndices;
2063 element->
Init(
this);
2077 element->
Init(
this);
2086 dmType = typeNameBuf.c_str();
2093 dmType = typeNameBuf.c_str();
2101 if (dmClassName.
Index(
"const ")==0) dmClassName.
Remove(0,6);
2106 Error(
"BuildOld",
"The class \"%s\" is compiled and for its data member \"%s\", we do not have a dictionary for the collection \"%s\", we will not be able to read or write this data member.",
GetName(),dm->
GetName(),elemDm->
GetName());
2123 element->
Init(
this);
2136 element->
Init(
this);
2137 if (pattern && pattern !=
this && pattern->IsBuilt()) {
2138 int pair_element_offset =
kMissing;
2139 pattern->GetStreamerElement(element->
GetName(), pair_element_offset);
2140 if (pair_element_offset !=
kMissing) {
2141 element->
SetOffset(pair_element_offset);
2153 auto theType = isStdArray ? dt : dm->
GetDataType();
2158 if ((
fClass == TObject::Class()) && !strcmp(dm->
GetName(),
"fBits")) {
2165 if ((newType ==
::kChar_t) && dmIsPtr && !isArray && !hasCount) {
2167 }
else if (dmIsPtr) {
2169 }
else if (isArray) {
2173 if (newType == -1) {
2180 if (newInfo && (newInfo !=
this)) {
2183 if (newClass == 0) {
2184 newType = newElems ? newElems->
GetType() : -1;
2208 }
else if (element->
GetType() != newType) {
2221 if (oldClass == newClass.
GetClass()) {
2223 }
else if (ClassWasMovedToNamespace(oldClass, newClass.
GetClass())) {
2225 if (0 != (oldv = ImportStreamerInfo(oldClass, newClass.
GetClass()))) {
2226 Warning(
"BuildOld",
"Can not properly load the TStreamerInfo from %s into %s due to a conflict for the class version %d", oldClass->
GetName(), newClass->
GetName(), oldv);
2233 }
else if (oldClass == TClonesArray::Class()) {
2234 if (ContainerMatchTClonesArray(newClass.
GetClass())) {
2257 TClass *oldFixedClass = FixCollectionV5(
GetClass(),oldClass,newClass);
2258 if (oldFixedClass && oldFixedClass != oldClass) {
2259 element->
Update(oldClass,oldFixedClass);
2260 oldClass = oldFixedClass;
2263 if (CollectionMatch(oldClass, newClass)) {
2278 switch( element->
GetType() ) {
2304 }
else if (CollectionMatchFloat16(oldClass,newClass)) {
2306 }
else if (CollectionMatchDouble32(oldClass,newClass)) {
2308 }
else if (CollectionMatchLong64(oldClass,newClass)) {
2311 }
else if (CollectionMatchULong64(oldClass,newClass)) {
2324 }
else if(oldClass &&
2341 if (strncmp(dm->
GetTitle(),
"->",2)==0) {
2362 }
else if (newClass == TString::Class()) {
2364 }
else if (newClass == TObject::Class()) {
2366 }
else if (newClass == TNamed::Class()) {
2374 if ((!dmIsPtr || newType==
kSTLp) && (isStdArray ? ndim : dm->
GetArrayDim()) > 0) {
2379 if (newInfo && (newInfo !=
this)) {
2382 newType = newElems->
GetType();
2390 && oldClass == TClonesArray::Class()))
2400 && oldClass == TClonesArray::Class()))
2413 if (newType != -1) {
2421 cannotConvert =
kTRUE;
2425 printf(
"%s We have no clue\n", dm->
GetName());
2426 cannotConvert =
kTRUE;
2429 if (newType != -1) {
2433 cannotConvert =
kTRUE;
2437 cannotConvert =
kTRUE;
2441 if (cannotConvert) {
2464 strcmp(element->
GetName(),
"This") == 0 &&
2470 asize =
sizeof(std::vector<int>);
2476 if ((offset % kSizeOfPtr) != 0) {
2477 offset = offset - (offset % kSizeOfPtr) + kSizeOfPtr;
2483 if (!wasCompiled && rules) {
2484 if (rules.HasRuleWithSource( element->
GetName(),
kTRUE ) ) {
2486 if (allocClass == 0) {
2494 allocClass = infoalloc->
GetClass();
2500 && !rules.HasRuleWithTarget( element->
GetName(),
kTRUE ) ) {
2522 }
else if (rules.HasRuleWithTarget( element->
GetName(),
kTRUE ) ) {
2534 }
else if (rules && rules.HasRuleWithTarget( element->
GetName(),
kTRUE ) ) {
2570 for (iel = 0; iel < narr; ++iel) {
2572 if (element->
IsBase() && (element->IsA() != TStreamerBase::Class())) {
2573 tai[kel++] = element;
2575 arr[jel++] = element;
2578 for (kel = 0; jel < narr;) {
2579 arr[jel++] = tai[kel++];
2586 if (!wasCompiled && allocClass) {
2624 element->SetOffset(0);
2650 TMemberInfo(
TClass *parent) : fParent(parent) {};
2652 void SetDataType(
Int_t datatype) {
2653 fDataType = datatype;
2659 void SetClassName(
const char *
name) {
2662 void SetComment(
const char *title) {
2663 const char *left = strstr(title,
"[");
2665 const char *right = strstr(left,
"]");
2668 fComment.
Append(left,right-left);
2686 if (fName != other.fName)
return kTRUE;
2689 if (fDataType != other.fDataType) {
2690 if ( (fDataType == 4 && other.fDataType == 16)
2691 || (fDataType == 16 && other.fDataType == 4) ) {
2693 }
else if ( (fDataType == 14 && other.fDataType == 17)
2694 || (fDataType == 17 && other.fDataType == 14) ) {
2696 }
else if ( (fDataType == 3 && other.fDataType == 6)
2697 ||(fDataType == 6 && other.fDataType == 3) ){
2706 }
else if (fClassName != other.fClassName) {
2707 if ( (fClassName ==
"long" && (other.fClassName ==
"long long" || other.fClassName ==
"Long64_t"))
2708 || ( (fClassName ==
"long long" || fClassName ==
"Long64_t") && other.fClassName ==
"long") ) {
2710 }
else if ( (fClassName ==
"unsigned long" && (other.fClassName ==
"unsigned long long" || other.fClassName ==
"ULong64_t"))
2711 || ( (fClassName ==
"unsigned long long" || fClassName ==
"ULong64_t") && other.fClassName ==
"unsigned long") ) {
2716 if (
name != othername) {
2719 if (!CollectionMatch(cl,otherCl)) {
2720 TClass *oldFixedClass = FixCollectionV5(fParent,cl,otherCl);
2721 if (!oldFixedClass || !CollectionMatch(oldFixedClass,otherCl)) {
2730 return fComment != other.fComment;
2752 char* eaddr = ((
char*)obj) + element->
GetOffset();
2771 if (ecl && (
fClass!=ecl )) {
2790 char* eaddr = ((
char*)obj) + element->
GetOffset();
2807 if (newname && newname[0] &&
fName != newname) {
2810 for(
Int_t i = 0; i < ndata; ++i) {
2812 if (element->IsA() == TStreamerLoop::Class()) {
2818 }
else if (element->IsA() == TStreamerBasicPointer::Class()) {
2843 R__ASSERT( (cl==0 || info==0) && (cl!=0 || info!=0) );
2876 if (el && el->
IsBase()) {
2891 if (infoel && infoel->
IsBase()) {
2892 otherClass = infoel->
GetName();
2903 if (localClass != otherClass) {
2907 "The in-memory layout version %d for class '%s' has a base class (%s) that the on-file layout version %d does not have.",
2909 }
else if (otherClass.
Length()==0) {
2911 "The on-file layout version %d for class '%s' has a base class (%s) that the in-memory layout version %d does not have",
2915 "One base class of the on-file layout version %d and of the in memory layout version %d for '%s' is different: '%s' vs '%s'",
2919 if (!complete)
return kFALSE;
2920 result = result &&
kFALSE;
2924 if (!localBase)
continue;
2927 if (!otherBaseClass)
continue;
2930 msg.
Form(
" The StreamerInfo of class %s read from %s%s\n"
2931 " has the same version (=%d) as the active class but a different checksum.\n"
2932 " You should update the version to ClassDef(%s,%d).\n"
2933 " The objects on this file might not be readable because:\n"
2934 " The in-memory layout version %d for class '%s' has a base class (%s) with version %d but the on-file layout version %d recorded the version number %d for this base class (%s).",
2943 if (!localBaseInfo) {
2947 const TList *list =
file->GetStreamerInfoCache();
2950 if (!localBaseInfo) {
2952 msg.
Form(
" The StreamerInfo of the base class %s (of class %s) read from %s%s\n"
2953 " refers to a checksum (%x) that can not be found neither in memory nor in the file.\n",
2967 msg.
Form(
" The StreamerInfo of class %s read from %s%s\n"
2968 " has the same version (=%d) as the active class but a different checksum.\n"
2969 " You should update the version to ClassDef(%s,%d).\n"
2970 " The objects on this file might not be readable because:\n"
2971 " The in-memory layout version %d for class '%s' has a base class (%s) with checksum %x but the on-file layout version %d recorded the checksum value %x for this base class (%s).",
2981 if (!localBase || !otherBase)
continue;
2987 msg.
Form(
" The StreamerInfo of class %s read from %s%s\n"
2988 " has the same version (=%d) as the active class but a different checksum.\n"
2989 " You should update the version to ClassDef(%s,%d).\n"
2990 " The objects on this file might not be readable because:\n"
2991 " The in-memory layout version %d for class '%s' has a base class (%s) with version %d but the on-file layout version %d recorded the version number %d for this base class (%s).",
3001 if (localBaseInfo == otherBaseInfo ||
3007 msg.
Form(
" The StreamerInfo of class %s read from %s%s\n"
3008 " has the same version (=%d) as the active class but a different checksum.\n"
3009 " You should update the version to ClassDef(%s,%d).\n"
3010 " The objects on this file might not be readable because:\n"
3011 " The in-memory layout version %d for class '%s' has a base class (%s) with checksum %x but the on-file layout version %d recorded the checksum value %x for this base class (%s).",
3019 if (!result && !complete) {
3028 TMemberInfo other(cl ? cl : info->
GetClass());
3034 while (el && (el->
IsBase() || el->IsA() == TStreamerArtificial::Class())) {
3039 local.SetName( el->
GetName() );
3041 local.SetComment( el->
GetTitle() );
3042 local.SetDataType( el->
GetType() );
3050 other.SetName( tdm->
GetName() );
3052 other.SetComment( tdm->
GetTitle() );
3075 while (infoel && (infoel->
IsBase() || infoel->IsA() == TStreamerArtificial::Class())) {
3079 other.SetName( infoel->
GetName() );
3081 other.SetComment( infoel->
GetTitle() );
3082 other.SetDataType( infoel->
GetType() );
3091 Warning(
"CompareContent",
"The following data member of\nthe in-memory layout version %d of class '%s' is missing from \nthe on-file layout version %d:\n"
3094 ,other.fClassName.Data(),other.fName.Data(),other.fComment.Data());
3096 }
else if (other.fName.Length()==0) {
3097 Warning(
"CompareContent",
"The following data member of\nthe in-memory layout version %d of class '%s' is missing from \nthe on-file layout version %d:\n"
3100 ,local.fClassName.Data(),local.fName.Data(),local.fComment.Data());
3102 Warning(
"CompareContent",
"The following data member of\nthe on-file layout version %d of class '%s' differs from \nthe in-memory layout version %d:\n"
3107 ,local.fClassName.Data(),local.fName.Data(),local.fComment.Data()
3108 ,other.fClassName.Data(),other.fName.Data(),other.fComment.Data());
3111 result = result &&
kFALSE;
3112 if (!complete)
return result;
3143 constexpr size_t kSizeOfPtr =
sizeof(
void*);
3180 auto recurseIntoContent = [
file, force](
TClass *contentClass)
3188 si = contentClass->GetCurrentStreamerInfo();
3190 si = contentClass->GetStreamerInfo();
3199 static TClassRef string_classref(
"string");
3200 if (
fClass == string_classref) {
3215 recurseIntoContent(valueClass);
3231 recurseIntoContent(cl);
3250 if (allocator)
return allocator->
GetClass();
3300 for (
int i=0; i<il; i++)
id =
id*3+
name[i];
3312 for (
int i=0; i<il; i++)
id =
id*3+
name[i];
3323 if (el->
IsBase())
continue;
3338 for (i=0; i<il; i++)
id =
id*3+
name[i];
3360 type.ReplaceAll(
"ULong64_t",
"unsigned long long");
3361 type.ReplaceAll(
"Long64_t",
"long long");
3362 type.ReplaceAll(
"signed char",
"char");
3363 type.ReplaceAll(
"<signed char",
"<char");
3364 type.ReplaceAll(
",signed char",
",char");
3365 if (
type==
"signed char")
type =
"char";
3369 for (i=0; i<il; i++)
id =
id*3+
type[i];
3384 const char *right = strstr(left,
"]");
3387 while (left != right) {
3431 constexpr auto auto_ptr_len =
str_length(
"auto_ptr<");
3432 constexpr auto unique_ptr_len =
str_length(
"unique_ptr<");
3436 return ((strncmp(
name,
"auto_ptr<", auto_ptr_len) == 0)
3437 || (strncmp(
name,
"unique_ptr<", unique_ptr_len) == 0));
3453 if (!defMod) { fprintf(
file,
" %s &modrhs = const_cast<%s &>( rhs );\n",protoname.
Data(),protoname.
Data()); defMod =
kTRUE; };
3454 const char *ename = element->
GetName();
3455 const char *colon2 = strstr(ename,
"::");
3456 if (colon2) ename = colon2+2;
3458 fprintf(
file,
" modrhs.%s = 0;\n",ename);
3460 fprintf(
file,
" memset(modrhs.%s,0,%d);\n",ename,element->
GetSize());
3463 const char *ename = element->
GetName();
3466 fprintf(
file,
" %s &modrhs = const_cast<%s &>( rhs );\n",protoname.
Data(),protoname.
Data()); defMod =
kTRUE;
3468 fprintf(
file,
" modrhs.%s = 0;\n",ename);
3471 fprintf(
file,
" %s &modrhs = const_cast<%s &>( rhs );\n",protoname.
Data(),protoname.
Data()); defMod =
kTRUE;
3473 fprintf(
file,
" modrhs.%s = 0;\n",ename);
3477 fprintf(
file,
" for (Int_t i=0;i<%d;i++) %s[i] = rhs.%s[i];\n",element->
GetArrayLength(),ename,ename);
3481 fprintf(
file,
"[0]");
3483 fprintf(
file,
"))[i] = (&(rhs.%s",ename);
3485 fprintf(
file,
"[0]");
3487 fprintf(
file,
"))[i];\n");
3490 if (!defMod) { fprintf(
file,
" %s &modrhs = const_cast<%s &>( rhs );\n",protoname.
Data(),protoname.
Data()); defMod =
kTRUE; };
3491 fprintf(
file,
" modrhs.%s = 0;\n",ename);
3494 fprintf(
file,
" %s &modrhs = const_cast<%s &>( rhs );\n",protoname.
Data(),protoname.
Data()); defMod =
kTRUE;
3498 std::string method_name =
"clear";
3500 method_name =
"reset";
3503 fprintf(
file,
" modrhs.%s();\n", method_name.c_str());
3505 fprintf(
file,
" modrhs.%s.%s();\n",ename, method_name.c_str());
3522 if (atstart) { fprintf(
file,
" : "); atstart =
kFALSE; }
3523 else fprintf(
file,
" , ");
3524 fprintf(
file,
"%s(const_cast<%s &>( rhs ))\n", element->
GetName(),protoname.
Data());
3527 if (atstart) { fprintf(
file,
" : "); atstart =
kFALSE; }
3528 else fprintf(
file,
" , ");
3530 fprintf(
file,
"%s(const_cast<%s &>( rhs ).%s.release() )\n",element->
GetName(),protoname.
Data(),element->
GetName());
3532 fprintf(
file,
"%s(const_cast<%s &>( rhs ).%s)\n",element->
GetName(),protoname.
Data(),element->
GetName());
3537 fprintf(
file,
"{\n");
3538 fprintf(
file,
" // This is NOT a copy constructor. This is actually a move constructor (for stl container's sake).\n");
3539 fprintf(
file,
" // Use at your own risk!\n");
3540 fprintf(
file,
" (void)rhs; // avoid warning about unused parameter\n");
3550 fprintf(
file,
"{\n");
3551 fprintf(
file,
" // This is NOT a copy operator=. This is actually a move operator= (for stl container's sake).\n");
3552 fprintf(
file,
" // Use at your own risk!\n");
3553 fprintf(
file,
" (void)rhs; // avoid warning about unused parameter\n");
3559 fprintf(
file,
" %s::operator=(const_cast<%s &>( rhs ));\n", element->
GetName(),protoname.
Data());
3563 fprintf(
file,
" %s = std::move((const_cast<%s &>( rhs ).%s));\n",element->
GetName(),protoname.
Data(),element->
GetName());
3565 fprintf(
file,
" %s = (const_cast<%s &>( rhs ).%s);\n",element->
GetName(),protoname.
Data(),element->
GetName());
3573 fprintf(
file,
" return *this;\n");
3587 const char *ename = element->
GetName();
3588 const char *colon2 = strstr(ename,
"::");
3589 if (colon2) ename = colon2+2;
3592 fprintf(
file,
" %s = 0;\n",ename);
3594 fprintf(
file,
" memset(%s,0,%d);\n",ename,element->
GetSize());
3598 fprintf(
file,
" delete %s; %s = 0;\n",ename,ename);
3600 fprintf(
file,
" for (Int_t i=0;i<%d;i++) delete %s[i]; memset(%s,0,%d);\n",element->
GetArrayLength(),ename,ename,element->
GetSize());
3605 const char *ename = element->
GetName();
3607 fprintf(
file,
" %s = 0;\n",ename);
3609 fprintf(
file,
" delete [] %s; %s = 0;\n",ename,ename);
3613 const char *ename = element->
GetName();
3615 fprintf(
file,
" %s = 0;\n",ename);
3617 fprintf(
file,
" delete %s; %s = 0;\n",ename,ename);
3619 fprintf(
file,
" delete [] %s; %s = 0;\n",ename,ename);
3623 const char *ename = element->
GetName();
3624 const char *prefix =
"";
3627 }
else if ( element->
IsBase() ) {
3636 fprintf(
file,
" std::for_each( (%s %s).rbegin(), (%s %s).rend(), DeleteObjectFunctor() );\n",prefix,ename,prefix,ename);
3644 std::vector<std::string> inside;
3647 if ((!inside[1].empty() && inside[1][inside[1].size()-1]==
'*')
3648 || (!inside[2].empty() && inside[2][inside[2].size()-1]==
'*')) {
3649 fprintf(
file,
" std::for_each( (%s %s).rbegin(), (%s %s).rend(), DeleteObjectFunctor() );\n",prefix,ename,prefix,ename);
3655 fprintf(
file,
" delete %s; %s = 0;\n",ename,ename);
3672 const char *clname =
GetName();
3674 if (strchr(clname,
':')) {
3676 Int_t len = strlen(clname);
3677 const char *
name = clname;
3680 for (
Int_t cur = 0; cur < len; ++cur) {
3681 switch (clname[cur]) {
3688 if (nest == 0) { cur = len;
continue; }
3692 if (nest == 0 && clname[cur+1] ==
':') {
3695 name = clname + cur + 2;
3702 template_protoname.
Append(clname,pr_pos);
3706 const char *where = strstr(clname,
"<");
3707 isTemplate = where != 0;
3709 template_protoname.
Append(clname,where-clname);
3713 if (needGenericTemplate && isTemplate) {
3715 fprintf(fp,
"#ifndef %s_h\n", templateName.
Data());
3716 fprintf(fp,
"#define %s_h\n", templateName.
Data());
3727 if (!element->
IsBase())
continue;
3729 const char *ename = element->
GetName();
3730 if (nbase == 1) fprintf(fp,
" : public %s",ename);
3731 else fprintf(fp,
" , public %s",ename);
3736 if (subClasses && subClasses->
GetEntries()) {
3737 Bool_t needheader =
true;
3739 TIter subnext(subClasses);
3744 if (subinfo->
GetName()[len+1]==
':' && strstr(subinfo->
GetName()+len+2,
":")==0) {
3746 fprintf(fp,
"\npublic:\n");
3747 fprintf(fp,
"// Nested classes forward declaration.\n");
3751 UInt_t sub_numberOfClasses = 0;
3752 UInt_t sub_numberOfNamespaces;
3760 for (
UInt_t i = 0;i < sub_numberOfClasses;++i) {
3761 fprintf(fp,
"}; // end of class.\n");
3763 if (sub_numberOfNamespaces > 0) {
3764 Error(
"GenerateDeclaration",
"Nested classes %s thought to be inside a namespace inside the class %s",subinfo->
GetName(),
GetName());
3771 fprintf(fp,
"\npublic:\n");
3772 fprintf(fp,
"// Nested classes declaration.\n");
3775 if (subClasses && subClasses->
GetEntries()) {
3781 if (subinfo->
GetName()[len+1]==
':' && strstr(subinfo->
GetName()+len+2,
":")==0) {
3788 fprintf(fp,
"\npublic:\n");
3789 fprintf(fp,
"// Data Members.\n");
3802 if (element->
IsBase())
continue;
3803 const char *ename = element->
GetName();
3813 if (element->IsA() == TStreamerSTL::Class()) {
3833 }
else if (strncmp(enamebasic.
Data(),
"auto_ptr<", strlen(
"auto_ptr<")) == 0) {
3837 lt = enamebasic.
Length();
3841 if (lt>=ltype) ltype = lt+1;
3843 for (is = 3+lt; is < (3+ltype); ++is)
line +=
' ';
3848 if (ld>=ldata) ldata = ld+1;
3849 for (is = 3+ltype+ld; is < (3+ltype+ldata); ++is)
line +=
' ';
3853 fprintf(fp,
"%s\n",
line.Data());
3856 if (needGenericTemplate && isTemplate) {
3858 fprintf(fp,
"\n %s() {\n",protoname.
Data());
3861 fprintf(fp,
" %s(%s && ) = default;\n",protoname.
Data(),protoname.
Data());
3862 fprintf(fp,
" %s &operator=(const %s & rhs)\n ",protoname.
Data(),protoname.
Data());
3865 fprintf(fp,
" %s(const %s & rhs )\n ",protoname.
Data(),protoname.
Data());
3868 fprintf(fp,
" virtual ~%s() {\n ",protoname.
Data());
3870 fprintf(fp,
" }\n\n");
3874 fprintf(fp,
"\n %s();\n",protoname.
Data());
3875 fprintf(fp,
" %s(%s && ) = default;\n",protoname.
Data(),protoname.
Data());
3876 fprintf(fp,
" %s &operator=(const %s & );\n",protoname.
Data(),protoname.
Data());
3877 fprintf(fp,
" %s(const %s & );\n",protoname.
Data(),protoname.
Data());
3878 fprintf(fp,
" virtual ~%s();\n\n",protoname.
Data());
3882 fprintf(sfp,
"#ifndef %s_cxx\n",guard.
Data());
3883 fprintf(sfp,
"#define %s_cxx\n",guard.
Data());
3884 fprintf(sfp,
"%s::%s() {\n",
GetName(),protoname.
Data());
3888 fprintf(sfp,
"%s &%s::operator=(const %s & rhs)\n",
GetName(),
GetName(),protoname.
Data());
3892 fprintf(sfp,
"%s::%s(const %s & rhs)\n",
GetName(),protoname.
Data(),protoname.
Data());
3896 fprintf(sfp,
"%s::~%s() {\n",
GetName(),protoname.
Data());
3899 fprintf(sfp,
"#endif // %s_cxx\n\n",guard.
Data());
3907 fprintf(fp,
" ClassDef(%s,%d); // Generated by MakeProject.\n",protoname.
Data(),0);
3909 fprintf(fp,
" ClassDef(%s,%d); // Generated by MakeProject.\n",protoname.
Data(),
fClassVersion + 1);
3914 for(
UInt_t i=0;i<numberOfNamespaces;++i) {
3915 fprintf(fp,
"} // namespace\n");
3918 if (needGenericTemplate && isTemplate) {
3919 fprintf(fp,
"#endif // generic template declaration\n");
3928 if (inclist[0]==0) {
3934 const char *clname =
GetName();
3935 if (strchr(clname,
'<')) {
3950 const char *ename = element->
GetName();
3951 const char *colon2 = strstr(ename,
"::");
3952 if (colon2) ename = colon2+2;
3959 if (ltype < lt) ltype = lt;
3960 if (ldata < ld) ldata = ld;
3963 if (!incRiostream && element->
InheritsFrom(TStreamerSTL::Class())) {
3964 incRiostream =
kTRUE;
3970 if (!include[0])
continue;
3972 Bool_t greater = (include[0]==
'<');
3975 if (strncmp(include,
"include/",8)==0) {
3978 if (strncmp(include,
"include\\",9)==0) {
3983 }
else if (strncmp(element->
GetTypeName(),
"auto_ptr<",strlen(
"auto_ptr<"))==0) {
3986 TString incName( include, strlen(include)-1 );
4008 if (strncmp(
GetName(),
"auto_ptr<",strlen(
"auto_ptr<"))==0)
return 0;
4019 for(
UInt_t i=len; i>0; --i) {
4021 case '>': ++nest;
if (scope==0) { isTemplate =
kTRUE; }
break;
4022 case '<': --nest;
break;
4024 if (nest==0 &&
GetName()[i-1]==
':') {
4031 }
else if (cl == 0 && extrainfos != 0) {
4046 if (
gDebug) printf(
"generating code for class %s\n",
GetName());
4052 filename.
Form(
"%s/%s.h",dirname,headername.
Data());
4054 FILE *fp = fopen(filename.
Data(),
"w");
4056 Error(
"MakeProject",
"Cannot open output file:%s\n",filename.
Data());
4061 FILE *allfp = fopen(filename.
Data(),
"a");
4063 Error(
"MakeProject",
"Cannot open output file:%s\n",filename.
Data());
4067 fprintf(allfp,
"#include \"%s.h\"\n", headername.
Data());
4070 char *inclist =
new char[50000];
4075 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
4076 fprintf(fp,
"// This class has been generated by TFile::MakeProject\n");
4077 fprintf(fp,
"// (%s by ROOT version %s)\n",td.
AsString(),
gROOT->GetVersion());
4078 fprintf(fp,
"// from the StreamerInfo in file %s\n",
gDirectory->GetFile()->GetName());
4079 fprintf(fp,
"//////////////////////////////////////////////////////////\n");
4082 fprintf(fp,
"#ifndef %s_h\n",headername.
Data());
4083 fprintf(fp,
"#define %s_h\n",headername.
Data());
4090 TIter subnext(subClasses);
4099 FILE *sfp = fopen( sourcename.
Data(),
"a" );
4103 Error(
"GenerateHeaderFile",
"Could not open %s for appending",sourcename.
Data());
4107 fprintf(fp,
"#endif\n");
4111 if (sfp) fclose(sfp);
4122 char dmbracket[256];
4136 char *rdmc = (
char*)rdm->
GetName();
4139 if (dm->
IsaPointer() && rdmc[0] ==
'*') rdmc++;
4142 if (strcmp(rdmc,dm->
GetName()) == 0) {
4154 if (strstr(rdm->
GetName(),dmbracket)) {
4168 if (elementName == 0)
return 0;
4230 Int_t base_offset = 0;
4231 Int_t local_offset = 0;
4237 if (!base_cl || !base_element) {
4240 base_offset = base_element->
GetOffset();
4243 offset = base_offset + local_offset;
4258 Int_t local_offset = 0;
4267 offset = base_offset + local_offset;
4315 ::Obsolete(
"TStreamerInfo::GetStreamerElementReal",
"v5-34-20",
"v6-00-02");
4317 if (i < 0 || i >=
fNdata)
return 0;
4318 if (j < 0)
return 0;
4323 for (
Int_t ise=0;ise < nelems;ise++) {
4325 if (ise+j >= nelems)
return 0;
4334template <
typename T>
4356#if defined(_MSC_VER) && (_MSC_VER <= 1200)
4378#if defined(_MSC_VER) && (_MSC_VER <= 1200)
4384#define READ_ARRAY(TYPE_t) \
4386 Int_t sub_instance, index; \
4387 Int_t instance = k; \
4389 index = instance / len; \
4390 sub_instance = instance % len; \
4395 TYPE_t **val =(TYPE_t**)(ladd); \
4396 return T((val[sub_instance])[index]); \
4414#if defined(_MSC_VER) && (_MSC_VER <= 1200)
4438template <
typename T>
4447 if (i < 0)
return 0;
4451 if (atype ==
kSTL) {
4453 if (newClass == 0) {
4465 if (j >= nc)
return 0;
4466 char *element_ptr = (
char*)proxy->
At(j);
4467 return GetTypedValueAux<T>(atype,element_ptr,0,1);
4471 return GetTypedValueAux<T>(atype,ladd,j,len);
4480template <
typename T>
4487 if (j >= nc)
return 0;
4491 return GetTypedValueAux<T>(
fCompFull[i]->fType,ladd,k,((