Logo ROOT  
Reference Guide
Loading...
Searching...
No Matches
TBufferXML.cxx
Go to the documentation of this file.
1// @(#)root/:$Id: 5400e36954e1dc109fcfc306242c30234beb7312 $
2// Author: Sergey Linev, Rene Brun 10.05.2004
3
4/*************************************************************************
5 * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12/**
13\class TBufferXML
14\ingroup io_xml
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 <limits>
52#include <memory>
53
54
55////////////////////////////////////////////////////////////////////////////////
56/// Creates buffer object to serialize/deserialize data to/from xml.
57/// Mode should be either TBuffer::kRead or TBuffer::kWrite.
58
62
63////////////////////////////////////////////////////////////////////////////////
64/// Creates buffer object to serialize/deserialize data to/from xml.
65/// This constructor should be used, if data from buffer supposed to be stored in file.
66/// Mode should be either TBuffer::kRead or TBuffer::kWrite.
67
69 : TBufferText(mode, file), TXMLSetup(*file)
70{
71 // this is for the case when StreamerInfo reads elements from
72 // buffer as ReadFastArray. When it checks if size of buffer is
73 // too small and skip reading. Actually, more improved method should
74 // be used here.
75
76 if (XmlFile()) {
77 SetXML(XmlFile()->XML());
80 }
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// Destroy xml buffer.
85
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
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/// Add "ptr" attribute to node, if ptr is null or
388/// if ptr is pointer on object, which is already saved in buffer
389/// Automatically add "ref" attribute to node, where referenced object is stored
390
392{
393 if (!node)
394 return kFALSE;
395
396 TString refvalue;
397
398 if (!ptr) {
399 refvalue = xmlio::Null; // null
400 } else {
402 if (!refnode)
403 return kFALSE;
404
405 if (fXML->HasAttr(refnode, xmlio::Ref)) {
406 refvalue = fXML->GetAttr(refnode, xmlio::Ref);
407 } else {
408 refvalue = xmlio::IdBase;
409 if (XmlFile())
410 refvalue += XmlFile()->GetNextRefCounter();
411 else
412 refvalue += GetNextRefCounter();
413 fXML->NewAttr(refnode, nullptr, xmlio::Ref, refvalue.Data());
414 }
415 }
416 if (refvalue.Length() > 0) {
417 fXML->NewAttr(node, nullptr, xmlio::Ptr, refvalue.Data());
418 return kTRUE;
419 }
420
421 return kFALSE;
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Searches for "ptr" attribute and returns pointer to object and class,
426/// if "ptr" attribute reference to read object
427
429{
430 cl = nullptr;
431
432 if (!fXML->HasAttr(node, xmlio::Ptr))
433 return kFALSE;
434
435 const char *ptrid = fXML->GetAttr(node, xmlio::Ptr);
436
437 if (!ptrid)
438 return kFALSE;
439
440 // null
441 if (strcmp(ptrid, xmlio::Null) == 0) {
442 ptr = nullptr;
443 return kTRUE;
444 }
445
446 if (strncmp(ptrid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
447 Error("ExtractPointer", "Pointer tag %s not started from %s", ptrid, xmlio::IdBase);
448 return kFALSE;
449 }
450
451 Int_t id = TString(ptrid + strlen(xmlio::IdBase)).Atoi();
452
453 GetMappedObject(id + 1, ptr, cl);
454
455 if (!ptr || !cl)
456 Error("ExtractPointer", "not found ptr %s result %p %s", ptrid, ptr, (cl ? cl->GetName() : "null"));
457
458 return ptr && cl;
459}
460
461////////////////////////////////////////////////////////////////////////////////
462/// Analyze if node has "ref" attribute and register it to object map
463
464void TBufferXML::ExtractReference(XMLNodePointer_t node, const void *ptr, const TClass *cl)
465{
466 if (!node || !ptr)
467 return;
468
469 const char *refid = fXML->GetAttr(node, xmlio::Ref);
470
471 if (!refid)
472 return;
473
474 if (strncmp(refid, xmlio::IdBase, strlen(xmlio::IdBase)) != 0) {
475 Error("ExtractReference", "Reference tag %s not started from %s", refid, xmlio::IdBase);
476 return;
477 }
478
479 Int_t id = TString(refid + strlen(xmlio::IdBase)).Atoi();
480
481 MapObject(ptr, cl, id + 1);
482
483 if (gDebug > 2)
484 Info("ExtractReference", "Find reference %s for object %p class %s", refid, ptr, (cl ? cl->GetName() : "null"));
485}
486
487////////////////////////////////////////////////////////////////////////////////
488/// Check if node has specified name
489
490Bool_t TBufferXML::VerifyNode(XMLNodePointer_t node, const char *name, const char *errinfo)
491{
492 if (!name || !node)
493 return kFALSE;
494
495 if (strcmp(fXML->GetNodeName(node), name) != 0) {
496 if (errinfo) {
497 Error("VerifyNode", "Reading XML file (%s). Get: %s, expects: %s", errinfo, fXML->GetNodeName(node), name);
498 fErrorFlag = 1;
499 }
500 return kFALSE;
501 }
502 return kTRUE;
503}
504
505////////////////////////////////////////////////////////////////////////////////
506/// Check, if stack node has specified name
507
508Bool_t TBufferXML::VerifyStackNode(const char *name, const char *errinfo)
509{
510 return VerifyNode(StackNode(), name, errinfo);
511}
512
513////////////////////////////////////////////////////////////////////////////////
514/// Checks, that attribute of specified name exists and has specified value
515
516Bool_t TBufferXML::VerifyAttr(XMLNodePointer_t node, const char *name, const char *value, const char *errinfo)
517{
518 if (!node || !name || !value)
519 return kFALSE;
520
521 const char *cont = fXML->GetAttr(node, name);
522 if ((!cont || (strcmp(cont, value) != 0))) {
523 if (errinfo) {
524 Error("VerifyAttr", "%s : attr %s = %s, expected: %s", errinfo, name, cont, value);
525 fErrorFlag = 1;
526 }
527 return kFALSE;
528 }
529 return kTRUE;
530}
531
532////////////////////////////////////////////////////////////////////////////////
533/// Checks stack attribute
534
535Bool_t TBufferXML::VerifyStackAttr(const char *name, const char *value, const char *errinfo)
536{
537 return VerifyAttr(StackNode(), name, value, errinfo);
538}
539
540////////////////////////////////////////////////////////////////////////////////
541/// Create item node of specified name
542
544{
545 XMLNodePointer_t node = nullptr;
546 if (GetXmlLayout() == kGeneralized) {
547 node = fXML->NewChild(StackNode(), nullptr, xmlio::Item);
548 fXML->NewAttr(node, nullptr, xmlio::Name, name);
549 } else
550 node = fXML->NewChild(StackNode(), nullptr, name);
551 return node;
552}
553
554////////////////////////////////////////////////////////////////////////////////
555/// Checks, if stack node is item and has specified name
556
557Bool_t TBufferXML::VerifyItemNode(const char *name, const char *errinfo)
558{
559 Bool_t res = kTRUE;
560 if (GetXmlLayout() == kGeneralized)
561 res = VerifyStackNode(xmlio::Item, errinfo) && VerifyStackAttr(xmlio::Name, name, errinfo);
562 else
563 res = VerifyStackNode(name, errinfo);
564 return res;
565}
566
567////////////////////////////////////////////////////////////////////////////////
568/// Create xml node correspondent to TStreamerElement object
569
571{
572 XMLNodePointer_t elemnode = nullptr;
573
574 const char *elemxmlname = XmlGetElementName(elem);
575
576 if (GetXmlLayout() == kGeneralized) {
577 elemnode = fXML->NewChild(StackNode(), nullptr, xmlio::Member);
578 fXML->NewAttr(elemnode, nullptr, xmlio::Name, elemxmlname);
579 } else {
580 // take namesapce for element only if it is not a base class or class name
582 if ((elem->GetType() == TStreamerInfo::kBase) ||
583 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())) ||
584 ((elem->GetType() == TStreamerInfo::kTObject) && !strcmp(elem->GetName(), TObject::Class()->GetName())) ||
585 ((elem->GetType() == TStreamerInfo::kTString) && !strcmp(elem->GetName(), TString::Class()->GetName())))
586 ns = nullptr;
587
588 elemnode = fXML->NewChild(StackNode(), ns, elemxmlname);
589 }
590
591 TXMLStackObj *curr = PushStack(elemnode);
592 curr->fElem = (TStreamerElement *)elem;
593}
594
595////////////////////////////////////////////////////////////////////////////////
596/// Checks if stack node correspond to TStreamerElement object
597
599{
600 const char *elemxmlname = XmlGetElementName(elem);
601
602 if (GetXmlLayout() == kGeneralized) {
604 return kFALSE;
605 if (!VerifyStackAttr(xmlio::Name, elemxmlname))
606 return kFALSE;
607 } else {
608 if (!VerifyStackNode(elemxmlname))
609 return kFALSE;
610 }
611
613
614 TXMLStackObj *curr = PushStack(StackNode()); // set pointer to first data inside element
615 curr->fElem = (TStreamerElement *)elem;
616 return kTRUE;
617}
618
619////////////////////////////////////////////////////////////////////////////////
620/// Write object to buffer
621/// If object was written before, only pointer will be stored
622/// Return pointer to top xml node, representing object
623
624XMLNodePointer_t TBufferXML::XmlWriteObject(const void *obj, const TClass *cl, Bool_t cacheReuse)
625{
626 XMLNodePointer_t objnode = fXML->NewChild(StackNode(), nullptr, xmlio::Object);
627
628 if (!cl)
629 obj = nullptr;
630
631 if (ProcessPointer(obj, objnode))
632 return objnode;
633
634 TString clname = XmlConvertClassName(cl->GetName());
635
636 fXML->NewAttr(objnode, nullptr, xmlio::ObjClass, clname);
637
638 if (cacheReuse)
639 fMap->Add(Void_Hash(obj), (Longptr_t)obj, (Longptr_t)objnode);
640
641 PushStack(objnode);
642
643 ((TClass *)cl)->Streamer((void *)obj, *this);
644
645 PopStack();
646
647 if (gDebug > 1)
648 Info("XmlWriteObject", "Done write for class: %s", cl ? cl->GetName() : "null");
649
650 return objnode;
651}
652
653////////////////////////////////////////////////////////////////////////////////
654/// Read object from the buffer
655
656void *TBufferXML::XmlReadObject(void *obj, TClass **cl)
657{
658 if (cl)
659 *cl = nullptr;
660
661 XMLNodePointer_t objnode = StackNode();
662
663 if (fErrorFlag > 0)
664 return obj;
665
666 if (!objnode)
667 return obj;
668
669 if (!VerifyNode(objnode, xmlio::Object, "XmlReadObjectNew"))
670 return obj;
671
672 TClass *objClass = nullptr;
673
674 if (ExtractPointer(objnode, obj, objClass)) {
675 ShiftStack("readobjptr");
676 if (cl)
677 *cl = objClass;
678 return obj;
679 }
680
681 TString clname = fXML->GetAttr(objnode, xmlio::ObjClass);
682 objClass = XmlDefineClass(clname);
683 if (objClass == TDirectory::Class())
684 objClass = TDirectoryFile::Class();
685
686 if (!objClass) {
687 Error("XmlReadObject", "Cannot find class %s", clname.Data());
688 ShiftStack("readobjerr");
689 return obj;
690 }
691
692 if (gDebug > 1)
693 Info("XmlReadObject", "Reading object of class %s", clname.Data());
694
695 if (!obj)
696 obj = objClass->New();
697
698 ExtractReference(objnode, obj, objClass);
699
700 PushStack(objnode);
701
702 objClass->Streamer((void *)obj, *this);
703
704 PopStack();
705
706 ShiftStack("readobj");
707
708 if (gDebug > 1)
709 Info("XmlReadObject", "Reading object of class %s done", clname.Data());
710
711 if (cl)
712 *cl = objClass;
713
714 return obj;
715}
716
717////////////////////////////////////////////////////////////////////////////////
718/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
719/// and indent new level in xml structure.
720/// This call indicates, that TStreamerInfo functions starts streaming
721/// object data of correspondent class
722
727
728////////////////////////////////////////////////////////////////////////////////
729/// Prepares buffer to stream data of specified class.
730
732{
734
735 if (sinfo)
736 cl = sinfo->GetClass();
737
738 if (!cl)
739 return;
740
741 TString clname = XmlConvertClassName(cl->GetName());
742
743 if (gDebug > 2)
744 Info("IncrementLevel", "Class: %s", clname.Data());
745
746 Bool_t compressClassNode = (fExpectedBaseClass == cl);
747 fExpectedBaseClass = nullptr;
748
749 TXMLStackObj *stack = Stack();
750
751 if (IsWriting()) {
752
753 XMLNodePointer_t classnode = nullptr;
754 if (compressClassNode) {
755 classnode = StackNode();
756 } else {
757 if (GetXmlLayout() == kGeneralized) {
758 classnode = fXML->NewChild(StackNode(), nullptr, xmlio::Class);
759 fXML->NewAttr(classnode, nullptr, "name", clname);
760 } else
761 classnode = fXML->NewChild(StackNode(), nullptr, clname);
762 stack = PushStack(classnode);
763 }
764
765 if (fVersionBuf >= -1) {
766 if (fVersionBuf == -1)
767 fVersionBuf = 1;
768 fXML->NewIntAttr(classnode, xmlio::ClassVersion, fVersionBuf);
769 fVersionBuf = -111;
770 }
771
773 stack->fClassNs = fXML->NewNS(classnode, XmlClassNameSpaceRef(cl), clname);
774
775 } else {
776 if (!compressClassNode) {
777 if (GetXmlLayout() == kGeneralized) {
778 if (!VerifyStackNode(xmlio::Class, "StartInfo"))
779 return;
780 if (!VerifyStackAttr("name", clname, "StartInfo"))
781 return;
782 } else if (!VerifyStackNode(clname, "StartInfo"))
783 return;
784 stack = PushStack(StackNode());
785 }
786 }
787
788 stack->fCompressedClassNode = compressClassNode;
789 stack->fInfo = sinfo;
790 stack->fIsStreamerInfo = kTRUE;
791}
792
793////////////////////////////////////////////////////////////////////////////////
794/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
795/// and decrease level in xml structure.
796
798{
800
802
803 if (gDebug > 2)
804 Info("DecrementLevel", "Class: %s", (info ? info->GetClass()->GetName() : "custom"));
805
806 TXMLStackObj *stack = Stack();
807
808 if (!stack->IsStreamerInfo()) {
810 stack = PopStack(); // remove stack of last element
811 }
812
813 if (stack->fCompressedClassNode) {
814 stack->fInfo = nullptr;
815 stack->fIsStreamerInfo = kFALSE;
817 } else {
818 PopStack(); // back from data of stack info
819 if (IsReading())
820 ShiftStack("declevel"); // shift to next element after streamer info
821 }
822}
823
824////////////////////////////////////////////////////////////////////////////////
825/// Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions
826/// and add/verify next element of xml structure
827/// This calls allows separate data, correspondent to one class member, from another
828
830{
831 WorkWithElement(elem, comptype);
832}
833
834////////////////////////////////////////////////////////////////////////////////
835/// This function is a part of SetStreamerElementNumber method.
836/// It is introduced for reading of data for specified data member of class.
837/// Used also in ReadFastArray methods to resolve problem of compressed data,
838/// when several data members of the same basic type streamed with single ...FastArray call
839
841{
843
845 fExpectedBaseClass = nullptr;
846
847 TXMLStackObj *stack = Stack();
848 if (!stack) {
849 Error("SetStreamerElementNumber", "stack is empty");
850 return;
851 }
852
853 if (!stack->IsStreamerInfo()) { // this is not a first element
855 PopStack(); // go level back
856 if (IsReading())
857 ShiftStack("startelem"); // shift to next element, only for reading
858 stack = Stack();
859 }
860
861 if (!stack) {
862 Error("SetStreamerElementNumber", "Lost of stack");
863 return;
864 }
865
866 if (!elem) {
867 Error("SetStreamerElementNumber", "Problem in Inc/Dec level");
868 return;
869 }
870
871 TStreamerInfo *info = stack->fInfo;
872
873 if (!stack->IsStreamerInfo()) {
874 Error("SetStreamerElementNumber", "Problem in Inc/Dec level");
875 return;
876 }
877 Int_t number = info ? info->GetElements()->IndexOf(elem) : -1;
878
879 if (gDebug > 4)
880 Info("SetStreamerElementNumber", " Next element %s", elem->GetName());
881
882 Bool_t isBasicType = (elem->GetType() > 0) && (elem->GetType() < 20);
883
885 isBasicType && ((elem->GetType() == comp_type) || (elem->GetType() == comp_type - TStreamerInfo::kConv) ||
886 (elem->GetType() == comp_type - TStreamerInfo::kSkip));
887
888 if ((elem->GetType() == TStreamerInfo::kBase) ||
889 ((elem->GetType() == TStreamerInfo::kTNamed) && !strcmp(elem->GetName(), TNamed::Class()->GetName())))
891
892 if (fExpectedBaseClass && (gDebug > 3))
893 Info("SetStreamerElementNumber", " Expects base class %s with standard streamer",
894 fExpectedBaseClass->GetName());
895
896 if (IsWriting()) {
897 CreateElemNode(elem);
898 } else {
899 if (!VerifyElemNode(elem))
900 return;
901 }
902
903 stack = Stack();
904 stack->fElemNumber = number;
905 stack->fIsElemOwner = (number < 0);
906}
907
908////////////////////////////////////////////////////////////////////////////////
909/// Should be called at the beginning of custom class streamer.
910///
911/// Informs buffer data about class which will be streamed now.
912/// ClassBegin(), ClassEnd() and ClassMemeber() should be used in
913/// custom class streamers to specify which kind of data are
914/// now streamed. Such information is used to correctly
915/// convert class data to XML. Without that functions calls
916/// classes with custom streamers cannot be used with TBufferXML
917
919{
920 WorkWithClass(nullptr, cl);
921}
922
923////////////////////////////////////////////////////////////////////////////////
924/// Should be called at the end of custom streamer
925/// See TBufferXML::ClassBegin for more details
926
928{
929 DecrementLevel(nullptr);
930}
931
932////////////////////////////////////////////////////////////////////////////////
933/// Method indicates name and typename of class member,
934/// which should be now streamed in custom streamer
935///
936/// Following combinations are supported:
937/// -# name = "ClassName", typeName = 0 or typename==ClassName.
938/// This is a case, when data of parent class "ClassName" should be streamed.
939/// For instance, if class directly inherited from TObject, custom streamer
940/// should include following code:
941/// ~~~{.cpp}
942/// b.ClassMember("TObject");
943/// TObject::Streamer(b);
944/// ~~~
945/// -# Basic data type
946/// ~~~{.cpp}
947/// b.ClassMember("fInt","Int_t");
948/// b >> fInt;
949/// ~~~
950/// -# Array of basic data types
951/// ~~~{.cpp}
952/// b.ClassMember("fArr","Int_t", 5);
953/// b.ReadFastArray(fArr, 5);
954/// ~~~
955/// -# Object as data member
956/// ~~~{.cpp}
957/// b.ClassMemeber("fName","TString");
958/// fName.Streamer(b);
959/// ~~~
960/// -# Pointer on object as data member
961/// ~~~{.cpp}
962/// b.ClassMemeber("fObj","TObject*");
963/// b.StreamObject(fObj);
964/// ~~~
965///
966/// Arrsize1 and arrsize2 arguments (when specified) indicate first and
967/// second dimension of array. Can be used for array of basic types.
968/// See ClassBegin() method for more details.
969
970void TBufferXML::ClassMember(const char *name, const char *typeName, Int_t arrsize1, Int_t arrsize2)
971{
972 if (!typeName)
973 typeName = name;
974
975 if (!name || (strlen(name) == 0)) {
976 Error("ClassMember", "Invalid member name");
977 fErrorFlag = 1;
978 return;
979 }
980
981 TString tname = typeName;
982
983 Int_t typ_id(-1), comp_type(-1);
984
985 if (strcmp(typeName, "raw:data") == 0)
987
988 if (typ_id < 0) {
989 TDataType *dt = gROOT->GetType(typeName);
990 if (dt)
991 if ((dt->GetType() > 0) && (dt->GetType() < 20))
992 typ_id = dt->GetType();
993 }
994
995 if (typ_id < 0)
996 if (strcmp(name, typeName) == 0) {
997 TClass *cl = TClass::GetClass(tname.Data());
998 if (cl)
999 typ_id = TStreamerInfo::kBase;
1000 }
1001
1002 if (typ_id < 0) {
1003 Bool_t isptr = kFALSE;
1004 if (tname[tname.Length() - 1] == '*') {
1005 tname.Resize(tname.Length() - 1);
1006 isptr = kTRUE;
1007 }
1008 TClass *cl = TClass::GetClass(tname.Data());
1009 if (!cl) {
1010 Error("ClassMember", "Invalid class specifier %s", typeName);
1011 fErrorFlag = 1;
1012 return;
1013 }
1014
1015 if (cl->IsTObject())
1017 else
1018 typ_id = isptr ? TStreamerInfo::kAnyp : TStreamerInfo::kAny;
1019
1020 if ((cl == TString::Class()) && !isptr)
1021 typ_id = TStreamerInfo::kTString;
1022 }
1023
1024 TStreamerElement *elem = nullptr;
1025
1026 if (typ_id == TStreamerInfo::kMissing) {
1027 elem = new TStreamerElement(name, "title", 0, typ_id, "raw:data");
1028 } else if (typ_id == TStreamerInfo::kBase) {
1029 TClass *cl = TClass::GetClass(tname.Data());
1030 if (cl) {
1031 TStreamerBase *b = new TStreamerBase(tname.Data(), "title", 0);
1032 b->SetBaseVersion(cl->GetClassVersion());
1033 elem = b;
1034 }
1035 } else if ((typ_id > 0) && (typ_id < 20)) {
1036 elem = new TStreamerBasicType(name, "title", 0, typ_id, typeName);
1037 comp_type = typ_id;
1038 } else if ((typ_id == TStreamerInfo::kObject) || (typ_id == TStreamerInfo::kTObject) ||
1039 (typ_id == TStreamerInfo::kTNamed)) {
1040 elem = new TStreamerObject(name, "title", 0, tname.Data());
1041 } else if (typ_id == TStreamerInfo::kObjectp) {
1042 elem = new TStreamerObjectPointer(name, "title", 0, tname.Data());
1043 } else if (typ_id == TStreamerInfo::kAny) {
1044 elem = new TStreamerObjectAny(name, "title", 0, tname.Data());
1045 } else if (typ_id == TStreamerInfo::kAnyp) {
1046 elem = new TStreamerObjectAnyPointer(name, "title", 0, tname.Data());
1047 } else if (typ_id == TStreamerInfo::kTString) {
1048 elem = new TStreamerString(name, "title", 0);
1049 }
1050
1051 if (!elem) {
1052 Error("ClassMember", "Invalid combination name = %s type = %s", name, typeName);
1053 fErrorFlag = 1;
1054 return;
1055 }
1056
1057 if (arrsize1 > 0) {
1058 elem->SetArrayDim(arrsize2 > 0 ? 2 : 1);
1059 elem->SetMaxIndex(0, arrsize1);
1060 if (arrsize2 > 0)
1061 elem->SetMaxIndex(1, arrsize2);
1062 }
1063
1064 // we indicate that there is no streamerinfo
1065 WorkWithElement(elem, comp_type);
1066}
1067
1068////////////////////////////////////////////////////////////////////////////////
1069/// Function is converts TObject and TString structures to more compact representation
1070
1072{
1073 if (GetXmlLayout() == kGeneralized)
1074 return;
1075
1076 const TStreamerElement *elem = Stack()->fElem;
1077 XMLNodePointer_t elemnode = IsWriting() ? Stack()->fNode : Stack(1)->fNode;
1078
1079 if (!elem || !elemnode)
1080 return;
1081
1082 if (elem->GetType() == TStreamerInfo::kTString) {
1083
1084 XMLNodePointer_t node = fXML->GetChild(elemnode);
1085 fXML->SkipEmpty(node);
1086
1087 XMLNodePointer_t nodecharstar(nullptr), nodeuchar(nullptr), nodeint(nullptr), nodestring(nullptr);
1088
1089 while (node) {
1090 const char *name = fXML->GetNodeName(node);
1091 if (strcmp(name, xmlio::String) == 0) {
1092 if (nodestring)
1093 return;
1094 nodestring = node;
1095 } else if (strcmp(name, xmlio::UChar) == 0) {
1096 if (nodeuchar)
1097 return;
1098 nodeuchar = node;
1099 } else if (strcmp(name, xmlio::Int) == 0) {
1100 if (nodeint)
1101 return;
1102 nodeint = node;
1103 } else if (strcmp(name, xmlio::CharStar) == 0) {
1104 if (nodecharstar)
1105 return;
1106 nodecharstar = node;
1107 } else
1108 return; // can not be something else
1109 fXML->ShiftToNext(node);
1110 }
1111
1112 TString str;
1113
1114 if (GetIOVersion() < 3) {
1115 if (!nodeuchar)
1116 return;
1117 if (nodecharstar)
1118 str = fXML->GetAttr(nodecharstar, xmlio::v);
1119 fXML->UnlinkFreeNode(nodeuchar);
1120 fXML->UnlinkFreeNode(nodeint);
1121 fXML->UnlinkFreeNode(nodecharstar);
1122 } else {
1123 if (nodestring)
1124 str = fXML->GetAttr(nodestring, xmlio::v);
1125 fXML->UnlinkFreeNode(nodestring);
1126 }
1127
1128 fXML->NewAttr(elemnode, nullptr, "str", str);
1129 } else if (elem->GetType() == TStreamerInfo::kTObject) {
1130 XMLNodePointer_t node = fXML->GetChild(elemnode);
1131 fXML->SkipEmpty(node);
1132
1133 XMLNodePointer_t vnode = nullptr, idnode = nullptr, bitsnode = nullptr, prnode = nullptr;
1134
1135 while (node) {
1136 const char *name = fXML->GetNodeName(node);
1137
1138 if (strcmp(name, xmlio::OnlyVersion) == 0) {
1139 if (vnode)
1140 return;
1141 vnode = node;
1142 } else if (strcmp(name, xmlio::UInt) == 0) {
1143 if (!idnode)
1144 idnode = node;
1145 else if (!bitsnode)
1146 bitsnode = node;
1147 else
1148 return;
1149 } else if (strcmp(name, xmlio::UShort) == 0) {
1150 if (prnode)
1151 return;
1152 prnode = node;
1153 } else
1154 return;
1155 fXML->ShiftToNext(node);
1156 }
1157
1158 if (!vnode || !idnode || !bitsnode)
1159 return;
1160
1161 TString str = fXML->GetAttr(idnode, xmlio::v);
1162 fXML->NewAttr(elemnode, nullptr, "fUniqueID", str);
1163
1164 str = fXML->GetAttr(bitsnode, xmlio::v);
1165 UInt_t bits;
1166 sscanf(str.Data(), "%u", &bits);
1168
1169 char sbuf[20];
1170 snprintf(sbuf, sizeof(sbuf), "%x", bits);
1171 fXML->NewAttr(elemnode, nullptr, "fBits", sbuf);
1172
1173 if (prnode) {
1174 str = fXML->GetAttr(prnode, xmlio::v);
1175 fXML->NewAttr(elemnode, nullptr, "fProcessID", str);
1176 }
1177
1178 fXML->UnlinkFreeNode(vnode);
1179 fXML->UnlinkFreeNode(idnode);
1180 fXML->UnlinkFreeNode(bitsnode);
1181 fXML->UnlinkFreeNode(prnode);
1182 }
1183}
1184
1185////////////////////////////////////////////////////////////////////////////////
1186/// Function is unpack TObject and TString structures to be able read
1187/// them from custom streamers of this objects
1188
1190{
1191 if (GetXmlLayout() == kGeneralized)
1192 return;
1193 if (!elem || !elemnode)
1194 return;
1195
1196 if (elem->GetType() == TStreamerInfo::kTString) {
1197
1198 if (!fXML->HasAttr(elemnode, "str"))
1199 return;
1200 TString str = fXML->GetAttr(elemnode, "str");
1201 fXML->FreeAttr(elemnode, "str");
1202
1203 if (GetIOVersion() < 3) {
1204 Int_t len = str.Length();
1205 XMLNodePointer_t ucharnode = fXML->NewChild(elemnode, nullptr, xmlio::UChar);
1206 char sbuf[20];
1207 snprintf(sbuf, sizeof(sbuf), "%d", len);
1208 if (len < 255) {
1209 fXML->NewAttr(ucharnode, nullptr, xmlio::v, sbuf);
1210 } else {
1211 fXML->NewAttr(ucharnode, nullptr, xmlio::v, "255");
1212 XMLNodePointer_t intnode = fXML->NewChild(elemnode, nullptr, xmlio::Int);
1213 fXML->NewAttr(intnode, nullptr, xmlio::v, sbuf);
1214 }
1215 if (len > 0) {
1216 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::CharStar);
1217 fXML->NewAttr(node, nullptr, xmlio::v, str);
1218 }
1219 } else {
1220 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::String);
1221 fXML->NewAttr(node, nullptr, xmlio::v, str);
1222 }
1223 } else if (elem->GetType() == TStreamerInfo::kTObject) {
1224 if (!fXML->HasAttr(elemnode, "fUniqueID"))
1225 return;
1226 if (!fXML->HasAttr(elemnode, "fBits"))
1227 return;
1228
1229 TString idstr = fXML->GetAttr(elemnode, "fUniqueID");
1230 TString bitsstr = fXML->GetAttr(elemnode, "fBits");
1231 TString prstr = fXML->GetAttr(elemnode, "fProcessID");
1232
1233 fXML->FreeAttr(elemnode, "fUniqueID");
1234 fXML->FreeAttr(elemnode, "fBits");
1235 fXML->FreeAttr(elemnode, "fProcessID");
1236
1237 XMLNodePointer_t node = fXML->NewChild(elemnode, nullptr, xmlio::OnlyVersion);
1238 fXML->NewAttr(node, nullptr, xmlio::v, "1");
1239
1240 node = fXML->NewChild(elemnode, nullptr, xmlio::UInt);
1241 fXML->NewAttr(node, nullptr, xmlio::v, idstr);
1242
1243 UInt_t bits = 0;
1244 sscanf(bitsstr.Data(), "%x", &bits);
1246 char sbuf[20];
1247 snprintf(sbuf, sizeof(sbuf), "%u", bits);
1248
1249 node = fXML->NewChild(elemnode, nullptr, xmlio::UInt);
1250 fXML->NewAttr(node, nullptr, xmlio::v, sbuf);
1251
1252 if (prstr.Length() > 0) {
1253 node = fXML->NewChild(elemnode, nullptr, xmlio::UShort);
1254 fXML->NewAttr(node, nullptr, xmlio::v, prstr.Data());
1255 }
1256 }
1257}
1258
1259////////////////////////////////////////////////////////////////////////////////
1260/// Function is called before any IO operation of TBuffer
1261/// Now is used to store version value if no proper calls are discovered
1262
1267
1268////////////////////////////////////////////////////////////////////////////////
1269/// Function to read class from buffer, used in old-style streamers
1270
1272{
1273 const char *clname = nullptr;
1274
1276 clname = XmlReadValue(xmlio::Class);
1277
1278 if (gDebug > 2)
1279 Info("ReadClass", "Try to read class %s", clname ? clname : "---");
1280
1281 return clname ? gROOT->GetClass(clname) : nullptr;
1282}
1283
1284////////////////////////////////////////////////////////////////////////////////
1285/// Function to write class into buffer, used in old-style streamers
1286
1288{
1289 if (gDebug > 2)
1290 Info("WriteClass", "Try to write class %s", cl->GetName());
1291
1293}
1294
1295////////////////////////////////////////////////////////////////////////////////
1296/// Read version value from buffer
1297
1299{
1301
1302 Version_t res = 0;
1303
1304 if (start)
1305 *start = 0;
1306 if (bcnt)
1307 *bcnt = 0;
1308
1311 } else if (fExpectedBaseClass && (fXML->HasAttr(Stack(1)->fNode, xmlio::ClassVersion))) {
1312 res = fXML->GetIntAttr(Stack(1)->fNode, xmlio::ClassVersion);
1313 } else if (fXML->HasAttr(StackNode(), xmlio::ClassVersion)) {
1314 res = fXML->GetIntAttr(StackNode(), xmlio::ClassVersion);
1315 } else {
1316 Error("ReadVersion", "No correspondent tags to read version");
1317 fErrorFlag = 1;
1318 }
1319
1320 if (gDebug > 2)
1321 Info("ReadVersion", "Version = %d", res);
1322
1323 return res;
1324}
1325
1326////////////////////////////////////////////////////////////////////////////////
1327/// Checks buffer, filled by WriteVersion
1328/// if next data is arriving, version should be stored in buffer
1329
1331{
1332 if (IsWriting() && (fVersionBuf >= -100)) {
1333 char sbuf[20];
1334 snprintf(sbuf, sizeof(sbuf), "%d", fVersionBuf);
1336 fVersionBuf = -111;
1337 }
1338}
1339
1340////////////////////////////////////////////////////////////////////////////////
1341/// Copies class version to buffer, but not writes it to xml
1342/// Version will be written with next I/O operation or
1343/// will be added as attribute of class tag, created by IncrementLevel call
1344
1346{
1348
1349 if (fExpectedBaseClass != cl)
1350 fExpectedBaseClass = nullptr;
1351
1353
1354 if (gDebug > 2)
1355 Info("WriteVersion", "Class: %s, version = %d", cl->GetName(), fVersionBuf);
1356
1357 return 0;
1358}
1359
1360////////////////////////////////////////////////////////////////////////////////
1361/// Read object from buffer. Only used from TBuffer
1362
1364{
1366 if (gDebug > 2)
1367 Info("ReadObjectAny", "From node %s", fXML->GetNodeName(StackNode()));
1368 void *res = XmlReadObject(nullptr);
1369 return res;
1370}
1371
1372////////////////////////////////////////////////////////////////////////////////
1373/// Skip any kind of object from buffer
1374/// Actually skip only one node on current level of xml structure
1375
1377{
1378 ShiftStack("skipobjectany");
1379}
1380
1381////////////////////////////////////////////////////////////////////////////////
1382/// Write object to buffer. Only used from TBuffer
1383
1384void TBufferXML::WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse)
1385{
1387 if (gDebug > 2)
1388 Info("WriteObject", "Class %s", (actualClass ? actualClass->GetName() : " null"));
1389 XmlWriteObject(actualObjStart, actualClass, cacheReuse);
1390}
1391
1392////////////////////////////////////////////////////////////////////////////////
1393/// Template method to read array content
1394
1395template <typename T>
1397{
1398 Int_t indx = 0, cnt, curr;
1399 while (indx < arrsize) {
1400 cnt = 1;
1401 if (fXML->HasAttr(StackNode(), xmlio::cnt))
1402 cnt = fXML->GetIntAttr(StackNode(), xmlio::cnt);
1403 XmlReadBasic(arr[indx]);
1404 curr = indx++;
1405 while (cnt-- > 1)
1406 arr[indx++] = arr[curr];
1407 }
1408}
1409
1410////////////////////////////////////////////////////////////////////////////////
1411/// Template method to read array with size attribute
1412/// If necessary, array is created
1413
1414template <typename T>
1416{
1418 if (!VerifyItemNode(xmlio::Array, is_static ? "ReadStaticArray" : "ReadArray"))
1419 return 0;
1420 Int_t n = fXML->GetIntAttr(StackNode(), xmlio::Size);
1421 if (n <= 0)
1422 return 0;
1423 if (!arr) {
1424 if (is_static)
1425 return 0;
1426 arr = new T[n];
1427 }
1429 XmlReadArrayContent(arr, n);
1430 PopStack();
1431 ShiftStack(is_static ? "readstatarr" : "readarr");
1432 return n;
1433}
1434
1435////////////////////////////////////////////////////////////////////////////////
1436/// Read array of Bool_t from buffer
1437
1439{
1440 return XmlReadArray(b);
1441}
1442
1443////////////////////////////////////////////////////////////////////////////////
1444/// Read array of Char_t from buffer
1445
1447{
1448 return XmlReadArray(c);
1449}
1450
1451////////////////////////////////////////////////////////////////////////////////
1452/// Read array of UChar_t from buffer
1453
1455{
1456 return XmlReadArray(c);
1457}
1458
1459////////////////////////////////////////////////////////////////////////////////
1460/// Read array of Short_t from buffer
1461
1463{
1464 return XmlReadArray(h);
1465}
1466
1467////////////////////////////////////////////////////////////////////////////////
1468/// Read array of UShort_t from buffer
1469
1474
1475////////////////////////////////////////////////////////////////////////////////
1476/// Read array of Int_t from buffer
1477
1479{
1480 return XmlReadArray(i);
1481}
1482
1483////////////////////////////////////////////////////////////////////////////////
1484/// Read array of UInt_t from buffer
1485
1487{
1488 return XmlReadArray(i);
1489}
1490
1491////////////////////////////////////////////////////////////////////////////////
1492/// Read array of Long_t from buffer
1493
1495{
1496 return XmlReadArray(l);
1497}
1498
1499////////////////////////////////////////////////////////////////////////////////
1500/// Read array of ULong_t from buffer
1501
1503{
1504 return XmlReadArray(l);
1505}
1506
1507////////////////////////////////////////////////////////////////////////////////
1508/// Read array of Long64_t from buffer
1509
1514
1515////////////////////////////////////////////////////////////////////////////////
1516/// Read array of ULong64_t from buffer
1517
1522
1523////////////////////////////////////////////////////////////////////////////////
1524/// Read array of Float_t from buffer
1525
1527{
1528 return XmlReadArray(f);
1529}
1530
1531////////////////////////////////////////////////////////////////////////////////
1532/// Read array of Double_t from buffer
1533
1538
1539////////////////////////////////////////////////////////////////////////////////
1540/// Read array of Bool_t from buffer
1541
1543{
1544 return XmlReadArray(b, true);
1545}
1546
1547////////////////////////////////////////////////////////////////////////////////
1548/// Read array of Char_t from buffer
1549
1551{
1552 return XmlReadArray(c, true);
1553}
1554
1555////////////////////////////////////////////////////////////////////////////////
1556/// Read array of UChar_t from buffer
1557
1559{
1560 return XmlReadArray(c, true);
1561}
1562
1563////////////////////////////////////////////////////////////////////////////////
1564/// Read array of Short_t from buffer
1565
1567{
1568 return XmlReadArray(h, true);
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572/// Read array of UShort_t from buffer
1573
1575{
1576 return XmlReadArray(h, true);
1577}
1578
1579////////////////////////////////////////////////////////////////////////////////
1580/// Read array of Int_t from buffer
1581
1583{
1584 return XmlReadArray(i, true);
1585}
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// Read array of UInt_t from buffer
1589
1591{
1592 return XmlReadArray(i, true);
1593}
1594
1595////////////////////////////////////////////////////////////////////////////////
1596/// Read array of Long_t from buffer
1597
1599{
1600 return XmlReadArray(l, true);
1601}
1602
1603////////////////////////////////////////////////////////////////////////////////
1604/// Read array of ULong_t from buffer
1605
1607{
1608 return XmlReadArray(l, true);
1609}
1610
1611////////////////////////////////////////////////////////////////////////////////
1612/// Read array of Long64_t from buffer
1613
1615{
1616 return XmlReadArray(l, true);
1617}
1618
1619////////////////////////////////////////////////////////////////////////////////
1620/// Read array of ULong64_t from buffer
1621
1623{
1624 return XmlReadArray(l, true);
1625}
1626
1627////////////////////////////////////////////////////////////////////////////////
1628/// Read array of Float_t from buffer
1629
1631{
1632 return XmlReadArray(f, true);
1633}
1634
1635////////////////////////////////////////////////////////////////////////////////
1636/// Read array of Double_t from buffer
1637
1639{
1640 return XmlReadArray(d, true);
1641}
1642
1643////////////////////////////////////////////////////////////////////////////////
1644/// Template method to read content of array, which not include size of array
1645/// Also treated situation, when instead of one single array chain
1646/// of several elements should be produced
1647
1648template <typename T>
1650{
1652 if (n <= 0)
1653 return;
1654 if (!VerifyItemNode(xmlio::Array, "ReadFastArray"))
1655 return;
1657 XmlReadArrayContent(arr, n);
1658 PopStack();
1659 ShiftStack("readfastarr");
1660}
1661
1662////////////////////////////////////////////////////////////////////////////////
1663/// Read array of Bool_t from buffer
1664
1669
1670////////////////////////////////////////////////////////////////////////////////
1671/// Read array of Char_t from buffer
1672/// if nodename==CharStar, read all array as string
1673
1675{
1676 if ((n > 0) && VerifyItemNode(xmlio::CharStar)) {
1677 const char *buf;
1678 if ((buf = XmlReadValue(xmlio::CharStar))) {
1679 Int_t size = strlen(buf);
1680 if (size < n)
1681 size = n;
1682 memcpy(c, buf, size);
1683 }
1684 } else {
1686 }
1687}
1688
1689////////////////////////////////////////////////////////////////////////////////
1690/// Read array of n characters from the I/O buffer.
1691/// Used only from TLeafC, dummy implementation here
1692
1697
1698////////////////////////////////////////////////////////////////////////////////
1699/// Read array of UChar_t from buffer
1700
1705
1706////////////////////////////////////////////////////////////////////////////////
1707/// Read array of Short_t from buffer
1708
1713
1714////////////////////////////////////////////////////////////////////////////////
1715/// Read array of UShort_t from buffer
1716
1721
1722////////////////////////////////////////////////////////////////////////////////
1723/// Read array of Int_t from buffer
1724
1729
1730////////////////////////////////////////////////////////////////////////////////
1731/// Read array of UInt_t from buffer
1732
1737
1738////////////////////////////////////////////////////////////////////////////////
1739/// Read array of Long_t from buffer
1740
1745
1746////////////////////////////////////////////////////////////////////////////////
1747/// Read array of ULong_t from buffer
1748
1753
1754////////////////////////////////////////////////////////////////////////////////
1755/// Read array of Long64_t from buffer
1756
1761
1762////////////////////////////////////////////////////////////////////////////////
1763/// Read array of ULong64_t from buffer
1764
1769
1770////////////////////////////////////////////////////////////////////////////////
1771/// Read array of Float_t from buffer
1772
1777
1778////////////////////////////////////////////////////////////////////////////////
1779/// Read array of Double_t from buffer
1780
1785
1786////////////////////////////////////////////////////////////////////////////////
1787/// Read an array of 'n' objects from the I/O buffer.
1788/// Stores the objects read starting at the address 'start'.
1789/// The objects in the array are assume to be of class 'cl'.
1790
1792 const TClass *onFileClass)
1793{
1794 if (streamer) {
1795 streamer->SetOnFileClass(onFileClass);
1796 (*streamer)(*this, start, 0);
1797 return;
1798 }
1799
1800 int objectSize = cl->Size();
1801 char *obj = (char *)start;
1802 char *end = obj + n * objectSize;
1803
1804 for (; obj < end; obj += objectSize)
1805 ((TClass *)cl)->Streamer(obj, *this, onFileClass);
1806}
1807
1808////////////////////////////////////////////////////////////////////////////////
1809/// Read an array of 'n' objects from the I/O buffer.
1810///
1811/// The objects read are stored starting at the address '*start'
1812/// The objects in the array are assumed to be of class 'cl' or a derived class.
1813/// 'mode' indicates whether the data member is marked with '->'
1814
1815void TBufferXML::ReadFastArray(void **start, const TClass *cl, Int_t n, Bool_t isPreAlloc, TMemberStreamer *streamer,
1816 const TClass *onFileClass)
1817{
1818
1819 Bool_t oldStyle = kFALSE; // flag used to reproduce old-style I/= actions for kSTLp
1820
1821 if ((GetIOVersion() < 4) && !isPreAlloc) {
1822 TStreamerElement *elem = Stack()->fElem;
1823 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
1825 oldStyle = kTRUE;
1826 }
1827
1828 if (streamer) {
1829 if (isPreAlloc) {
1830 for (Int_t j = 0; j < n; j++) {
1831 if (!start[j])
1832 start[j] = cl->New();
1833 }
1834 }
1835 streamer->SetOnFileClass(onFileClass);
1836 (*streamer)(*this, (void *)start, oldStyle ? n : 0);
1837 return;
1838 }
1839
1840 if (!isPreAlloc) {
1841
1842 for (Int_t j = 0; j < n; j++) {
1843 if (oldStyle) {
1844 if (!start[j])
1845 start[j] = ((TClass *)cl)->New();
1846 ((TClass *)cl)->Streamer(start[j], *this);
1847 continue;
1848 }
1849 // delete the object or collection
1850 void *old = start[j];
1851 start[j] = ReadObjectAny(cl);
1852 if (old && old != start[j] && TStreamerInfo::CanDelete()
1853 // There are some cases where the user may set up a pointer in the (default)
1854 // constructor but not mark this pointer as transient. Sometime the value
1855 // of this pointer is the address of one of the object with just created
1856 // and the following delete would result in the deletion (possibly of the
1857 // top level object we are goint to return!).
1858 // Eventhough this is a user error, we could prevent the crash by simply
1859 // adding:
1860 // && !CheckObject(start[j],cl)
1861 // However this can increase the read time significantly (10% in the case
1862 // of one TLine pointer in the test/Track and run ./Event 200 0 0 20 30000
1863 //
1864 // If ReadObjectAny returned the same value as we previous had, this means
1865 // that when writing this object (start[j] had already been written and
1866 // is indeed pointing to the same object as the object the user set up
1867 // in the default constructor).
1868 ) {
1869 ((TClass *)cl)->Destructor(old, kFALSE); // call delete and destructor
1870 }
1871 }
1872
1873 } else {
1874 // case //-> in comment
1875
1876 for (Int_t j = 0; j < n; j++) {
1877 if (!start[j])
1878 start[j] = ((TClass *)cl)->New();
1879 ((TClass *)cl)->Streamer(start[j], *this, onFileClass);
1880 }
1881 }
1882}
1883
1884template <typename T>
1886{
1887 if (fCompressLevel > 0) {
1888 Int_t indx = 0;
1889 while (indx < arrsize) {
1890 XMLNodePointer_t elemnode = XmlWriteBasic(arr[indx]);
1891 Int_t curr = indx++;
1892 while ((indx < arrsize) && (arr[indx] == arr[curr]))
1893 indx++;
1894 if (indx - curr > 1)
1895 fXML->NewIntAttr(elemnode, xmlio::cnt, indx - curr);
1896 }
1897 } else {
1898 for (Int_t indx = 0; indx < arrsize; indx++)
1899 XmlWriteBasic(arr[indx]);
1900 }
1901}
1902
1903////////////////////////////////////////////////////////////////////////////////
1904/// Write array, including it size
1905/// Content may be compressed
1906
1907template <typename T>
1909{
1912 fXML->NewIntAttr(arrnode, xmlio::Size, arrsize);
1913 PushStack(arrnode);
1914 XmlWriteArrayContent(arr, arrsize);
1915 PopStack();
1916}
1917
1918////////////////////////////////////////////////////////////////////////////////
1919/// Write array of Bool_t to buffer
1920
1922{
1923 XmlWriteArray(b, n);
1924}
1925
1926////////////////////////////////////////////////////////////////////////////////
1927/// Write array of Char_t to buffer
1928
1930{
1931 XmlWriteArray(c, n);
1932}
1933
1934////////////////////////////////////////////////////////////////////////////////
1935/// Write array of UChar_t to buffer
1936
1938{
1939 XmlWriteArray(c, n);
1940}
1941
1942////////////////////////////////////////////////////////////////////////////////
1943/// Write array of Short_t to buffer
1944
1946{
1947 XmlWriteArray(h, n);
1948}
1949
1950////////////////////////////////////////////////////////////////////////////////
1951/// Write array of UShort_t to buffer
1952
1954{
1955 XmlWriteArray(h, n);
1956}
1957
1958////////////////////////////////////////////////////////////////////////////////
1959/// Write array of Int_ to buffer
1960
1962{
1963 XmlWriteArray(i, n);
1964}
1965
1966////////////////////////////////////////////////////////////////////////////////
1967/// Write array of UInt_t to buffer
1968
1970{
1971 XmlWriteArray(i, n);
1972}
1973
1974////////////////////////////////////////////////////////////////////////////////
1975/// Write array of Long_t to buffer
1976
1978{
1979 XmlWriteArray(l, n);
1980}
1981
1982////////////////////////////////////////////////////////////////////////////////
1983/// Write array of ULong_t to buffer
1984
1986{
1987 XmlWriteArray(l, n);
1988}
1989
1990////////////////////////////////////////////////////////////////////////////////
1991/// Write array of Long64_t to buffer
1992
1994{
1995 XmlWriteArray(l, n);
1996}
1997
1998////////////////////////////////////////////////////////////////////////////////
1999/// Write array of ULong64_t to buffer
2000
2002{
2003 XmlWriteArray(l, n);
2004}
2005
2006////////////////////////////////////////////////////////////////////////////////
2007/// Write array of Float_t to buffer
2008
2010{
2011 XmlWriteArray(f, n);
2012}
2013
2014////////////////////////////////////////////////////////////////////////////////
2015/// Write array of Double_t to buffer
2016
2018{
2019 XmlWriteArray(d, n);
2020}
2021
2022/////////////////////////////////////////////////////////////////////////////////
2023/// Write array without size attribute
2024/// Also treat situation, when instead of one single array
2025/// chain of several elements should be produced
2026/// \note Due to the current limit of the buffer size, the function aborts execution of the program in case of underflow or overflow. See https://github.com/root-project/root/issues/6734 for more details.
2027///
2028template <typename T>
2030{
2032 if (n <= 0)
2033 return;
2034 if (n > std::numeric_limits<Int_t>::max()) {
2035 Fatal("XmlWriteFastArray", "Array larger than 2^31 elements cannot be stored in XML");
2036 return; // In case the user re-routes the error handler to not die when Fatal is called
2037 }
2039 PushStack(arrnode);
2040 XmlWriteArrayContent(arr, n);
2041 PopStack();
2042}
2043
2044////////////////////////////////////////////////////////////////////////////////
2045/// Write array of Bool_t to buffer
2046
2051
2052////////////////////////////////////////////////////////////////////////////////
2053/// Write array of Char_t to buffer
2054/// If array does not include any special characters,
2055/// it will be reproduced as CharStar node with string as attribute
2056
2058{
2059 Bool_t usedefault = (n == 0);
2060 const Char_t *buf = c;
2061 if (!usedefault)
2062 for (Long64_t i = 0; i < n; i++) {
2063 if (*buf < 27) {
2064 usedefault = kTRUE;
2065 break;
2066 }
2067 buf++;
2068 }
2069 if (usedefault) {
2071 } else {
2072 Char_t *buf2 = new Char_t[n + 1];
2073 memcpy(buf2, c, n);
2074 buf2[n] = 0;
2076 delete[] buf2;
2077 }
2078}
2079
2080////////////////////////////////////////////////////////////////////////////////
2081/// Write array of UChar_t to buffer
2082
2087
2088////////////////////////////////////////////////////////////////////////////////
2089/// Write array of Short_t to buffer
2090
2095
2096////////////////////////////////////////////////////////////////////////////////
2097/// Write array of UShort_t to buffer
2098
2103
2104////////////////////////////////////////////////////////////////////////////////
2105/// Write array of Int_t to buffer
2106
2108{
2109 XmlWriteFastArray(i, n);
2110}
2111
2112////////////////////////////////////////////////////////////////////////////////
2113/// Write array of UInt_t to buffer
2114
2116{
2117 XmlWriteFastArray(i, n);
2118}
2119
2120////////////////////////////////////////////////////////////////////////////////
2121/// Write array of Long_t to buffer
2122
2127
2128////////////////////////////////////////////////////////////////////////////////
2129/// Write array of ULong_t to buffer
2130
2135
2136////////////////////////////////////////////////////////////////////////////////
2137/// Write array of Long64_t to buffer
2138
2143
2144////////////////////////////////////////////////////////////////////////////////
2145/// Write array of ULong64_t to buffer
2146
2151
2152////////////////////////////////////////////////////////////////////////////////
2153/// Write array of Float_t to buffer
2154
2159
2160////////////////////////////////////////////////////////////////////////////////
2161/// Write array of Double_t to buffer
2162
2167
2168////////////////////////////////////////////////////////////////////////////////
2169/// Write array of n characters into the I/O buffer.
2170/// Used only by TLeafC, just dummy implementation here
2171
2176
2177////////////////////////////////////////////////////////////////////////////////
2178/// Write an array of object starting at the address 'start' and of length 'n'
2179/// the objects in the array are assumed to be of class 'cl'
2180
2182{
2183 if (streamer) {
2184 (*streamer)(*this, start, 0);
2185 return;
2186 }
2187
2188 char *obj = (char *)start;
2189 if (!n)
2190 n = 1;
2191 int size = cl->Size();
2192
2193 for (Long64_t j = 0; j < n; j++, obj += size) {
2194 ((TClass *)cl)->Streamer(obj, *this);
2195 }
2196}
2197
2198////////////////////////////////////////////////////////////////////////////////
2199/// Write an array of object starting at the address '*start' and of length 'n'
2200/// the objects in the array are of class 'cl'
2201/// 'isPreAlloc' indicates whether the data member is marked with '->'
2202/// Return:
2203/// - 0: success
2204/// - 2: truncated success (i.e actual class is missing. Only ptrClass saved.)
2205
2207{
2208 // if isPreAlloc is true (data member has a ->) we can assume that the pointer
2209 // is never 0.
2210
2211 Bool_t oldStyle = kFALSE; // flag used to reproduce old-style I/O actions for kSTLp
2212
2213 if ((GetIOVersion() < 4) && !isPreAlloc) {
2214 TStreamerElement *elem = Stack()->fElem;
2215 if (elem && ((elem->GetType() == TStreamerInfo::kSTLp) ||
2217 oldStyle = kTRUE;
2218 }
2219
2220 if (streamer) {
2221 (*streamer)(*this, (void *)start, oldStyle ? n : 0);
2222 return 0;
2223 }
2224
2225 int strInfo = 0;
2226
2227 Int_t res = 0;
2228
2229 if (!isPreAlloc) {
2230
2231 for (Long64_t j = 0; j < n; j++) {
2232 // must write StreamerInfo if pointer is null
2233 if (!strInfo && !start[j] && !oldStyle) {
2234 if (cl->Property() & kIsAbstract) {
2235 // Do not try to generate the StreamerInfo for an abstract class
2236 } else {
2237 TStreamerInfo *info = (TStreamerInfo *)((TClass *)cl)->GetStreamerInfo();
2238 ForceWriteInfo(info, kFALSE);
2239 }
2240 }
2241 strInfo = 2003;
2242 if (oldStyle)
2243 ((TClass *)cl)->Streamer(start[j], *this);
2244 else
2245 res |= WriteObjectAny(start[j], cl);
2246 }
2247
2248 } else {
2249 // case //-> in comment
2250
2251 for (Long64_t j = 0; j < n; j++) {
2252 if (!start[j])
2253 start[j] = ((TClass *)cl)->New();
2254 ((TClass *)cl)->Streamer(start[j], *this);
2255 }
2256 }
2257 return res;
2258}
2259
2260////////////////////////////////////////////////////////////////////////////////
2261/// Stream object to/from buffer
2262
2263void TBufferXML::StreamObject(void *obj, const TClass *cl, const TClass * /* onfileClass */)
2264{
2265 if (GetIOVersion() < 4) {
2266 TStreamerElement *elem = Stack()->fElem;
2267 if (elem && (elem->GetType() == TStreamerInfo::kTObject)) {
2268 ((TObject *)obj)->TObject::Streamer(*this);
2269 return;
2270 } else if (elem && (elem->GetType() == TStreamerInfo::kTNamed)) {
2271 ((TNamed *)obj)->TNamed::Streamer(*this);
2272 return;
2273 }
2274 }
2275
2277 if (gDebug > 1)
2278 Info("StreamObject", "Class: %s", (cl ? cl->GetName() : "none"));
2279 if (IsReading())
2280 XmlReadObject(obj);
2281 else
2282 XmlWriteObject(obj, cl, kTRUE);
2283}
2284
2285////////////////////////////////////////////////////////////////////////////////
2286/// Reads Bool_t value from buffer
2287
2293
2294////////////////////////////////////////////////////////////////////////////////
2295/// Reads Char_t value from buffer
2296
2302
2303////////////////////////////////////////////////////////////////////////////////
2304/// Reads UChar_t value from buffer
2305
2311
2312////////////////////////////////////////////////////////////////////////////////
2313/// Reads Short_t value from buffer
2314
2320
2321////////////////////////////////////////////////////////////////////////////////
2322/// Reads UShort_t value from buffer
2323
2329
2330////////////////////////////////////////////////////////////////////////////////
2331/// Reads Int_t value from buffer
2332
2334{
2336 XmlReadBasic(i);
2337}
2338
2339////////////////////////////////////////////////////////////////////////////////
2340/// Reads UInt_t value from buffer
2341
2343{
2345 XmlReadBasic(i);
2346}
2347
2348////////////////////////////////////////////////////////////////////////////////
2349/// Reads Long_t value from buffer
2350
2356
2357////////////////////////////////////////////////////////////////////////////////
2358/// Reads ULong_t value from buffer
2359
2365
2366////////////////////////////////////////////////////////////////////////////////
2367/// Reads Long64_t value from buffer
2368
2374
2375////////////////////////////////////////////////////////////////////////////////
2376/// Reads ULong64_t value from buffer
2377
2383
2384////////////////////////////////////////////////////////////////////////////////
2385/// Reads Float_t value from buffer
2386
2392
2393////////////////////////////////////////////////////////////////////////////////
2394/// Reads Double_t value from buffer
2395
2401
2402////////////////////////////////////////////////////////////////////////////////
2403/// Reads array of characters from buffer
2404
2406{
2408 const char *buf;
2409 if ((buf = XmlReadValue(xmlio::CharStar)))
2410 strcpy(c, buf); // NOLINT unfortunately, size of target buffer cannot be controlled here
2411}
2412
2413////////////////////////////////////////////////////////////////////////////////
2414/// Reads a TString
2415
2417{
2418 if (GetIOVersion() < 3) {
2419 // original TBufferFile method can not be used, while used TString methods are private
2420 // try to reimplement close to the original
2421 Int_t nbig;
2422 UChar_t nwh;
2423 *this >> nwh;
2424 if (nwh == 0) {
2425 s.Resize(0);
2426 } else {
2427 if (nwh == 255)
2428 *this >> nbig;
2429 else
2430 nbig = nwh;
2431
2432 char *data = new char[nbig+1];
2433 data[nbig] = 0;
2434 ReadFastArray(data, nbig);
2435 s = data;
2436 delete[] data;
2437 }
2438 } else {
2440 const char *buf = XmlReadValue(xmlio::String);
2441 if (buf)
2442 s = buf;
2443 }
2444}
2445
2446////////////////////////////////////////////////////////////////////////////////
2447/// Reads a std::string
2448
2449void TBufferXML::ReadStdString(std::string *obj)
2450{
2451 if (GetIOVersion() < 3) {
2452 if (!obj) {
2453 Error("ReadStdString", "The std::string address is nullptr but should not");
2454 return;
2455 }
2456 Int_t nbig;
2457 UChar_t nwh;
2458 *this >> nwh;
2459 if (nwh == 0) {
2460 obj->clear();
2461 } else {
2462 if (obj->size()) {
2463 // Insure that the underlying data storage is not shared
2464 (*obj)[0] = '\0';
2465 }
2466 if (nwh == 255) {
2467 *this >> nbig;
2468 obj->resize(nbig, '\0');
2469 ReadFastArray((char *)obj->data(), nbig);
2470 } else {
2471 obj->resize(nwh, '\0');
2472 ReadFastArray((char *)obj->data(), nwh);
2473 }
2474 }
2475 } else {
2477 const char *buf = XmlReadValue(xmlio::String);
2478 if (buf && obj)
2479 *obj = buf;
2480 }
2481}
2482
2483////////////////////////////////////////////////////////////////////////////////
2484/// Read a char* string
2485
2487{
2488 delete[] s;
2489 s = nullptr;
2490
2491 Int_t nch;
2492 *this >> nch;
2493 if (nch > 0) {
2494 s = new char[nch + 1];
2495 ReadFastArray(s, nch);
2496 s[nch] = 0;
2497 }
2498}
2499
2500////////////////////////////////////////////////////////////////////////////////
2501/// Writes Bool_t value to buffer
2502
2508
2509////////////////////////////////////////////////////////////////////////////////
2510/// Writes Char_t value to buffer
2511
2517
2518////////////////////////////////////////////////////////////////////////////////
2519/// Writes UChar_t value to buffer
2520
2526
2527////////////////////////////////////////////////////////////////////////////////
2528/// Writes Short_t value to buffer
2529
2535
2536////////////////////////////////////////////////////////////////////////////////
2537/// Writes UShort_t value to buffer
2538
2544
2545////////////////////////////////////////////////////////////////////////////////
2546/// Writes Int_t value to buffer
2547
2549{
2551 XmlWriteBasic(i);
2552}
2553
2554////////////////////////////////////////////////////////////////////////////////
2555/// Writes UInt_t value to buffer
2556
2562
2563////////////////////////////////////////////////////////////////////////////////
2564/// Writes Long_t value to buffer
2565
2571
2572////////////////////////////////////////////////////////////////////////////////
2573/// Writes ULong_t value to buffer
2574
2580
2581////////////////////////////////////////////////////////////////////////////////
2582/// Writes Long64_t value to buffer
2583
2589
2590////////////////////////////////////////////////////////////////////////////////
2591/// Writes ULong64_t value to buffer
2592
2598
2599////////////////////////////////////////////////////////////////////////////////
2600/// Writes Float_t value to buffer
2601
2607
2608////////////////////////////////////////////////////////////////////////////////
2609/// Writes Double_t value to buffer
2610
2616
2617////////////////////////////////////////////////////////////////////////////////
2618/// Writes array of characters to buffer
2619
2625
2626////////////////////////////////////////////////////////////////////////////////
2627/// Writes a TString
2628
2630{
2631 if (GetIOVersion() < 3) {
2632 // original TBufferFile method, keep for compatibility
2633 Int_t nbig = s.Length();
2634 UChar_t nwh;
2635 if (nbig > 254) {
2636 nwh = 255;
2637 *this << nwh;
2638 *this << nbig;
2639 } else {
2640 nwh = UChar_t(nbig);
2641 *this << nwh;
2642 }
2643 const char *data = s.Data();
2644 WriteFastArray(data, nbig);
2645 } else {
2648 }
2649}
2650
2651////////////////////////////////////////////////////////////////////////////////
2652/// Writes a std::string
2653
2654void TBufferXML::WriteStdString(const std::string *obj)
2655{
2656 if (GetIOVersion() < 3) {
2657 if (!obj) {
2658 *this << (UChar_t)0;
2659 WriteFastArray("", 0);
2660 return;
2661 }
2662
2663 UChar_t nwh;
2664 Int_t nbig = obj->length();
2665 if (nbig > 254) {
2666 nwh = 255;
2667 *this << nwh;
2668 *this << nbig;
2669 } else {
2670 nwh = UChar_t(nbig);
2671 *this << nwh;
2672 }
2673 WriteFastArray(obj->data(), nbig);
2674 } else {
2676 XmlWriteValue(obj ? obj->c_str() : "", xmlio::String);
2677 }
2678}
2679
2680////////////////////////////////////////////////////////////////////////////////
2681/// Write a char* string
2682
2684{
2685 Int_t nch = 0;
2686 if (s) {
2687 nch = strlen(s);
2688 *this << nch;
2689 WriteFastArray(s, nch);
2690 } else {
2691 *this << nch;
2692 }
2693}
2694
2695////////////////////////////////////////////////////////////////////////////////
2696/// Converts Char_t to string and add xml node to buffer
2697
2699{
2700 char buf[50];
2701 snprintf(buf, sizeof(buf), "%d", value);
2702 return XmlWriteValue(buf, xmlio::Char);
2703}
2704
2705////////////////////////////////////////////////////////////////////////////////
2706/// Converts Short_t to string and add xml node to buffer
2707
2709{
2710 char buf[50];
2711 snprintf(buf, sizeof(buf), "%hd", value);
2712 return XmlWriteValue(buf, xmlio::Short);
2713}
2714
2715////////////////////////////////////////////////////////////////////////////////
2716/// Converts Int_t to string and add xml node to buffer
2717
2719{
2720 char buf[50];
2721 snprintf(buf, sizeof(buf), "%d", value);
2722 return XmlWriteValue(buf, xmlio::Int);
2723}
2724
2725////////////////////////////////////////////////////////////////////////////////
2726/// Converts Long_t to string and add xml node to buffer
2727
2729{
2730 char buf[50];
2731 snprintf(buf, sizeof(buf), "%ld", value);
2732 return XmlWriteValue(buf, xmlio::Long);
2733}
2734
2735////////////////////////////////////////////////////////////////////////////////
2736/// Converts Long64_t to string and add xml node to buffer
2737
2739{
2740 std::string buf = std::to_string(value);
2741 return XmlWriteValue(buf.c_str(), xmlio::Long64);
2742}
2743
2744////////////////////////////////////////////////////////////////////////////////
2745/// Converts Float_t to string and add xml node to buffer
2746
2748{
2749 char buf[200];
2750 ConvertFloat(value, buf, sizeof(buf), kTRUE);
2751 return XmlWriteValue(buf, xmlio::Float);
2752}
2753
2754////////////////////////////////////////////////////////////////////////////////
2755/// Converts Double_t to string and add xml node to buffer
2756
2758{
2759 char buf[1000];
2760 ConvertDouble(value, buf, sizeof(buf), kTRUE);
2761 return XmlWriteValue(buf, xmlio::Double);
2762}
2763
2764////////////////////////////////////////////////////////////////////////////////
2765/// Converts Bool_t to string and add xml node to buffer
2766
2771
2772////////////////////////////////////////////////////////////////////////////////
2773/// Converts UChar_t to string and add xml node to buffer
2774
2776{
2777 char buf[50];
2778 snprintf(buf, sizeof(buf), "%u", value);
2779 return XmlWriteValue(buf, xmlio::UChar);
2780}
2781
2782////////////////////////////////////////////////////////////////////////////////
2783/// Converts UShort_t to string and add xml node to buffer
2784
2786{
2787 char buf[50];
2788 snprintf(buf, sizeof(buf), "%hu", value);
2789 return XmlWriteValue(buf, xmlio::UShort);
2790}
2791
2792////////////////////////////////////////////////////////////////////////////////
2793/// Converts UInt_t to string and add xml node to buffer
2794
2796{
2797 char buf[50];
2798 snprintf(buf, sizeof(buf), "%u", value);
2799 return XmlWriteValue(buf, xmlio::UInt);
2800}
2801
2802////////////////////////////////////////////////////////////////////////////////
2803/// Converts ULong_t to string and add xml node to buffer
2804
2806{
2807 char buf[50];
2808 snprintf(buf, sizeof(buf), "%lu", value);
2809 return XmlWriteValue(buf, xmlio::ULong);
2810}
2811
2812////////////////////////////////////////////////////////////////////////////////
2813/// Converts ULong64_t to string and add xml node to buffer
2814
2816{
2817 std::string buf = std::to_string(value);
2818 return XmlWriteValue(buf.c_str(), xmlio::ULong64);
2819}
2820
2821////////////////////////////////////////////////////////////////////////////////
2822/// Create xml node with specified name and adds it to stack node
2823
2824XMLNodePointer_t TBufferXML::XmlWriteValue(const char *value, const char *name)
2825{
2826 XMLNodePointer_t node = nullptr;
2827
2828 if (fCanUseCompact)
2829 node = StackNode();
2830 else
2831 node = CreateItemNode(name);
2832
2833 fXML->NewAttr(node, nullptr, xmlio::v, value);
2834
2836
2837 return node;
2838}
2839
2840////////////////////////////////////////////////////////////////////////////////
2841/// Reads string from current xml node and convert it to Char_t value
2842
2844{
2845 const char *res = XmlReadValue(xmlio::Char);
2846 if (res) {
2847 int n;
2848 sscanf(res, "%d", &n);
2849 value = n;
2850 } else
2851 value = 0;
2852}
2853
2854////////////////////////////////////////////////////////////////////////////////
2855/// Reads string from current xml node and convert it to Short_t value
2856
2858{
2859 const char *res = XmlReadValue(xmlio::Short);
2860 if (res)
2861 sscanf(res, "%hd", &value);
2862 else
2863 value = 0;
2864}
2865
2866////////////////////////////////////////////////////////////////////////////////
2867/// Reads string from current xml node and convert it to Int_t value
2868
2870{
2871 const char *res = XmlReadValue(xmlio::Int);
2872 if (res)
2873 sscanf(res, "%d", &value);
2874 else
2875 value = 0;
2876}
2877
2878////////////////////////////////////////////////////////////////////////////////
2879/// Reads string from current xml node and convert it to Long_t value
2880
2882{
2883 const char *res = XmlReadValue(xmlio::Long);
2884 if (res)
2885 sscanf(res, "%ld", &value);
2886 else
2887 value = 0;
2888}
2889
2890////////////////////////////////////////////////////////////////////////////////
2891/// Reads string from current xml node and convert it to Long64_t value
2892
2894{
2895 const char *res = XmlReadValue(xmlio::Long64);
2896 if (res)
2897 value = (Long64_t)std::stoll(res);
2898 else
2899 value = 0;
2900}
2901
2902////////////////////////////////////////////////////////////////////////////////
2903/// Reads string from current xml node and convert it to Float_t value
2904
2906{
2907 const char *res = XmlReadValue(xmlio::Float);
2908 if (res)
2909 sscanf(res, "%f", &value);
2910 else
2911 value = 0.;
2912}
2913
2914////////////////////////////////////////////////////////////////////////////////
2915/// Reads string from current xml node and convert it to Double_t value
2916
2918{
2919 const char *res = XmlReadValue(xmlio::Double);
2920 if (res)
2921 sscanf(res, "%lf", &value);
2922 else
2923 value = 0.;
2924}
2925
2926////////////////////////////////////////////////////////////////////////////////
2927/// Reads string from current xml node and convert it to Bool_t value
2928
2930{
2931 const char *res = XmlReadValue(xmlio::Bool);
2932 if (res)
2933 value = (strcmp(res, xmlio::True) == 0);
2934 else
2935 value = kFALSE;
2936}
2937
2938////////////////////////////////////////////////////////////////////////////////
2939/// Reads string from current xml node and convert it to UChar_t value
2940
2942{
2943 const char *res = XmlReadValue(xmlio::UChar);
2944 if (res) {
2945 unsigned int n;
2946 sscanf(res, "%ud", &n);
2947 value = n;
2948 } else
2949 value = 0;
2950}
2951
2952////////////////////////////////////////////////////////////////////////////////
2953/// Reads string from current xml node and convert it to UShort_t value
2954
2956{
2957 const char *res = XmlReadValue(xmlio::UShort);
2958 if (res)
2959 sscanf(res, "%hud", &value);
2960 else
2961 value = 0;
2962}
2963
2964////////////////////////////////////////////////////////////////////////////////
2965/// Reads string from current xml node and convert it to UInt_t value
2966
2968{
2969 const char *res = XmlReadValue(xmlio::UInt);
2970 if (res)
2971 sscanf(res, "%u", &value);
2972 else
2973 value = 0;
2974}
2975
2976////////////////////////////////////////////////////////////////////////////////
2977/// Reads string from current xml node and convert it to ULong_t value
2978
2980{
2981 const char *res = XmlReadValue(xmlio::ULong);
2982 if (res)
2983 sscanf(res, "%lu", &value);
2984 else
2985 value = 0;
2986}
2987
2988////////////////////////////////////////////////////////////////////////////////
2989/// Reads string from current xml node and convert it to ULong64_t value
2990
2992{
2993 const char *res = XmlReadValue(xmlio::ULong64);
2994 if (res)
2995 value = (ULong64_t)std::stoull(res);
2996 else
2997 value = 0;
2998}
2999
3000////////////////////////////////////////////////////////////////////////////////
3001/// read string value from current stack node
3002
3003const char *TBufferXML::XmlReadValue(const char *name)
3004{
3005 if (fErrorFlag > 0)
3006 return nullptr;
3007
3008 Bool_t trysimple = fCanUseCompact;
3010
3011 if (trysimple) {
3012 if (fXML->HasAttr(Stack(1)->fNode, xmlio::v))
3013 fValueBuf = fXML->GetAttr(Stack(1)->fNode, xmlio::v);
3014 else
3015 trysimple = kFALSE;
3016 }
3017
3018 if (!trysimple) {
3019 if (!VerifyItemNode(name, "XmlReadValue"))
3020 return nullptr;
3021 fValueBuf = fXML->GetAttr(StackNode(), xmlio::v);
3022 }
3023
3024 if (gDebug > 4)
3025 Info("XmlReadValue", " Name = %s value = %s", name, fValueBuf.Data());
3026
3027 if (!trysimple)
3028 ShiftStack("readvalue");
3029
3030 return fValueBuf.Data();
3031}
3032
3033////////////////////////////////////////////////////////////////////////////////
3034/// Return current streamer info element
3035
#define R__ALWAYS_INLINE
Definition RConfig.hxx:552
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define h(i)
Definition RSha256.hxx:106
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
start
Definition Rotated.cxx:223
unsigned short UShort_t
Unsigned Short integer 2 bytes (unsigned short).
Definition RtypesCore.h:54
int Int_t
Signed integer 4 bytes (int).
Definition RtypesCore.h:59
long Longptr_t
Integer large enough to hold a pointer (platform-dependent).
Definition RtypesCore.h:89
short Version_t
Class version identifier (short).
Definition RtypesCore.h:79
unsigned char UChar_t
Unsigned Character 1 byte (unsigned char).
Definition RtypesCore.h:52
char Char_t
Character 1 byte (char).
Definition RtypesCore.h:51
unsigned int UInt_t
Unsigned integer 4 bytes (unsigned int).
Definition RtypesCore.h:60
unsigned long ULong_t
Unsigned long integer 4 bytes (unsigned long). Size depends on architecture.
Definition RtypesCore.h:69
long Long_t
Signed long integer 4 bytes (long). Size depends on architecture.
Definition RtypesCore.h:68
bool Bool_t
Boolean (0=false, 1=true) (bool).
Definition RtypesCore.h:77
short Short_t
Signed Short integer 2 bytes (short).
Definition RtypesCore.h:53
constexpr Bool_t kFALSE
Definition RtypesCore.h:108
double Double_t
Double 8 bytes.
Definition RtypesCore.h:73
long long Long64_t
Portable signed long integer 8 bytes.
Definition RtypesCore.h:83
unsigned long long ULong64_t
Portable unsigned long integer 8 bytes.
Definition RtypesCore.h:84
float Float_t
Float 4 bytes (float).
Definition RtypesCore.h:71
constexpr Bool_t kTRUE
Definition RtypesCore.h:107
@ kIsAbstract
Definition TDictionary.h:71
char name[80]
Definition TGX11.cxx:148
Int_t gDebug
Definition TROOT.cxx:777
#define gROOT
Definition TROOT.h:417
void * XMLNodePointer_t
Definition TXMLEngine.h:17
void * XMLNsPointer_t
Definition TXMLEngine.h:18
#define snprintf
Definition civetweb.c:1579
void InitMap() override
Create the fMap container and initialize them with the null object.
void ForceWriteInfo(TVirtualStreamerInfo *info, Bool_t force) override
force writing the TStreamerInfo to the file
TExMap * fMap
Map containing object,offset pairs for reading/writing.
Definition TBufferIO.h:39
void MapObject(const TObject *obj, UInt_t offset=1) override
Add object to the fMap container.
Long64_t GetObjectTag(const void *obj)
Returns tag for specified object from objects map (if exists) Returns 0 if object not included into o...
static ULong_t Void_Hash(const void *ptr)
Return hash value for provided object.
Definition TBufferIO.h:53
void GetMappedObject(UInt_t tag, void *&ptr, TClass *&ClassPtr) const override
Retrieve the object stored in the buffer's object map at 'tag' Set ptr and ClassPtr respectively to t...
Int_t WriteObjectAny(const void *obj, const TClass *ptrClass, Bool_t cacheReuse=kTRUE) override
Write object to I/O buffer.
static const char * ConvertFloat(Float_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
TBufferText()
Default constructor.
static const char * ConvertDouble(Double_t v, char *buf, unsigned len, Bool_t not_optimize=kFALSE)
convert float to string with configured format
Bool_t ProcessPointer(const void *ptr, XMLNodePointer_t node)
Add "ptr" attribute to node, if ptr is null or if ptr is pointer on object, which is already saved in...
void WriteLong(Long_t l) final
Writes Long_t value to buffer.
void SetXML(TXMLEngine *xml)
Definition TBufferXML.h:229
Int_t GetCompressionSettings() const
Definition TBufferXML.h:346
TXMLStackObj * PushStack(XMLNodePointer_t current, Bool_t simple=kFALSE)
Add new level to xml stack.
Bool_t VerifyAttr(XMLNodePointer_t node, const char *name, const char *value, const char *errinfo=nullptr)
Checks, that attribute of specified name exists and has specified value.
void WorkWithClass(TStreamerInfo *info, const TClass *cl=nullptr)
Prepares buffer to stream data of specified class.
Bool_t VerifyStackNode(const char *name, const char *errinfo=nullptr)
Check, if stack node has specified name.
void ReadUShort(UShort_t &s) final
Reads UShort_t value from buffer.
void XmlWriteFastArray(const T *arr, Long64_t n)
Write array without size attribute Also treat situation, when instead of one single array chain of se...
void ReadUInt(UInt_t &i) final
Reads UInt_t value from buffer.
Int_t fCompressLevel
! Compression level and algorithm
Definition TBufferXML.h:327
void SetCompressionSettings(Int_t settings=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault)
Used to specify the compression level and algorithm.
Int_t XmlReadArray(T *&arr, bool is_static=false)
Template method to read array with size attribute If necessary, array is created.
TString fValueBuf
! Current value buffer
Definition TBufferXML.h:323
void StreamObject(void *obj, const TClass *cl, const TClass *onFileClass=nullptr) final
Stream object to/from buffer.
void WriteStdString(const std::string *s) final
Writes a std::string.
void ReadDouble(Double_t &d) final
Reads Double_t value from buffer.
TBufferXML(TBuffer::EMode mode)
Creates buffer object to serialize/deserialize data to/from xml.
Bool_t VerifyNode(XMLNodePointer_t node, const char *name, const char *errinfo=nullptr)
Check if node has specified name.
void ReadFastArrayString(Char_t *c, Int_t n) final
Read array of n characters from the I/O buffer.
void WriteLong64(Long64_t l) final
Writes Long64_t value to buffer.
void WriteChar(Char_t c) final
Writes Char_t value to buffer.
TXMLEngine * fXML
! instance of TXMLEngine for working with XML structures
Definition TBufferXML.h:320
std::deque< std::unique_ptr< TXMLStackObj > > fStack
! Stack of processed objects
Definition TBufferXML.h:321
static TString ConvertToXML(const TObject *obj, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Converts object, inherited from TObject class, to XML string GenericLayout defines layout choice for ...
void WriteFloat(Float_t f) final
Writes Float_t value to buffer.
void ReadTString(TString &s) final
Reads a TString.
void WriteTString(const TString &s) final
Writes a TString.
void IncrementLevel(TVirtualStreamerInfo *) final
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and indent new level in xm...
void SetIOVersion(Int_t v)
Definition TBufferXML.h:66
void WriteArray(const Bool_t *b, Int_t n) final
Write array of Bool_t to buffer.
XMLNodePointer_t XmlWriteAny(const void *obj, const TClass *cl)
Convert object of any class to xml structures Return pointer on top xml element.
void XmlReadBasic(Char_t &value)
Reads string from current xml node and convert it to Char_t value.
void ReadULong(ULong_t &l) final
Reads ULong_t value from buffer.
Int_t GetIOVersion() const
Definition TBufferXML.h:65
XMLNodePointer_t XmlWriteValue(const char *value, const char *name)
Create xml node with specified name and adds it to stack node.
void SkipObjectAny() final
Skip any kind of object from buffer Actually skip only one node on current level of xml structure.
Bool_t VerifyStackAttr(const char *name, const char *value, const char *errinfo=nullptr)
Checks stack attribute.
void ReadFloat(Float_t &f) final
Reads Float_t value from buffer.
void ReadULong64(ULong64_t &l) final
Reads ULong64_t value from buffer.
XMLNodePointer_t XmlWriteBasic(Char_t value)
Converts Char_t to string and add xml node to buffer.
void ShiftStack(const char *info=nullptr)
Shift stack node to next.
void PerformPreProcessing(const TStreamerElement *elem, XMLNodePointer_t elemnode)
Function is unpack TObject and TString structures to be able read them from custom streamers of this ...
void ReadShort(Short_t &s) final
Reads Short_t value from buffer.
void BeforeIOoperation()
Function is called before any IO operation of TBuffer Now is used to store version value if no proper...
TClass * ReadClass(const TClass *cl=nullptr, UInt_t *objTag=nullptr) final
Function to read class from buffer, used in old-style streamers.
Int_t fErrorFlag
! Error flag
Definition TBufferXML.h:324
void ReadChar(Char_t &c) final
Reads Char_t value from buffer.
void XmlWriteArrayContent(const T *arr, Int_t arrsize)
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:322
void ClassBegin(const TClass *, Version_t=-1) final
Should be called at the beginning of custom class streamer.
void XmlWriteArray(const T *arr, Int_t arrsize)
Write array, including it size Content may be compressed.
void * XmlReadObject(void *obj, TClass **cl=nullptr)
Read object from the buffer.
void XmlReadArrayContent(T *arr, Int_t arrsize)
Template method to read array content.
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:325
void ReadStdString(std::string *s) final
Reads a std::string.
void WriteFastArrayString(const Char_t *c, Long64_t n) final
Write array of n characters into the I/O buffer.
void ReadBool(Bool_t &b) final
Reads Bool_t value from buffer.
void WriteUShort(UShort_t s) final
Writes UShort_t value to buffer.
void WriteClass(const TClass *cl) final
Function to write class into buffer, used in old-style streamers.
void WriteCharStar(char *s) final
Write a char* string.
const char * XmlReadValue(const char *name)
read string value from current stack node
Bool_t ExtractPointer(XMLNodePointer_t node, void *&ptr, TClass *&cl)
Searches for "ptr" attribute and returns pointer to object and class, if "ptr" attribute reference to...
void ReadFastArray(Bool_t *b, Int_t n) final
Read array of Bool_t from buffer.
void DecrementLevel(TVirtualStreamerInfo *) final
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and decrease level in xml ...
void XmlReadFastArray(T *arr, Int_t n)
Template method to read content of array, which not include size of array Also treated situation,...
void PerformPostProcessing()
Function is converts TObject and TString structures to more compact representation.
void SetStreamerElementNumber(TStreamerElement *elem, Int_t comp_type) final
Function is called from TStreamerInfo WriteBuffer and ReadBuffer functions and add/verify next elemen...
void WriteCharP(const Char_t *c) final
Writes array of characters to buffer.
static TObject * ConvertFromXML(const char *str, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object from XML, produced by ConvertToXML() method.
void ClassMember(const char *name, const char *typeName=nullptr, Int_t arrsize1=-1, Int_t arrsize2=-1) final
Method indicates name and typename of class member, which should be now streamed in custom streamer.
Int_t ReadStaticArray(Bool_t *b) final
Read array of Bool_t from buffer.
void * XmlReadAny(XMLNodePointer_t node, void *obj, TClass **cl)
Recreate object from xml structure.
XMLNodePointer_t StackNode()
Return pointer on current xml node.
void WriteObjectClass(const void *actualObjStart, const TClass *actualClass, Bool_t cacheReuse) final
Write object to buffer. Only used from TBuffer.
Bool_t VerifyItemNode(const char *name, const char *errinfo=nullptr)
Checks, if stack node is item and has specified name.
static void * ConvertFromXMLChecked(const char *xml, const TClass *expectedClass, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Convert from XML and check if object derived from specified class When possible, cast to given class.
void * ReadObjectAny(const TClass *clCast) final
Read object from buffer. Only used from TBuffer.
void ReadLong(Long_t &l) final
Reads Long_t value from buffer.
void ExtractReference(XMLNodePointer_t node, const void *ptr, const TClass *cl)
Analyze if node has "ref" attribute and register it to object map.
void SetCompressionLevel(Int_t level=ROOT::RCompressionSetting::ELevel::kUseMin)
See comments for function SetCompressionSettings.
Version_t ReadVersion(UInt_t *start=nullptr, UInt_t *bcnt=nullptr, const TClass *cl=nullptr) final
Read version value from buffer.
void ReadInt(Int_t &i) final
Reads Int_t value from buffer.
Int_t ReadArray(Bool_t *&b) final
Read array of Bool_t from buffer.
void SetCompressionAlgorithm(Int_t algorithm=ROOT::RCompressionSetting::EAlgorithm::kUseGlobal)
See comments for function SetCompressionSettings.
void WriteDouble(Double_t d) final
Writes Double_t value to buffer.
void CheckVersionBuf()
Checks buffer, filled by WriteVersion if next data is arriving, version should be stored in buffer.
XMLNodePointer_t XmlWriteObject(const void *obj, const TClass *objClass, Bool_t cacheReuse)
Write object to buffer If object was written before, only pointer will be stored Return pointer to to...
TXMLFile * XmlFile()
Returns pointer to TXMLFile object.
TVirtualStreamerInfo * GetInfo() final
Return current streamer info element.
void WriteUInt(UInt_t i) final
Writes UInt_t value to buffer.
void WorkWithElement(TStreamerElement *elem, Int_t comp_type)
This function is a part of SetStreamerElementNumber method.
void WriteBool(Bool_t b) final
Writes Bool_t value to buffer.
TClass * fExpectedBaseClass
! Pointer to class, which should be stored as parent of current
Definition TBufferXML.h:326
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:240
XMLNodePointer_t CreateItemNode(const char *name)
Create item node of specified name.
void WriteULong(ULong_t l) final
Writes ULong_t value to buffer.
TXMLStackObj * PopStack()
Remove one level from xml stack.
void CreateElemNode(const TStreamerElement *elem)
Create xml node correspondent to TStreamerElement object.
static void * ConvertFromXMLAny(const char *str, TClass **cl=nullptr, Bool_t GenericLayout=kFALSE, Bool_t UseNamespaces=kFALSE)
Read object of any class from XML, produced by ConvertToXML() method.
~TBufferXML() override
Destroy xml buffer.
Bool_t VerifyElemNode(const TStreamerElement *elem)
Checks if stack node correspond to TStreamerElement object.
void ReadCharStar(char *&s) final
Read a char* string.
void ReadUChar(UChar_t &c) final
Reads UChar_t value from buffer.
void WriteFastArray(const Bool_t *b, Long64_t n) final
Write array of Bool_t to buffer.
UInt_t WriteVersion(const TClass *cl, Bool_t useBcnt=kFALSE) final
Copies class version to buffer, but not writes it to xml Version will be written with next I/O operat...
void WriteUChar(UChar_t c) final
Writes UChar_t value to buffer.
void WriteInt(Int_t i) final
Writes Int_t value to buffer.
TObject * GetParent() const
Return pointer to parent of this buffer.
Definition TBuffer.cxx:261
@ 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
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition TClass.h:84
void Streamer(void *obj, TBuffer &b, const TClass *onfile_class=nullptr) const
Definition TClass.h:626
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5048
void Destructor(void *obj, Bool_t dtorOnly=kFALSE)
Explicitly call destructor for object.
Definition TClass.cxx:5470
Int_t Size() const
Return size of object of this class.
Definition TClass.cxx:5806
Bool_t IsTObject() const
Return kTRUE is the class inherits from TObject.
Definition TClass.cxx:6043
Int_t GetBaseClassOffset(const TClass *toBase, void *address=nullptr, bool isDerivedObject=true)
Definition TClass.cxx:2812
Long_t Property() const override
Returns the properties of the TClass as a bit field stored as a Long_t value.
Definition TClass.cxx:6191
Version_t GetClassVersion() const
Definition TClass.h:434
TClass * GetActualClass(const void *object) const
Return a pointer to the real class of the object.
Definition TClass.cxx:2614
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:2994
Basic data type descriptor (datatype information is obtained from CINT).
Definition TDataType.h:44
Int_t GetType() const
Definition TDataType.h:71
static TClass * Class()
static TClass * Class()
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:49
static TClass * Class()
Int_t IndexOf(const TObject *obj) const override
Mother of all ROOT objects.
Definition TObject.h:42
@ kIsOnHeap
object is on heap
Definition TObject.h:90
@ kNotDeleted
object has not been deleted
Definition TObject.h:91
static TClass * Class()
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1098
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1126
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition TObject.cxx:1072
Describe one element (data member) to be Streamed.
Int_t GetType() const
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element and updates fClassObject.
virtual void SetArrayDim(Int_t dim)
Set number of array dimensions.
virtual void SetMaxIndex(Int_t dim, Int_t max)
set maximum index for array with dimension dim
Describes a persistent version of a class.
TClass * GetClass() const override
TObjArray * GetElements() const override
Basic string class.
Definition TString.h:138
Ssiz_t Length() const
Definition TString.h:425
Int_t Atoi() const
Return integer value of string.
Definition TString.cxx:1994
const char * Data() const
Definition TString.h:384
void Resize(Ssiz_t n)
Resize the string. Truncate or add blanks as necessary.
Definition TString.cxx:1159
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
void SaveSingleNode(XMLNodePointer_t xmlnode, TString *res, Int_t layout=1)
convert single xmlnode (and its child node) to string if layout<=0, no any spaces or newlines will be...
XMLNodePointer_t ReadSingleNode(const char *src)
read single xmlnode from provided string
void FreeNode(XMLNodePointer_t xmlnode)
release all memory, allocated from this node and destroys node itself
TClass * XmlDefineClass(const char *xmlClassName)
define class for the converted class name, where special symbols were replaced by '_'
const char * XmlClassNameSpaceRef(const TClass *cl)
produce string which used as reference in class namespace definition
EXMLLayout GetXmlLayout() const
Definition TXMLSetup.h:97
virtual void SetUseNamespaces(Bool_t iUseNamespaces=kTRUE)
Definition TXMLSetup.h:105
const char * XmlConvertClassName(const char *name)
convert class name to exclude any special symbols like ':', '<' '>' ',' and spaces
Int_t AtoI(const char *sbuf, Int_t def=0, const char *errinfo=nullptr)
converts string to integer.
const char * XmlGetElementName(const TStreamerElement *el)
return converted name for TStreamerElement
TXMLSetup()=default
Int_t GetNextRefCounter()
Definition TXMLSetup.h:111
Bool_t IsUseNamespaces() const
Definition TXMLSetup.h:100
@ kSpecialized
Definition TXMLSetup.h:84
@ kGeneralized
Definition TXMLSetup.h:84
virtual void SetXmlLayout(EXMLLayout layout)
Definition TXMLSetup.h:102
Bool_t fIsStreamerInfo
TStreamerInfo * fInfo
TStreamerElement * fElem
Bool_t fCompressedClassNode
XMLNodePointer_t fNode
XMLNsPointer_t fClassNs
Bool_t fIsElemOwner
Bool_t IsStreamerInfo() const
TXMLStackObj(XMLNodePointer_t node)
const Int_t n
Definition legend1.C:16
const char * UChar
Definition TXMLSetup.cxx:88
const char * Ptr
Definition TXMLSetup.cxx:51
const char * Name
Definition TXMLSetup.cxx:66
const char * v
Definition TXMLSetup.cxx:73
const char * Bool
Definition TXMLSetup.cxx:80
const char * Long64
Definition TXMLSetup.cxx:85
const char * False
Definition TXMLSetup.cxx:76
const char * True
Definition TXMLSetup.cxx:75
const char * Int
Definition TXMLSetup.cxx:83
const char * ULong64
Definition TXMLSetup.cxx:92
const char * Member
Definition TXMLSetup.cxx:64
const char * OnlyVersion
Definition TXMLSetup.cxx:50
const char * Long
Definition TXMLSetup.cxx:84
const char * Float
Definition TXMLSetup.cxx:86
const char * Array
Definition TXMLSetup.cxx:79
const char * ClassVersion
Definition TXMLSetup.cxx:48
const char * String
Definition TXMLSetup.cxx:93
const char * Double
Definition TXMLSetup.cxx:87
const char * Object
Definition TXMLSetup.cxx:61
const char * Ref
Definition TXMLSetup.cxx:52
const char * cnt
Definition TXMLSetup.cxx:74
const char * IdBase
Definition TXMLSetup.cxx:54
const char * Size
Definition TXMLSetup.cxx:55
const char * Null
Definition TXMLSetup.cxx:53
const char * Char
Definition TXMLSetup.cxx:81
const char * UShort
Definition TXMLSetup.cxx:89
const char * CharStar
Definition TXMLSetup.cxx:94
const char * UInt
Definition TXMLSetup.cxx:90
const char * ULong
Definition TXMLSetup.cxx:91
const char * Class
Definition TXMLSetup.cxx:63
const char * ObjClass
Definition TXMLSetup.cxx:62
const char * Short
Definition TXMLSetup.cxx:82
const char * Item
Definition TXMLSetup.cxx:65
@ kUndefined
Undefined compression algorithm (must be kept the last of the list in case a new algorithm is added).
@ kUseMin
Compression level reserved when we are not sure what to use (1 is for the fastest compression).
Definition Compression.h:72
TLine l
Definition textangle.C:4