Logo ROOT  
Reference Guide
TBufferXML.cxx
Go to the documentation of this file.
1// @(#)root/:$Id: 5400e36954e1dc109fcfc306242c30234beb7312 $
2// Author: Sergey Linev, Rene Brun 10.05.2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\class TBufferXML
14\ingroup IO
15
16Class for serializing/deserializing object to/from xml.
17
18The simple way to create XML representation is:
19~~~{.cpp}
20 TNamed *obj = new TNamed("name", "title");
21 TString xml = TBufferXML::ToXML(obj);
22~~~
23Produced xml can be decoded into new object:
24~~~{.cpp}
25 TNamed *obj2 = nullptr;
26 TBufferXML::FromXML(obj2, xml);
27~~~
28
29TBufferXML class uses streaming mechanism, provided by ROOT system,
30therefore most of ROOT and user classes can be stored to xml.
31There are limitations for complex objects like TTree, which can not be converted to xml.
32*/
33
34#include "TBufferXML.h"
35
36#include "Compression.h"
37#include "TXMLFile.h"
38#include "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
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
2159template <typename T>
2161{
2163 if (n <= 0)
2164 return;
2166 PushStack(arrnode);
2167 XmlWriteArrayContent(arr, n);
2168 PopStack();
2169}
2170
2171////////////////////////////////////////////////////////////////////////////////
2172/// Write array of Bool_t to buffer
2173
2175{
2177}
2178
2179////////////////////////////////////////////////////////////////////////////////
2180/// Write array of Char_t to buffer
2181/// If array does not include any special characters,
2182/// it will be reproduced as CharStar node with string as attribute
2183
2185{
2186 Bool_t usedefault = (n == 0);
2187 const Char_t *buf = c;
2188 if (!usedefault)
2189 for (int i = 0; i < n; i++) {
2190 if (*buf < 27) {
2191 usedefault = kTRUE;
2192 break;
2193 }
2194 buf++;
2195 }
2196 if (usedefault) {
2198 } else {
2199 Char_t *buf2 = new Char_t[n + 1];
2200 memcpy(buf2, c, n);
2201 buf2[n] = 0;
2203 delete[] buf2;
2204 }
2205}
2206
2207////////////////////////////////////////////////////////////////////////////////
2208/// Write array of UChar_t to buffer
2209
2211{
2213}
2214
2215////////////////////////////////////////////////////////////////////////////////
2216/// Write array of Short_t to buffer
2217
2219{
2221}
2222
2223////////////////////////////////////////////////////////////////////////////////
2224/// Write array of UShort_t to buffer
2225
2227{
2229}
2230
2231////////////////////////////////////////////////////////////////////////////////
2232/// Write array of Int_t to buffer
2233
2235{
2236 XmlWriteFastArray(i, n);
2237}
2238
2239////////////////////////////////////////////////////////////////////////////////
2240/// Write array of UInt_t to buffer
2241
2243{
2244 XmlWriteFastArray(i, n);
2245}
2246
2247////////////////////////////////////////////////////////////////////////////////
2248/// Write array of Long_t to buffer
2249
2251{
2253}
2254
2255////////////////////////////////////////////////////////////////////////////////
2256/// Write array of ULong_t to buffer
2257
2259{
2261}
2262
2263////////////////////////////////////////////////////////////////////////////////
2264/// Write array of Long64_t to buffer
2265
2267{
2269}
2270
2271////////////////////////////////////////////////////////////////////////////////
2272/// Write array of ULong64_t to buffer
2273
2275{
2277}
2278
2279////////////////////////////////////////////////////////////////////////////////
2280/// Write array of Float_t to buffer
2281
2283{
2285}
2286
2287////////////////////////////////////////////////////////////////////////////////
2288/// Write array of Double_t to buffer
2289
2291{
2293}
2294
2295////////////////////////////////////////////////////////////////////////////////
2296/// Write array of n characters into the I/O buffer.
2297/// Used only by TLeafC, just dummy implementation here
2298
2300{
2301 WriteFastArray(c, n);
2302}
2303
2304////////////////////////////////////////////////////////////////////////////////
2305/// Write an array of object starting at the address 'start' and of length 'n'
2306/// the objects in the array are assumed to be of class 'cl'
2307
2308void TBufferXML::WriteFastArray(void *start, const TClass *cl, Int_t n, TMemberStreamer *streamer)
2309{
2310 if (streamer) {
2311 (*streamer)(*this, start, 0);
2312 return;
2313 }
2314
2315 char *obj = (char *)start;
2316 if (!n)
2317 n = 1;
2318 int size = cl->Size();
2319
2320 for (Int_t j = 0; j < n; j++, obj += size) {
2321 ((TClass *)cl)->Streamer(obj, *this);
2322 }
2323}
2324
2325////////////////////////////////////////////////////////////////////////////////
2326/// Write an array of object starting at the address '*start' and of length 'n'
2327/// the objects in the array are of class 'cl'
2328/// 'isPreAlloc' indicates whether the data member is marked with '->'
2329/// Return:
2330/// - 0: success
2331/// - 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
2332
2333Int_t TBufferXML::WriteFastArray(void **start, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer)
2334{
2335 // if isPreAlloc is true (data member has a ->) we can assume that the pointer
2336 // is never 0.
2337
2338 Bool_t oldStyle = kFALSE; // flag used to reproduce old-style I/O actions for kSTLp
2339
2340 if ((GetIOVersion() < 4) && !isPreAlloc) {
2341 TStreamerElement *elem = Stack()->fElem;
2342 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
2344 oldStyle = kTRUE;
2345 }
2346
2347 if (streamer) {
2348 (*streamer)(*this, (void *)start, oldStyle ? n : 0);
2349 return 0;
2350 }
2351
2352 int strInfo = 0;
2353
2354 Int_t res = 0;
2355
2356 if (!isPreAlloc) {
2357
2358 for (Int_t j = 0; j < n; j++) {
2359 // must write StreamerInfo if pointer is null
2360 if (!strInfo && !start[j] && !oldStyle) {
2361 if (cl->Property() & kIsAbstract) {
2362 // Do not try to generate the StreamerInfo for an abstract class
2363 } else {
2364 TStreamerInfo *info = (TStreamerInfo *)((TClass *)cl)->GetStreamerInfo();
2365 ForceWriteInfo(info, kFALSE);
2366 }
2367 }
2368 strInfo = 2003;
2369 if (oldStyle)
2370 ((TClass *)cl)->Streamer(start[j], *this);
2371 else
2372 res |= WriteObjectAny(start[j], cl);
2373 }
2374
2375 } else {
2376 // case //-> in comment
2377
2378 for (Int_t j = 0; j < n; j++) {
2379 if (!start[j])
2380 start[j] = ((TClass *)cl)->New();
2381 ((TClass *)cl)->Streamer(start[j], *this);
2382 }
2383 }
2384 return res;
2385}
2386
2387////////////////////////////////////////////////////////////////////////////////
2388/// Stream object to/from buffer
2389
2390void TBufferXML::StreamObject(void *obj, const TClass *cl, const TClass * /* onfileClass */)
2391{
2392 if (GetIOVersion() < 4) {
2393 TStreamerElement *elem = Stack()->fElem;
2394 if (elem && (elem->GetType() == TStreamerInfo::kTObject)) {
2395 ((TObject *)obj)->TObject::Streamer(*this);
2396 return;
2397 } else if (elem && (elem->GetType() == TStreamerInfo::kTNamed)) {
2398 ((TNamed *)obj)->TNamed::Streamer(*this);
2399 return;
2400 }
2401 }
2402
2404 if (gDebug > 1)
2405 Info("StreamObject", "Class: %s", (cl ? cl->GetName() : "none"));
2406 if (IsReading())
2407 XmlReadObject(obj);
2408 else
2409 XmlWriteObject(obj, cl, kTRUE);
2410}
2411
2412////////////////////////////////////////////////////////////////////////////////
2413/// Reads Bool_t value from buffer
2414
2416{
2418 XmlReadBasic(b);
2419}
2420
2421////////////////////////////////////////////////////////////////////////////////
2422/// Reads Char_t value from buffer
2423
2425{
2427 XmlReadBasic(c);
2428}
2429
2430////////////////////////////////////////////////////////////////////////////////
2431/// Reads UChar_t value from buffer
2432
2434{
2436 XmlReadBasic(c);
2437}
2438
2439////////////////////////////////////////////////////////////////////////////////
2440/// Reads Short_t value from buffer
2441
2443{
2445 XmlReadBasic(h);
2446}
2447
2448////////////////////////////////////////////////////////////////////////////////
2449/// Reads UShort_t value from buffer
2450
2452{
2454 XmlReadBasic(h);
2455}
2456
2457////////////////////////////////////////////////////////////////////////////////
2458/// Reads Int_t value from buffer
2459
2461{
2463 XmlReadBasic(i);
2464}
2465
2466////////////////////////////////////////////////////////////////////////////////
2467/// Reads UInt_t value from buffer
2468
2470{
2472 XmlReadBasic(i);
2473}
2474
2475////////////////////////////////////////////////////////////////////////////////
2476/// Reads Long_t value from buffer
2477
2479{
2481 XmlReadBasic(l);
2482}
2483
2484////////////////////////////////////////////////////////////////////////////////
2485/// Reads ULong_t value from buffer
2486
2488{
2490 XmlReadBasic(l);
2491}
2492
2493////////////////////////////////////////////////////////////////////////////////
2494/// Reads Long64_t value from buffer
2495
2497{
2499 XmlReadBasic(l);
2500}
2501
2502////////////////////////////////////////////////////////////////////////////////
2503/// Reads ULong64_t value from buffer
2504
2506{
2508 XmlReadBasic(l);
2509}
2510
2511////////////////////////////////////////////////////////////////////////////////
2512/// Reads Float_t value from buffer
2513
2515{
2517 XmlReadBasic(f);
2518}
2519
2520////////////////////////////////////////////////////////////////////////////////
2521/// Reads Double_t value from buffer
2522
2524{
2526 XmlReadBasic(d);
2527}
2528
2529////////////////////////////////////////////////////////////////////////////////
2530/// Reads array of characters from buffer
2531
2533{
2535 const char *buf;
2536 if ((buf = XmlReadValue(xmlio::CharStar)))
2537 strcpy(c, buf); // NOLINT unfortunately, size of target buffer cannot be controlled here
2538}
2539
2540////////////////////////////////////////////////////////////////////////////////
2541/// Reads a TString
2542
2544{
2545 if (GetIOVersion() < 3) {
2546 // original TBufferFile method can not be used, while used TString methods are private
2547 // try to reimplement close to the original
2548 Int_t nbig;
2549 UChar_t nwh;
2550 *this >> nwh;
2551 if (nwh == 0) {
2552 s.Resize(0);
2553 } else {
2554 if (nwh == 255)
2555 *this >> nbig;
2556 else
2557 nbig = nwh;
2558
2559 char *data = new char[nbig+1];
2560 data[nbig] = 0;
2561 ReadFastArray(data, nbig);
2562 s = data;
2563 delete[] data;
2564 }
2565 } else {
2567 const char *buf = XmlReadValue(xmlio::String);
2568 if (buf)
2569 s = buf;
2570 }
2571}
2572
2573////////////////////////////////////////////////////////////////////////////////
2574/// Reads a std::string
2575
2576void TBufferXML::ReadStdString(std::string *obj)
2577{
2578 if (GetIOVersion() < 3) {
2579 if (!obj) {
2580 Error("ReadStdString", "The std::string address is nullptr but should not");
2581 return;
2582 }
2583 Int_t nbig;
2584 UChar_t nwh;
2585 *this >> nwh;
2586 if (nwh == 0) {
2587 obj->clear();
2588 } else {
2589 if (obj->size()) {
2590 // Insure that the underlying data storage is not shared
2591 (*obj)[0] = '\0';
2592 }
2593 if (nwh == 255) {
2594 *this >> nbig;
2595 obj->resize(nbig, '\0');
2596 ReadFastArray((char *)obj->data(), nbig);
2597 } else {
2598 obj->resize(nwh, '\0');
2599 ReadFastArray((char *)obj->data(), nwh);
2600 }
2601 }
2602 } else {
2604 const char *buf = XmlReadValue(xmlio::String);
2605 if (buf && obj)
2606 *obj = buf;
2607 }
2608}
2609
2610////////////////////////////////////////////////////////////////////////////////
2611/// Read a char* string
2612
2614{
2615 delete[] s;
2616 s = nullptr;
2617
2618 Int_t nch;
2619 *this >> nch;
2620 if (nch > 0) {
2621 s = new char[nch + 1];
2622 ReadFastArray(s, nch);
2623 s[nch] = 0;
2624 }
2625}
2626
2627////////////////////////////////////////////////////////////////////////////////
2628/// Writes Bool_t value to buffer
2629
2631{
2634}
2635
2636////////////////////////////////////////////////////////////////////////////////
2637/// Writes Char_t value to buffer
2638
2640{
2643}
2644
2645////////////////////////////////////////////////////////////////////////////////
2646/// Writes UChar_t value to buffer
2647
2649{
2652}
2653
2654////////////////////////////////////////////////////////////////////////////////
2655/// Writes Short_t value to buffer
2656
2658{
2661}
2662
2663////////////////////////////////////////////////////////////////////////////////
2664/// Writes UShort_t value to buffer
2665
2667{
2670}
2671
2672////////////////////////////////////////////////////////////////////////////////
2673/// Writes Int_t value to buffer
2674
2676{
2678 XmlWriteBasic(i);
2679}
2680
2681////////////////////////////////////////////////////////////////////////////////
2682/// Writes UInt_t value to buffer
2683
2685{
2687 XmlWriteBasic(i);
2688}
2689
2690////////////////////////////////////////////////////////////////////////////////
2691/// Writes Long_t value to buffer
2692
2694{
2697}
2698
2699////////////////////////////////////////////////////////////////////////////////
2700/// Writes ULong_t value to buffer
2701
2703{
2706}
2707
2708////////////////////////////////////////////////////////////////////////////////
2709/// Writes Long64_t value to buffer
2710
2712{
2715}
2716
2717////////////////////////////////////////////////////////////////////////////////
2718/// Writes ULong64_t value to buffer
2719
2721{
2724}
2725
2726////////////////////////////////////////////////////////////////////////////////
2727/// Writes Float_t value to buffer
2728
2730{
2733}
2734
2735////////////////////////////////////////////////////////////////////////////////
2736/// Writes Double_t value to buffer
2737
2739{
2742}
2743
2744////////////////////////////////////////////////////////////////////////////////
2745/// Writes array of characters to buffer
2746
2748{
2751}
2752
2753////////////////////////////////////////////////////////////////////////////////
2754/// Writes a TString
2755
2757{
2758 if (GetIOVersion() < 3) {
2759 // original TBufferFile method, keep for compatibility
2760 Int_t nbig = s.Length();
2761 UChar_t nwh;
2762 if (nbig > 254) {
2763 nwh = 255;
2764 *this << nwh;
2765 *this << nbig;
2766 } else {
2767 nwh = UChar_t(nbig);
2768 *this << nwh;
2769 }
2770 const char *data = s.Data();
2771 WriteFastArray(data, nbig);
2772 } else {
2774 XmlWriteValue(s.Data(), xmlio::String);
2775 }
2776}
2777
2778////////////////////////////////////////////////////////////////////////////////
2779/// Writes a std::string
2780
2781void TBufferXML::WriteStdString(const std::string *obj)
2782{
2783 if (GetIOVersion() < 3) {
2784 if (!obj) {
2785 *this << (UChar_t)0;
2786 WriteFastArray("", 0);
2787 return;
2788 }
2789
2790 UChar_t nwh;
2791 Int_t nbig = obj->length();
2792 if (nbig > 254) {
2793 nwh = 255;
2794 *this << nwh;
2795 *this << nbig;
2796 } else {
2797 nwh = UChar_t(nbig);
2798 *this << nwh;
2799 }
2800 WriteFastArray(obj->data(), nbig);
2801 } else {
2803 XmlWriteValue(obj ? obj->c_str() : "", xmlio::String);
2804 }
2805}
2806
2807////////////////////////////////////////////////////////////////////////////////
2808/// Write a char* string
2809
2811{
2812 Int_t nch = 0;
2813 if (s) {
2814 nch = strlen(s);
2815 *this << nch;
2816 WriteFastArray(s, nch);
2817 } else {
2818 *this << nch;
2819 }
2820}
2821
2822////////////////////////////////////////////////////////////////////////////////
2823/// Converts Char_t to string and add xml node to buffer
2824
2826{
2827 char buf[50];
2828 snprintf(buf, sizeof(buf), "%d", value);
2829 return XmlWriteValue(buf, xmlio::Char);
2830}
2831
2832////////////////////////////////////////////////////////////////////////////////
2833/// Converts Short_t to string and add xml node to buffer
2834
2836{
2837 char buf[50];
2838 snprintf(buf, sizeof(buf), "%hd", value);
2839 return XmlWriteValue(buf, xmlio::Short);
2840}
2841
2842////////////////////////////////////////////////////////////////////////////////
2843/// Converts Int_t to string and add xml node to buffer
2844
2846{
2847 char buf[50];
2848 snprintf(buf, sizeof(buf), "%d", value);
2849 return XmlWriteValue(buf, xmlio::Int);
2850}
2851
2852////////////////////////////////////////////////////////////////////////////////
2853/// Converts Long_t to string and add xml node to buffer
2854
2856{
2857 char buf[50];
2858 snprintf(buf, sizeof(buf), "%ld", value);
2859 return XmlWriteValue(buf, xmlio::Long);
2860}
2861
2862////////////////////////////////////////////////////////////////////////////////
2863/// Converts Long64_t to string and add xml node to buffer
2864
2866{
2867 std::string buf = std::to_string(value);
2868 return XmlWriteValue(buf.c_str(), xmlio::Long64);
2869}
2870
2871////////////////////////////////////////////////////////////////////////////////
2872/// Converts Float_t to string and add xml node to buffer
2873
2875{
2876 char buf[200];
2877 ConvertFloat(value, buf, sizeof(buf), kTRUE);
2878 return XmlWriteValue(buf, xmlio::Float);
2879}
2880
2881////////////////////////////////////////////////////////////////////////////////
2882/// Converts Double_t to string and add xml node to buffer
2883
2885{
2886 char buf[1000];
2887 ConvertDouble(value, buf, sizeof(buf), kTRUE);
2888 return XmlWriteValue(buf, xmlio::Double);
2889}
2890
2891////////////////////////////////////////////////////////////////////////////////
2892/// Converts Bool_t to string and add xml node to buffer
2893
2895{
2897}
2898
2899////////////////////////////////////////////////////////////////////////////////
2900/// Converts UChar_t to string and add xml node to buffer
2901
2903{
2904 char buf[50];
2905 snprintf(buf, sizeof(buf), "%u", value);
2906 return XmlWriteValue(buf, xmlio::UChar);
2907}
2908
2909////////////////////////////////////////////////////////////////////////////////
2910/// Converts UShort_t to string and add xml node to buffer
2911
2913{
2914 char buf[50];
2915 snprintf(buf, sizeof(buf), "%hu", value);
2916 return XmlWriteValue(buf, xmlio::UShort);
2917}
2918
2919////////////////////////////////////////////////////////////////////////////////
2920/// Converts UInt_t to string and add xml node to buffer
2921
2923{
2924 char buf[50];
2925 snprintf(buf, sizeof(buf), "%u", value);
2926 return XmlWriteValue(buf, xmlio::UInt);
2927}
2928
2929////////////////////////////////////////////////////////////////////////////////
2930/// Converts ULong_t to string and add xml node to buffer
2931
2933{
2934 char buf[50];
2935 snprintf(buf, sizeof(buf), "%lu", value);
2936 return XmlWriteValue(buf, xmlio::ULong);
2937}
2938
2939////////////////////////////////////////////////////////////////////////////////
2940/// Converts ULong64_t to string and add xml node to buffer
2941
2943{
2944 std::string buf = std::to_string(value);
2945 return XmlWriteValue(buf.c_str(), xmlio::ULong64);
2946}
2947
2948////////////////////////////////////////////////////////////////////////////////
2949/// Create xml node with specified name and adds it to stack node
2950
2952{
2953 XMLNodePointer_t node = nullptr;
2954
2955 if (fCanUseCompact)
2956 node = StackNode();
2957 else
2958 node = CreateItemNode(name);
2959
2960 fXML->NewAttr(node, nullptr, xmlio::v, value);
2961
2963
2964 return node;
2965}
2966
2967////////////////////////////////////////////////////////////////////////////////
2968/// Reads string from current xml node and convert it to Char_t value
2969
2971{
2972 const char *res = XmlReadValue(xmlio::Char);
2973 if (res) {
2974 int n;
2975 sscanf(res, "%d", &n);
2976 value = n;
2977 } else
2978 value = 0;
2979}
2980
2981////////////////////////////////////////////////////////////////////////////////
2982/// Reads string from current xml node and convert it to Short_t value
2983
2985{
2986 const char *res = XmlReadValue(xmlio::Short);
2987 if (res)
2988 sscanf(res, "%hd", &value);
2989 else
2990 value = 0;
2991}
2992
2993////////////////////////////////////////////////////////////////////////////////
2994/// Reads string from current xml node and convert it to Int_t value
2995
2997{
2998 const char *res = XmlReadValue(xmlio::Int);
2999 if (res)
3000 sscanf(res, "%d", &value);
3001 else
3002 value = 0;
3003}
3004
3005////////////////////////////////////////////////////////////////////////////////
3006/// Reads string from current xml node and convert it to Long_t value
3007
3009{
3010 const char *res = XmlReadValue(xmlio::Long);
3011 if (res)
3012 sscanf(res, "%ld", &value);
3013 else
3014 value = 0;
3015}
3016
3017////////////////////////////////////////////////////////////////////////////////
3018/// Reads string from current xml node and convert it to Long64_t value
3019
3021{
3022 const char *res = XmlReadValue(xmlio::Long64);
3023 if (res)
3024 value = (Long64_t)std::stoll(res);
3025 else
3026 value = 0;
3027}
3028
3029////////////////////////////////////////////////////////////////////////////////
3030/// Reads string from current xml node and convert it to Float_t value
3031
3033{
3034 const char *res = XmlReadValue(xmlio::Float);
3035 if (res)
3036 sscanf(res, "%f", &value);
3037 else
3038 value = 0.;
3039}
3040
3041////////////////////////////////////////////////////////////////////////////////
3042/// Reads string from current xml node and convert it to Double_t value
3043
3045{
3046 const char *res = XmlReadValue(xmlio::Double);
3047 if (res)
3048 sscanf(res, "%lf", &value);
3049 else
3050 value = 0.;
3051}
3052
3053////////////////////////////////////////////////////////////////////////////////
3054/// Reads string from current xml node and convert it to Bool_t value
3055
3057{
3058 const char *res = XmlReadValue(xmlio::Bool);
3059 if (res)
3060 value = (strcmp(res, xmlio::True) == 0);
3061 else
3062 value = kFALSE;
3063}
3064
3065////////////////////////////////////////////////////////////////////////////////
3066/// Reads string from current xml node and convert it to UChar_t value
3067
3069{
3070 const char *res = XmlReadValue(xmlio::UChar);
3071 if (res) {
3072 unsigned int n;
3073 sscanf(res, "%ud", &n);
3074 value = n;
3075 } else
3076 value = 0;
3077}
3078
3079////////////////////////////////////////////////////////////////////////////////
3080/// Reads string from current xml node and convert it to UShort_t value
3081
3083{
3084 const char *res = XmlReadValue(xmlio::UShort);
3085 if (res)
3086 sscanf(res, "%hud", &value);
3087 else
3088 value = 0;
3089}
3090
3091////////////////////////////////////////////////////////////////////////////////
3092/// Reads string from current xml node and convert it to UInt_t value
3093
3095{
3096 const char *res = XmlReadValue(xmlio::UInt);
3097 if (res)
3098 sscanf(res, "%u", &value);
3099 else
3100 value = 0;
3101}
3102
3103////////////////////////////////////////////////////////////////////////////////
3104/// Reads string from current xml node and convert it to ULong_t value
3105
3107{
3108 const char *res = XmlReadValue(xmlio::ULong);
3109 if (res)
3110 sscanf(res, "%lu", &value);
3111 else
3112 value = 0;
3113}
3114
3115////////////////////////////////////////////////////////////////////////////////
3116/// Reads string from current xml node and convert it to ULong64_t value
3117
3119{
3120 const char *res = XmlReadValue(xmlio::ULong64);
3121 if (res)
3122 value = (ULong64_t)std::stoull(res);
3123 else
3124 value = 0;
3125}
3126
3127////////////////////////////////////////////////////////////////////////////////
3128/// read string value from current stack node
3129
3130const char *TBufferXML::XmlReadValue(const char *name)
3131{
3132 if (fErrorFlag > 0)
3133 return nullptr;
3134
3135 Bool_t trysimple = fCanUseCompact;
3137
3138 if (trysimple) {
3139 if (fXML->HasAttr(Stack(1)->fNode, xmlio::v))
3140 fValueBuf = fXML->GetAttr(Stack(1)->fNode, xmlio::v);
3141 else
3142 trysimple = kFALSE;
3143 }
3144
3145 if (!trysimple) {
3146 if (!VerifyItemNode(name, "XmlReadValue"))
3147 return nullptr;
3149 }
3150
3151 if (gDebug > 4)
3152 Info("XmlReadValue", " Name = %s value = %s", name, fValueBuf.Data());
3153
3154 if (!trysimple)
3155 ShiftStack("readvalue");
3156
3157 return fValueBuf.Data();
3158}
3159
3160////////////////////////////////////////////////////////////////////////////////
3161/// Return current streamer info element
3162
3164{
3165 return Stack()->fInfo;
3166}
#define R__ALWAYS_INLINE
Definition: RConfig.hxx:564
#define d(i)
Definition: RSha256.hxx:102
#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
const Bool_t kFALSE
Definition: RtypesCore.h:101
long Long_t
Definition: RtypesCore.h:54
float Float_t
Definition: RtypesCore.h:57
short Short_t
Definition: RtypesCore.h:39
long long Long64_t
Definition: RtypesCore.h:80
unsigned long long ULong64_t
Definition: RtypesCore.h:81
const Bool_t kTRUE
Definition: RtypesCore.h:100
unsigned long ULong_t
Definition: RtypesCore.h:55
#define ClassImp(name)
Definition: Rtypes.h:375
@ kIsAbstract
Definition: TDictionary.h:71
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 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 char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
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:585
#define gROOT
Definition: TROOT.h:405
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.
Definition: TBufferIO.cxx:129
void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force) override
force writing the TStreamerInfo to the file
Definition: TBufferIO.cxx:329
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.
Definition: TBufferIO.cxx:163
Long64_t GetObjectTag(const void *obj)
Returns tag for specified object from objects map (if exists) Returns 0 if object not included into o...
Definition: TBufferIO.cxx:277
static R__ALWAYS_INLINE ULong_t Void_Hash(const void *ptr)
Return hash value for provided object.
Definition: TBufferIO.h:53
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...
Definition: TBufferIO.cxx:260
Int_t WriteObjectAny(const void *obj, const TClass *ptrClass, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
Definition: TBufferIO.cxx:492
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...
Definition: TBufferXML.cxx:523
void WriteLong(Long_t l) final
Writes Long_t value to buffer.
void WriteFastArray(const Bool_t *b, Int_t n) final
Write array of Bool_t 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.
Definition: TBufferXML.cxx:298
Bool_t VerifyAttr(XMLNodePointer_t node, const char *name, const char *value, const char *errinfo=nullptr)
Checks, that attribute of specified name exists and has specified value.
Definition: TBufferXML.cxx:648
void WorkWithClass(TStreamerInfo *info, const TClass *cl=nullptr)
Prepares buffer to stream data of specified class.
Definition: TBufferXML.cxx:863
Bool_t VerifyStackNode(const char *name, const char *errinfo=nullptr)
Check, if stack node has specified name.
Definition: TBufferXML.cxx:640
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.
Definition: TBufferXML.cxx:381
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.
Definition: TBufferXML.cxx:59
Bool_t VerifyNode(XMLNodePointer_t node, const char *name, const char *errinfo=nullptr)
Check if node has specified name.
Definition: TBufferXML.cxx:622
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 ...
Definition: TBufferXML.cxx:105
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...
Definition: TBufferXML.cxx:855
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.
Definition: TBufferXML.cxx:228
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.
Definition: TBufferXML.cxx:667
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.
Definition: TBufferXML.cxx:331
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 WriteFastArrayString(const Char_t *c, Int_t n) final
Write array of n characters into the I/O buffer.
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.
Definition: TBufferXML.cxx:452
void * XmlReadObject(void *obj, TClass **cl=nullptr)
Read object from the buffer.
Definition: TBufferXML.cxx:788
void ReadCharP(Char_t *c) final
Reads array of characters from buffer.
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 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...
Definition: TBufferXML.cxx:560
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 ...
Definition: TBufferXML.cxx:929
R__ALWAYS_INLINE void XmlWriteFastArray(const T *arr, Int_t n)
Write array without size attribute Also treat situation, when instead of one single array chain of se...
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...
Definition: TBufferXML.cxx:961
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.
Definition: TBufferXML.cxx:154
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.
Definition: TBufferXML.cxx:245
XMLNodePointer_t StackNode()
Return pointer on current xml node.
Definition: TBufferXML.cxx:322
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.
Definition: TBufferXML.cxx:689
static void * ConvertFromXMLChecked(const char *xml, const TClass *expectedClass, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Convert from XML and check if object derived from specified class When possible, cast to given class.
Definition: TBufferXML.cxx:201
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.
Definition: TBufferXML.cxx:596
void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Definition: TBufferXML.cxx:359
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.
Definition: TBufferXML.cxx:344
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...
Definition: TBufferXML.cxx:756
TXMLFile * XmlFile()
Returns pointer to TXMLFile object.
Definition: TBufferXML.cxx:94
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.
Definition: TBufferXML.cxx:972
virtual ~TBufferXML()
Destroy xml buffer.
Definition: TBufferXML.cxx:86
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.
Definition: TBufferXML.cxx:390
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.
Definition: TBufferXML.cxx:675
void WriteULong(ULong_t l) final
Writes ULong_t value to buffer.
TXMLStackObj * PopStack()
Remove one level from xml stack.
Definition: TBufferXML.cxx:312
void CreateElemNode(const TStreamerElement *elem)
Create xml node correspondent to TStreamerElement object.
Definition: TBufferXML.cxx:702
static void * ConvertFromXMLAny(const char *str, TClass **cl=nullptr, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object of any class from XML, produced by ConvertToXML() method.
Definition: TBufferXML.cxx:177
Bool_t VerifyElemNode(const TStreamerElement *elem)
Checks if stack node correspond to TStreamerElement object.
Definition: TBufferXML.cxx:730
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.
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:603
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition: TClass.cxx:4967
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition: TClass.cxx:5389
Int_t Size() const
Return size of object of this class.
Definition: TClass.cxx:5693
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition: TClass.cxx:5927
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:6075
Version_t GetClassVersion() const
Definition: TClass.h:418
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
Definition: TObjArray.cxx:605
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:969
virtual ~TObject()
TObject destructor.
Definition: TObject.cxx:158
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:943
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.
Definition: TStreamerInfo.h:39
TClass * GetClass() const override
TObjArray * GetElements() const override
Basic string class.
Definition: TString.h:136
Ssiz_t Length() const
Definition: TString.h:410
Int_t Atoi() const
Return integer value of string.
Definition: TString.cxx:1967
const char * Data() const
Definition: TString.h:369
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition: TString.cxx:1141
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
Definition: TXMLEngine.cxx:715
XMLNodePointer_t GetChild(XMLNodePointer_t xmlnode, Bool_t realnode=kTRUE)
returns first child of xmlnode
XMLAttrPointer_t NewAttr(XMLNodePointer_t xmlnode, XMLNsPointer_t, const char *name, const char *value)
creates new attribute for xmlnode, namespaces are not supported for attributes
Definition: TXMLEngine.cxx:586
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
Definition: TXMLEngine.cxx:612
Bool_t HasAttr(XMLNodePointer_t xmlnode, const char *name)
checks if node has attribute of specified name
Definition: TXMLEngine.cxx:539
XMLNodePointer_t ReadSingleNode(const char *src)
read single xmlnode from provided string
const char * GetNodeContent(XMLNodePointer_t xmlnode)
get contents (if any) of xmlnode
const char * GetNodeName(XMLNodePointer_t xmlnode)
returns name of xmlnode
void FreeAttr(XMLNodePointer_t xmlnode, const char *name)
remove attribute from xmlnode
Definition: TXMLEngine.cxx:622
const char * GetAttr(XMLNodePointer_t xmlnode, const char *name)
returns value of attribute for xmlnode
Definition: TXMLEngine.cxx:555
XMLNsPointer_t NewNS(XMLNodePointer_t xmlnode, const char *reference, const char *name=nullptr)
create namespace attribute for xmlnode.
Definition: TXMLEngine.cxx:741
Int_t GetIntAttr(XMLNodePointer_t node, const char *name)
returns value of attribute as integer
Definition: TXMLEngine.cxx:571
void UnlinkFreeNode(XMLNodePointer_t xmlnode)
combined operation. Unlink node and free used memory
void FreeNode(XMLNodePointer_t xmlnode)
release all memory, allocated from this node and destroys node itself
void SkipEmpty(XMLNodePointer_t &xmlnode)
Skip all current empty nodes and locate on first "true" node.
void ShiftToNext(XMLNodePointer_t &xmlnode, Bool_t realnode=kTRUE)
shifts specified node to next if realnode==kTRUE, any special nodes in between will be skipped
TClass * XmlDefineClass(const char *xmlClassName)
define class for the converted class name, where special symbols were replaced by '_'
Definition: TXMLSetup.cxx:265
const char * XmlClassNameSpaceRef(const TClass *cl)
produce string which used as reference in class namespace definition
Definition: TXMLSetup.cxx:225
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
Definition: TXMLSetup.cxx:211
Int_t AtoI(const char *sbuf, Int_t def=0, const char *errinfo=nullptr)
converts string to integer.
Definition: TXMLSetup.cxx:284
const char * XmlGetElementName(const TStreamerElement *el)
return converted name for TStreamerElement
Definition: TXMLSetup.cxx:238
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
Definition: TBufferXML.cxx:291
TStreamerInfo * fInfo
Definition: TBufferXML.cxx:286
Int_t fElemNumber
Definition: TBufferXML.cxx:288
TStreamerElement * fElem
Definition: TBufferXML.cxx:287
Bool_t fCompressedClassNode
Definition: TBufferXML.cxx:289
XMLNodePointer_t fNode
Definition: TBufferXML.cxx:285
XMLNsPointer_t fClassNs
Definition: TBufferXML.cxx:290
Bool_t fIsElemOwner
Definition: TBufferXML.cxx:292
Bool_t IsStreamerInfo() const
Definition: TBufferXML.cxx:283
TXMLStackObj(XMLNodePointer_t node)
Definition: TBufferXML.cxx:273
const Int_t n
Definition: legend1.C:16
double T(double x)
Definition: ChebyshevPol.h:34
static constexpr double s
static constexpr double ns
Definition: file.py:1
const char * UChar
Definition: TXMLSetup.cxx: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:83
@ kUndefined
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added).
Definition: Compression.h:100
@ kUseMin
Compression level reserved when we are not sure what to use (1 is for the fastest compression)
Definition: Compression.h:68
TLine l
Definition: textangle.C:4