Logo ROOT   6.18/05
Reference Guide
TBufferXML.cxx
Go to the documentation of this file.
1// @(#)root/:$Id: 5400e36954e1dc109fcfc306242c30234beb7312 $
2// Author: Sergey Linev, Rene Brun 10.05.2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\class TBufferXML
14\ingroup IO
15
16Class for serializing/deserializing object to/from xml.
17
18The simple way to create XML representation is:
19~~~{.cpp}
20 TNamed *obj = new TNamed("name", "title");
21 TString xml = TBufferXML::ToXML(obj);
22~~~
23Produced xml can be decoded into new object:
24~~~{.cpp}
25 TNamed *obj2 = nullptr;
26 TBufferXML::FromXML(obj2, xml);
27~~~
28
29TBufferXML class uses streaming mechanism, provided by ROOT system,
30therefore most of ROOT and user classes can be stored to xml.
31There are limitations for complex objects like TTree, which can not be converted to xml.
32*/
33
34#include "TBufferXML.h"
35
36#include "Compression.h"
37#include "TXMLFile.h"
38#include "TObjArray.h"
39#include "TROOT.h"
40#include "TError.h"
41#include "TClass.h"
42#include "TClassTable.h"
43#include "TDataType.h"
44#include "TExMap.h"
45#include "TMethodCall.h"
46#include "TStreamerInfo.h"
47#include "TStreamerElement.h"
48#include "TFile.h"
49#include "TMemberStreamer.h"
50#include "TStreamer.h"
51#include "RZip.h"
52
54
55////////////////////////////////////////////////////////////////////////////////
56/// Default constructor
57
59 : TBufferText(), TXMLSetup(), fXML(nullptr), fStack(), fVersionBuf(-111), fErrorFlag(0), fCanUseCompact(kFALSE),
60 fExpectedBaseClass(nullptr), fCompressLevel(0), fIOVersion(3)
61{
62}
63
64////////////////////////////////////////////////////////////////////////////////
65/// Creates buffer object to serialize/deserialize data to/from xml.
66/// Mode should be either TBuffer::kRead or TBuffer::kWrite.
67
69 : TBufferText(mode), TXMLSetup(), fXML(nullptr), fStack(), fVersionBuf(-111), fErrorFlag(0), fCanUseCompact(kFALSE),
70 fExpectedBaseClass(nullptr), fCompressLevel(0), fIOVersion(3)
71{
72}
73
74////////////////////////////////////////////////////////////////////////////////
75/// Creates buffer object to serialize/deserialize data to/from xml.
76/// This constructor should be used, if data from buffer supposed to be stored in file.
77/// Mode should be either TBuffer::kRead or TBuffer::kWrite.
78
80 : TBufferText(mode, file), TXMLSetup(*file), fXML(nullptr), fStack(), fVersionBuf(-111), fErrorFlag(0),
81 fCanUseCompact(kFALSE), fExpectedBaseClass(nullptr), fCompressLevel(0), fIOVersion(3)
82{
83 // this is for the case when StreamerInfo reads elements from
84 // buffer as ReadFastArray. When it checks if size of buffer is
85 // too small and skip reading. Actually, more improved method should
86 // be used here.
87
88 if (XmlFile()) {
89 SetXML(XmlFile()->XML());
92 }
93}
94
95////////////////////////////////////////////////////////////////////////////////
96/// Destroy xml buffer.
97
99{
100 while (fStack.size() > 0)
101 PopStack();
102}
103
104////////////////////////////////////////////////////////////////////////////////
105/// Returns pointer to TXMLFile object.
106/// Access to file is necessary to produce unique identifier for object references.
107
109{
110 return dynamic_cast<TXMLFile *>(GetParent());
111}
112
113////////////////////////////////////////////////////////////////////////////////
114/// Converts object, inherited from TObject class, to XML string
115/// GenericLayout defines layout choice for XML file
116/// UseNamespaces allow XML namespaces.
117/// See TXMLSetup class for details
118
119TString TBufferXML::ConvertToXML(const TObject *obj, Bool_t GenericLayout, Bool_t UseNamespaces)
120{
121 TClass *clActual = nullptr;
122 void *ptr = (void *)obj;
123
124 if (obj) {
125 clActual = TObject::Class()->GetActualClass(obj);
126 if (!clActual)
127 clActual = TObject::Class();
128 else if (clActual != TObject::Class())
129 ptr = (void *)((Long_t)obj - clActual->GetBaseClassOffset(TObject::Class()));
130 }
131
132 return ConvertToXML(ptr, clActual, GenericLayout, UseNamespaces);
133}
134
135////////////////////////////////////////////////////////////////////////////////
136/// Converts any type of object to XML string.
137/// GenericLayout defines layout choice for XML file
138/// UseNamespaces allow XML namespaces.
139/// See TXMLSetup class for details
140
141TString TBufferXML::ConvertToXML(const void *obj, const TClass *cl, Bool_t GenericLayout, Bool_t UseNamespaces)
142{
143 TXMLEngine xml;
144
146 buf.SetXML(&xml);
147 buf.InitMap();
148
150 buf.SetUseNamespaces(UseNamespaces);
151
152 XMLNodePointer_t xmlnode = buf.XmlWriteAny(obj, cl);
153
154 TString res;
155
156 xml.SaveSingleNode(xmlnode, &res);
157
158 xml.FreeNode(xmlnode);
159
160 return res;
161}
162
163////////////////////////////////////////////////////////////////////////////////
164/// Read object from XML, produced by ConvertToXML() method.
165/// If object does not inherit from TObject class, return 0.
166/// GenericLayout and UseNamespaces should be the same as in ConvertToXML()
167
168TObject *TBufferXML::ConvertFromXML(const char *str, Bool_t GenericLayout, Bool_t UseNamespaces)
169{
170 TClass *cl = nullptr;
171 void *obj = ConvertFromXMLAny(str, &cl, GenericLayout, UseNamespaces);
172
173 if (!cl || !obj)
174 return nullptr;
175
177
178 if (delta < 0) {
179 cl->Destructor(obj);
180 return nullptr;
181 }
182
183 return (TObject *)(((char *)obj) + delta);
184}
185
186////////////////////////////////////////////////////////////////////////////////
187/// Read object of any class from XML, produced by ConvertToXML() method.
188/// If cl!=0, return actual class of object.
189/// GenericLayout and UseNamespaces should be the same as in ConvertToXML()
190
191void *TBufferXML::ConvertFromXMLAny(const char *str, TClass **cl, Bool_t GenericLayout, Bool_t UseNamespaces)
192{
193 TXMLEngine xml;
195
196 buf.SetXML(&xml);
197 buf.InitMap();
198
200 buf.SetUseNamespaces(UseNamespaces);
201
202 XMLNodePointer_t xmlnode = xml.ReadSingleNode(str);
203
204 void *obj = buf.XmlReadAny(xmlnode, nullptr, cl);
205
206 xml.FreeNode(xmlnode);
207
208 return obj;
209}
210
211////////////////////////////////////////////////////////////////////////////////
212/// Convert from XML and check if object derived from specified class
213/// When possible, cast to given class
214
215void *TBufferXML::ConvertFromXMLChecked(const char *xml, const TClass *expectedClass, Bool_t GenericLayout,
216 Bool_t UseNamespaces)
217{
218 TClass *objClass = nullptr;
219 void *res = ConvertFromXMLAny(xml, &objClass, GenericLayout, UseNamespaces);
220
221 if (!res || !objClass)
222 return nullptr;
223
224 if (objClass == expectedClass)
225 return res;
226
227 Int_t offset = objClass->GetBaseClassOffset(expectedClass);
228 if (offset < 0) {
229 ::Error("TBufferXML::ConvertFromXMLChecked", "expected class %s is not base for read class %s",
230 expectedClass->GetName(), objClass->GetName());
231 objClass->Destructor(res);
232 return nullptr;
233 }
234
235 return (char *)res - offset;
236}
237
238////////////////////////////////////////////////////////////////////////////////
239/// Convert object of any class to xml structures
240/// Return pointer on top xml element
241
243{
244 fErrorFlag = 0;
245
246 if (!fXML)
247 return nullptr;
248
249 XMLNodePointer_t res = XmlWriteObject(obj, cl, kTRUE);
250
251 return res;
252}
253
254////////////////////////////////////////////////////////////////////////////////
255/// Recreate object from xml structure.
256/// Return pointer to read object.
257/// if (cl!=0) returns pointer to class of object
258
260{
261 if (!node)
262 return nullptr;
263
264 if (cl)
265 *cl = nullptr;
266
267 fErrorFlag = 0;
268
269 if (!fXML)
270 return nullptr;
271
272 PushStack(node, kTRUE);
273
274 void *res = XmlReadObject(obj, cl);
275
276 PopStack();
277
278 return res;
279}
280
281// TXMLStackObj is used to keep stack of object hierarchy,
282// stored in TBuffer. For example, data for parent class(es)
283// stored in subnodes, but initial object node will be kept.
284
285class TXMLStackObj : public TObject {
286public:
287 TXMLStackObj(XMLNodePointer_t node)
288 : TObject(), fNode(node), fInfo(nullptr), fElem(nullptr), fElemNumber(0), fCompressedClassNode(kFALSE),
289 fClassNs(nullptr), fIsStreamerInfo(kFALSE), fIsElemOwner(kFALSE)
290 {
291 }
292
293 virtual ~TXMLStackObj()
294 {
295 if (fIsElemOwner)
296 delete fElem;
297 }
298
299 Bool_t IsStreamerInfo() const { return fIsStreamerInfo; }
300
301 XMLNodePointer_t fNode;
302 TStreamerInfo *fInfo;
303 TStreamerElement *fElem;
304 Int_t fElemNumber;
305 Bool_t fCompressedClassNode;
306 XMLNsPointer_t fClassNs;
307 Bool_t fIsStreamerInfo;
308 Bool_t fIsElemOwner;
309};
310
311////////////////////////////////////////////////////////////////////////////////
312/// Add new level to xml stack.
313
314TXMLStackObj *TBufferXML::PushStack(XMLNodePointer_t current, Bool_t simple)
315{
316 if (IsReading() && !simple) {
317 current = fXML->GetChild(current);
318 fXML->SkipEmpty(current);
319 }
320
321 TXMLStackObj *stack = new TXMLStackObj(current);
322 fStack.push_back(stack);
323 return stack;
324}
325
326////////////////////////////////////////////////////////////////////////////////
327/// Remove one level from xml stack.
328
329TXMLStackObj *TBufferXML::PopStack()
330{
331 if (fStack.size() > 0) {
332 delete fStack.back();
333 fStack.pop_back();
334 }
335 return fStack.size() > 0 ? Stack() : nullptr;
336}
337
338////////////////////////////////////////////////////////////////////////////////
339/// Return pointer on current xml node.
340
342{
343 TXMLStackObj *stack = Stack();
344 return stack ? stack->fNode : nullptr;
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// Shift stack node to next.
349
350void TBufferXML::ShiftStack(const char *errinfo)
351{
352 TXMLStackObj *stack = Stack();
353 if (stack) {
354 fXML->ShiftToNext(stack->fNode);
355 if (gDebug > 4)
356 Info("ShiftStack", "%s to node %s", errinfo, fXML->GetNodeName(stack->fNode));
357 }
358}
359
360////////////////////////////////////////////////////////////////////////////////
361/// See comments for function SetCompressionSettings.
362
364{
365 if (algorithm < 0 || algorithm >= ROOT::RCompressionSetting::EAlgorithm::kUndefined)
366 algorithm = 0;
367 if (fCompressLevel < 0) {
369 } else {
370 int level = fCompressLevel % 100;
371 fCompressLevel = 100 * algorithm + level;
372 }
373}
374
375////////////////////////////////////////////////////////////////////////////////
376/// See comments for function SetCompressionSettings.
377
379{
380 if (level < 0)
381 level = 0;
382 if (level > 99)
383 level = 99;
384 if (fCompressLevel < 0) {
385 // if the algorithm is not defined yet use 0 as a default
386 fCompressLevel = level;
387 } else {
388 int algorithm = fCompressLevel / 100;
390 algorithm = 0;
391 fCompressLevel = 100 * algorithm + level;
392 }
393}
394
395////////////////////////////////////////////////////////////////////////////////
396/// Used to specify the compression level and algorithm.
397///
398/// See TFile constructor for the details.
399
401{
402 fCompressLevel = settings;
403}
404
405////////////////////////////////////////////////////////////////////////////////
406/// Write binary data block from buffer to xml.
407/// This data can be produced only by direct call of TBuffer::WriteBuf() functions.
408
410{
411 if (!node || (Length() == 0))
412 return;
413
414 const char *src = Buffer();
415 int srcSize = Length();
416
417 char *fZipBuffer = 0;
418
419 Int_t compressionLevel = GetCompressionLevel();
422
423 if ((Length() > 512) && (compressionLevel > 0)) {
424 int zipBufferSize = Length();
425 fZipBuffer = new char[zipBufferSize + 9];
426 int dataSize = Length();
427 int compressedSize = 0;
428 R__zipMultipleAlgorithm(compressionLevel, &dataSize, Buffer(), &zipBufferSize, fZipBuffer, &compressedSize,
429 compressionAlgorithm);
430 if (compressedSize > 0) {
431 src = fZipBuffer;
432 srcSize = compressedSize;
433 } else {
434 delete[] fZipBuffer;
435 fZipBuffer = nullptr;
436 }
437 }
438
439 TString res;
440 char sbuf[500];
441 int block = 0;
442 char *tgt = sbuf;
443 int srcCnt = 0;
444
445 while (srcCnt++ < srcSize) {
446 tgt += sprintf(tgt, " %02x", (unsigned char)*src);
447 src++;
448 if (block++ == 100) {
449 res += sbuf;
450 block = 0;
451 tgt = sbuf;
452 }
453 }
454
455 if (block > 0)
456 res += sbuf;
457
458 XMLNodePointer_t blocknode = fXML->NewChild(node, nullptr, xmlio::XmlBlock, res);
459 fXML->NewIntAttr(blocknode, xmlio::Size, Length());
460
461 if (fZipBuffer) {
462 fXML->NewIntAttr(blocknode, xmlio::Zip, srcSize);
463 delete[] fZipBuffer;
464 }
465}
466
467////////////////////////////////////////////////////////////////////////////////
468/// Read binary block of data from xml.
469
471{
472 if (!blocknode)
473 return;
474
475 Int_t blockSize = fXML->GetIntAttr(blocknode, xmlio::Size);
476 Bool_t blockCompressed = fXML->HasAttr(blocknode, xmlio::Zip);
477 char *fUnzipBuffer = nullptr;
478
479 if (gDebug > 2)
480 Info("XmlReadBlock", "Block size = %d, Length = %d, Compressed = %d", blockSize, Length(), blockCompressed);
481
482 if (blockSize > BufferSize())
483 Expand(blockSize);
484
485 char *tgt = Buffer();
486 Int_t readSize = blockSize;
487
488 TString content = fXML->GetNodeContent(blocknode);
489
490 if (blockCompressed) {
491 Int_t zipSize = fXML->GetIntAttr(blocknode, xmlio::Zip);
492 fUnzipBuffer = new char[zipSize];
493
494 tgt = fUnzipBuffer;
495 readSize = zipSize;
496 }
497
498 char *ptr = (char *)content.Data();
499
500 if (gDebug > 3)
501 Info("XmlReadBlock", "Content %s", ptr);
502
503 for (int i = 0; i < readSize; i++) {
504 while ((*ptr < 48) || ((*ptr > 57) && (*ptr < 97)) || (*ptr > 102))
505 ptr++;
506
507 int b_hi = (*ptr > 57) ? *ptr - 87 : *ptr - 48;
508 ptr++;
509 int b_lo = (*ptr > 57) ? *ptr - 87 : *ptr - 48;
510 ptr++;
511
512 *tgt = b_hi * 16 + b_lo;
513 tgt++;
514
515 if (gDebug > 4)
516 Info("XmlReadBlock", " Buf[%d] = %d", i, b_hi * 16 + b_lo);
517 }
518
519 if (fUnzipBuffer) {
520
521 int srcsize(0), tgtsize(0), unzipRes(0);
522 int status = R__unzip_header(&srcsize, (UChar_t *)fUnzipBuffer, &tgtsize);
523
524 if (status == 0)
525 R__unzip(&readSize, (unsigned char *)fUnzipBuffer, &blockSize, (unsigned char *)Buffer(), &unzipRes);
526
527 if (status != 0 || unzipRes != blockSize)
528 Error("XmlReadBlock", "Decompression error %d", unzipRes);
529 else if (gDebug > 2)
530 Info("XmlReadBlock", "Unzip ok");
531
532 delete[] fUnzipBuffer;
533 }
534}
535
536////////////////////////////////////////////////////////////////////////////////
537/// Add "ptr" attribute to node, if ptr is null or
538/// if ptr is pointer on object, which is already saved in buffer
539/// Automatically add "ref" attribute to node, where referenced object is stored
540
542{
543 if (!node)
544 return kFALSE;
545
546 TString refvalue;
547
548 if (!ptr) {
549 refvalue = xmlio::Null; // null
550 } else {
552 if (!refnode)
553 return kFALSE;
554
555 if (fXML->HasAttr(refnode, xmlio::Ref)) {
556 refvalue = fXML->GetAttr(refnode, xmlio::Ref);
557 } else {
558 refvalue = xmlio::IdBase;
559 if (XmlFile())
560 refvalue += XmlFile()->GetNextRefCounter();
561 else
562 refvalue += GetNextRefCounter();
563 fXML->NewAttr(refnode, nullptr, xmlio::Ref, refvalue.Data());
564 }
565 }
566 if (refvalue.Length() > 0) {
567 fXML->NewAttr(node, nullptr, xmlio::Ptr, refvalue.Data());
568 return kTRUE;
569 }
570
571 return kFALSE;
572}
573
574////////////////////////////////////////////////////////////////////////////////
575/// Searches for "ptr" attribute and returns pointer to object and class,
576/// if "ptr" attribute reference to read object
577
579{
580 cl = nullptr;
581
582 if (!fXML->HasAttr(node, xmlio::Ptr))
583 return kFALSE;
584
585 const char *ptrid = fXML->GetAttr(node, xmlio::Ptr);
586
587 if (!ptrid)
588 return kFALSE;
589
590 // null
591 if (strcmp(ptrid, xmlio::Null) == 0) {
592 ptr = nullptr;
593 return kTRUE;
594 }
595
596 if (strncmp(ptrid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
597 Error("ExtractPointer", "Pointer tag %s not started from %s", ptrid, xmlio::IdBase);
598 return kFALSE;
599 }
600
601 Int_t id = TString(ptrid + strlen(xmlio::IdBase)).Atoi();
602
603 GetMappedObject(id + 1, ptr, cl);
604
605 if (!ptr || !cl)
606 Error("ExtractPointer", "not found ptr %s result %p %s", ptrid, ptr, (cl ? cl->GetName() : "null"));
607
608 return ptr && cl;
609}
610
611////////////////////////////////////////////////////////////////////////////////
612/// Analyze if node has "ref" attribute and register it to object map
613
614void TBufferXML::ExtractReference(XMLNodePointer_t node, const void *ptr, const TClass *cl)
615{
616 if (!node || !ptr)
617 return;
618
619 const char *refid = fXML->GetAttr(node, xmlio::Ref);
620
621 if (!refid)
622 return;
623
624 if (strncmp(refid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
625 Error("ExtractReference", "Reference tag %s not started from %s", refid, xmlio::IdBase);
626 return;
627 }
628
629 Int_t id = TString(refid + strlen(xmlio::IdBase)).Atoi();
630
631 MapObject(ptr, cl, id + 1);
632
633 if (gDebug > 2)
634 Info("ExtractReference", "Find reference %s for object %p class %s", refid, ptr, (cl ? cl->GetName() : "null"));
635}
636
637////////////////////////////////////////////////////////////////////////////////
638/// Check if node has specified name
639
640Bool_t TBufferXML::VerifyNode(XMLNodePointer_t node, const char *name, const char *errinfo)
641{
642 if (!name || !node)
643 return kFALSE;
644
645 if (strcmp(fXML->GetNodeName(node), name) != 0) {
646 if (errinfo) {
647 Error("VerifyNode", "Reading XML file (%s). Get: %s, expects: %s", errinfo, fXML->GetNodeName(node), name);
648 fErrorFlag = 1;
649 }
650 return kFALSE;
651 }
652 return kTRUE;
653}
654
655////////////////////////////////////////////////////////////////////////////////
656/// Check, if stack node has specified name
657
658Bool_t TBufferXML::VerifyStackNode(const char *name, const char *errinfo)
659{
660 return VerifyNode(StackNode(), name, errinfo);
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Checks, that attribute of specified name exists and has specified value
665
666Bool_t TBufferXML::VerifyAttr(XMLNodePointer_t node, const char *name, const char *value, const char *errinfo)
667{
668 if (!node || !name || !value)
669 return kFALSE;
670
671 const char *cont = fXML->GetAttr(node, name);
672 if ((!cont || (strcmp(cont, value) != 0))) {
673 if (errinfo) {
674 Error("VerifyAttr", "%s : attr %s = %s, expected: %s", errinfo, name, cont, value);
675 fErrorFlag = 1;
676 }
677 return kFALSE;
678 }
679 return kTRUE;
680}
681
682////////////////////////////////////////////////////////////////////////////////
683/// Checks stack attribute
684
685Bool_t TBufferXML::VerifyStackAttr(const char *name, const char *value, const char *errinfo)
686{
687 return VerifyAttr(StackNode(), name, value, errinfo);
688}
689
690////////////////////////////////////////////////////////////////////////////////
691/// Create item node of specified name
692
694{
695 XMLNodePointer_t node = nullptr;
696 if (GetXmlLayout() == kGeneralized) {
697 node = fXML->NewChild(StackNode(), nullptr, xmlio::Item);
698 fXML->NewAttr(node, nullptr, xmlio::Name, name);
699 } else
700 node = fXML->NewChild(StackNode(), nullptr, name);
701 return node;
702}
703
704////////////////////////////////////////////////////////////////////////////////
705/// Checks, if stack node is item and has specified name
706
707Bool_t TBufferXML::VerifyItemNode(const char *name, const char *errinfo)
708{
709 Bool_t res = kTRUE;
710 if (GetXmlLayout() == kGeneralized)
711 res = VerifyStackNode(xmlio::Item, errinfo) && VerifyStackAttr(xmlio::Name, name, errinfo);
712 else
713 res = VerifyStackNode(name, errinfo);
714 return res;
715}
716
717////////////////////////////////////////////////////////////////////////////////
718/// Create xml node correspondent to TStreamerElement object
719
721{
722 XMLNodePointer_t elemnode = nullptr;
723
724 const char *elemxmlname = XmlGetElementName(elem);
725
726 if (GetXmlLayout() == kGeneralized) {
727 elemnode = fXML->NewChild(StackNode(), nullptr, xmlio::Member);
728 fXML->NewAttr(elemnode, nullptr, xmlio::Name, elemxmlname);
729 } else {
730 // take namesapce for element only if it is not a base class or class name
731 XMLNsPointer_t ns = Stack()->fClassNs;
732 if ((elem->GetType() == TStreamerInfo::kBase) ||
733 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())) ||
734 ((elem->GetType() == TStreamerInfo::kTObject) && !strcmp(elem->GetName(), TObject::Class()->GetName())) ||
735 ((elem->GetType() == TStreamerInfo::kTString) && !strcmp(elem->GetName(), TString::Class()->GetName())))
736 ns = nullptr;
737
738 elemnode = fXML->NewChild(StackNode(), ns, elemxmlname);
739 }
740
741 TXMLStackObj *curr = PushStack(elemnode);
742 curr->fElem = (TStreamerElement *)elem;
743}
744
745////////////////////////////////////////////////////////////////////////////////
746/// Checks if stack node correspond to TStreamerElement object
747
749{
750 const char *elemxmlname = XmlGetElementName(elem);
751
752 if (GetXmlLayout() == kGeneralized) {
754 return kFALSE;
755 if (!VerifyStackAttr(xmlio::Name, elemxmlname))
756 return kFALSE;
757 } else {
758 if (!VerifyStackNode(elemxmlname))
759 return kFALSE;
760 }
761
763
764 TXMLStackObj *curr = PushStack(StackNode()); // set pointer to first data inside element
765 curr->fElem = (TStreamerElement *)elem;
766 return kTRUE;
767}
768
769////////////////////////////////////////////////////////////////////////////////
770/// Write object to buffer
771/// If object was written before, only pointer will be stored
772/// Return pointer to top xml node, representing object
773
774XMLNodePointer_t TBufferXML::XmlWriteObject(const void *obj, const TClass *cl, Bool_t cacheReuse)
775{
776 XMLNodePointer_t objnode = fXML->NewChild(StackNode(), nullptr, xmlio::Object);
777
778 if (!cl)
779 obj = nullptr;
780
781 if (ProcessPointer(obj, objnode))
782 return objnode;
783
784 TString clname = XmlConvertClassName(cl->GetName());
785
786 fXML->NewAttr(objnode, nullptr, xmlio::ObjClass, clname);
787
788 if (cacheReuse)
789 fMap->Add(Void_Hash(obj), (Long_t)obj, (Long_t)objnode);
790
791 PushStack(objnode);
792
793 ((TClass *)cl)->Streamer((void *)obj, *this);
794
795 PopStack();
796
797 if (gDebug > 1)
798 Info("XmlWriteObject", "Done write for class: %s", cl ? cl->GetName() : "null");
799
800 return objnode;
801}
802
803////////////////////////////////////////////////////////////////////////////////
804/// Read object from the buffer
805
806void *TBufferXML::XmlReadObject(void *obj, TClass **cl)
807{
808 if (cl)
809 *cl = nullptr;
810
811 XMLNodePointer_t objnode = StackNode();
812
813 if (fErrorFlag > 0)
814 return obj;
815
816 if (!objnode)
817 return obj;
818
819 if (!VerifyNode(objnode, xmlio::Object, "XmlReadObjectNew"))
820 return obj;
821
822 TClass *objClass = nullptr;
823
824 if (ExtractPointer(objnode, obj, objClass)) {
825 ShiftStack("readobjptr");
826 if (cl)
827 *cl = objClass;
828 return obj;
829 }
830
831 TString clname = fXML->GetAttr(objnode, xmlio::ObjClass);
832 objClass = XmlDefineClass(clname);
833 if (objClass == TDirectory::Class())
834 objClass = TDirectoryFile::Class();
835
836 if (!objClass) {
837 Error("XmlReadObject", "Cannot find class %s", clname.Data());
838 ShiftStack("readobjerr");
839 return obj;
840 }
841
842 if (gDebug > 1)
843 Info("XmlReadObject", "Reading object of class %s", clname.Data());
844
845 if (!obj)
846 obj = objClass->New();
847
848 ExtractReference(objnode, obj, objClass);
849
850 PushStack(objnode);
851
852 objClass->Streamer((void *)obj, *this);
853
854 PopStack();
855
856 ShiftStack("readobj");
857
858 if (gDebug > 1)
859 Info("XmlReadObject", "Reading object of class %s done", clname.Data());
860
861 if (cl)
862 *cl = objClass;
863
864 return obj;
865}
866
867////////////////////////////////////////////////////////////////////////////////
868/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
869/// and indent new level in xml structure.
870/// This call indicates, that TStreamerInfo functions starts streaming
871/// object data of correspondent class
872
874{
876}
877
878////////////////////////////////////////////////////////////////////////////////
879/// Prepares buffer to stream data of specified class.
880
882{
884
885 if (sinfo)
886 cl = sinfo->GetClass();
887
888 if (!cl)
889 return;
890
891 TString clname = XmlConvertClassName(cl->GetName());
892
893 if (gDebug > 2)
894 Info("IncrementLevel", "Class: %s", clname.Data());
895
896 Bool_t compressClassNode = (fExpectedBaseClass == cl);
897 fExpectedBaseClass = nullptr;
898
899 TXMLStackObj *stack = Stack();
900
901 if (IsWriting()) {
902
903 XMLNodePointer_t classnode = nullptr;
904 if (compressClassNode) {
905 classnode = StackNode();
906 } else {
907 if (GetXmlLayout() == kGeneralized) {
908 classnode = fXML->NewChild(StackNode(), nullptr, xmlio::Class);
909 fXML->NewAttr(classnode, nullptr, "name", clname);
910 } else
911 classnode = fXML->NewChild(StackNode(), nullptr, clname);
912 stack = PushStack(classnode);
913 }
914
915 if (fVersionBuf >= -1) {
916 if (fVersionBuf == -1)
917 fVersionBuf = 1;
919 fVersionBuf = -111;
920 }
921
923 stack->fClassNs = fXML->NewNS(classnode, XmlClassNameSpaceRef(cl), clname);
924
925 } else {
926 if (!compressClassNode) {
927 if (GetXmlLayout() == kGeneralized) {
928 if (!VerifyStackNode(xmlio::Class, "StartInfo"))
929 return;
930 if (!VerifyStackAttr("name", clname, "StartInfo"))
931 return;
932 } else if (!VerifyStackNode(clname, "StartInfo"))
933 return;
934 stack = PushStack(StackNode());
935 }
936 }
937
938 stack->fCompressedClassNode = compressClassNode;
939 stack->fInfo = sinfo;
940 stack->fIsStreamerInfo = kTRUE;
941}
942
943////////////////////////////////////////////////////////////////////////////////
944/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
945/// and decrease level in xml structure.
946
948{
950
952
953 if (gDebug > 2)
954 Info("DecrementLevel", "Class: %s", (info ? info->GetClass()->GetName() : "custom"));
955
956 TXMLStackObj *stack = Stack();
957
958 if (!stack->IsStreamerInfo()) {
960 stack = PopStack(); // remove stack of last element
961 }
962
963 if (stack->fCompressedClassNode) {
964 stack->fInfo = nullptr;
965 stack->fIsStreamerInfo = kFALSE;
966 stack->fCompressedClassNode = kFALSE;
967 } else {
968 PopStack(); // back from data of stack info
969 if (IsReading())
970 ShiftStack("declevel"); // shift to next element after streamer info
971 }
972}
973
974////////////////////////////////////////////////////////////////////////////////
975/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
976/// and add/verify next element of xml structure
977/// This calls allows separate data, correspondent to one class member, from another
978
980{
981 WorkWithElement(elem, comptype);
982}
983
984////////////////////////////////////////////////////////////////////////////////
985/// This function is a part of SetStreamerElementNumber method.
986/// It is introduced for reading of data for specified data member of class.
987/// Used also in ReadFastArray methods to resolve problem of compressed data,
988/// when several data members of the same basic type streamed with single ...FastArray call
989
991{
993
995 fExpectedBaseClass = nullptr;
996
997 TXMLStackObj *stack = Stack();
998 if (!stack) {
999 Error("SetStreamerElementNumber", "stack is empty");
1000 return;
1001 }
1002
1003 if (!stack->IsStreamerInfo()) { // this is not a first element
1005 PopStack(); // go level back
1006 if (IsReading())
1007 ShiftStack("startelem"); // shift to next element, only for reading
1008 stack = Stack();
1009 }
1010
1011 if (!stack) {
1012 Error("SetStreamerElementNumber", "Lost of stack");
1013 return;
1014 }
1015
1016 if (!elem) {
1017 Error("SetStreamerElementNumber", "Problem in Inc/Dec level");
1018 return;
1019 }
1020
1021 TStreamerInfo *info = stack->fInfo;
1022
1023 if (!stack->IsStreamerInfo()) {
1024 Error("SetStreamerElementNumber", "Problem in Inc/Dec level");
1025 return;
1026 }
1027 Int_t number = info ? info->GetElements()->IndexOf(elem) : -1;
1028
1029 if (gDebug > 4)
1030 Info("SetStreamerElementNumber", " Next element %s", elem->GetName());
1031
1032 Bool_t isBasicType = (elem->GetType() > 0) && (elem->GetType() < 20);
1033
1035 isBasicType && ((elem->GetType() == comp_type) || (elem->GetType() == comp_type - TStreamerInfo::kConv) ||
1036 (elem->GetType() == comp_type - TStreamerInfo::kSkip));
1037
1038 if ((elem->GetType() == TStreamerInfo::kBase) ||
1039 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())))
1041
1042 if (fExpectedBaseClass && (gDebug > 3))
1043 Info("SetStreamerElementNumber", " Expects base class %s with standard streamer",
1045
1046 if (IsWriting()) {
1047 CreateElemNode(elem);
1048 } else {
1049 if (!VerifyElemNode(elem))
1050 return;
1051 }
1052
1053 stack = Stack();
1054 stack->fElemNumber = number;
1055 stack->fIsElemOwner = (number < 0);
1056}
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Should be called at the beginning of custom class streamer.
1060///
1061/// Informs buffer data about class which will be streamed now.
1062/// ClassBegin(), ClassEnd() and ClassMemeber() should be used in
1063/// custom class streamers to specify which kind of data are
1064/// now streamed. Such information is used to correctly
1065/// convert class data to XML. Without that functions calls
1066/// classes with custom streamers cannot be used with TBufferXML
1067
1069{
1070 WorkWithClass(nullptr, cl);
1071}
1072
1073////////////////////////////////////////////////////////////////////////////////
1074/// Should be called at the end of custom streamer
1075/// See TBufferXML::ClassBegin for more details
1076
1078{
1079 DecrementLevel(0);
1080}
1081
1082////////////////////////////////////////////////////////////////////////////////
1083/// Method indicates name and typename of class member,
1084/// which should be now streamed in custom streamer
1085///
1086/// Following combinations are supported:
1087/// -# name = "ClassName", typeName = 0 or typename==ClassName.
1088/// This is a case, when data of parent class "ClassName" should be streamed.
1089/// For instance, if class directly inherited from TObject, custom streamer
1090/// should include following code:
1091/// ~~~{.cpp}
1092/// b.ClassMember("TObject");
1093/// TObject::Streamer(b);
1094/// ~~~
1095/// -# Basic data type
1096/// ~~~{.cpp}
1097/// b.ClassMember("fInt","Int_t");
1098/// b >> fInt;
1099/// ~~~
1100/// -# Array of basic data types
1101/// ~~~{.cpp}
1102/// b.ClassMember("fArr","Int_t", 5);
1103/// b.ReadFastArray(fArr, 5);
1104/// ~~~
1105/// -# Object as data member
1106/// ~~~{.cpp}
1107/// b.ClassMemeber("fName","TString");
1108/// fName.Streamer(b);
1109/// ~~~
1110/// -# Pointer on object as data member
1111/// ~~~{.cpp}
1112/// b.ClassMemeber("fObj","TObject*");
1113/// b.StreamObject(fObj);
1114/// ~~~
1115///
1116/// Arrsize1 and arrsize2 arguments (when specified) indicate first and
1117/// second dimension of array. Can be used for array of basic types.
1118/// See ClassBegin() method for more details.
1119
1120void TBufferXML::ClassMember(const char *name, const char *typeName, Int_t arrsize1, Int_t arrsize2)
1121{
1122 if (!typeName)
1123 typeName = name;
1124
1125 if (!name || (strlen(name) == 0)) {
1126 Error("ClassMember", "Invalid member name");
1127 fErrorFlag = 1;
1128 return;
1129 }
1130
1131 TString tname = typeName;
1132
1133 Int_t typ_id(-1), comp_type(-1);
1134
1135 if (strcmp(typeName, "raw:data") == 0)
1136 typ_id = TStreamerInfo::kMissing;
1137
1138 if (typ_id < 0) {
1139 TDataType *dt = gROOT->GetType(typeName);
1140 if (dt)
1141 if ((dt->GetType() > 0) && (dt->GetType() < 20))
1142 typ_id = dt->GetType();
1143 }
1144
1145 if (typ_id < 0)
1146 if (strcmp(name, typeName) == 0) {
1147 TClass *cl = TClass::GetClass(tname.Data());
1148 if (cl)
1149 typ_id = TStreamerInfo::kBase;
1150 }
1151
1152 if (typ_id < 0) {
1153 Bool_t isptr = kFALSE;
1154 if (tname[tname.Length() - 1] == '*') {
1155 tname.Resize(tname.Length() - 1);
1156 isptr = kTRUE;
1157 }
1158 TClass *cl = TClass::GetClass(tname.Data());
1159 if (!cl) {
1160 Error("ClassMember", "Invalid class specifier %s", typeName);
1161 fErrorFlag = 1;
1162 return;
1163 }
1164
1165 if (cl->IsTObject())
1167 else
1168 typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
1169
1170 if ((cl == TString::Class()) && !isptr)
1171 typ_id = TStreamerInfo::kTString;
1172 }
1173
1174 TStreamerElement *elem = nullptr;
1175
1176 if (typ_id == TStreamerInfo::kMissing) {
1177 elem = new TStreamerElement(name, "title", 0, typ_id, "raw:data");
1178 } else if (typ_id == TStreamerInfo::kBase) {
1179 TClass *cl = TClass::GetClass(tname.Data());
1180 if (cl) {
1181 TStreamerBase *b = new TStreamerBase(tname.Data(), "title", 0);
1182 b->SetBaseVersion(cl->GetClassVersion());
1183 elem = b;
1184 }
1185 } else if ((typ_id > 0) && (typ_id < 20)) {
1186 elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
1187 comp_type = typ_id;
1188 } else if ((typ_id == TStreamerInfo::kObject) || (typ_id == TStreamerInfo::kTObject) ||
1189 (typ_id == TStreamerInfo::kTNamed)) {
1190 elem = new TStreamerObject(name, "title", 0, tname.Data());
1191 } else if (typ_id == TStreamerInfo::kObjectp) {
1192 elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
1193 } else if (typ_id == TStreamerInfo::kAny) {
1194 elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
1195 } else if (typ_id == TStreamerInfo::kAnyp) {
1196 elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
1197 } else if (typ_id == TStreamerInfo::kTString) {
1198 elem = new TStreamerString(name, "title", 0);
1199 }
1200
1201 if (!elem) {
1202 Error("ClassMember", "Invalid combination name = %s type = %s", name, typeName);
1203 fErrorFlag = 1;
1204 return;
1205 }
1206
1207 if (arrsize1 > 0) {
1208 elem->SetArrayDim(arrsize2 > 0 ? 2 : 1);
1209 elem->SetMaxIndex(0, arrsize1);
1210 if (arrsize2 > 0)
1211 elem->SetMaxIndex(1, arrsize2);
1212 }
1213
1214 // we indicate that there is no streamerinfo
1215 WorkWithElement(elem, comp_type);
1216}
1217
1218////////////////////////////////////////////////////////////////////////////////
1219/// Function is converts TObject and TString structures to more compact representation
1220
1222{
1223 if (GetXmlLayout() == kGeneralized)
1224 return;
1225
1226 const TStreamerElement *elem = Stack()->fElem;
1227 XMLNodePointer_t elemnode = IsWriting() ? Stack()->fNode : Stack(1)->fNode;
1228
1229 if (!elem || !elemnode)
1230 return;
1231
1232 if (elem->GetType() == TStreamerInfo::kTString) {
1233
1234 XMLNodePointer_t node = fXML->GetChild(elemnode);
1235 fXML->SkipEmpty(node);
1236
1237 XMLNodePointer_t nodecharstar(nullptr), nodeuchar(nullptr), nodeint(nullptr), nodestring(nullptr);
1238
1239 while (node) {
1240 const char *name = fXML->GetNodeName(node);
1241 if (strcmp(name, xmlio::String) == 0) {
1242 if (nodestring)
1243 return;
1244 nodestring = node;
1245 } else if (strcmp(name, xmlio::UChar) == 0) {
1246 if (nodeuchar)
1247 return;
1248 nodeuchar = node;
1249 } else if (strcmp(name, xmlio::Int) == 0) {
1250 if (nodeint)
1251 return;
1252 nodeint = node;
1253 } else if (strcmp(name, xmlio::CharStar) == 0) {
1254 if (nodecharstar)
1255 return;
1256 nodecharstar = node;
1257 } else
1258 return; // can not be something else
1259 fXML->ShiftToNext(node);
1260 }
1261
1262 TString str;
1263
1264 if (GetIOVersion() < 3) {
1265 if (!nodeuchar)
1266 return;
1267 if (nodecharstar)
1268 str = fXML->GetAttr(nodecharstar, xmlio::v);
1269 fXML->UnlinkFreeNode(nodeuchar);
1270 fXML->UnlinkFreeNode(nodeint);
1271 fXML->UnlinkFreeNode(nodecharstar);
1272 } else {
1273 if (nodestring)
1274 str = fXML->GetAttr(nodestring, xmlio::v);
1275 fXML->UnlinkFreeNode(nodestring);
1276 }
1277
1278 fXML->NewAttr(elemnode, nullptr, "str", str);
1279 } else if (elem->GetType() == TStreamerInfo::kTObject) {
1280 XMLNodePointer_t node = fXML->GetChild(elemnode);
1281 fXML->SkipEmpty(node);
1282
1283 XMLNodePointer_t vnode = nullptr, idnode = nullptr, bitsnode = nullptr, prnode = nullptr;
1284
1285 while (node) {
1286 const char *name = fXML->GetNodeName(node);
1287
1288 if (strcmp(name, xmlio::OnlyVersion) == 0) {
1289 if (vnode)
1290 return;
1291 vnode = node;
1292 } else if (strcmp(name, xmlio::UInt) == 0) {
1293 if (!idnode)
1294 idnode = node;
1295 else if (!bitsnode)
1296 bitsnode = node;
1297 else
1298 return;
1299 } else if (strcmp(name, xmlio::UShort) == 0) {
1300 if (prnode)
1301 return;
1302 prnode = node;
1303 } else
1304 return;
1305 fXML->ShiftToNext(node);
1306 }
1307
1308 if (!vnode || !idnode || !bitsnode)
1309 return;
1310
1311 TString str = fXML->GetAttr(idnode, xmlio::v);
1312 fXML->NewAttr(elemnode, nullptr, "fUniqueID", str);
1313
1314 str = fXML->GetAttr(bitsnode, xmlio::v);
1315 UInt_t bits;
1316 sscanf(str.Data(), "%u", &bits);
1317
1318 char sbuf[20];
1319 snprintf(sbuf, sizeof(sbuf), "%x", bits);
1320 fXML->NewAttr(elemnode, nullptr, "fBits", sbuf);
1321
1322 if (prnode) {
1323 str = fXML->GetAttr(prnode, xmlio::v);
1324 fXML->NewAttr(elemnode, nullptr, "fProcessID", str);
1325 }
1326
1327 fXML->UnlinkFreeNode(vnode);
1328 fXML->UnlinkFreeNode(idnode);
1329 fXML->UnlinkFreeNode(bitsnode);
1330 fXML->UnlinkFreeNode(prnode);
1331 }
1332}
1333
1334////////////////////////////////////////////////////////////////////////////////
1335/// Function is unpack TObject and TString structures to be able read
1336/// them from custom streamers of this objects
1337
1339{
1340 if (GetXmlLayout() == kGeneralized)
1341 return;
1342 if (!elem || !elemnode)
1343 return;
1344
1345 if (elem->GetType() == TStreamerInfo::kTString) {
1346
1347 if (!fXML->HasAttr(elemnode, "str"))
1348 return;
1349 TString str = fXML->GetAttr(elemnode, "str");
1350 fXML->FreeAttr(elemnode, "str");
1351
1352 if (GetIOVersion() < 3) {
1353 Int_t len = str.Length();
1354 XMLNodePointer_t ucharnode = fXML->NewChild(elemnode, nullptr, xmlio::UChar);
1355 char sbuf[20];
1356 snprintf(sbuf, sizeof(sbuf), "%d", len);
1357 if (len < 255) {
1358 fXML->NewAttr(ucharnode, nullptr, xmlio::v, sbuf);
1359 } else {
1360 fXML->NewAttr(ucharnode, nullptr, xmlio::v, "255");
1361 XMLNodePointer_t intnode = fXML->NewChild(elemnode, nullptr, xmlio::Int);
1362 fXML->NewAttr(intnode, nullptr, xmlio::v, sbuf);
1363 }
1364 if (len > 0) {
1365 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::CharStar);
1366 fXML->NewAttr(node, nullptr, xmlio::v, str);
1367 }
1368 } else {
1369 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::String);
1370 fXML->NewAttr(node, nullptr, xmlio::v, str);
1371 }
1372 } else if (elem->GetType() == TStreamerInfo::kTObject) {
1373 if (!fXML->HasAttr(elemnode, "fUniqueID"))
1374 return;
1375 if (!fXML->HasAttr(elemnode, "fBits"))
1376 return;
1377
1378 TString idstr = fXML->GetAttr(elemnode, "fUniqueID");
1379 TString bitsstr = fXML->GetAttr(elemnode, "fBits");
1380 TString prstr = fXML->GetAttr(elemnode, "fProcessID");
1381
1382 fXML->FreeAttr(elemnode, "fUniqueID");
1383 fXML->FreeAttr(elemnode, "fBits");
1384 fXML->FreeAttr(elemnode, "fProcessID");
1385
1386 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::OnlyVersion);
1387 fXML->NewAttr(node, nullptr, xmlio::v, "1");
1388
1389 node = fXML->NewChild(elemnode, nullptr, xmlio::UInt);
1390 fXML->NewAttr(node, nullptr, xmlio::v, idstr);
1391
1392 UInt_t bits;
1393 sscanf(bitsstr.Data(), "%x", &bits);
1394 char sbuf[20];
1395 snprintf(sbuf, sizeof(sbuf), "%u", bits);
1396
1397 node = fXML->NewChild(elemnode, nullptr, xmlio::UInt);
1398 fXML->NewAttr(node, nullptr, xmlio::v, sbuf);
1399
1400 if (prstr.Length() > 0) {
1401 node = fXML->NewChild(elemnode, nullptr, xmlio::UShort);
1402 fXML->NewAttr(node, nullptr, xmlio::v, prstr.Data());
1403 }
1404 }
1405}
1406
1407////////////////////////////////////////////////////////////////////////////////
1408/// Function is called before any IO operation of TBuffer
1409/// Now is used to store version value if no proper calls are discovered
1410
1412{
1414}
1415
1416////////////////////////////////////////////////////////////////////////////////
1417/// Function to read class from buffer, used in old-style streamers
1418
1420{
1421 const char *clname = nullptr;
1422
1424 clname = XmlReadValue(xmlio::Class);
1425
1426 if (gDebug > 2)
1427 Info("ReadClass", "Try to read class %s", clname ? clname : "---");
1428
1429 return clname ? gROOT->GetClass(clname) : nullptr;
1430}
1431
1432////////////////////////////////////////////////////////////////////////////////
1433/// Function to write class into buffer, used in old-style streamers
1434
1436{
1437 if (gDebug > 2)
1438 Info("WriteClass", "Try to write class %s", cl->GetName());
1439
1441}
1442
1443////////////////////////////////////////////////////////////////////////////////
1444/// Read version value from buffer
1445
1447{
1449
1450 Version_t res = 0;
1451
1452 if (start)
1453 *start = 0;
1454 if (bcnt)
1455 *bcnt = 0;
1456
1459 } else if (fExpectedBaseClass && (fXML->HasAttr(Stack(1)->fNode, xmlio::ClassVersion))) {
1460 res = fXML->GetIntAttr(Stack(1)->fNode, xmlio::ClassVersion);
1461 } else if (fXML->HasAttr(StackNode(), xmlio::ClassVersion)) {
1463 } else {
1464 Error("ReadVersion", "No correspondent tags to read version");
1465 fErrorFlag = 1;
1466 }
1467
1468 if (gDebug > 2)
1469 Info("ReadVersion", "Version = %d", res);
1470
1471 return res;
1472}
1473
1474////////////////////////////////////////////////////////////////////////////////
1475/// Checks buffer, filled by WriteVersion
1476/// if next data is arriving, version should be stored in buffer
1477
1479{
1480 if (IsWriting() && (fVersionBuf >= -100)) {
1481 char sbuf[20];
1482 snprintf(sbuf, sizeof(sbuf), "%d", fVersionBuf);
1484 fVersionBuf = -111;
1485 }
1486}
1487
1488////////////////////////////////////////////////////////////////////////////////
1489/// Copies class version to buffer, but not writes it to xml
1490/// Version will be written with next I/O operation or
1491/// will be added as attribute of class tag, created by IncrementLevel call
1492
1494{
1496
1497 if (fExpectedBaseClass != cl)
1498 fExpectedBaseClass = nullptr;
1499
1501
1502 if (gDebug > 2)
1503 Info("WriteVersion", "Class: %s, version = %d", cl->GetName(), fVersionBuf);
1504
1505 return 0;
1506}
1507
1508////////////////////////////////////////////////////////////////////////////////
1509/// Read object from buffer. Only used from TBuffer
1510
1512{
1514 if (gDebug > 2)
1515 Info("ReadObjectAny", "From node %s", fXML->GetNodeName(StackNode()));
1516 void *res = XmlReadObject(nullptr);
1517 return res;
1518}
1519
1520////////////////////////////////////////////////////////////////////////////////
1521/// Skip any kind of object from buffer
1522/// Actually skip only one node on current level of xml structure
1523
1525{
1526 ShiftStack("skipobjectany");
1527}
1528
1529////////////////////////////////////////////////////////////////////////////////
1530/// Write object to buffer. Only used from TBuffer
1531
1532void TBufferXML::WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse)
1533{
1535 if (gDebug > 2)
1536 Info("WriteObject", "Class %s", (actualClass ? actualClass->GetName() : " null"));
1537 XmlWriteObject(actualObjStart, actualClass, cacheReuse);
1538}
1539
1540////////////////////////////////////////////////////////////////////////////////
1541/// Template method to read array content
1542
1543template <typename T>
1545{
1546 Int_t indx = 0, cnt, curr;
1547 while (indx < arrsize) {
1548 cnt = 1;
1551 XmlReadBasic(arr[indx]);
1552 curr = indx++;
1553 while (cnt-- > 1)
1554 arr[indx++] = arr[curr];
1555 }
1556}
1557
1558////////////////////////////////////////////////////////////////////////////////
1559/// Template method to read array with size attribute
1560/// If necessary, array is created
1561
1562template <typename T>
1564{
1566 if (!VerifyItemNode(xmlio::Array, is_static ? "ReadStaticArray" : "ReadArray"))
1567 return 0;
1569 if (n <= 0)
1570 return 0;
1571 if (!arr) {
1572 if (is_static)
1573 return 0;
1574 arr = new T[n];
1575 }
1577 XmlReadArrayContent(arr, n);
1578 PopStack();
1579 ShiftStack(is_static ? "readstatarr" : "readarr");
1580 return n;
1581}
1582
1583////////////////////////////////////////////////////////////////////////////////
1584/// Read array of Bool_t from buffer
1585
1587{
1588 return XmlReadArray(b);
1589}
1590
1591////////////////////////////////////////////////////////////////////////////////
1592/// Read array of Char_t from buffer
1593
1595{
1596 return XmlReadArray(c);
1597}
1598
1599////////////////////////////////////////////////////////////////////////////////
1600/// Read array of UChar_t from buffer
1601
1603{
1604 return XmlReadArray(c);
1605}
1606
1607////////////////////////////////////////////////////////////////////////////////
1608/// Read array of Short_t from buffer
1609
1611{
1612 return XmlReadArray(h);
1613}
1614
1615////////////////////////////////////////////////////////////////////////////////
1616/// Read array of UShort_t from buffer
1617
1619{
1620 return XmlReadArray(h);
1621}
1622
1623////////////////////////////////////////////////////////////////////////////////
1624/// Read array of Int_t from buffer
1625
1627{
1628 return XmlReadArray(i);
1629}
1630
1631////////////////////////////////////////////////////////////////////////////////
1632/// Read array of UInt_t from buffer
1633
1635{
1636 return XmlReadArray(i);
1637}
1638
1639////////////////////////////////////////////////////////////////////////////////
1640/// Read array of Long_t from buffer
1641
1643{
1644 return XmlReadArray(l);
1645}
1646
1647////////////////////////////////////////////////////////////////////////////////
1648/// Read array of ULong_t from buffer
1649
1651{
1652 return XmlReadArray(l);
1653}
1654
1655////////////////////////////////////////////////////////////////////////////////
1656/// Read array of Long64_t from buffer
1657
1659{
1660 return XmlReadArray(l);
1661}
1662
1663////////////////////////////////////////////////////////////////////////////////
1664/// Read array of ULong64_t from buffer
1665
1667{
1668 return XmlReadArray(l);
1669}
1670
1671////////////////////////////////////////////////////////////////////////////////
1672/// Read array of Float_t from buffer
1673
1675{
1676 return XmlReadArray(f);
1677}
1678
1679////////////////////////////////////////////////////////////////////////////////
1680/// Read array of Double_t from buffer
1681
1683{
1684 return XmlReadArray(d);
1685}
1686
1687////////////////////////////////////////////////////////////////////////////////
1688/// Read array of Bool_t from buffer
1689
1691{
1692 return XmlReadArray(b, true);
1693}
1694
1695////////////////////////////////////////////////////////////////////////////////
1696/// Read array of Char_t from buffer
1697
1699{
1700 return XmlReadArray(c, true);
1701}
1702
1703////////////////////////////////////////////////////////////////////////////////
1704/// Read array of UChar_t from buffer
1705
1707{
1708 return XmlReadArray(c, true);
1709}
1710
1711////////////////////////////////////////////////////////////////////////////////
1712/// Read array of Short_t from buffer
1713
1715{
1716 return XmlReadArray(h, true);
1717}
1718
1719////////////////////////////////////////////////////////////////////////////////
1720/// Read array of UShort_t from buffer
1721
1723{
1724 return XmlReadArray(h, true);
1725}
1726
1727////////////////////////////////////////////////////////////////////////////////
1728/// Read array of Int_t from buffer
1729
1731{
1732 return XmlReadArray(i, true);
1733}
1734
1735////////////////////////////////////////////////////////////////////////////////
1736/// Read array of UInt_t from buffer
1737
1739{
1740 return XmlReadArray(i, true);
1741}
1742
1743////////////////////////////////////////////////////////////////////////////////
1744/// Read array of Long_t from buffer
1745
1747{
1748 return XmlReadArray(l, true);
1749}
1750
1751////////////////////////////////////////////////////////////////////////////////
1752/// Read array of ULong_t from buffer
1753
1755{
1756 return XmlReadArray(l, true);
1757}
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Read array of Long64_t from buffer
1761
1763{
1764 return XmlReadArray(l, true);
1765}
1766
1767////////////////////////////////////////////////////////////////////////////////
1768/// Read array of ULong64_t from buffer
1769
1771{
1772 return XmlReadArray(l, true);
1773}
1774
1775////////////////////////////////////////////////////////////////////////////////
1776/// Read array of Float_t from buffer
1777
1779{
1780 return XmlReadArray(f, true);
1781}
1782
1783////////////////////////////////////////////////////////////////////////////////
1784/// Read array of Double_t from buffer
1785
1787{
1788 return XmlReadArray(d, true);
1789}
1790
1791////////////////////////////////////////////////////////////////////////////////
1792/// Template method to read content of array, which not include size of array
1793/// Also treated situation, when instead of one single array chain
1794/// of several elements should be produced
1795
1796template <typename T>
1798{
1800 if (n <= 0)
1801 return;
1802 if (!VerifyItemNode(xmlio::Array, "ReadFastArray"))
1803 return;
1805 XmlReadArrayContent(arr, n);
1806 PopStack();
1807 ShiftStack("readfastarr");
1808}
1809
1810////////////////////////////////////////////////////////////////////////////////
1811/// Read array of Bool_t from buffer
1812
1814{
1816}
1817
1818////////////////////////////////////////////////////////////////////////////////
1819/// Read array of Char_t from buffer
1820/// if nodename==CharStar, read all array as string
1821
1823{
1824 if ((n > 0) && VerifyItemNode(xmlio::CharStar)) {
1825 const char *buf;
1826 if ((buf = XmlReadValue(xmlio::CharStar))) {
1827 Int_t size = strlen(buf);
1828 if (size < n)
1829 size = n;
1830 memcpy(c, buf, size);
1831 }
1832 } else {
1834 }
1835}
1836
1837////////////////////////////////////////////////////////////////////////////////
1838/// Read array of n characters from the I/O buffer.
1839/// Used only from TLeafC, dummy implementation here
1840
1842{
1843 ReadFastArray(c, n);
1844}
1845
1846////////////////////////////////////////////////////////////////////////////////
1847/// Read array of UChar_t from buffer
1848
1850{
1852}
1853
1854////////////////////////////////////////////////////////////////////////////////
1855/// Read array of Short_t from buffer
1856
1858{
1860}
1861
1862////////////////////////////////////////////////////////////////////////////////
1863/// Read array of UShort_t from buffer
1864
1866{
1868}
1869
1870////////////////////////////////////////////////////////////////////////////////
1871/// Read array of Int_t from buffer
1872
1874{
1875 XmlReadFastArray(i, n);
1876}
1877
1878////////////////////////////////////////////////////////////////////////////////
1879/// Read array of UInt_t from buffer
1880
1882{
1883 XmlReadFastArray(i, n);
1884}
1885
1886////////////////////////////////////////////////////////////////////////////////
1887/// Read array of Long_t from buffer
1888
1890{
1892}
1893
1894////////////////////////////////////////////////////////////////////////////////
1895/// Read array of ULong_t from buffer
1896
1898{
1900}
1901
1902////////////////////////////////////////////////////////////////////////////////
1903/// Read array of Long64_t from buffer
1904
1906{
1908}
1909
1910////////////////////////////////////////////////////////////////////////////////
1911/// Read array of ULong64_t from buffer
1912
1914{
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919/// Read array of Float_t from buffer
1920
1922{
1924}
1925
1926////////////////////////////////////////////////////////////////////////////////
1927/// Read array of Double_t from buffer
1928
1930{
1932}
1933
1934////////////////////////////////////////////////////////////////////////////////
1935/// Read an array of 'n' objects from the I/O buffer.
1936/// Stores the objects read starting at the address 'start'.
1937/// The objects in the array are assume to be of class 'cl'.
1938
1939void TBufferXML::ReadFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *streamer,
1940 const TClass *onFileClass)
1941{
1942 if (streamer) {
1943 streamer->SetOnFileClass(onFileClass);
1944 (*streamer)(*this, start, 0);
1945 return;
1946 }
1947
1948 int objectSize = cl->Size();
1949 char *obj = (char *)start;
1950 char *end = obj + n * objectSize;
1951
1952 for (; obj < end; obj += objectSize)
1953 ((TClass *)cl)->Streamer(obj, *this, onFileClass);
1954}
1955
1956////////////////////////////////////////////////////////////////////////////////
1957/// Read an array of 'n' objects from the I/O buffer.
1958///
1959/// The objects read are stored starting at the address '*start'
1960/// The objects in the array are assumed to be of class 'cl' or a derived class.
1961/// 'mode' indicates whether the data member is marked with '->'
1962
1963void TBufferXML::ReadFastArray(void **start, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer,
1964 const TClass *onFileClass)
1965{
1966
1967 Bool_t oldStyle = kFALSE; // flag used to reproduce old-style I/= actions for kSTLp
1968
1969 if ((GetIOVersion() < 4) && !isPreAlloc) {
1970 TStreamerElement *elem = Stack()->fElem;
1971 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
1973 oldStyle = kTRUE;
1974 }
1975
1976 if (streamer) {
1977 if (isPreAlloc) {
1978 for (Int_t j = 0; j < n; j++) {
1979 if (!start[j])
1980 start[j] = cl->New();
1981 }
1982 }
1983 streamer->SetOnFileClass(onFileClass);
1984 (*streamer)(*this, (void *)start, oldStyle ? n : 0);
1985 return;
1986 }
1987
1988 if (!isPreAlloc) {
1989
1990 for (Int_t j = 0; j < n; j++) {
1991 if (oldStyle) {
1992 if (!start[j])
1993 start[j] = ((TClass *)cl)->New();
1994 ((TClass *)cl)->Streamer(start[j], *this);
1995 continue;
1996 }
1997 // delete the object or collection
1998 void *old = start[j];
1999 start[j] = ReadObjectAny(cl);
2000 if (old && old != start[j] && TStreamerInfo::CanDelete()
2001 // There are some cases where the user may set up a pointer in the (default)
2002 // constructor but not mark this pointer as transient. Sometime the value
2003 // of this pointer is the address of one of the object with just created
2004 // and the following delete would result in the deletion (possibly of the
2005 // top level object we are goint to return!).
2006 // Eventhough this is a user error, we could prevent the crash by simply
2007 // adding:
2008 // && !CheckObject(start[j],cl)
2009 // However this can increase the read time significantly (10% in the case
2010 // of one TLine pointer in the test/Track and run ./Event 200 0 0 20 30000
2011 //
2012 // If ReadObjectAny returned the same value as we previous had, this means
2013 // that when writing this object (start[j] had already been written and
2014 // is indeed pointing to the same object as the object the user set up
2015 // in the default constructor).
2016 ) {
2017 ((TClass *)cl)->Destructor(old, kFALSE); // call delete and desctructor
2018 }
2019 }
2020
2021 } else {
2022 // case //-> in comment
2023
2024 for (Int_t j = 0; j < n; j++) {
2025 if (!start[j])
2026 start[j] = ((TClass *)cl)->New();
2027 ((TClass *)cl)->Streamer(start[j], *this, onFileClass);
2028 }
2029 }
2030}
2031
2032template <typename T>
2034{
2035 if (fCompressLevel > 0) {
2036 Int_t indx = 0;
2037 while (indx < arrsize) {
2038 XMLNodePointer_t elemnode = XmlWriteBasic(arr[indx]);
2039 Int_t curr = indx++;
2040 while ((indx < arrsize) && (arr[indx] == arr[curr]))
2041 indx++;
2042 if (indx - curr > 1)
2043 fXML->NewIntAttr(elemnode, xmlio::cnt, indx - curr);
2044 }
2045 } else {
2046 for (Int_t indx = 0; indx < arrsize; indx++)
2047 XmlWriteBasic(arr[indx]);
2048 }
2049}
2050
2051////////////////////////////////////////////////////////////////////////////////
2052/// Write array, including it size
2053/// Content may be compressed
2054
2055template <typename T>
2057{
2060 fXML->NewIntAttr(arrnode, xmlio::Size, arrsize);
2061 PushStack(arrnode);
2062 XmlWriteArrayContent(arr, arrsize);
2063 PopStack();
2064}
2065
2066////////////////////////////////////////////////////////////////////////////////
2067/// Write array of Bool_t to buffer
2068
2070{
2071 XmlWriteArray(b, n);
2072}
2073
2074////////////////////////////////////////////////////////////////////////////////
2075/// Write array of Char_t to buffer
2076
2078{
2079 XmlWriteArray(c, n);
2080}
2081
2082////////////////////////////////////////////////////////////////////////////////
2083/// Write array of UChar_t to buffer
2084
2086{
2087 XmlWriteArray(c, n);
2088}
2089
2090////////////////////////////////////////////////////////////////////////////////
2091/// Write array of Short_t to buffer
2092
2094{
2095 XmlWriteArray(h, n);
2096}
2097
2098////////////////////////////////////////////////////////////////////////////////
2099/// Write array of UShort_t to buffer
2100
2102{
2103 XmlWriteArray(h, n);
2104}
2105
2106////////////////////////////////////////////////////////////////////////////////
2107/// Write array of Int_ to buffer
2108
2110{
2111 XmlWriteArray(i, n);
2112}
2113
2114////////////////////////////////////////////////////////////////////////////////
2115/// Write array of UInt_t to buffer
2116
2118{
2119 XmlWriteArray(i, n);
2120}
2121
2122////////////////////////////////////////////////////////////////////////////////
2123/// Write array of Long_t to buffer
2124
2126{
2127 XmlWriteArray(l, n);
2128}
2129
2130////////////////////////////////////////////////////////////////////////////////
2131/// Write array of ULong_t to buffer
2132
2134{
2135 XmlWriteArray(l, n);
2136}
2137
2138////////////////////////////////////////////////////////////////////////////////
2139/// Write array of Long64_t to buffer
2140
2142{
2143 XmlWriteArray(l, n);
2144}
2145
2146////////////////////////////////////////////////////////////////////////////////
2147/// Write array of ULong64_t to buffer
2148
2150{
2151 XmlWriteArray(l, n);
2152}
2153
2154////////////////////////////////////////////////////////////////////////////////
2155/// Write array of Float_t to buffer
2156
2158{
2159 XmlWriteArray(f, n);
2160}
2161
2162////////////////////////////////////////////////////////////////////////////////
2163/// Write array of Double_t to buffer
2164
2166{
2167 XmlWriteArray(d, n);
2168}
2169
2170/////////////////////////////////////////////////////////////////////////////////
2171/// Write array without size attribute
2172/// Also treat situation, when instead of one single array
2173/// chain of several elements should be produced
2174
2175template <typename T>
2177{
2179 if (n <= 0)
2180 return;
2182 PushStack(arrnode);
2183 XmlWriteArrayContent(arr, n);
2184 PopStack();
2185}
2186
2187////////////////////////////////////////////////////////////////////////////////
2188/// Write array of Bool_t to buffer
2189
2191{
2193}
2194
2195////////////////////////////////////////////////////////////////////////////////
2196/// Write array of Char_t to buffer
2197/// If array does not include any special characters,
2198/// it will be reproduced as CharStar node with string as attribute
2199
2201{
2202 Bool_t usedefault = (n == 0);
2203 const Char_t *buf = c;
2204 if (!usedefault)
2205 for (int i = 0; i < n; i++) {
2206 if (*buf < 27) {
2207 usedefault = kTRUE;
2208 break;
2209 }
2210 buf++;
2211 }
2212 if (usedefault) {
2214 } else {
2215 Char_t *buf2 = new Char_t[n + 1];
2216 memcpy(buf2, c, n);
2217 buf2[n] = 0;
2219 delete[] buf2;
2220 }
2221}
2222
2223////////////////////////////////////////////////////////////////////////////////
2224/// Write array of UChar_t to buffer
2225
2227{
2229}
2230
2231////////////////////////////////////////////////////////////////////////////////
2232/// Write array of Short_t to buffer
2233
2235{
2237}
2238
2239////////////////////////////////////////////////////////////////////////////////
2240/// Write array of UShort_t to buffer
2241
2243{
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// Write array of Int_t to buffer
2249
2251{
2252 XmlWriteFastArray(i, n);
2253}
2254
2255////////////////////////////////////////////////////////////////////////////////
2256/// Write array of UInt_t to buffer
2257
2259{
2260 XmlWriteFastArray(i, n);
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// Write array of Long_t to buffer
2265
2267{
2269}
2270
2271////////////////////////////////////////////////////////////////////////////////
2272/// Write array of ULong_t to buffer
2273
2275{
2277}
2278
2279////////////////////////////////////////////////////////////////////////////////
2280/// Write array of Long64_t to buffer
2281
2283{
2285}
2286
2287////////////////////////////////////////////////////////////////////////////////
2288/// Write array of ULong64_t to buffer
2289
2291{
2293}
2294
2295////////////////////////////////////////////////////////////////////////////////
2296/// Write array of Float_t to buffer
2297
2299{
2301}
2302
2303////////////////////////////////////////////////////////////////////////////////
2304/// Write array of Double_t to buffer
2305
2307{
2309}
2310
2311////////////////////////////////////////////////////////////////////////////////
2312/// Write array of n characters into the I/O buffer.
2313/// Used only by TLeafC, just dummy implementation here
2314
2316{
2317 WriteFastArray(c, n);
2318}
2319
2320////////////////////////////////////////////////////////////////////////////////
2321/// Write an array of object starting at the address 'start' and of length 'n'
2322/// the objects in the array are assumed to be of class 'cl'
2323
2324void TBufferXML::WriteFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *streamer)
2325{
2326 if (streamer) {
2327 (*streamer)(*this, start, 0);
2328 return;
2329 }
2330
2331 char *obj = (char *)start;
2332 if (!n)
2333 n = 1;
2334 int size = cl->Size();
2335
2336 for (Int_t j = 0; j < n; j++, obj += size) {
2337 ((TClass *)cl)->Streamer(obj, *this);
2338 }
2339}
2340
2341////////////////////////////////////////////////////////////////////////////////
2342/// Write an array of object starting at the address '*start' and of length 'n'
2343/// the objects in the array are of class 'cl'
2344/// 'isPreAlloc' indicates whether the data member is marked with '->'
2345/// Return:
2346/// - 0: success
2347/// - 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
2348
2349Int_t TBufferXML::WriteFastArray(void **start, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer)
2350{
2351 // if isPreAlloc is true (data member has a ->) we can assume that the pointer
2352 // is never 0.
2353
2354 Bool_t oldStyle = kFALSE; // flag used to reproduce old-style I/O actions for kSTLp
2355
2356 if ((GetIOVersion() < 4) && !isPreAlloc) {
2357 TStreamerElement *elem = Stack()->fElem;
2358 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
2360 oldStyle = kTRUE;
2361 }
2362
2363 if (streamer) {
2364 (*streamer)(*this, (void *)start, oldStyle ? n : 0);
2365 return 0;
2366 }
2367
2368 int strInfo = 0;
2369
2370 Int_t res = 0;
2371
2372 if (!isPreAlloc) {
2373
2374 for (Int_t j = 0; j < n; j++) {
2375 // must write StreamerInfo if pointer is null
2376 if (!strInfo && !start[j] && !oldStyle) {
2377 if (cl->Property() & kIsAbstract) {
2378 // Do not try to generate the StreamerInfo for an abstract class
2379 } else {
2380 TStreamerInfo *info = (TStreamerInfo *)((TClass *)cl)->GetStreamerInfo();
2381 ForceWriteInfo(info, kFALSE);
2382 }
2383 }
2384 strInfo = 2003;
2385 if (oldStyle)
2386 ((TClass *)cl)->Streamer(start[j], *this);
2387 else
2388 res |= WriteObjectAny(start[j], cl);
2389 }
2390
2391 } else {
2392 // case //-> in comment
2393
2394 for (Int_t j = 0; j < n; j++) {
2395 if (!start[j])
2396 start[j] = ((TClass *)cl)->New();
2397 ((TClass *)cl)->Streamer(start[j], *this);
2398 }
2399 }
2400 return res;
2401}
2402
2403////////////////////////////////////////////////////////////////////////////////
2404/// Stream object to/from buffer
2405
2406void TBufferXML::StreamObject(void *obj, const TClass *cl, const TClass * /* onfileClass */)
2407{
2408 if (GetIOVersion() < 4) {
2409 TStreamerElement *elem = Stack()->fElem;
2410 if (elem && (elem->GetType() == TStreamerInfo::kTObject)) {
2411 ((TObject *)obj)->TObject::Streamer(*this);
2412 return;
2413 } else if (elem && (elem->GetType() == TStreamerInfo::kTNamed)) {
2414 ((TNamed *)obj)->TNamed::Streamer(*this);
2415 return;
2416 }
2417 }
2418
2420 if (gDebug > 1)
2421 Info("StreamObject", "Class: %s", (cl ? cl->GetName() : "none"));
2422 if (IsReading())
2423 XmlReadObject(obj);
2424 else
2425 XmlWriteObject(obj, cl, kTRUE);
2426}
2427
2428////////////////////////////////////////////////////////////////////////////////
2429/// Reads Bool_t value from buffer
2430
2432{
2434 XmlReadBasic(b);
2435}
2436
2437////////////////////////////////////////////////////////////////////////////////
2438/// Reads Char_t value from buffer
2439
2441{
2443 XmlReadBasic(c);
2444}
2445
2446////////////////////////////////////////////////////////////////////////////////
2447/// Reads UChar_t value from buffer
2448
2450{
2452 XmlReadBasic(c);
2453}
2454
2455////////////////////////////////////////////////////////////////////////////////
2456/// Reads Short_t value from buffer
2457
2459{
2461 XmlReadBasic(h);
2462}
2463
2464////////////////////////////////////////////////////////////////////////////////
2465/// Reads UShort_t value from buffer
2466
2468{
2470 XmlReadBasic(h);
2471}
2472
2473////////////////////////////////////////////////////////////////////////////////
2474/// Reads Int_t value from buffer
2475
2477{
2479 XmlReadBasic(i);
2480}
2481
2482////////////////////////////////////////////////////////////////////////////////
2483/// Reads UInt_t value from buffer
2484
2486{
2488 XmlReadBasic(i);
2489}
2490
2491////////////////////////////////////////////////////////////////////////////////
2492/// Reads Long_t value from buffer
2493
2495{
2497 XmlReadBasic(l);
2498}
2499
2500////////////////////////////////////////////////////////////////////////////////
2501/// Reads ULong_t value from buffer
2502
2504{
2506 XmlReadBasic(l);
2507}
2508
2509////////////////////////////////////////////////////////////////////////////////
2510/// Reads Long64_t value from buffer
2511
2513{
2515 XmlReadBasic(l);
2516}
2517
2518////////////////////////////////////////////////////////////////////////////////
2519/// Reads ULong64_t value from buffer
2520
2522{
2524 XmlReadBasic(l);
2525}
2526
2527////////////////////////////////////////////////////////////////////////////////
2528/// Reads Float_t value from buffer
2529
2531{
2533 XmlReadBasic(f);
2534}
2535
2536////////////////////////////////////////////////////////////////////////////////
2537/// Reads Double_t value from buffer
2538
2540{
2542 XmlReadBasic(d);
2543}
2544
2545////////////////////////////////////////////////////////////////////////////////
2546/// Reads array of characters from buffer
2547
2549{
2551 const char *buf;
2552 if ((buf = XmlReadValue(xmlio::CharStar)))
2553 strcpy(c, buf);
2554}
2555
2556////////////////////////////////////////////////////////////////////////////////
2557/// Reads a TString
2558
2560{
2561 if (GetIOVersion() < 3) {
2562 // original TBufferFile method can not be used, while used TString methods are private
2563 // try to reimplement close to the original
2564 Int_t nbig;
2565 UChar_t nwh;
2566 *this >> nwh;
2567 if (nwh == 0) {
2568 s.Resize(0);
2569 } else {
2570 if (nwh == 255)
2571 *this >> nbig;
2572 else
2573 nbig = nwh;
2574
2575 char *data = new char[nbig];
2576 data[nbig] = 0;
2577 ReadFastArray(data, nbig);
2578 s = data;
2579 delete[] data;
2580 }
2581 } else {
2583 const char *buf = XmlReadValue(xmlio::String);
2584 if (buf)
2585 s = buf;
2586 }
2587}
2588
2589////////////////////////////////////////////////////////////////////////////////
2590/// Reads a std::string
2591
2592void TBufferXML::ReadStdString(std::string *obj)
2593{
2594 if (GetIOVersion() < 3) {
2595 if (!obj) {
2596 Error("ReadStdString", "The std::string address is nullptr but should not");
2597 return;
2598 }
2599 Int_t nbig;
2600 UChar_t nwh;
2601 *this >> nwh;
2602 if (nwh == 0) {
2603 obj->clear();
2604 } else {
2605 if (obj->size()) {
2606 // Insure that the underlying data storage is not shared
2607 (*obj)[0] = '\0';
2608 }
2609 if (nwh == 255) {
2610 *this >> nbig;
2611 obj->resize(nbig, '\0');
2612 ReadFastArray((char *)obj->data(), nbig);
2613 } else {
2614 obj->resize(nwh, '\0');
2615 ReadFastArray((char *)obj->data(), nwh);
2616 }
2617 }
2618 } else {
2620 const char *buf = XmlReadValue(xmlio::String);
2621 if (buf && obj)
2622 *obj = buf;
2623 }
2624}
2625
2626////////////////////////////////////////////////////////////////////////////////
2627/// Read a char* string
2628
2630{
2631 delete[] s;
2632 s = nullptr;
2633
2634 Int_t nch;
2635 *this >> nch;
2636 if (nch > 0) {
2637 s = new char[nch + 1];
2638 ReadFastArray(s, nch);
2639 s[nch] = 0;
2640 }
2641}
2642
2643////////////////////////////////////////////////////////////////////////////////
2644/// Writes Bool_t value to buffer
2645
2647{
2650}
2651
2652////////////////////////////////////////////////////////////////////////////////
2653/// Writes Char_t value to buffer
2654
2656{
2659}
2660
2661////////////////////////////////////////////////////////////////////////////////
2662/// Writes UChar_t value to buffer
2663
2665{
2668}
2669
2670////////////////////////////////////////////////////////////////////////////////
2671/// Writes Short_t value to buffer
2672
2674{
2677}
2678
2679////////////////////////////////////////////////////////////////////////////////
2680/// Writes UShort_t value to buffer
2681
2683{
2686}
2687
2688////////////////////////////////////////////////////////////////////////////////
2689/// Writes Int_t value to buffer
2690
2692{
2694 XmlWriteBasic(i);
2695}
2696
2697////////////////////////////////////////////////////////////////////////////////
2698/// Writes UInt_t value to buffer
2699
2701{
2703 XmlWriteBasic(i);
2704}
2705
2706////////////////////////////////////////////////////////////////////////////////
2707/// Writes Long_t value to buffer
2708
2710{
2713}
2714
2715////////////////////////////////////////////////////////////////////////////////
2716/// Writes ULong_t value to buffer
2717
2719{
2722}
2723
2724////////////////////////////////////////////////////////////////////////////////
2725/// Writes Long64_t value to buffer
2726
2728{
2731}
2732
2733////////////////////////////////////////////////////////////////////////////////
2734/// Writes ULong64_t value to buffer
2735
2737{
2740}
2741
2742////////////////////////////////////////////////////////////////////////////////
2743/// Writes Float_t value to buffer
2744
2746{
2749}
2750
2751////////////////////////////////////////////////////////////////////////////////
2752/// Writes Double_t value to buffer
2753
2755{
2758}
2759
2760////////////////////////////////////////////////////////////////////////////////
2761/// Writes array of characters to buffer
2762
2764{
2767}
2768
2769////////////////////////////////////////////////////////////////////////////////
2770/// Writes a TString
2771
2773{
2774 if (GetIOVersion() < 3) {
2775 // original TBufferFile method, keep for compatibility
2776 Int_t nbig = s.Length();
2777 UChar_t nwh;
2778 if (nbig > 254) {
2779 nwh = 255;
2780 *this << nwh;
2781 *this << nbig;
2782 } else {
2783 nwh = UChar_t(nbig);
2784 *this << nwh;
2785 }
2786 const char *data = s.Data();
2787 WriteFastArray(data, nbig);
2788 } else {
2790 XmlWriteValue(s.Data(), xmlio::String);
2791 }
2792}
2793
2794////////////////////////////////////////////////////////////////////////////////
2795/// Writes a std::string
2796
2797void TBufferXML::WriteStdString(const std::string *obj)
2798{
2799 if (GetIOVersion() < 3) {
2800 if (!obj) {
2801 *this << (UChar_t)0;
2802 WriteFastArray("", 0);
2803 return;
2804 }
2805
2806 UChar_t nwh;
2807 Int_t nbig = obj->length();
2808 if (nbig > 254) {
2809 nwh = 255;
2810 *this << nwh;
2811 *this << nbig;
2812 } else {
2813 nwh = UChar_t(nbig);
2814 *this << nwh;
2815 }
2816 WriteFastArray(obj->data(), nbig);
2817 } else {
2819 XmlWriteValue(obj ? obj->c_str() : "", xmlio::String);
2820 }
2821}
2822
2823////////////////////////////////////////////////////////////////////////////////
2824/// Write a char* string
2825
2827{
2828 Int_t nch = 0;
2829 if (s) {
2830 nch = strlen(s);
2831 *this << nch;
2832 WriteFastArray(s, nch);
2833 } else {
2834 *this << nch;
2835 }
2836}
2837
2838////////////////////////////////////////////////////////////////////////////////
2839/// Converts Char_t to string and add xml node to buffer
2840
2842{
2843 char buf[50];
2844 snprintf(buf, sizeof(buf), "%d", value);
2845 return XmlWriteValue(buf, xmlio::Char);
2846}
2847
2848////////////////////////////////////////////////////////////////////////////////
2849/// Converts Short_t to string and add xml node to buffer
2850
2852{
2853 char buf[50];
2854 snprintf(buf, sizeof(buf), "%hd", value);
2855 return XmlWriteValue(buf, xmlio::Short);
2856}
2857
2858////////////////////////////////////////////////////////////////////////////////
2859/// Converts Int_t to string and add xml node to buffer
2860
2862{
2863 char buf[50];
2864 snprintf(buf, sizeof(buf), "%d", value);
2865 return XmlWriteValue(buf, xmlio::Int);
2866}
2867
2868////////////////////////////////////////////////////////////////////////////////
2869/// Converts Long_t to string and add xml node to buffer
2870
2872{
2873 char buf[50];
2874 snprintf(buf, sizeof(buf), "%ld", value);
2875 return XmlWriteValue(buf, xmlio::Long);
2876}
2877
2878////////////////////////////////////////////////////////////////////////////////
2879/// Converts Long64_t to string and add xml node to buffer
2880
2882{
2883 std::string buf = std::to_string(value);
2884 return XmlWriteValue(buf.c_str(), xmlio::Long64);
2885}
2886
2887////////////////////////////////////////////////////////////////////////////////
2888/// Converts Float_t to string and add xml node to buffer
2889
2891{
2892 char buf[200];
2893 ConvertFloat(value, buf, sizeof(buf), kTRUE);
2894 return XmlWriteValue(buf, xmlio::Float);
2895}
2896
2897////////////////////////////////////////////////////////////////////////////////
2898/// Converts Double_t to string and add xml node to buffer
2899
2901{
2902 char buf[1000];
2903 ConvertDouble(value, buf, sizeof(buf), kTRUE);
2904 return XmlWriteValue(buf, xmlio::Double);
2905}
2906
2907////////////////////////////////////////////////////////////////////////////////
2908/// Converts Bool_t to string and add xml node to buffer
2909
2911{
2913}
2914
2915////////////////////////////////////////////////////////////////////////////////
2916/// Converts UChar_t to string and add xml node to buffer
2917
2919{
2920 char buf[50];
2921 snprintf(buf, sizeof(buf), "%u", value);
2922 return XmlWriteValue(buf, xmlio::UChar);
2923}
2924
2925////////////////////////////////////////////////////////////////////////////////
2926/// Converts UShort_t to string and add xml node to buffer
2927
2929{
2930 char buf[50];
2931 snprintf(buf, sizeof(buf), "%hu", value);
2932 return XmlWriteValue(buf, xmlio::UShort);
2933}
2934
2935////////////////////////////////////////////////////////////////////////////////
2936/// Converts UInt_t to string and add xml node to buffer
2937
2939{
2940 char buf[50];
2941 snprintf(buf, sizeof(buf), "%u", value);
2942 return XmlWriteValue(buf, xmlio::UInt);
2943}
2944
2945////////////////////////////////////////////////////////////////////////////////
2946/// Converts ULong_t to string and add xml node to buffer
2947
2949{
2950 char buf[50];
2951 snprintf(buf, sizeof(buf), "%lu", value);
2952 return XmlWriteValue(buf, xmlio::ULong);
2953}
2954
2955////////////////////////////////////////////////////////////////////////////////
2956/// Converts ULong64_t to string and add xml node to buffer
2957
2959{
2960 std::string buf = std::to_string(value);
2961 return XmlWriteValue(buf.c_str(), xmlio::ULong64);
2962}
2963
2964////////////////////////////////////////////////////////////////////////////////
2965/// Create xml node with specified name and adds it to stack node
2966
2967XMLNodePointer_t TBufferXML::XmlWriteValue(const char *value, const char *name)
2968{
2969 XMLNodePointer_t node = nullptr;
2970
2971 if (fCanUseCompact)
2972 node = StackNode();
2973 else
2974 node = CreateItemNode(name);
2975
2976 fXML->NewAttr(node, nullptr, xmlio::v, value);
2977
2979
2980 return node;
2981}
2982
2983////////////////////////////////////////////////////////////////////////////////
2984/// Reads string from current xml node and convert it to Char_t value
2985
2987{
2988 const char *res = XmlReadValue(xmlio::Char);
2989 if (res) {
2990 int n;
2991 sscanf(res, "%d", &n);
2992 value = n;
2993 } else
2994 value = 0;
2995}
2996
2997////////////////////////////////////////////////////////////////////////////////
2998/// Reads string from current xml node and convert it to Short_t value
2999
3001{
3002 const char *res = XmlReadValue(xmlio::Short);
3003 if (res)
3004 sscanf(res, "%hd", &value);
3005 else
3006 value = 0;
3007}
3008
3009////////////////////////////////////////////////////////////////////////////////
3010/// Reads string from current xml node and convert it to Int_t value
3011
3013{
3014 const char *res = XmlReadValue(xmlio::Int);
3015 if (res)
3016 sscanf(res, "%d", &value);
3017 else
3018 value = 0;
3019}
3020
3021////////////////////////////////////////////////////////////////////////////////
3022/// Reads string from current xml node and convert it to Long_t value
3023
3025{
3026 const char *res = XmlReadValue(xmlio::Long);
3027 if (res)
3028 sscanf(res, "%ld", &value);
3029 else
3030 value = 0;
3031}
3032
3033////////////////////////////////////////////////////////////////////////////////
3034/// Reads string from current xml node and convert it to Long64_t value
3035
3037{
3038 const char *res = XmlReadValue(xmlio::Long64);
3039 if (res)
3040 value = (Long64_t)std::stoll(res);
3041 else
3042 value = 0;
3043}
3044
3045////////////////////////////////////////////////////////////////////////////////
3046/// Reads string from current xml node and convert it to Float_t value
3047
3049{
3050 const char *res = XmlReadValue(xmlio::Float);
3051 if (res)
3052 sscanf(res, "%f", &value);
3053 else
3054 value = 0.;
3055}
3056
3057////////////////////////////////////////////////////////////////////////////////
3058/// Reads string from current xml node and convert it to Double_t value
3059
3061{
3062 const char *res = XmlReadValue(xmlio::Double);
3063 if (res)
3064 sscanf(res, "%lf", &value);
3065 else
3066 value = 0.;
3067}
3068
3069////////////////////////////////////////////////////////////////////////////////
3070/// Reads string from current xml node and convert it to Bool_t value
3071
3073{
3074 const char *res = XmlReadValue(xmlio::Bool);
3075 if (res)
3076 value = (strcmp(res, xmlio::True) == 0);
3077 else
3078 value = kFALSE;
3079}
3080
3081////////////////////////////////////////////////////////////////////////////////
3082/// Reads string from current xml node and convert it to UChar_t value
3083
3085{
3086 const char *res = XmlReadValue(xmlio::UChar);
3087 if (res) {
3088 unsigned int n;
3089 sscanf(res, "%ud", &n);
3090 value = n;
3091 } else
3092 value = 0;
3093}
3094
3095////////////////////////////////////////////////////////////////////////////////
3096/// Reads string from current xml node and convert it to UShort_t value
3097
3099{
3100 const char *res = XmlReadValue(xmlio::UShort);
3101 if (res)
3102 sscanf(res, "%hud", &value);
3103 else
3104 value = 0;
3105}
3106
3107////////////////////////////////////////////////////////////////////////////////
3108/// Reads string from current xml node and convert it to UInt_t value
3109
3111{
3112 const char *res = XmlReadValue(xmlio::UInt);
3113 if (res)
3114 sscanf(res, "%u", &value);
3115 else
3116 value = 0;
3117}
3118
3119////////////////////////////////////////////////////////////////////////////////
3120/// Reads string from current xml node and convert it to ULong_t value
3121
3123{
3124 const char *res = XmlReadValue(xmlio::ULong);
3125 if (res)
3126 sscanf(res, "%lu", &value);
3127 else
3128 value = 0;
3129}
3130
3131////////////////////////////////////////////////////////////////////////////////
3132/// Reads string from current xml node and convert it to ULong64_t value
3133
3135{
3136 const char *res = XmlReadValue(xmlio::ULong64);
3137 if (res)
3138 value = (ULong64_t)std::stoull(res);
3139 else
3140 value = 0;
3141}
3142
3143////////////////////////////////////////////////////////////////////////////////
3144/// read string value from current stack node
3145
3146const char *TBufferXML::XmlReadValue(const char *name)
3147{
3148 if (fErrorFlag > 0)
3149 return 0;
3150
3151 Bool_t trysimple = fCanUseCompact;
3153
3154 if (trysimple) {
3155 if (fXML->HasAttr(Stack(1)->fNode, xmlio::v))
3156 fValueBuf = fXML->GetAttr(Stack(1)->fNode, xmlio::v);
3157 else
3158 trysimple = kFALSE;
3159 }
3160
3161 if (!trysimple) {
3162 if (!VerifyItemNode(name, "XmlReadValue"))
3163 return 0;
3165 }
3166
3167 if (gDebug > 4)
3168 Info("XmlReadValue", " Name = %s value = %s", name, fValueBuf.Data());
3169
3170 if (!trysimple)
3171 ShiftStack("readvalue");
3172
3173 return fValueBuf.Data();
3174}
3175
3176////////////////////////////////////////////////////////////////////////////////
3177/// Return current streamer info element
3178
3180{
3181 return Stack()->fInfo;
3182}
void Class()
Definition: Class.C:29
#define R__ALWAYS_INLINE
Definition: RConfig.hxx:570
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#define c(i)
Definition: RSha256.hxx:101
#define h(i)
Definition: RSha256.hxx:106
unsigned short UShort_t
Definition: RtypesCore.h:36
int Int_t
Definition: RtypesCore.h:41
short Version_t
Definition: RtypesCore.h:61
unsigned char UChar_t
Definition: RtypesCore.h:34
char Char_t
Definition: RtypesCore.h:29
unsigned int UInt_t
Definition: RtypesCore.h:42
const Bool_t kFALSE
Definition: RtypesCore.h:88
unsigned long ULong_t
Definition: RtypesCore.h:51
long Long_t
Definition: RtypesCore.h:50
bool Bool_t
Definition: RtypesCore.h:59
short Short_t
Definition: RtypesCore.h:35
double Double_t
Definition: RtypesCore.h:55
long long Long64_t
Definition: RtypesCore.h:69
unsigned long long ULong64_t
Definition: RtypesCore.h:70
float Float_t
Definition: RtypesCore.h:53
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
R__EXTERN Int_t gDebug
Definition: Rtypes.h:91
@ kIsAbstract
Definition: TDictionary.h:71
char name[80]
Definition: TGX11.cxx:109
#define gROOT
Definition: TROOT.h:414
void R__unzip(Int_t *nin, UChar_t *bufin, Int_t *lout, char *bufout, Int_t *nout)
int R__unzip_header(Int_t *nin, UChar_t *bufin, Int_t *lout)
void * XMLNodePointer_t
Definition: TXMLEngine.h:17
void * XMLNsPointer_t
Definition: TXMLEngine.h:18
#define snprintf
Definition: civetweb.c:1540
virtual void GetMappedObject(UInt_t tag, void *&ptr, TClass *&ClassPtr) const
Retrieve the object stored in the buffer's object map at 'tag' Set ptr and ClassPtr respectively to t...
Definition: TBufferIO.cxx:260
TExMap * fMap
Map containing object,offset pairs for reading/writing.
Definition: TBufferIO.h:39
virtual void MapObject(const TObject *obj, UInt_t offset=1)
Add object to the fMap container.
Definition: TBufferIO.cxx:163
virtual void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force)
force writing the TStreamerInfo to the file
Definition: TBufferIO.cxx:329
Long64_t GetObjectTag(const void *obj)
Returns tag for specified object from objects map (if exists) Returns 0 if object not included into o...
Definition: TBufferIO.cxx:277
static R__ALWAYS_INLINE ULong_t Void_Hash(const void *ptr)
Return hash value for provided object.
Definition: TBufferIO.h:53
virtual Int_t WriteObjectAny(const void *obj, const TClass *ptrClass, Bool_t cacheReuse=kTRUE)
Write object to I/O buffer.
Definition: TBufferIO.cxx:492
virtual void InitMap()
Create the fMap container and initialize them with the null object.
Definition: TBufferIO.cxx:129
Base class for text-based streamers like TBufferJSON or TBufferXML Special actions list will use meth...
Definition: TBufferText.h:21
static const char * ConvertFloat(Float_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
static const char * ConvertDouble(Double_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
Class for serializing/deserializing object to/from xml.
Definition: TBufferXML.h:36
Bool_t ProcessPointer(const void *ptr, XMLNodePointer_t node)
Add "ptr" attribute to node, if ptr is null or if ptr is pointer on object, which is already saved in...
Definition: TBufferXML.cxx:541
virtual void ReadDouble(Double_t &d)
Reads Double_t value from buffer.
virtual void ReadUChar(UChar_t &c)
Reads UChar_t value from buffer.
virtual Int_t ReadStaticArray(Bool_t *b)
Read array of Bool_t from buffer.
void SetXML(TXMLEngine *xml)
Definition: TBufferXML.h:234
virtual void WriteDouble(Double_t d)
Writes Double_t value to buffer.
Int_t GetCompressionSettings() const
Definition: TBufferXML.h:353
TXMLStackObj * PushStack(XMLNodePointer_t current, Bool_t simple=kFALSE)
Add new level to xml stack.
Definition: TBufferXML.cxx:314
Bool_t VerifyAttr(XMLNodePointer_t node, const char *name, const char *value, const char *errinfo=nullptr)
Checks, that attribute of specified name exists and has specified value.
Definition: TBufferXML.cxx:666
void WorkWithClass(TStreamerInfo *info, const TClass *cl=nullptr)
Prepares buffer to stream data of specified class.
Definition: TBufferXML.cxx:881
Bool_t VerifyStackNode(const char *name, const char *errinfo=nullptr)
Check, if stack node has specified name.
Definition: TBufferXML.cxx:658
Int_t GetCompressionAlgorithm() const
Definition: TBufferXML.h:341
virtual void WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse)
Write object to buffer. Only used from TBuffer.
Int_t fCompressLevel
! Compression level and algorithm
Definition: TBufferXML.h:334
virtual void ReadCharStar(char *&s)
Read a char* string.
TString fValueBuf
! Current value buffer
Definition: TBufferXML.h:330
Int_t GetCompressionLevel() const
Definition: TBufferXML.h:347
virtual void WriteULong64(ULong64_t l)
Writes ULong64_t value to buffer.
Bool_t VerifyNode(XMLNodePointer_t node, const char *name, const char *errinfo=nullptr)
Check if node has specified name.
Definition: TBufferXML.cxx:640
virtual void ReadChar(Char_t &c)
Reads Char_t value from buffer.
virtual void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type)
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and add/verify next elemen...
Definition: TBufferXML.cxx:979
TXMLEngine * fXML
! instance of TXMLEngine for working with XML structures
Definition: TBufferXML.h:327
virtual void ReadFastArray(Bool_t *b, Int_t n)
Read array of Bool_t from buffer.
static TString ConvertToXML(const TObject *obj, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Converts object, inherited from TObject class, to XML string GenericLayout defines layout choice for ...
Definition: TBufferXML.cxx:119
virtual void ClassEnd(const TClass *)
Should be called at the end of custom streamer See TBufferXML::ClassBegin for more details.
virtual Int_t ReadArray(Bool_t *&b)
Read array of Bool_t from buffer.
void SetIOVersion(Int_t v)
Definition: TBufferXML.h:69
virtual void WriteShort(Short_t s)
Writes Short_t value to buffer.
XMLNodePointer_t XmlWriteAny(const void *obj, const TClass *cl)
Convert object of any class to xml structures Return pointer on top xml element.
Definition: TBufferXML.cxx:242
void XmlReadBasic(Char_t &value)
Reads string from current xml node and convert it to Char_t value.
Int_t GetIOVersion() const
Definition: TBufferXML.h:68
R__ALWAYS_INLINE void XmlWriteArrayContent(const T *arr, Int_t arrsize)
XMLNodePointer_t XmlWriteValue(const char *value, const char *name)
Create xml node with specified name and adds it to stack node.
virtual void ReadFastArrayString(Char_t *c, Int_t n)
Read array of n characters from the I/O buffer.
std::deque< TXMLStackObj * > fStack
! Stack of processed objects
Definition: TBufferXML.h:328
virtual void ReadULong64(ULong64_t &l)
Reads ULong64_t value from buffer.
virtual void WriteLong(Long_t l)
Writes Long_t value to buffer.
Bool_t VerifyStackAttr(const char *name, const char *value, const char *errinfo=nullptr)
Checks stack attribute.
Definition: TBufferXML.cxx:685
virtual void WriteLong64(Long64_t l)
Writes Long64_t value to buffer.
virtual void WriteChar(Char_t c)
Writes Char_t value to buffer.
virtual void ReadShort(Short_t &s)
Reads Short_t value from buffer.
XMLNodePointer_t XmlWriteBasic(Char_t value)
Converts Char_t to string and add xml node to buffer.
void ShiftStack(const char *info=nullptr)
Shift stack node to next.
Definition: TBufferXML.cxx:350
virtual void ReadCharP(Char_t *c)
Reads array of characters from buffer.
void PerformPreProcessing(const TStreamerElement *elem, XMLNodePointer_t elemnode)
Function is unpack TObject and TString structures to be able read them from custom streamers of this ...
virtual void SkipObjectAny()
Skip any kind of object from buffer Actually skip only one node on current level of xml structure.
void BeforeIOoperation()
Function is called before any IO operation of TBuffer Now is used to store version value if no proper...
Int_t fErrorFlag
! Error flag
Definition: TBufferXML.h:331
virtual void ReadInt(Int_t &i)
Reads Int_t value from buffer.
R__ALWAYS_INLINE void XmlReadArrayContent(T *arr, Int_t arrsize)
Template method to read array content.
virtual void * ReadObjectAny(const TClass *clCast)
Read object from buffer. Only used from TBuffer.
virtual void ReadLong64(Long64_t &l)
Reads Long64_t value from buffer.
virtual void StreamObject(void *obj, const TClass *cl, const TClass *onFileClass=nullptr)
Stream object to/from buffer.
virtual void ReadLong(Long_t &l)
Reads Long_t value from buffer.
virtual void WriteULong(ULong_t l)
Writes ULong_t value to buffer.
Version_t fVersionBuf
! Current version buffer
Definition: TBufferXML.h:329
virtual void ReadTString(TString &s)
Reads a TString.
void XmlReadBlock(XMLNodePointer_t node)
Read binary block of data from xml.
Definition: TBufferXML.cxx:470
void * XmlReadObject(void *obj, TClass **cl=nullptr)
Read object from the buffer.
Definition: TBufferXML.cxx:806
Bool_t fCanUseCompact
! Flag indicate that basic type (like Int_t) can be placed in the same tag
Definition: TBufferXML.h:332
R__ALWAYS_INLINE void XmlWriteArray(const T *arr, Int_t arrsize)
Write array, including it size Content may be compressed.
virtual UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE)
Copies class version to buffer, but not writes it to xml Version will be written with next I/O operat...
virtual void WriteBool(Bool_t b)
Writes Bool_t value to buffer.
virtual TClass * ReadClass(const TClass *cl=nullptr, UInt_t *objTag=nullptr)
Function to read class from buffer, used in old-style streamers.
virtual void WriteCharStar(char *s)
Write a char* string.
const char * XmlReadValue(const char *name)
read string value from current stack node
Bool_t ExtractPointer(XMLNodePointer_t node, void *&ptr, TClass *&cl)
Searches for "ptr" attribute and returns pointer to object and class, if "ptr" attribute reference to...
Definition: TBufferXML.cxx:578
virtual void WriteStdString(const std::string *s)
Writes a std::string.
virtual void ReadUShort(UShort_t &s)
Reads UShort_t value from buffer.
R__ALWAYS_INLINE void XmlWriteFastArray(const T *arr, Int_t n)
Write array without size attribute Also treat situation, when instead of one single array chain of se...
virtual void ReadUInt(UInt_t &i)
Reads UInt_t value from buffer.
virtual void WriteFastArray(const Bool_t *b, Int_t n)
Write array of Bool_t to buffer.
void PerformPostProcessing()
Function is converts TObject and TString structures to more compact representation.
static TObject * ConvertFromXML(const char *str, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object from XML, produced by ConvertToXML() method.
Definition: TBufferXML.cxx:168
virtual void DecrementLevel(TVirtualStreamerInfo *)
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and decrease level in xml ...
Definition: TBufferXML.cxx:947
void * XmlReadAny(XMLNodePointer_t node, void *obj, TClass **cl)
Recreate object from xml structure.
Definition: TBufferXML.cxx:259
virtual void ClassMember(const char *name, const char *typeName=nullptr, Int_t arrsize1=-1, Int_t arrsize2=-1)
Method indicates name and typename of class member, which should be now streamed in custom streamer.
XMLNodePointer_t StackNode()
Return pointer on current xml node.
Definition: TBufferXML.cxx:341
R__ALWAYS_INLINE void XmlReadFastArray(T *arr, Int_t n)
Template method to read content of array, which not include size of array Also treated situation,...
Bool_t VerifyItemNode(const char *name, const char *errinfo=nullptr)
Checks, if stack node is item and has specified name.
Definition: TBufferXML.cxx:707
static void * ConvertFromXMLChecked(const char *xml, const TClass *expectedClass, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Convert from XML and check if object derived from specified class When possible, cast to given class.
Definition: TBufferXML.cxx:215
TBufferXML()
Default constructor.
Definition: TBufferXML.cxx:58
virtual void WriteCharP(const Char_t *c)
Writes array of characters to buffer.
virtual void ReadULong(ULong_t &l)
Reads ULong_t value from buffer.
virtual void ClassBegin(const TClass *, Version_t=-1)
Should be called at the beginning of custom class streamer.
virtual void WriteTString(const TString &s)
Writes a TString.
virtual void ReadBool(Bool_t &b)
Reads Bool_t value from buffer.
virtual void WriteInt(Int_t i)
Writes Int_t value to buffer.
virtual Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr)
Read version value from buffer.
void ExtractReference(XMLNodePointer_t node, const void *ptr, const TClass *cl)
Analyze if node has "ref" attribute and register it to object map.
Definition: TBufferXML.cxx:614
void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseGeneralPurpose)
Used to specify the compression level and algorithm.
Definition: TBufferXML.cxx:400
virtual void WriteFloat(Float_t f)
Writes Float_t value to buffer.
void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Definition: TBufferXML.cxx:378
virtual void WriteArray(const Bool_t *b, Int_t n)
Write array of Bool_t to buffer.
void SetCompressionAlgorithm(Int_t algorithm=ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
See comments for function SetCompressionSettings.
Definition: TBufferXML.cxx:363
virtual void WriteFastArrayString(const Char_t *c, Int_t n)
Write array of n characters into the I/O buffer.
virtual void WriteUChar(UChar_t c)
Writes UChar_t value to buffer.
void CheckVersionBuf()
Checks buffer, filled by WriteVersion if next data is arriving, version should be stored in buffer.
XMLNodePointer_t XmlWriteObject(const void *obj, const TClass *objClass, Bool_t cacheReuse)
Write object to buffer If object was written before, only pointer will be stored Return pointer to to...
Definition: TBufferXML.cxx:774
TXMLFile * XmlFile()
Returns pointer to TXMLFile object.
Definition: TBufferXML.cxx:108
void WorkWithElement(TStreamerElement *elem, Int_t comp_type)
This function is a part of SetStreamerElementNumber method.
Definition: TBufferXML.cxx:990
virtual void IncrementLevel(TVirtualStreamerInfo *)
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and indent new level in xm...
Definition: TBufferXML.cxx:873
virtual ~TBufferXML()
Destroy xml buffer.
Definition: TBufferXML.cxx:98
virtual void WriteUShort(UShort_t s)
Writes UShort_t value to buffer.
virtual TVirtualStreamerInfo * GetInfo()
Return current streamer info element.
void XmlWriteBlock(XMLNodePointer_t node)
Write binary data block from buffer to xml.
Definition: TBufferXML.cxx:409
TClass * fExpectedBaseClass
! Pointer to class, which should be stored as parent of current
Definition: TBufferXML.h:333
TXMLStackObj * Stack(UInt_t depth=0)
Definition: TBufferXML.h:247
virtual void WriteUInt(UInt_t i)
Writes UInt_t value to buffer.
XMLNodePointer_t CreateItemNode(const char *name)
Create item node of specified name.
Definition: TBufferXML.cxx:693
virtual void ReadFloat(Float_t &f)
Reads Float_t value from buffer.
TXMLStackObj * PopStack()
Remove one level from xml stack.
Definition: TBufferXML.cxx:329
void CreateElemNode(const TStreamerElement *elem)
Create xml node correspondent to TStreamerElement object.
Definition: TBufferXML.cxx:720
static void * ConvertFromXMLAny(const char *str, TClass **cl=nullptr, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object of any class from XML, produced by ConvertToXML() method.
Definition: TBufferXML.cxx:191
Bool_t VerifyElemNode(const TStreamerElement *elem)
Checks if stack node correspond to TStreamerElement object.
Definition: TBufferXML.cxx:748
R__ALWAYS_INLINE Int_t XmlReadArray(T *&arr, bool is_static=false)
Template method to read array with size attribute If necessary, array is created.
virtual void ReadStdString(std::string *s)
Reads a std::string.
virtual void WriteClass(const TClass *cl)
Function to write class into buffer, used in old-style streamers.
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition: TBuffer.cxx:262
void Expand(Int_t newsize, Bool_t copy=kTRUE)
Expand (or shrink) the I/O buffer to newsize bytes.
Definition: TBuffer.cxx:223
Int_t BufferSize() const
Definition: TBuffer.h:97
@ kWrite
Definition: TBuffer.h:72
@ kRead
Definition: TBuffer.h:72
Bool_t IsWriting() const
Definition: TBuffer.h:86
Bool_t IsReading() const
Definition: TBuffer.h:85
Int_t Length() const
Definition: TBuffer.h:99
char * Buffer() const
Definition: TBuffer.h:95
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4841
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:5198
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5483
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5717
Int_t GetBaseClassOffset(const TClass *toBase, void *address=0, bool isDerivedObject=true)
Definition: TClass.cxx:2718
Long_t Property() const
Set TObject::fBits and fStreamerType to cache information about the class.
Definition: TClass.cxx:5817
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=0) const
Definition: TClass.h:568
Version_t GetClassVersion() const
Definition: TClass.h:391
static TClass * GetClass(const char *name, Bool_t load=kTRUE, Bool_t silent=kFALSE)
Static method returning pointer to TClass of the specified class name.
Definition: TClass.cxx:2895
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
void Add(ULong64_t hash, Long64_t key, Long64_t value)
Add an (key,value) pair to the table. The key should be unique.
Definition: TExMap.cxx:87
virtual void SetOnFileClass(const TClass *cl)
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Int_t IndexOf(const TObject *obj) const
Definition: TObjArray.cxx:604
Mother of all ROOT objects.
Definition: TObject.h:37
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:880
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:854
Int_t GetType() const
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
virtual void SetArrayDim(Int_t dim)
Set number of array dimensions.
virtual void SetMaxIndex(Int_t dim, Int_t max)
set maximum index for array with dimension dim
Describe Streamer information for one class version.
Definition: TStreamerInfo.h:43
TObjArray * GetElements() const
TClass * GetClass() const
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1921
const char * Data() const
Definition: TString.h:364
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1095
Abstract Interface class describing Streamer information for one class.
static Bool_t CanDelete()
static function returning true if ReadBuffer can delete object
virtual TClass * GetClass() const =0
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xmlnode
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:580
XMLNsPointer_t NewNS(XMLNodePointer_t xmlnode, const char *reference, const char *name=0)
create namespace attribute for xmlnode.
Definition: TXMLEngine.cxx:735
void SaveSingleNode(XMLNodePointer_t xmlnode, TString *res, Int_t layout=1)
convert single xmlnode (and its child node) to string if layout<=0, no any spaces or newlines will be...
XMLNodePointer_t NewChild(XMLNodePointer_t parent, XMLNsPointer_t ns, const char *name, const char *content=0)
create new child element for parent node
Definition: TXMLEngine.cxx:709
XMLAttrPointer_t NewIntAttr(XMLNodePointer_t xmlnode, const char *name, Int_t value)
create node attribute with integer value
Definition: TXMLEngine.cxx:606
Bool_t HasAttr(XMLNodePointer_t xmlnode, const char *name)
checks if node has attribute of specified name
Definition: TXMLEngine.cxx:533
XMLNodePointer_t ReadSingleNode(const char *src)
read single xmlnode from provided string
const char * GetNodeContent(XMLNodePointer_t xmlnode)
get contents (if any) of xmlnode
const char * GetNodeName(XMLNodePointer_t xmlnode)
returns name of xmlnode
void FreeAttr(XMLNodePointer_t xmlnode, const char *name)
remove attribute from xmlnode
Definition: TXMLEngine.cxx:616
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
returns value of attribute for xmlnode
Definition: TXMLEngine.cxx:549
Int_t GetIntAttr(XMLNodePointer_t node, const char *name)
returns value of attribute as integer
Definition: TXMLEngine.cxx:565
void UnlinkFreeNode(XMLNodePointer_t xmlnode)
combined operation. Unlink node and free used memory
void FreeNode(XMLNodePointer_t xmlnode)
release all memory, allocated from this node and destroys node itself
void SkipEmpty(XMLNodePointer_t &xmlnode)
Skip all current empty nodes and locate on first "true" node.
void ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode=kTRUE)
shifts specified node to next if realnode==kTRUE, any special nodes in between will be skipped
TClass * XmlDefineClass(const char *xmlClassName)
define class for the converted class name, where special symbols were replaced by '_'
Definition: TXMLSetup.cxx:268
const char * XmlClassNameSpaceRef(const TClass *cl)
produce string which used as reference in class namespace definition
Definition: TXMLSetup.cxx:228
EXMLLayout GetXmlLayout() const
Definition: TXMLSetup.h:95
virtual void SetUseNamespaces(Bool_t iUseNamespaces=kTRUE)
Definition: TXMLSetup.h:103
const char * XmlConvertClassName(const char *name)
convert class name to exclude any special symbols like ':', '<' '>' ',' and spaces
Definition: TXMLSetup.cxx:214
Int_t AtoI(const char *sbuf, Int_t def=0, const char *errinfo=0)
converts string to integer.
Definition: TXMLSetup.cxx:287
const char * XmlGetElementName(const TStreamerElement *el)
return converted name for TStreamerElement
Definition: TXMLSetup.cxx:241
Int_t GetNextRefCounter()
Definition: TXMLSetup.h:109
Bool_t IsUseNamespaces() const
Definition: TXMLSetup.h:98
@ kSpecialized
Definition: TXMLSetup.h:84
@ kGeneralized
Definition: TXMLSetup.h:84
virtual void SetXmlLayout(EXMLLayout layout)
Definition: TXMLSetup.h:100
const Int_t n
Definition: legend1.C:16
double T(double x)
Definition: ChebyshevPol.h:34
static constexpr double s
static constexpr double ns
Definition: file.py:1
const char * UChar
Definition: TXMLSetup.cxx:88
const char * Ptr
Definition: TXMLSetup.cxx:51
const char * Name
Definition: TXMLSetup.cxx:66
const char * v
Definition: TXMLSetup.cxx:73
const char * Bool
Definition: TXMLSetup.cxx:80
const char * Long64
Definition: TXMLSetup.cxx:85
const char * False
Definition: TXMLSetup.cxx:76
const char * True
Definition: TXMLSetup.cxx:75
const char * Int
Definition: TXMLSetup.cxx:83
const char * ULong64
Definition: TXMLSetup.cxx:92
const char * Member
Definition: TXMLSetup.cxx:64
const char * OnlyVersion
Definition: TXMLSetup.cxx:50
const char * Long
Definition: TXMLSetup.cxx:84
const char * Float
Definition: TXMLSetup.cxx:86
const char * Array
Definition: TXMLSetup.cxx:79
const char * ClassVersion
Definition: TXMLSetup.cxx:48
const char * String
Definition: TXMLSetup.cxx:93
const char * Double
Definition: TXMLSetup.cxx:87
const char * Object
Definition: TXMLSetup.cxx:61
const char * Ref
Definition: TXMLSetup.cxx:52
const char * cnt
Definition: TXMLSetup.cxx:74
const char * IdBase
Definition: TXMLSetup.cxx:54
const char * Size
Definition: TXMLSetup.cxx:55
const char * XmlBlock
Definition: TXMLSetup.cxx:59
const char * Null
Definition: TXMLSetup.cxx:53
const char * Char
Definition: TXMLSetup.cxx:81
const char * UShort
Definition: TXMLSetup.cxx:89
const char * CharStar
Definition: TXMLSetup.cxx:94
const char * UInt
Definition: TXMLSetup.cxx:90
const char * ULong
Definition: TXMLSetup.cxx:91
const char * Class
Definition: TXMLSetup.cxx:63
const char * ObjClass
Definition: TXMLSetup.cxx:62
const char * Short
Definition: TXMLSetup.cxx:82
const char * Zip
Definition: TXMLSetup.cxx:60
const char * Item
Definition: TXMLSetup.cxx:65
EValues
Note: this is only temporarily a struct and will become a enum class hence the name.
Definition: Compression.h:76
@ kUndefined
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added).
Definition: Compression.h:91
auto * l
Definition: textangle.C:4