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