58 TBufferXML::TBufferXML(TBuffer::EMode mode) : TBufferText(mode)
67 TBufferXML::TBufferXML(TBuffer::EMode mode, TXMLFile *file)
68 : TBufferText(mode, file), TXMLSetup(*file)
76 SetXML(XmlFile()->XML());
77 SetCompressionSettings(XmlFile()->GetCompressionSettings());
78 SetIOVersion(XmlFile()->GetIOVersion());
85 TBufferXML::~TBufferXML()
93 TXMLFile *TBufferXML::XmlFile()
95 return dynamic_cast<TXMLFile *
>(GetParent());
104 TString TBufferXML::ConvertToXML(
const TObject *obj, Bool_t GenericLayout, Bool_t UseNamespaces)
106 TClass *clActual =
nullptr;
107 void *ptr = (
void *)obj;
110 clActual = TObject::Class()->GetActualClass(obj);
112 clActual = TObject::Class();
113 else if (clActual != TObject::Class())
114 ptr = (
void *)((Long_t)obj - clActual->GetBaseClassOffset(TObject::Class()));
117 return ConvertToXML(ptr, clActual, GenericLayout, UseNamespaces);
126 TString TBufferXML::ConvertToXML(
const void *obj,
const TClass *cl, Bool_t GenericLayout, Bool_t UseNamespaces)
130 TBufferXML buf(TBuffer::kWrite);
134 buf.SetXmlLayout(GenericLayout ? TXMLSetup::kGeneralized : TXMLSetup::kSpecialized);
135 buf.SetUseNamespaces(UseNamespaces);
137 XMLNodePointer_t xmlnode = buf.XmlWriteAny(obj, cl);
141 xml.SaveSingleNode(xmlnode, &res);
143 xml.FreeNode(xmlnode);
153 TObject *TBufferXML::ConvertFromXML(
const char *str, Bool_t GenericLayout, Bool_t UseNamespaces)
155 TClass *cl =
nullptr;
156 void *obj = ConvertFromXMLAny(str, &cl, GenericLayout, UseNamespaces);
161 Int_t delta = cl->GetBaseClassOffset(TObject::Class());
168 return (TObject *)(((
char *)obj) + delta);
176 void *TBufferXML::ConvertFromXMLAny(
const char *str, TClass **cl, Bool_t GenericLayout, Bool_t UseNamespaces)
179 TBufferXML buf(TBuffer::kRead);
184 buf.SetXmlLayout(GenericLayout ? TXMLSetup::kGeneralized : TXMLSetup::kSpecialized);
185 buf.SetUseNamespaces(UseNamespaces);
187 XMLNodePointer_t xmlnode = xml.ReadSingleNode(str);
189 void *obj = buf.XmlReadAny(xmlnode,
nullptr, cl);
191 xml.FreeNode(xmlnode);
200 void *TBufferXML::ConvertFromXMLChecked(
const char *xml,
const TClass *expectedClass, Bool_t GenericLayout,
201 Bool_t UseNamespaces)
203 TClass *objClass =
nullptr;
204 void *res = ConvertFromXMLAny(xml, &objClass, GenericLayout, UseNamespaces);
206 if (!res || !objClass)
209 if (objClass == expectedClass)
212 Int_t offset = objClass->GetBaseClassOffset(expectedClass);
214 ::Error(
"TBufferXML::ConvertFromXMLChecked",
"expected class %s is not base for read class %s",
215 expectedClass->GetName(), objClass->GetName());
216 objClass->Destructor(res);
220 return (
char *)res - offset;
227 XMLNodePointer_t TBufferXML::XmlWriteAny(
const void *obj,
const TClass *cl)
234 XMLNodePointer_t res = XmlWriteObject(obj, cl, kTRUE);
244 void *TBufferXML::XmlReadAny(XMLNodePointer_t node,
void *obj, TClass **cl)
257 PushStack(node, kTRUE);
259 void *res = XmlReadObject(obj, cl);
272 TXMLStackObj(XMLNodePointer_t node) : fNode(node)
282 Bool_t IsStreamerInfo()
const {
return fIsStreamerInfo; }
284 XMLNodePointer_t fNode{
nullptr};
285 TStreamerInfo *fInfo{
nullptr};
286 TStreamerElement *fElem{
nullptr};
287 Int_t fElemNumber{0};
288 Bool_t fCompressedClassNode{kFALSE};
289 XMLNsPointer_t fClassNs{
nullptr};
290 Bool_t fIsStreamerInfo{kFALSE};
291 Bool_t fIsElemOwner{kFALSE};
297 TXMLStackObj *TBufferXML::PushStack(XMLNodePointer_t current, Bool_t simple)
299 if (IsReading() && !simple) {
300 current = fXML->GetChild(current);
301 fXML->SkipEmpty(current);
304 fStack.emplace_back(std::make_unique<TXMLStackObj>(current));
305 return fStack.back().get();
311 TXMLStackObj *TBufferXML::PopStack()
313 if (fStack.size() > 0)
315 return fStack.size() > 0 ? fStack.back().get() :
nullptr;
321 XMLNodePointer_t TBufferXML::StackNode()
323 TXMLStackObj *stack = Stack();
324 return stack ? stack->fNode :
nullptr;
330 void TBufferXML::ShiftStack(
const char *errinfo)
332 TXMLStackObj *stack = Stack();
334 fXML->ShiftToNext(stack->fNode);
336 Info(
"ShiftStack",
"%s to node %s", errinfo, fXML->GetNodeName(stack->fNode));
343 void TBufferXML::SetCompressionAlgorithm(Int_t algorithm)
345 if (algorithm < 0 || algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined)
347 if (fCompressLevel < 0) {
348 fCompressLevel = 100 * algorithm + ROOT::RCompressionSetting::ELevel::kUseMin;
350 int level = fCompressLevel % 100;
351 fCompressLevel = 100 * algorithm + level;
358 void TBufferXML::SetCompressionLevel(Int_t level)
364 if (fCompressLevel < 0) {
366 fCompressLevel = level;
368 int algorithm = fCompressLevel / 100;
369 if (algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined)
371 fCompressLevel = 100 * algorithm + level;
380 void TBufferXML::SetCompressionSettings(Int_t settings)
382 fCompressLevel = settings;
389 void TBufferXML::XmlWriteBlock(XMLNodePointer_t node)
391 if (!node || (Length() == 0))
394 const char *src = Buffer();
395 int srcSize = Length();
397 char *fZipBuffer = 0;
399 Int_t compressionLevel = GetCompressionLevel();
400 ROOT::RCompressionSetting::EAlgorithm::EValues compressionAlgorithm =
401 static_cast<ROOT::RCompressionSetting::EAlgorithm::EValues
>(GetCompressionAlgorithm());
403 if ((Length() > 512) && (compressionLevel > 0)) {
404 int zipBufferSize = Length();
405 fZipBuffer =
new char[zipBufferSize + 9];
406 int dataSize = Length();
407 int compressedSize = 0;
408 R__zipMultipleAlgorithm(compressionLevel, &dataSize, Buffer(), &zipBufferSize, fZipBuffer, &compressedSize,
409 compressionAlgorithm);
410 if (compressedSize > 0) {
412 srcSize = compressedSize;
415 fZipBuffer =
nullptr;
425 while (srcCnt++ < srcSize) {
426 tgt += sprintf(tgt,
" %02x", (
unsigned char)*src);
428 if (block++ == 100) {
438 XMLNodePointer_t blocknode = fXML->NewChild(node,
nullptr, xmlio::XmlBlock, res);
439 fXML->NewIntAttr(blocknode, xmlio::Size, Length());
442 fXML->NewIntAttr(blocknode, xmlio::Zip, srcSize);
450 void TBufferXML::XmlReadBlock(XMLNodePointer_t blocknode)
455 Int_t blockSize = fXML->GetIntAttr(blocknode, xmlio::Size);
456 Bool_t blockCompressed = fXML->HasAttr(blocknode, xmlio::Zip);
457 char *fUnzipBuffer =
nullptr;
460 Info(
"XmlReadBlock",
"Block size = %d, Length = %d, Compressed = %d", blockSize, Length(), blockCompressed);
462 if (blockSize > BufferSize())
465 char *tgt = Buffer();
466 Int_t readSize = blockSize;
468 TString content = fXML->GetNodeContent(blocknode);
470 if (blockCompressed) {
471 Int_t zipSize = fXML->GetIntAttr(blocknode, xmlio::Zip);
472 fUnzipBuffer =
new char[zipSize];
478 char *ptr = (
char *)content.Data();
481 Info(
"XmlReadBlock",
"Content %s", ptr);
483 for (
int i = 0; i < readSize; i++) {
484 while ((*ptr < 48) || ((*ptr > 57) && (*ptr < 97)) || (*ptr > 102))
487 int b_hi = (*ptr > 57) ? *ptr - 87 : *ptr - 48;
489 int b_lo = (*ptr > 57) ? *ptr - 87 : *ptr - 48;
492 *tgt = b_hi * 16 + b_lo;
496 Info(
"XmlReadBlock",
" Buf[%d] = %d", i, b_hi * 16 + b_lo);
501 int srcsize(0), tgtsize(0), unzipRes(0);
502 int status = R__unzip_header(&srcsize, (UChar_t *)fUnzipBuffer, &tgtsize);
505 R__unzip(&readSize, (
unsigned char *)fUnzipBuffer, &blockSize, (
unsigned char *)Buffer(), &unzipRes);
507 if (status != 0 || unzipRes != blockSize)
508 Error(
"XmlReadBlock",
"Decompression error %d", unzipRes);
510 Info(
"XmlReadBlock",
"Unzip ok");
512 delete[] fUnzipBuffer;
521 Bool_t TBufferXML::ProcessPointer(
const void *ptr, XMLNodePointer_t node)
529 refvalue = xmlio::Null;
531 XMLNodePointer_t refnode = (XMLNodePointer_t)(Long_t)GetObjectTag(ptr);
535 if (fXML->HasAttr(refnode, xmlio::Ref)) {
536 refvalue = fXML->GetAttr(refnode, xmlio::Ref);
538 refvalue = xmlio::IdBase;
540 refvalue += XmlFile()->GetNextRefCounter();
542 refvalue += GetNextRefCounter();
543 fXML->NewAttr(refnode,
nullptr, xmlio::Ref, refvalue.Data());
546 if (refvalue.Length() > 0) {
547 fXML->NewAttr(node,
nullptr, xmlio::Ptr, refvalue.Data());
558 Bool_t TBufferXML::ExtractPointer(XMLNodePointer_t node,
void *&ptr, TClass *&cl)
562 if (!fXML->HasAttr(node, xmlio::Ptr))
565 const char *ptrid = fXML->GetAttr(node, xmlio::Ptr);
571 if (strcmp(ptrid, xmlio::Null) == 0) {
576 if (strncmp(ptrid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
577 Error(
"ExtractPointer",
"Pointer tag %s not started from %s", ptrid, xmlio::IdBase);
581 Int_t
id = TString(ptrid + strlen(xmlio::IdBase)).Atoi();
583 GetMappedObject(
id + 1, ptr, cl);
586 Error(
"ExtractPointer",
"not found ptr %s result %p %s", ptrid, ptr, (cl ? cl->GetName() :
"null"));
594 void TBufferXML::ExtractReference(XMLNodePointer_t node,
const void *ptr,
const TClass *cl)
599 const char *refid = fXML->GetAttr(node, xmlio::Ref);
604 if (strncmp(refid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
605 Error(
"ExtractReference",
"Reference tag %s not started from %s", refid, xmlio::IdBase);
609 Int_t
id = TString(refid + strlen(xmlio::IdBase)).Atoi();
611 MapObject(ptr, cl,
id + 1);
614 Info(
"ExtractReference",
"Find reference %s for object %p class %s", refid, ptr, (cl ? cl->GetName() :
"null"));
620 Bool_t TBufferXML::VerifyNode(XMLNodePointer_t node,
const char *name,
const char *errinfo)
625 if (strcmp(fXML->GetNodeName(node), name) != 0) {
627 Error(
"VerifyNode",
"Reading XML file (%s). Get: %s, expects: %s", errinfo, fXML->GetNodeName(node), name);
638 Bool_t TBufferXML::VerifyStackNode(
const char *name,
const char *errinfo)
640 return VerifyNode(StackNode(), name, errinfo);
646 Bool_t TBufferXML::VerifyAttr(XMLNodePointer_t node,
const char *name,
const char *value,
const char *errinfo)
648 if (!node || !name || !value)
651 const char *cont = fXML->GetAttr(node, name);
652 if ((!cont || (strcmp(cont, value) != 0))) {
654 Error(
"VerifyAttr",
"%s : attr %s = %s, expected: %s", errinfo, name, cont, value);
665 Bool_t TBufferXML::VerifyStackAttr(
const char *name,
const char *value,
const char *errinfo)
667 return VerifyAttr(StackNode(), name, value, errinfo);
673 XMLNodePointer_t TBufferXML::CreateItemNode(
const char *name)
675 XMLNodePointer_t node =
nullptr;
676 if (GetXmlLayout() == kGeneralized) {
677 node = fXML->NewChild(StackNode(),
nullptr, xmlio::Item);
678 fXML->NewAttr(node,
nullptr, xmlio::Name, name);
680 node = fXML->NewChild(StackNode(),
nullptr, name);
687 Bool_t TBufferXML::VerifyItemNode(
const char *name,
const char *errinfo)
690 if (GetXmlLayout() == kGeneralized)
691 res = VerifyStackNode(xmlio::Item, errinfo) && VerifyStackAttr(xmlio::Name, name, errinfo);
693 res = VerifyStackNode(name, errinfo);
700 void TBufferXML::CreateElemNode(
const TStreamerElement *elem)
702 XMLNodePointer_t elemnode =
nullptr;
704 const char *elemxmlname = XmlGetElementName(elem);
706 if (GetXmlLayout() == kGeneralized) {
707 elemnode = fXML->NewChild(StackNode(),
nullptr, xmlio::Member);
708 fXML->NewAttr(elemnode,
nullptr, xmlio::Name, elemxmlname);
711 XMLNsPointer_t ns = Stack()->fClassNs;
712 if ((elem->GetType() == TStreamerInfo::kBase) ||
713 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())) ||
714 ((elem->GetType() == TStreamerInfo::kTObject) && !strcmp(elem->GetName(), TObject::Class()->GetName())) ||
715 ((elem->GetType() == TStreamerInfo::kTString) && !strcmp(elem->GetName(), TString::Class()->GetName())))
718 elemnode = fXML->NewChild(StackNode(), ns, elemxmlname);
721 TXMLStackObj *curr = PushStack(elemnode);
722 curr->fElem = (TStreamerElement *)elem;
728 Bool_t TBufferXML::VerifyElemNode(
const TStreamerElement *elem)
730 const char *elemxmlname = XmlGetElementName(elem);
732 if (GetXmlLayout() == kGeneralized) {
733 if (!VerifyStackNode(xmlio::Member))
735 if (!VerifyStackAttr(xmlio::Name, elemxmlname))
738 if (!VerifyStackNode(elemxmlname))
742 PerformPreProcessing(elem, StackNode());
744 TXMLStackObj *curr = PushStack(StackNode());
745 curr->fElem = (TStreamerElement *)elem;
754 XMLNodePointer_t TBufferXML::XmlWriteObject(
const void *obj,
const TClass *cl, Bool_t cacheReuse)
756 XMLNodePointer_t objnode = fXML->NewChild(StackNode(),
nullptr, xmlio::Object);
761 if (ProcessPointer(obj, objnode))
764 TString clname = XmlConvertClassName(cl->GetName());
766 fXML->NewAttr(objnode,
nullptr, xmlio::ObjClass, clname);
769 fMap->Add(Void_Hash(obj), (Long_t)obj, (Long_t)objnode);
773 ((TClass *)cl)->Streamer((
void *)obj, *
this);
778 Info(
"XmlWriteObject",
"Done write for class: %s", cl ? cl->GetName() :
"null");
786 void *TBufferXML::XmlReadObject(
void *obj, TClass **cl)
791 XMLNodePointer_t objnode = StackNode();
799 if (!VerifyNode(objnode, xmlio::Object,
"XmlReadObjectNew"))
802 TClass *objClass =
nullptr;
804 if (ExtractPointer(objnode, obj, objClass)) {
805 ShiftStack(
"readobjptr");
811 TString clname = fXML->GetAttr(objnode, xmlio::ObjClass);
812 objClass = XmlDefineClass(clname);
813 if (objClass == TDirectory::Class())
814 objClass = TDirectoryFile::Class();
817 Error(
"XmlReadObject",
"Cannot find class %s", clname.Data());
818 ShiftStack(
"readobjerr");
823 Info(
"XmlReadObject",
"Reading object of class %s", clname.Data());
826 obj = objClass->New();
828 ExtractReference(objnode, obj, objClass);
832 objClass->Streamer((
void *)obj, *
this);
836 ShiftStack(
"readobj");
839 Info(
"XmlReadObject",
"Reading object of class %s done", clname.Data());
853 void TBufferXML::IncrementLevel(TVirtualStreamerInfo *info)
855 WorkWithClass((TStreamerInfo *)info);
861 void TBufferXML::WorkWithClass(TStreamerInfo *sinfo,
const TClass *cl)
863 fCanUseCompact = kFALSE;
866 cl = sinfo->GetClass();
871 TString clname = XmlConvertClassName(cl->GetName());
874 Info(
"IncrementLevel",
"Class: %s", clname.Data());
876 Bool_t compressClassNode = (fExpectedBaseClass == cl);
877 fExpectedBaseClass =
nullptr;
879 TXMLStackObj *stack = Stack();
883 XMLNodePointer_t classnode =
nullptr;
884 if (compressClassNode) {
885 classnode = StackNode();
887 if (GetXmlLayout() == kGeneralized) {
888 classnode = fXML->NewChild(StackNode(),
nullptr, xmlio::Class);
889 fXML->NewAttr(classnode,
nullptr,
"name", clname);
891 classnode = fXML->NewChild(StackNode(),
nullptr, clname);
892 stack = PushStack(classnode);
895 if (fVersionBuf >= -1) {
896 if (fVersionBuf == -1)
898 fXML->NewIntAttr(classnode, xmlio::ClassVersion, fVersionBuf);
902 if (IsUseNamespaces() && (GetXmlLayout() != kGeneralized))
903 stack->fClassNs = fXML->NewNS(classnode, XmlClassNameSpaceRef(cl), clname);
906 if (!compressClassNode) {
907 if (GetXmlLayout() == kGeneralized) {
908 if (!VerifyStackNode(xmlio::Class,
"StartInfo"))
910 if (!VerifyStackAttr(
"name", clname,
"StartInfo"))
912 }
else if (!VerifyStackNode(clname,
"StartInfo"))
914 stack = PushStack(StackNode());
918 stack->fCompressedClassNode = compressClassNode;
919 stack->fInfo = sinfo;
920 stack->fIsStreamerInfo = kTRUE;
927 void TBufferXML::DecrementLevel(TVirtualStreamerInfo *info)
931 fCanUseCompact = kFALSE;
934 Info(
"DecrementLevel",
"Class: %s", (info ? info->GetClass()->GetName() :
"custom"));
936 TXMLStackObj *stack = Stack();
938 if (!stack->IsStreamerInfo()) {
939 PerformPostProcessing();
943 if (stack->fCompressedClassNode) {
944 stack->fInfo =
nullptr;
945 stack->fIsStreamerInfo = kFALSE;
946 stack->fCompressedClassNode = kFALSE;
950 ShiftStack(
"declevel");
959 void TBufferXML::SetStreamerElementNumber(TStreamerElement *elem, Int_t comptype)
961 WorkWithElement(elem, comptype);
970 void TBufferXML::WorkWithElement(TStreamerElement *elem, Int_t comp_type)
974 fCanUseCompact = kFALSE;
975 fExpectedBaseClass =
nullptr;
977 TXMLStackObj *stack = Stack();
979 Error(
"SetStreamerElementNumber",
"stack is empty");
983 if (!stack->IsStreamerInfo()) {
984 PerformPostProcessing();
987 ShiftStack(
"startelem");
992 Error(
"SetStreamerElementNumber",
"Lost of stack");
997 Error(
"SetStreamerElementNumber",
"Problem in Inc/Dec level");
1001 TStreamerInfo *info = stack->fInfo;
1003 if (!stack->IsStreamerInfo()) {
1004 Error(
"SetStreamerElementNumber",
"Problem in Inc/Dec level");
1007 Int_t number = info ? info->GetElements()->IndexOf(elem) : -1;
1010 Info(
"SetStreamerElementNumber",
" Next element %s", elem->GetName());
1012 Bool_t isBasicType = (elem->GetType() > 0) && (elem->GetType() < 20);
1015 isBasicType && ((elem->GetType() == comp_type) || (elem->GetType() == comp_type - TStreamerInfo::kConv) ||
1016 (elem->GetType() == comp_type - TStreamerInfo::kSkip));
1018 if ((elem->GetType() == TStreamerInfo::kBase) ||
1019 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())))
1020 fExpectedBaseClass = elem->GetClassPointer();
1022 if (fExpectedBaseClass && (gDebug > 3))
1023 Info(
"SetStreamerElementNumber",
" Expects base class %s with standard streamer",
1024 fExpectedBaseClass->GetName());
1027 CreateElemNode(elem);
1029 if (!VerifyElemNode(elem))
1034 stack->fElemNumber = number;
1035 stack->fIsElemOwner = (number < 0);
1048 void TBufferXML::ClassBegin(
const TClass *cl, Version_t)
1050 WorkWithClass(
nullptr, cl);
1057 void TBufferXML::ClassEnd(
const TClass *)
1100 void TBufferXML::ClassMember(
const char *name,
const char *typeName, Int_t arrsize1, Int_t arrsize2)
1105 if (!name || (strlen(name) == 0)) {
1106 Error(
"ClassMember",
"Invalid member name");
1111 TString tname = typeName;
1113 Int_t typ_id(-1), comp_type(-1);
1115 if (strcmp(typeName,
"raw:data") == 0)
1116 typ_id = TStreamerInfo::kMissing;
1119 TDataType *dt = gROOT->GetType(typeName);
1121 if ((dt->GetType() > 0) && (dt->GetType() < 20))
1122 typ_id = dt->GetType();
1126 if (strcmp(name, typeName) == 0) {
1127 TClass *cl = TClass::GetClass(tname.Data());
1129 typ_id = TStreamerInfo::kBase;
1133 Bool_t isptr = kFALSE;
1134 if (tname[tname.Length() - 1] ==
'*') {
1135 tname.Resize(tname.Length() - 1);
1138 TClass *cl = TClass::GetClass(tname.Data());
1140 Error(
"ClassMember",
"Invalid class specifier %s", typeName);
1145 if (cl->IsTObject())
1146 typ_id = isptr ? TStreamerInfo::kObjectp : TStreamerInfo::kObject;
1148 typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
1150 if ((cl == TString::Class()) && !isptr)
1151 typ_id = TStreamerInfo::kTString;
1154 TStreamerElement *elem =
nullptr;
1156 if (typ_id == TStreamerInfo::kMissing) {
1157 elem =
new TStreamerElement(name,
"title", 0, typ_id,
"raw:data");
1158 }
else if (typ_id == TStreamerInfo::kBase) {
1159 TClass *cl = TClass::GetClass(tname.Data());
1161 TStreamerBase *b =
new TStreamerBase(tname.Data(),
"title", 0);
1162 b->SetBaseVersion(cl->GetClassVersion());
1165 }
else if ((typ_id > 0) && (typ_id < 20)) {
1166 elem =
new TStreamerBasicType(name,
"title", 0, typ_id, typeName);
1168 }
else if ((typ_id == TStreamerInfo::kObject) || (typ_id == TStreamerInfo::kTObject) ||
1169 (typ_id == TStreamerInfo::kTNamed)) {
1170 elem =
new TStreamerObject(name,
"title", 0, tname.Data());
1171 }
else if (typ_id == TStreamerInfo::kObjectp) {
1172 elem =
new TStreamerObjectPointer(name,
"title", 0, tname.Data());
1173 }
else if (typ_id == TStreamerInfo::kAny) {
1174 elem =
new TStreamerObjectAny(name,
"title", 0, tname.Data());
1175 }
else if (typ_id == TStreamerInfo::kAnyp) {
1176 elem =
new TStreamerObjectAnyPointer(name,
"title", 0, tname.Data());
1177 }
else if (typ_id == TStreamerInfo::kTString) {
1178 elem =
new TStreamerString(name,
"title", 0);
1182 Error(
"ClassMember",
"Invalid combination name = %s type = %s", name, typeName);
1188 elem->SetArrayDim(arrsize2 > 0 ? 2 : 1);
1189 elem->SetMaxIndex(0, arrsize1);
1191 elem->SetMaxIndex(1, arrsize2);
1195 WorkWithElement(elem, comp_type);
1201 void TBufferXML::PerformPostProcessing()
1203 if (GetXmlLayout() == kGeneralized)
1206 const TStreamerElement *elem = Stack()->fElem;
1207 XMLNodePointer_t elemnode = IsWriting() ? Stack()->fNode : Stack(1)->fNode;
1209 if (!elem || !elemnode)
1212 if (elem->GetType() == TStreamerInfo::kTString) {
1214 XMLNodePointer_t node = fXML->GetChild(elemnode);
1215 fXML->SkipEmpty(node);
1217 XMLNodePointer_t nodecharstar(
nullptr), nodeuchar(
nullptr), nodeint(
nullptr), nodestring(
nullptr);
1220 const char *name = fXML->GetNodeName(node);
1221 if (strcmp(name, xmlio::String) == 0) {
1225 }
else if (strcmp(name, xmlio::UChar) == 0) {
1229 }
else if (strcmp(name, xmlio::Int) == 0) {
1233 }
else if (strcmp(name, xmlio::CharStar) == 0) {
1236 nodecharstar = node;
1239 fXML->ShiftToNext(node);
1244 if (GetIOVersion() < 3) {
1248 str = fXML->GetAttr(nodecharstar, xmlio::v);
1249 fXML->UnlinkFreeNode(nodeuchar);
1250 fXML->UnlinkFreeNode(nodeint);
1251 fXML->UnlinkFreeNode(nodecharstar);
1254 str = fXML->GetAttr(nodestring, xmlio::v);
1255 fXML->UnlinkFreeNode(nodestring);
1258 fXML->NewAttr(elemnode,
nullptr,
"str", str);
1259 }
else if (elem->GetType() == TStreamerInfo::kTObject) {
1260 XMLNodePointer_t node = fXML->GetChild(elemnode);
1261 fXML->SkipEmpty(node);
1263 XMLNodePointer_t vnode =
nullptr, idnode =
nullptr, bitsnode =
nullptr, prnode =
nullptr;
1266 const char *name = fXML->GetNodeName(node);
1268 if (strcmp(name, xmlio::OnlyVersion) == 0) {
1272 }
else if (strcmp(name, xmlio::UInt) == 0) {
1279 }
else if (strcmp(name, xmlio::UShort) == 0) {
1285 fXML->ShiftToNext(node);
1288 if (!vnode || !idnode || !bitsnode)
1291 TString str = fXML->GetAttr(idnode, xmlio::v);
1292 fXML->NewAttr(elemnode,
nullptr,
"fUniqueID", str);
1294 str = fXML->GetAttr(bitsnode, xmlio::v);
1296 sscanf(str.Data(),
"%u", &bits);
1297 bits = bits & ~TObject::kNotDeleted & ~TObject::kIsOnHeap;
1300 snprintf(sbuf,
sizeof(sbuf),
"%x", bits);
1301 fXML->NewAttr(elemnode,
nullptr,
"fBits", sbuf);
1304 str = fXML->GetAttr(prnode, xmlio::v);
1305 fXML->NewAttr(elemnode,
nullptr,
"fProcessID", str);
1308 fXML->UnlinkFreeNode(vnode);
1309 fXML->UnlinkFreeNode(idnode);
1310 fXML->UnlinkFreeNode(bitsnode);
1311 fXML->UnlinkFreeNode(prnode);
1319 void TBufferXML::PerformPreProcessing(
const TStreamerElement *elem, XMLNodePointer_t elemnode)
1321 if (GetXmlLayout() == kGeneralized)
1323 if (!elem || !elemnode)
1326 if (elem->GetType() == TStreamerInfo::kTString) {
1328 if (!fXML->HasAttr(elemnode,
"str"))
1330 TString str = fXML->GetAttr(elemnode,
"str");
1331 fXML->FreeAttr(elemnode,
"str");
1333 if (GetIOVersion() < 3) {
1334 Int_t len = str.Length();
1335 XMLNodePointer_t ucharnode = fXML->NewChild(elemnode,
nullptr, xmlio::UChar);
1337 snprintf(sbuf,
sizeof(sbuf),
"%d", len);
1339 fXML->NewAttr(ucharnode,
nullptr, xmlio::v, sbuf);
1341 fXML->NewAttr(ucharnode,
nullptr, xmlio::v,
"255");
1342 XMLNodePointer_t intnode = fXML->NewChild(elemnode,
nullptr, xmlio::Int);
1343 fXML->NewAttr(intnode,
nullptr, xmlio::v, sbuf);
1346 XMLNodePointer_t node = fXML->NewChild(elemnode,
nullptr, xmlio::CharStar);
1347 fXML->NewAttr(node,
nullptr, xmlio::v, str);
1350 XMLNodePointer_t node = fXML->NewChild(elemnode,
nullptr, xmlio::String);
1351 fXML->NewAttr(node,
nullptr, xmlio::v, str);
1353 }
else if (elem->GetType() == TStreamerInfo::kTObject) {
1354 if (!fXML->HasAttr(elemnode,
"fUniqueID"))
1356 if (!fXML->HasAttr(elemnode,
"fBits"))
1359 TString idstr = fXML->GetAttr(elemnode,
"fUniqueID");
1360 TString bitsstr = fXML->GetAttr(elemnode,
"fBits");
1361 TString prstr = fXML->GetAttr(elemnode,
"fProcessID");
1363 fXML->FreeAttr(elemnode,
"fUniqueID");
1364 fXML->FreeAttr(elemnode,
"fBits");
1365 fXML->FreeAttr(elemnode,
"fProcessID");
1367 XMLNodePointer_t node = fXML->NewChild(elemnode,
nullptr, xmlio::OnlyVersion);
1368 fXML->NewAttr(node,
nullptr, xmlio::v,
"1");
1370 node = fXML->NewChild(elemnode,
nullptr, xmlio::UInt);
1371 fXML->NewAttr(node,
nullptr, xmlio::v, idstr);
1374 sscanf(bitsstr.Data(),
"%x", &bits);
1375 bits = bits | TObject::kNotDeleted | TObject::kIsOnHeap;
1377 snprintf(sbuf,
sizeof(sbuf),
"%u", bits);
1379 node = fXML->NewChild(elemnode,
nullptr, xmlio::UInt);
1380 fXML->NewAttr(node,
nullptr, xmlio::v, sbuf);
1382 if (prstr.Length() > 0) {
1383 node = fXML->NewChild(elemnode,
nullptr, xmlio::UShort);
1384 fXML->NewAttr(node,
nullptr, xmlio::v, prstr.Data());
1393 void TBufferXML::BeforeIOoperation()
1401 TClass *TBufferXML::ReadClass(
const TClass *, UInt_t *)
1403 const char *clname =
nullptr;
1405 if (VerifyItemNode(xmlio::Class))
1406 clname = XmlReadValue(xmlio::Class);
1409 Info(
"ReadClass",
"Try to read class %s", clname ? clname :
"---");
1411 return clname ? gROOT->GetClass(clname) :
nullptr;
1417 void TBufferXML::WriteClass(
const TClass *cl)
1420 Info(
"WriteClass",
"Try to write class %s", cl->GetName());
1422 XmlWriteValue(cl->GetName(), xmlio::Class);
1428 Version_t TBufferXML::ReadVersion(UInt_t *start, UInt_t *bcnt,
const TClass * )
1430 BeforeIOoperation();
1439 if (VerifyItemNode(xmlio::OnlyVersion)) {
1440 res = AtoI(XmlReadValue(xmlio::OnlyVersion));
1441 }
else if (fExpectedBaseClass && (fXML->HasAttr(Stack(1)->fNode, xmlio::ClassVersion))) {
1442 res = fXML->GetIntAttr(Stack(1)->fNode, xmlio::ClassVersion);
1443 }
else if (fXML->HasAttr(StackNode(), xmlio::ClassVersion)) {
1444 res = fXML->GetIntAttr(StackNode(), xmlio::ClassVersion);
1446 Error(
"ReadVersion",
"No correspondent tags to read version");
1451 Info(
"ReadVersion",
"Version = %d", res);
1460 void TBufferXML::CheckVersionBuf()
1462 if (IsWriting() && (fVersionBuf >= -100)) {
1464 snprintf(sbuf,
sizeof(sbuf),
"%d", fVersionBuf);
1465 XmlWriteValue(sbuf, xmlio::OnlyVersion);
1475 UInt_t TBufferXML::WriteVersion(
const TClass *cl, Bool_t )
1477 BeforeIOoperation();
1479 if (fExpectedBaseClass != cl)
1480 fExpectedBaseClass =
nullptr;
1482 fVersionBuf = cl->GetClassVersion();
1485 Info(
"WriteVersion",
"Class: %s, version = %d", cl->GetName(), fVersionBuf);
1493 void *TBufferXML::ReadObjectAny(
const TClass *)
1495 BeforeIOoperation();
1497 Info(
"ReadObjectAny",
"From node %s", fXML->GetNodeName(StackNode()));
1498 void *res = XmlReadObject(
nullptr);
1506 void TBufferXML::SkipObjectAny()
1508 ShiftStack(
"skipobjectany");
1514 void TBufferXML::WriteObjectClass(
const void *actualObjStart,
const TClass *actualClass, Bool_t cacheReuse)
1516 BeforeIOoperation();
1518 Info(
"WriteObject",
"Class %s", (actualClass ? actualClass->GetName() :
" null"));
1519 XmlWriteObject(actualObjStart, actualClass, cacheReuse);
1525 template <
typename T>
1526 R__ALWAYS_INLINE
void TBufferXML::XmlReadArrayContent(T *arr, Int_t arrsize)
1528 Int_t indx = 0, cnt, curr;
1529 while (indx < arrsize) {
1531 if (fXML->HasAttr(StackNode(), xmlio::cnt))
1532 cnt = fXML->GetIntAttr(StackNode(), xmlio::cnt);
1533 XmlReadBasic(arr[indx]);
1536 arr[indx++] = arr[curr];
1544 template <
typename T>
1545 R__ALWAYS_INLINE Int_t TBufferXML::XmlReadArray(T *&arr,
bool is_static)
1547 BeforeIOoperation();
1548 if (!VerifyItemNode(xmlio::Array, is_static ?
"ReadStaticArray" :
"ReadArray"))
1550 Int_t n = fXML->GetIntAttr(StackNode(), xmlio::Size);
1558 PushStack(StackNode());
1559 XmlReadArrayContent(arr, n);
1561 ShiftStack(is_static ?
"readstatarr" :
"readarr");
1568 Int_t TBufferXML::ReadArray(Bool_t *&b)
1570 return XmlReadArray(b);
1576 Int_t TBufferXML::ReadArray(Char_t *&c)
1578 return XmlReadArray(c);
1584 Int_t TBufferXML::ReadArray(UChar_t *&c)
1586 return XmlReadArray(c);
1592 Int_t TBufferXML::ReadArray(Short_t *&h)
1594 return XmlReadArray(h);
1600 Int_t TBufferXML::ReadArray(UShort_t *&h)
1602 return XmlReadArray(h);
1608 Int_t TBufferXML::ReadArray(Int_t *&i)
1610 return XmlReadArray(i);
1616 Int_t TBufferXML::ReadArray(UInt_t *&i)
1618 return XmlReadArray(i);
1624 Int_t TBufferXML::ReadArray(Long_t *&l)
1626 return XmlReadArray(l);
1632 Int_t TBufferXML::ReadArray(ULong_t *&l)
1634 return XmlReadArray(l);
1640 Int_t TBufferXML::ReadArray(Long64_t *&l)
1642 return XmlReadArray(l);
1648 Int_t TBufferXML::ReadArray(ULong64_t *&l)
1650 return XmlReadArray(l);
1656 Int_t TBufferXML::ReadArray(Float_t *&f)
1658 return XmlReadArray(f);
1664 Int_t TBufferXML::ReadArray(Double_t *&d)
1666 return XmlReadArray(d);
1672 Int_t TBufferXML::ReadStaticArray(Bool_t *b)
1674 return XmlReadArray(b,
true);
1680 Int_t TBufferXML::ReadStaticArray(Char_t *c)
1682 return XmlReadArray(c,
true);
1688 Int_t TBufferXML::ReadStaticArray(UChar_t *c)
1690 return XmlReadArray(c,
true);
1696 Int_t TBufferXML::ReadStaticArray(Short_t *h)
1698 return XmlReadArray(h,
true);
1704 Int_t TBufferXML::ReadStaticArray(UShort_t *h)
1706 return XmlReadArray(h,
true);
1712 Int_t TBufferXML::ReadStaticArray(Int_t *i)
1714 return XmlReadArray(i,
true);
1720 Int_t TBufferXML::ReadStaticArray(UInt_t *i)
1722 return XmlReadArray(i,
true);
1728 Int_t TBufferXML::ReadStaticArray(Long_t *l)
1730 return XmlReadArray(l,
true);
1736 Int_t TBufferXML::ReadStaticArray(ULong_t *l)
1738 return XmlReadArray(l,
true);
1744 Int_t TBufferXML::ReadStaticArray(Long64_t *l)
1746 return XmlReadArray(l,
true);
1752 Int_t TBufferXML::ReadStaticArray(ULong64_t *l)
1754 return XmlReadArray(l,
true);
1760 Int_t TBufferXML::ReadStaticArray(Float_t *f)
1762 return XmlReadArray(f,
true);
1768 Int_t TBufferXML::ReadStaticArray(Double_t *d)
1770 return XmlReadArray(d,
true);
1778 template <
typename T>
1779 R__ALWAYS_INLINE
void TBufferXML::XmlReadFastArray(T *arr, Int_t n)
1781 BeforeIOoperation();
1784 if (!VerifyItemNode(xmlio::Array,
"ReadFastArray"))
1786 PushStack(StackNode());
1787 XmlReadArrayContent(arr, n);
1789 ShiftStack(
"readfastarr");
1795 void TBufferXML::ReadFastArray(Bool_t *b, Int_t n)
1797 XmlReadFastArray(b, n);
1804 void TBufferXML::ReadFastArray(Char_t *c, Int_t n)
1806 if ((n > 0) && VerifyItemNode(xmlio::CharStar)) {
1808 if ((buf = XmlReadValue(xmlio::CharStar))) {
1809 Int_t size = strlen(buf);
1812 memcpy(c, buf, size);
1815 XmlReadFastArray(c, n);
1823 void TBufferXML::ReadFastArrayString(Char_t *c, Int_t n)
1825 ReadFastArray(c, n);
1831 void TBufferXML::ReadFastArray(UChar_t *c, Int_t n)
1833 XmlReadFastArray(c, n);
1839 void TBufferXML::ReadFastArray(Short_t *h, Int_t n)
1841 XmlReadFastArray(h, n);
1847 void TBufferXML::ReadFastArray(UShort_t *h, Int_t n)
1849 XmlReadFastArray(h, n);
1855 void TBufferXML::ReadFastArray(Int_t *i, Int_t n)
1857 XmlReadFastArray(i, n);
1863 void TBufferXML::ReadFastArray(UInt_t *i, Int_t n)
1865 XmlReadFastArray(i, n);
1871 void TBufferXML::ReadFastArray(Long_t *l, Int_t n)
1873 XmlReadFastArray(l, n);
1879 void TBufferXML::ReadFastArray(ULong_t *l, Int_t n)
1881 XmlReadFastArray(l, n);
1887 void TBufferXML::ReadFastArray(Long64_t *l, Int_t n)
1889 XmlReadFastArray(l, n);
1895 void TBufferXML::ReadFastArray(ULong64_t *l, Int_t n)
1897 XmlReadFastArray(l, n);
1903 void TBufferXML::ReadFastArray(Float_t *f, Int_t n)
1905 XmlReadFastArray(f, n);
1911 void TBufferXML::ReadFastArray(Double_t *d, Int_t n)
1913 XmlReadFastArray(d, n);
1921 void TBufferXML::ReadFastArray(
void *start,
const TClass *cl, Int_t n, TMemberStreamer *streamer,
1922 const TClass *onFileClass)
1925 streamer->SetOnFileClass(onFileClass);
1926 (*streamer)(*
this, start, 0);
1930 int objectSize = cl->Size();
1931 char *obj = (
char *)start;
1932 char *end = obj + n * objectSize;
1934 for (; obj < end; obj += objectSize)
1935 ((TClass *)cl)->Streamer(obj, *
this, onFileClass);
1945 void TBufferXML::ReadFastArray(
void **start,
const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer,
1946 const TClass *onFileClass)
1949 Bool_t oldStyle = kFALSE;
1951 if ((GetIOVersion() < 4) && !isPreAlloc) {
1952 TStreamerElement *elem = Stack()->fElem;
1953 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
1954 (elem->GetType() == TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL)))
1960 for (Int_t j = 0; j < n; j++) {
1962 start[j] = cl->New();
1965 streamer->SetOnFileClass(onFileClass);
1966 (*streamer)(*
this, (
void *)start, oldStyle ? n : 0);
1972 for (Int_t j = 0; j < n; j++) {
1975 start[j] = ((TClass *)cl)->New();
1976 ((TClass *)cl)->Streamer(start[j], *
this);
1980 void *old = start[j];
1981 start[j] = ReadObjectAny(cl);
1982 if (old && old != start[j] && TStreamerInfo::CanDelete()
1999 ((TClass *)cl)->Destructor(old, kFALSE);
2006 for (Int_t j = 0; j < n; j++) {
2008 start[j] = ((TClass *)cl)->New();
2009 ((TClass *)cl)->Streamer(start[j], *
this, onFileClass);
2014 template <
typename T>
2015 R__ALWAYS_INLINE
void TBufferXML::XmlWriteArrayContent(
const T *arr, Int_t arrsize)
2017 if (fCompressLevel > 0) {
2019 while (indx < arrsize) {
2020 XMLNodePointer_t elemnode = XmlWriteBasic(arr[indx]);
2021 Int_t curr = indx++;
2022 while ((indx < arrsize) && (arr[indx] == arr[curr]))
2024 if (indx - curr > 1)
2025 fXML->NewIntAttr(elemnode, xmlio::cnt, indx - curr);
2028 for (Int_t indx = 0; indx < arrsize; indx++)
2029 XmlWriteBasic(arr[indx]);
2037 template <
typename T>
2038 R__ALWAYS_INLINE
void TBufferXML::XmlWriteArray(
const T *arr, Int_t arrsize)
2040 BeforeIOoperation();
2041 XMLNodePointer_t arrnode = CreateItemNode(xmlio::Array);
2042 fXML->NewIntAttr(arrnode, xmlio::Size, arrsize);
2044 XmlWriteArrayContent(arr, arrsize);
2051 void TBufferXML::WriteArray(
const Bool_t *b, Int_t n)
2053 XmlWriteArray(b, n);
2059 void TBufferXML::WriteArray(
const Char_t *c, Int_t n)
2061 XmlWriteArray(c, n);
2067 void TBufferXML::WriteArray(
const UChar_t *c, Int_t n)
2069 XmlWriteArray(c, n);
2075 void TBufferXML::WriteArray(
const Short_t *h, Int_t n)
2077 XmlWriteArray(h, n);
2083 void TBufferXML::WriteArray(
const UShort_t *h, Int_t n)
2085 XmlWriteArray(h, n);
2091 void TBufferXML::WriteArray(
const Int_t *i, Int_t n)
2093 XmlWriteArray(i, n);
2099 void TBufferXML::WriteArray(
const UInt_t *i, Int_t n)
2101 XmlWriteArray(i, n);
2107 void TBufferXML::WriteArray(
const Long_t *l, Int_t n)
2109 XmlWriteArray(l, n);
2115 void TBufferXML::WriteArray(
const ULong_t *l, Int_t n)
2117 XmlWriteArray(l, n);
2123 void TBufferXML::WriteArray(
const Long64_t *l, Int_t n)
2125 XmlWriteArray(l, n);
2131 void TBufferXML::WriteArray(
const ULong64_t *l, Int_t n)
2133 XmlWriteArray(l, n);
2139 void TBufferXML::WriteArray(
const Float_t *f, Int_t n)
2141 XmlWriteArray(f, n);
2147 void TBufferXML::WriteArray(
const Double_t *d, Int_t n)
2149 XmlWriteArray(d, n);
2157 template <
typename T>
2158 R__ALWAYS_INLINE
void TBufferXML::XmlWriteFastArray(
const T *arr, Int_t n)
2160 BeforeIOoperation();
2163 XMLNodePointer_t arrnode = CreateItemNode(xmlio::Array);
2165 XmlWriteArrayContent(arr, n);
2172 void TBufferXML::WriteFastArray(
const Bool_t *b, Int_t n)
2174 XmlWriteFastArray(b, n);
2182 void TBufferXML::WriteFastArray(
const Char_t *c, Int_t n)
2184 Bool_t usedefault = (n == 0);
2185 const Char_t *buf = c;
2187 for (
int i = 0; i < n; i++) {
2195 XmlWriteFastArray(c, n);
2197 Char_t *buf2 =
new Char_t[n + 1];
2200 XmlWriteValue(buf2, xmlio::CharStar);
2208 void TBufferXML::WriteFastArray(
const UChar_t *c, Int_t n)
2210 XmlWriteFastArray(c, n);
2216 void TBufferXML::WriteFastArray(
const Short_t *h, Int_t n)
2218 XmlWriteFastArray(h, n);
2224 void TBufferXML::WriteFastArray(
const UShort_t *h, Int_t n)
2226 XmlWriteFastArray(h, n);
2232 void TBufferXML::WriteFastArray(
const Int_t *i, Int_t n)
2234 XmlWriteFastArray(i, n);
2240 void TBufferXML::WriteFastArray(
const UInt_t *i, Int_t n)
2242 XmlWriteFastArray(i, n);
2248 void TBufferXML::WriteFastArray(
const Long_t *l, Int_t n)
2250 XmlWriteFastArray(l, n);
2256 void TBufferXML::WriteFastArray(
const ULong_t *l, Int_t n)
2258 XmlWriteFastArray(l, n);
2264 void TBufferXML::WriteFastArray(
const Long64_t *l, Int_t n)
2266 XmlWriteFastArray(l, n);
2272 void TBufferXML::WriteFastArray(
const ULong64_t *l, Int_t n)
2274 XmlWriteFastArray(l, n);
2280 void TBufferXML::WriteFastArray(
const Float_t *f, Int_t n)
2282 XmlWriteFastArray(f, n);
2288 void TBufferXML::WriteFastArray(
const Double_t *d, Int_t n)
2290 XmlWriteFastArray(d, n);
2297 void TBufferXML::WriteFastArrayString(
const Char_t *c, Int_t n)
2299 WriteFastArray(c, n);
2306 void TBufferXML::WriteFastArray(
void *start,
const TClass *cl, Int_t n, TMemberStreamer *streamer)
2309 (*streamer)(*
this, start, 0);
2313 char *obj = (
char *)start;
2316 int size = cl->Size();
2318 for (Int_t j = 0; j < n; j++, obj += size) {
2319 ((TClass *)cl)->Streamer(obj, *
this);
2331 Int_t TBufferXML::WriteFastArray(
void **start,
const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer)
2336 Bool_t oldStyle = kFALSE;
2338 if ((GetIOVersion() < 4) && !isPreAlloc) {
2339 TStreamerElement *elem = Stack()->fElem;
2340 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
2341 (elem->GetType() == TStreamerInfo::kSTLp + TStreamerInfo::kOffsetL)))
2346 (*streamer)(*
this, (
void *)start, oldStyle ? n : 0);
2356 for (Int_t j = 0; j < n; j++) {
2358 if (!strInfo && !start[j] && !oldStyle) {
2359 if (cl->Property() & kIsAbstract) {
2362 TStreamerInfo *info = (TStreamerInfo *)((TClass *)cl)->GetStreamerInfo();
2363 ForceWriteInfo(info, kFALSE);
2368 ((TClass *)cl)->Streamer(start[j], *
this);
2370 res |= WriteObjectAny(start[j], cl);
2376 for (Int_t j = 0; j < n; j++) {
2378 start[j] = ((TClass *)cl)->New();
2379 ((TClass *)cl)->Streamer(start[j], *
this);
2388 void TBufferXML::StreamObject(
void *obj,
const TClass *cl,
const TClass * )
2390 if (GetIOVersion() < 4) {
2391 TStreamerElement *elem = Stack()->fElem;
2392 if (elem && (elem->GetType() == TStreamerInfo::kTObject)) {
2393 ((TObject *)obj)->TObject::Streamer(*
this);
2395 }
else if (elem && (elem->GetType() == TStreamerInfo::kTNamed)) {
2396 ((TNamed *)obj)->TNamed::Streamer(*
this);
2401 BeforeIOoperation();
2403 Info(
"StreamObject",
"Class: %s", (cl ? cl->GetName() :
"none"));
2407 XmlWriteObject(obj, cl, kTRUE);
2413 void TBufferXML::ReadBool(Bool_t &b)
2415 BeforeIOoperation();
2422 void TBufferXML::ReadChar(Char_t &c)
2424 BeforeIOoperation();
2431 void TBufferXML::ReadUChar(UChar_t &c)
2433 BeforeIOoperation();
2440 void TBufferXML::ReadShort(Short_t &h)
2442 BeforeIOoperation();
2449 void TBufferXML::ReadUShort(UShort_t &h)
2451 BeforeIOoperation();
2458 void TBufferXML::ReadInt(Int_t &i)
2460 BeforeIOoperation();
2467 void TBufferXML::ReadUInt(UInt_t &i)
2469 BeforeIOoperation();
2476 void TBufferXML::ReadLong(Long_t &l)
2478 BeforeIOoperation();
2485 void TBufferXML::ReadULong(ULong_t &l)
2487 BeforeIOoperation();
2494 void TBufferXML::ReadLong64(Long64_t &l)
2496 BeforeIOoperation();
2503 void TBufferXML::ReadULong64(ULong64_t &l)
2505 BeforeIOoperation();
2512 void TBufferXML::ReadFloat(Float_t &f)
2514 BeforeIOoperation();
2521 void TBufferXML::ReadDouble(Double_t &d)
2523 BeforeIOoperation();
2530 void TBufferXML::ReadCharP(Char_t *c)
2532 BeforeIOoperation();
2534 if ((buf = XmlReadValue(xmlio::CharStar)))
2541 void TBufferXML::ReadTString(TString &s)
2543 if (GetIOVersion() < 3) {
2557 char *data =
new char[nbig];
2559 ReadFastArray(data, nbig);
2564 BeforeIOoperation();
2565 const char *buf = XmlReadValue(xmlio::String);
2574 void TBufferXML::ReadStdString(std::string *obj)
2576 if (GetIOVersion() < 3) {
2578 Error(
"ReadStdString",
"The std::string address is nullptr but should not");
2593 obj->resize(nbig,
'\0');
2594 ReadFastArray((
char *)obj->data(), nbig);
2596 obj->resize(nwh,
'\0');
2597 ReadFastArray((
char *)obj->data(), nwh);
2601 BeforeIOoperation();
2602 const char *buf = XmlReadValue(xmlio::String);
2611 void TBufferXML::ReadCharStar(
char *&s)
2619 s =
new char[nch + 1];
2620 ReadFastArray(s, nch);
2628 void TBufferXML::WriteBool(Bool_t b)
2630 BeforeIOoperation();
2637 void TBufferXML::WriteChar(Char_t c)
2639 BeforeIOoperation();
2646 void TBufferXML::WriteUChar(UChar_t c)
2648 BeforeIOoperation();
2655 void TBufferXML::WriteShort(Short_t h)
2657 BeforeIOoperation();
2664 void TBufferXML::WriteUShort(UShort_t h)
2666 BeforeIOoperation();
2673 void TBufferXML::WriteInt(Int_t i)
2675 BeforeIOoperation();
2682 void TBufferXML::WriteUInt(UInt_t i)
2684 BeforeIOoperation();
2691 void TBufferXML::WriteLong(Long_t l)
2693 BeforeIOoperation();
2700 void TBufferXML::WriteULong(ULong_t l)
2702 BeforeIOoperation();
2709 void TBufferXML::WriteLong64(Long64_t l)
2711 BeforeIOoperation();
2718 void TBufferXML::WriteULong64(ULong64_t l)
2720 BeforeIOoperation();
2727 void TBufferXML::WriteFloat(Float_t f)
2729 BeforeIOoperation();
2736 void TBufferXML::WriteDouble(Double_t d)
2738 BeforeIOoperation();
2745 void TBufferXML::WriteCharP(
const Char_t *c)
2747 BeforeIOoperation();
2748 XmlWriteValue(c, xmlio::CharStar);
2754 void TBufferXML::WriteTString(
const TString &s)
2756 if (GetIOVersion() < 3) {
2758 Int_t nbig = s.Length();
2765 nwh = UChar_t(nbig);
2768 const char *data = s.Data();
2769 WriteFastArray(data, nbig);
2771 BeforeIOoperation();
2772 XmlWriteValue(s.Data(), xmlio::String);
2779 void TBufferXML::WriteStdString(
const std::string *obj)
2781 if (GetIOVersion() < 3) {
2783 *
this << (UChar_t)0;
2784 WriteFastArray(
"", 0);
2789 Int_t nbig = obj->length();
2795 nwh = UChar_t(nbig);
2798 WriteFastArray(obj->data(), nbig);
2800 BeforeIOoperation();
2801 XmlWriteValue(obj ? obj->c_str() :
"", xmlio::String);
2808 void TBufferXML::WriteCharStar(
char *s)
2814 WriteFastArray(s, nch);
2823 XMLNodePointer_t TBufferXML::XmlWriteBasic(Char_t value)
2826 snprintf(buf,
sizeof(buf),
"%d", value);
2827 return XmlWriteValue(buf, xmlio::Char);
2833 XMLNodePointer_t TBufferXML::XmlWriteBasic(Short_t value)
2836 snprintf(buf,
sizeof(buf),
"%hd", value);
2837 return XmlWriteValue(buf, xmlio::Short);
2843 XMLNodePointer_t TBufferXML::XmlWriteBasic(Int_t value)
2846 snprintf(buf,
sizeof(buf),
"%d", value);
2847 return XmlWriteValue(buf, xmlio::Int);
2853 XMLNodePointer_t TBufferXML::XmlWriteBasic(Long_t value)
2856 snprintf(buf,
sizeof(buf),
"%ld", value);
2857 return XmlWriteValue(buf, xmlio::Long);
2863 XMLNodePointer_t TBufferXML::XmlWriteBasic(Long64_t value)
2865 std::string buf = std::to_string(value);
2866 return XmlWriteValue(buf.c_str(), xmlio::Long64);
2872 XMLNodePointer_t TBufferXML::XmlWriteBasic(Float_t value)
2875 ConvertFloat(value, buf,
sizeof(buf), kTRUE);
2876 return XmlWriteValue(buf, xmlio::Float);
2882 XMLNodePointer_t TBufferXML::XmlWriteBasic(Double_t value)
2885 ConvertDouble(value, buf,
sizeof(buf), kTRUE);
2886 return XmlWriteValue(buf, xmlio::Double);
2892 XMLNodePointer_t TBufferXML::XmlWriteBasic(Bool_t value)
2894 return XmlWriteValue(value ? xmlio::True : xmlio::False, xmlio::Bool);
2900 XMLNodePointer_t TBufferXML::XmlWriteBasic(UChar_t value)
2903 snprintf(buf,
sizeof(buf),
"%u", value);
2904 return XmlWriteValue(buf, xmlio::UChar);
2910 XMLNodePointer_t TBufferXML::XmlWriteBasic(UShort_t value)
2913 snprintf(buf,
sizeof(buf),
"%hu", value);
2914 return XmlWriteValue(buf, xmlio::UShort);
2920 XMLNodePointer_t TBufferXML::XmlWriteBasic(UInt_t value)
2923 snprintf(buf,
sizeof(buf),
"%u", value);
2924 return XmlWriteValue(buf, xmlio::UInt);
2930 XMLNodePointer_t TBufferXML::XmlWriteBasic(ULong_t value)
2933 snprintf(buf,
sizeof(buf),
"%lu", value);
2934 return XmlWriteValue(buf, xmlio::ULong);
2940 XMLNodePointer_t TBufferXML::XmlWriteBasic(ULong64_t value)
2942 std::string buf = std::to_string(value);
2943 return XmlWriteValue(buf.c_str(), xmlio::ULong64);
2949 XMLNodePointer_t TBufferXML::XmlWriteValue(
const char *value,
const char *name)
2951 XMLNodePointer_t node =
nullptr;
2956 node = CreateItemNode(name);
2958 fXML->NewAttr(node,
nullptr, xmlio::v, value);
2960 fCanUseCompact = kFALSE;
2968 void TBufferXML::XmlReadBasic(Char_t &value)
2970 const char *res = XmlReadValue(xmlio::Char);
2973 sscanf(res,
"%d", &n);
2982 void TBufferXML::XmlReadBasic(Short_t &value)
2984 const char *res = XmlReadValue(xmlio::Short);
2986 sscanf(res,
"%hd", &value);
2994 void TBufferXML::XmlReadBasic(Int_t &value)
2996 const char *res = XmlReadValue(xmlio::Int);
2998 sscanf(res,
"%d", &value);
3006 void TBufferXML::XmlReadBasic(Long_t &value)
3008 const char *res = XmlReadValue(xmlio::Long);
3010 sscanf(res,
"%ld", &value);
3018 void TBufferXML::XmlReadBasic(Long64_t &value)
3020 const char *res = XmlReadValue(xmlio::Long64);
3022 value = (Long64_t)std::stoll(res);
3030 void TBufferXML::XmlReadBasic(Float_t &value)
3032 const char *res = XmlReadValue(xmlio::Float);
3034 sscanf(res,
"%f", &value);
3042 void TBufferXML::XmlReadBasic(Double_t &value)
3044 const char *res = XmlReadValue(xmlio::Double);
3046 sscanf(res,
"%lf", &value);
3054 void TBufferXML::XmlReadBasic(Bool_t &value)
3056 const char *res = XmlReadValue(xmlio::Bool);
3058 value = (strcmp(res, xmlio::True) == 0);
3066 void TBufferXML::XmlReadBasic(UChar_t &value)
3068 const char *res = XmlReadValue(xmlio::UChar);
3071 sscanf(res,
"%ud", &n);
3080 void TBufferXML::XmlReadBasic(UShort_t &value)
3082 const char *res = XmlReadValue(xmlio::UShort);
3084 sscanf(res,
"%hud", &value);
3092 void TBufferXML::XmlReadBasic(UInt_t &value)
3094 const char *res = XmlReadValue(xmlio::UInt);
3096 sscanf(res,
"%u", &value);
3104 void TBufferXML::XmlReadBasic(ULong_t &value)
3106 const char *res = XmlReadValue(xmlio::ULong);
3108 sscanf(res,
"%lu", &value);
3116 void TBufferXML::XmlReadBasic(ULong64_t &value)
3118 const char *res = XmlReadValue(xmlio::ULong64);
3120 value = (ULong64_t)std::stoull(res);
3128 const char *TBufferXML::XmlReadValue(
const char *name)
3133 Bool_t trysimple = fCanUseCompact;
3134 fCanUseCompact = kFALSE;
3137 if (fXML->HasAttr(Stack(1)->fNode, xmlio::v))
3138 fValueBuf = fXML->GetAttr(Stack(1)->fNode, xmlio::v);
3144 if (!VerifyItemNode(name,
"XmlReadValue"))
3146 fValueBuf = fXML->GetAttr(StackNode(), xmlio::v);
3150 Info(
"XmlReadValue",
" Name = %s value = %s", name, fValueBuf.Data());
3153 ShiftStack(
"readvalue");
3155 return fValueBuf.Data();
3161 TVirtualStreamerInfo *TBufferXML::GetInfo()
3163 return Stack()->fInfo;