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