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