Logo ROOT  
Reference Guide
TXMLPlayer.cxx
Go to the documentation of this file.
1// @(#)root/xml:$Id$
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//
14// Class for xml code generation
15// It should be used for generation of xml streamers, which could be used outside root
16// environment. This means, that with help of such streamers user can read and write
17// objects from/to xml file, which later can be accepted by ROOT.
18//
19// At the moment supported only classes, which are not inherited from TObject
20// and which not contains any TObject members.
21//
22// To generate xml code:
23//
24// 1. ROOT library with required classes should be created.
25// In general, without such library non of user objects can be stored and
26// retrieved from any ROOT file
27//
28// 2. Generate xml streamers by root script like:
29//
30// void generate() {
31// gSystem->Load("libRXML.so"); // load ROOT xml library
32// gSystem->Load("libuser.so"); // load user ROOT library
33//
34// TList lst;
35// lst.Add(TClass::GetClass("TUserClass1"));
36// lst.Add(TClass::GetClass("TUserClass2"));
37// ...
38// TXMLPlayer player;
39// player.ProduceCode(&lst, "streamers"); // create xml streamers
40// }
41//
42// 3. Copy "streamers.h", "streamers.cxx", "TXmlFile.h", "TXmlFile.cxx" files
43// to user project and compile them. TXmlFile class implementation can be taken
44// from http://web-docs.gsi.de/~linev/xmlfile.tar.gz
45//
46// TXMLPlayer class generates one function per class, which called class streamer.
47// Name of such function for class TExample will be TExample_streamer.
48//
49// Following data members for streamed classes are supported:
50// - simple data types (int, double, float)
51// - array of simple types (int[5], double[5][6])
52// - dynamic array of simple types (int* with comment field // [fSize])
53// - const char*
54// - object of any nonROOT class
55// - pointer on object
56// - array of objects
57// - array of pointers on objects
58// - stl string
59// - stl vector, list, deque, set, multiset, map, multimap
60// - allowed arguments for stl containers are: simple data types, string, object, pointer on object
61// Any other data member can not be (yet) read from xml file and write to xml file.
62//
63// If data member of class is private or protected, it can not be accessed via
64// member name. Two alternative way is supported. First, if for class member fValue
65// exists function GetValue(), it will be used to get value from the class, and if
66// exists SetValue(), it will be used to set appropriate data member. Names of setter
67// and getter methods can be specified in comments filed like:
68//
69// int fValue; // *OPTION={GetMethod="GetV";SetMethod="SetV"}
70//
71// If getter or setter methods does not available, address to data member will be
72// calculated as predefined offset to object start address. In that case generated code
73// should be used only on the same platform (OS + compiler), where it was generated.
74//
75// Generated streamers resolve inheritance tree for given class. This allows to have
76// array (or vector) of object pointers on some basic class, while objects of derived
77// class(es) are used.
78//
79// To access data from xml files, user should use TXmlFile class, which is different from
80// ROOT TXMLFile, but provides very similar functionality. For example, to read
81// object from xml file:
82//
83// TXmlFile file("test.xml"); // open xml file
84// file.ls(); // show list of keys in file
85// TExample* ex1 = (TExample*) file.Get("ex1", TExample_streamer); // get object
86// file.Close();
87//
88// To write object to file:
89//
90// TXmlFile outfile("test2.xml", "recreate"); // create xml file
91// TExample* ex1 = new TExample;
92// outfile.Write(ex1, "ex1", TExample_streamer); // write object to file
93// outfile.Close();
94//
95// Complete example for generating and using of external xml streamers can be taken from
96// http://www-docs.gsi.de/~linev/xmlreader.tar.gz
97//
98// Any bug reports and requests for additional functionality are welcome.
99//
100// Sergey Linev, S.Linev@gsi.de
101//
102//________________________________________________________________________
103
104#include "TXMLPlayer.h"
105
106#include "Riostream.h"
107#include "TROOT.h"
108#include "TClass.h"
109#include "TVirtualStreamerInfo.h"
110#include "TStreamerElement.h"
111#include "TObjArray.h"
112#include "TObjString.h"
113#include "TDataMember.h"
114#include "TMethod.h"
115#include "TDataType.h"
116#include "TMethodCall.h"
118#include "TClassEdit.h"
119#include <string>
120#include <vector>
121
122const char *tab1 = " ";
123const char *tab2 = " ";
124const char *tab3 = " ";
125const char *tab4 = " ";
126
127const char *names_xmlfileclass = "TXmlFile";
128
130
131////////////////////////////////////////////////////////////////////////////////
132/// default constructor
133
135{
136}
137
138////////////////////////////////////////////////////////////////////////////////
139/// destructor of TXMLPlayer object
140
142{
143}
144
145////////////////////////////////////////////////////////////////////////////////
146/// returns streamer function name for given class
147
149{
150 if (cl == 0)
151 return "";
152 TString res = cl->GetName();
153 res += "_streamer";
154 return res;
155}
156
157////////////////////////////////////////////////////////////////////////////////
158/// Produce streamers for provide class list
159/// TList should include list of classes, for which code should be generated.
160/// filename specify name of file (without extension), where streamers should be
161/// created. Function produces two files: header file and source file.
162/// For instance, if filename is "streamers", files "streamers.h" and "streamers.cxx"
163/// will be created.
164
165Bool_t TXMLPlayer::ProduceCode(TList *cllist, const char *filename)
166{
167 if ((cllist == 0) || (filename == 0))
168 return kFALSE;
169
170 std::ofstream fh(TString(filename) + ".h");
171 std::ofstream fs(TString(filename) + ".cxx");
172
173 fh << "// generated header file" << std::endl << std::endl;
174 fh << "#ifndef " << filename << "_h" << std::endl;
175 fh << "#define " << filename << "_h" << std::endl << std::endl;
176
177 fh << "#include \"" << names_xmlfileclass << ".h\"" << std::endl << std::endl;
178
179 fs << "// generated source file" << std::endl << std::endl;
180 fs << "#include \"" << filename << ".h\"" << std::endl << std::endl;
181
182 // produce appropriate include for all classes
183
184 TObjArray inclfiles;
185 TIter iter(cllist);
186 TClass *cl = 0;
187 while ((cl = (TClass *)iter()) != 0) {
188 if (inclfiles.FindObject(cl->GetDeclFileName()) == 0) {
189 fs << "#include \"" << cl->GetDeclFileName() << "\"" << std::endl;
190 inclfiles.Add(new TNamed(cl->GetDeclFileName(), ""));
191 }
192 }
193 inclfiles.Delete();
194
195 fh << std::endl;
196 fs << std::endl;
197
198 // produce streamers declarations and implementations
199
200 iter.Reset();
201
202 while ((cl = (TClass *)iter()) != 0) {
203
204 fh << "extern void* " << GetStreamerName(cl) << "(" << names_xmlfileclass
205 << " &buf, void* ptr = 0, bool checktypes = true);" << std::endl
206 << std::endl;
207
208 ProduceStreamerSource(fs, cl, cllist);
209 }
210
211 fh << "#endif" << std::endl << std::endl;
212 fs << std::endl << std::endl;
213
214 return kTRUE;
215}
216
217////////////////////////////////////////////////////////////////////////////////
218/// returns name of simple data type for given data member
219
221{
222 if (member == 0)
223 return "int";
224
225 if (member->IsBasic())
226 switch (member->GetDataType()->GetType()) {
227 case kChar_t: return "char";
228 case kShort_t: return "short";
229 case kInt_t: return "int";
230 case kLong_t: return "long";
231 case kLong64_t: return "long long";
232 case kFloat16_t:
233 case kFloat_t: return "float";
234 case kDouble32_t:
235 case kDouble_t: return "double";
236 case kUChar_t: {
237 char first = member->GetDataType()->GetTypeName()[0];
238 if ((first == 'B') || (first == 'b'))
239 return "bool";
240 return "unsigned char";
241 }
242 case kBool_t: return "bool";
243 case kUShort_t: return "unsigned short";
244 case kUInt_t: return "unsigned int";
245 case kULong_t: return "unsigned long";
246 case kULong64_t: return "unsigned long long";
247 }
248
249 if (member->IsEnum())
250 return "int";
251
252 return member->GetTypeName();
253}
254
255////////////////////////////////////////////////////////////////////////////////
256/// return simple data types for given TStreamerElement object
257
259{
261 return "int";
262
263 switch (el->GetType() % 20) {
264 case TVirtualStreamerInfo::kChar: return "char";
265 case TVirtualStreamerInfo::kShort: return "short";
266 case TVirtualStreamerInfo::kInt: return "int";
267 case TVirtualStreamerInfo::kLong: return "long";
268 case TVirtualStreamerInfo::kLong64: return "long long";
270 case TVirtualStreamerInfo::kFloat: return "float";
272 case TVirtualStreamerInfo::kDouble: return "double";
274 char first = el->GetTypeNameBasic()[0];
275 if ((first == 'B') || (first == 'b'))
276 return "bool";
277 return "unsigned char";
278 }
279 case TVirtualStreamerInfo::kBool: return "bool";
280 case TVirtualStreamerInfo::kUShort: return "unsigned short";
281 case TVirtualStreamerInfo::kUInt: return "unsigned int";
282 case TVirtualStreamerInfo::kULong: return "unsigned long";
283 case TVirtualStreamerInfo::kULong64: return "unsigned long long";
284 }
285 return "int";
286}
287
288////////////////////////////////////////////////////////////////////////////////
289/// return functions name to read simple data type from xml file
290
292{
294 return "ReadInt";
295
296 switch (type % 20) {
297 case TVirtualStreamerInfo::kChar: return "ReadChar";
298 case TVirtualStreamerInfo::kShort: return "ReadShort";
299 case TVirtualStreamerInfo::kInt: return "ReadInt";
300 case TVirtualStreamerInfo::kLong: return "ReadLong";
301 case TVirtualStreamerInfo::kLong64: return "ReadLong64";
303 case TVirtualStreamerInfo::kFloat: return "ReadFloat";
305 case TVirtualStreamerInfo::kDouble: return "ReadDouble";
307 Bool_t isbool = false;
308 if (realname != 0)
309 isbool = (TString(realname).Index("bool", 0, TString::kIgnoreCase) >= 0);
310 if (isbool)
311 return "ReadBool";
312 return "ReadUChar";
313 }
314 case TVirtualStreamerInfo::kBool: return "ReadBool";
315 case TVirtualStreamerInfo::kUShort: return "ReadUShort";
316 case TVirtualStreamerInfo::kUInt: return "ReadUInt";
317 case TVirtualStreamerInfo::kULong: return "ReadULong";
318 case TVirtualStreamerInfo::kULong64: return "ReadULong64";
319 }
320 return "ReadValue";
321}
322
323////////////////////////////////////////////////////////////////////////////////
324/// produce code to access member of given class.
325/// Parameter specials has following meaning:
326/// 0 - nothing special
327/// 1 - cast to data type
328/// 2 - produce pointer on given member
329/// 3 - skip casting when produce pointer by buf.P() function
330
331const char *TXMLPlayer::ElementGetter(TClass *cl, const char *membername, int specials)
332{
333 TClass *membercl = cl ? cl->GetBaseDataMember(membername) : 0;
334 TDataMember *member = membercl ? membercl->GetDataMember(membername) : 0;
335 TMethodCall *mgetter = member ? member->GetterMethod(0) : 0;
336
337 if ((mgetter != 0) && (mgetter->GetMethod()->Property() & kIsPublic)) {
338 fGetterName = "obj->";
339 fGetterName += mgetter->GetMethodName();
340 fGetterName += "()";
341 } else if ((member == 0) || ((member->Property() & kIsPublic) != 0)) {
342 fGetterName = "obj->";
343 fGetterName += membername;
344 } else {
345 fGetterName = "";
346 Bool_t deref = (member->GetArrayDim() == 0) && (specials != 2);
347 if (deref)
348 fGetterName += "*(";
349 if (specials != 3) {
350 fGetterName += "(";
351 if (member->Property() & kIsConstant)
352 fGetterName += "const ";
354 if (member->IsaPointer())
355 fGetterName += "*";
356 fGetterName += "*) ";
357 }
358 fGetterName += "buf.P(obj,";
359 fGetterName += member->GetOffset();
360 fGetterName += ")";
361 if (deref)
362 fGetterName += ")";
363 specials = 0;
364 }
365
366 if ((specials == 1) && (member != 0)) {
367 TString cast = "(";
368 cast += GetMemberTypeName(member);
369 if (member->IsaPointer() || (member->GetArrayDim() > 0))
370 cast += "*";
371 cast += ") ";
372 cast += fGetterName;
373 fGetterName = cast;
374 }
375
376 if ((specials == 2) && (member != 0)) {
377 TString buf = "&(";
378 buf += fGetterName;
379 buf += ")";
380 fGetterName = buf;
381 }
382
383 return fGetterName.Data();
384}
385
386////////////////////////////////////////////////////////////////////////////////
387/// Produce code to set value to given data member.
388/// endch should be output after value is specified.
389
390const char *TXMLPlayer::ElementSetter(TClass *cl, const char *membername, char *endch)
391{
392 strcpy(endch, "");
393
394 TClass *membercl = cl ? cl->GetBaseDataMember(membername) : 0;
395 TDataMember *member = membercl ? membercl->GetDataMember(membername) : 0;
396 TMethodCall *msetter = member ? member->SetterMethod(cl) : 0;
397
398 if ((msetter != 0) && (msetter->GetMethod()->Property() & kIsPublic)) {
399 fSetterName = "obj->";
400 fSetterName += msetter->GetMethodName();
401 fSetterName += "(";
402 strcpy(endch, ")");
403 } else if ((member == 0) || (member->Property() & kIsPublic) != 0) {
404 fSetterName = "obj->";
405 fSetterName += membername;
406 fSetterName += " = ";
407 } else {
408 fSetterName = "";
409 if (member->GetArrayDim() == 0)
410 fSetterName += "*";
411 fSetterName += "((";
412 if (member->Property() & kIsConstant)
413 fSetterName += "const ";
415 if (member->IsaPointer())
416 fSetterName += "*";
417 fSetterName += "*) buf.P(obj,";
418 fSetterName += member->GetOffset();
419 fSetterName += ")) = ";
420 }
421 return fSetterName.Data();
422}
423
424////////////////////////////////////////////////////////////////////////////////
425/// Produce source code of streamer function for specified class
426
427void TXMLPlayer::ProduceStreamerSource(std::ostream &fs, TClass *cl, TList *cllist)
428{
429 if (cl == 0)
430 return;
432 TObjArray *elements = info->GetElements();
433 if (elements == 0)
434 return;
435
436 fs << "//__________________________________________________________________________" << std::endl;
437 fs << "void* " << GetStreamerName(cl) << "(" << names_xmlfileclass << " &buf, void* ptr, bool checktypes)"
438 << std::endl;
439 fs << "{" << std::endl;
440 fs << tab1 << cl->GetName() << " *obj = (" << cl->GetName() << "*) ptr;" << std::endl;
441
442 fs << tab1 << "if (buf.IsReading()) { " << std::endl;
443
444 TIter iter(cllist);
445 TClass *c1 = 0;
446 Bool_t firstchild = true;
447
448 while ((c1 = (TClass *)iter()) != 0) {
449 if (c1 == cl)
450 continue;
451 if (c1->GetListOfBases()->FindObject(cl->GetName()) == 0)
452 continue;
453 if (firstchild) {
454 fs << tab2 << "if (checktypes) {" << std::endl;
455 fs << tab3 << "void* ";
456 firstchild = false;
457 } else
458 fs << tab3;
459 fs << "res = " << GetStreamerName(c1) << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));" << std::endl;
460 fs << tab3 << "if (res) return dynamic_cast<" << cl->GetName() << "*>((" << c1->GetName() << " *) res);"
461 << std::endl;
462 }
463 if (!firstchild)
464 fs << tab2 << "}" << std::endl;
465
466 fs << tab2 << "if (!buf.CheckClassNode(\"" << cl->GetName() << "\", " << info->GetClassVersion() << ")) return 0;"
467 << std::endl;
468
469 fs << tab2 << "if (obj==0) obj = new " << cl->GetName() << ";" << std::endl;
470
471 int n;
472 for (n = 0; n <= elements->GetLast(); n++) {
473
474 TStreamerElement *el = dynamic_cast<TStreamerElement *>(elements->At(n));
475 if (el == 0)
476 continue;
477
478 Int_t typ = el->GetType();
479
480 switch (typ) {
481 // basic types
498 char endch[5];
499 fs << tab2 << ElementSetter(cl, el->GetName(), endch);
500 fs << "buf." << GetBasicTypeReaderMethodName(el->GetType(), 0) << "(\"" << el->GetName() << "\")" << endch
501 << ";" << std::endl;
502 continue;
503 }
504
505 // array of basic types like bool[10]
521 fs << tab2 << "buf.ReadArray(" << ElementGetter(cl, el->GetName(), (el->GetArrayDim() > 1) ? 1 : 0);
522 fs << ", " << el->GetArrayLength() << ", \"" << el->GetName() << "\");" << std::endl;
523 continue;
524 }
525
526 // array of basic types like bool[n]
542 TStreamerBasicPointer *elp = dynamic_cast<TStreamerBasicPointer *>(el);
543 if (elp == 0) {
544 std::cout << "fatal error with TStreamerBasicPointer" << std::endl;
545 continue;
546 }
547 char endch[5];
548
549 fs << tab2 << ElementSetter(cl, el->GetName(), endch);
550 fs << "buf.ReadArray(" << ElementGetter(cl, el->GetName());
551 fs << ", " << ElementGetter(cl, elp->GetCountName());
552 fs << ", \"" << el->GetName() << "\", true)" << endch << ";" << std::endl;
553 continue;
554 }
555
557 char endch[5];
558 fs << tab2 << ElementSetter(cl, el->GetName(), endch);
559 fs << "buf.ReadCharStar(" << ElementGetter(cl, el->GetName());
560 fs << ", \"" << el->GetName() << "\")" << endch << ";" << std::endl;
561 continue;
562 }
563
565 fs << tab2 << GetStreamerName(el->GetClassPointer()) << "(buf, dynamic_cast<"
566 << el->GetClassPointer()->GetName() << "*>(obj), false);" << std::endl;
567 continue;
568 }
569
570 // Class* Class not derived from TObject and with comment field //->
573 if (el->GetArrayLength() > 0) {
574 fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
575 fs << ", " << el->GetArrayLength() << ", -1"
576 << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
577 } else {
578 fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName());
579 fs << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
580 }
581 continue;
582 }
583
584 // Class* Class not derived from TObject and no comment
587 if (el->GetArrayLength() > 0) {
588 fs << tab2 << "for (int n=0;n<" << el->GetArrayLength() << ";n++) "
589 << "delete (" << ElementGetter(cl, el->GetName()) << ")[n];" << std::endl;
590 fs << tab2 << "buf.ReadObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
591 fs << ", " << el->GetArrayLength() << ", \"" << el->GetName() << "\", "
592 << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
593 } else {
594 char endch[5];
595
596 fs << tab2 << "delete " << ElementGetter(cl, el->GetName()) << ";" << std::endl;
597 fs << tab2 << ElementSetter(cl, el->GetName(), endch);
598 fs << "(" << el->GetClassPointer()->GetName() << "*) buf.ReadObjectPtr(\"" << el->GetName() << "\", "
599 << GetStreamerName(el->GetClassPointer()) << ")" << endch << ";" << std::endl;
600 }
601 continue;
602 }
603
604 // Class NOT derived from TObject
606 fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName(), 2);
607 fs << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
608 continue;
609 }
610
611 // Class NOT derived from TObject, array
613 fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
614 fs << ", " << el->GetArrayLength() << ", sizeof(" << el->GetClassPointer()->GetName() << "), \""
615 << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
616 continue;
617 }
618
619 // container with no virtual table (stl) and no comment
624 TStreamerSTL *elstl = dynamic_cast<TStreamerSTL *>(el);
625 if (elstl == 0)
626 break; // to make skip
627
628 if (ProduceSTLstreamer(fs, cl, elstl, false))
629 continue;
630
631 fs << tab2 << "// STL type = " << elstl->GetSTLtype() << std::endl;
632 break;
633 }
634 }
635 fs << tab2 << "buf.SkipMember(\"" << el->GetName() << "\"); // sinfo type " << el->GetType() << " of class "
636 << el->GetClassPointer()->GetName() << " not supported" << std::endl;
637 }
638
639 fs << tab2 << "buf.EndClassNode();" << std::endl;
640
641 fs << tab1 << "} else {" << std::endl;
642
643 // generation of writing part of class streamer
644
645 fs << tab2 << "if (obj==0) return 0;" << std::endl;
646
647 firstchild = true;
648 iter.Reset();
649 while ((c1 = (TClass *)iter()) != 0) {
650 if (c1 == cl)
651 continue;
652 if (c1->GetListOfBases()->FindObject(cl->GetName()) == 0)
653 continue;
654 if (firstchild) {
655 firstchild = false;
656 fs << tab2 << "if (checktypes) {" << std::endl;
657 }
658 fs << tab3 << "if (dynamic_cast<" << c1->GetName() << "*>(obj))" << std::endl;
659 fs << tab4 << "return " << GetStreamerName(c1) << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));"
660 << std::endl;
661 }
662 if (!firstchild)
663 fs << tab2 << "}" << std::endl;
664
665 fs << tab2 << "buf.StartClassNode(\"" << cl->GetName() << "\", " << info->GetClassVersion() << ");" << std::endl;
666
667 for (n = 0; n <= elements->GetLast(); n++) {
668
669 TStreamerElement *el = dynamic_cast<TStreamerElement *>(elements->At(n));
670 if (el == 0)
671 continue;
672
673 Int_t typ = el->GetType();
674
675 switch (typ) {
676 // write basic types
693 fs << tab2 << "buf.WriteValue(";
695 fs << "(unsigned char) " << ElementGetter(cl, el->GetName());
696 else
697 fs << ElementGetter(cl, el->GetName());
698 fs << ", \"" << el->GetName() << "\");" << std::endl;
699 continue;
700 }
701
702 // array of basic types
718 fs << tab2 << "buf.WriteArray(" << ElementGetter(cl, el->GetName(), (el->GetArrayDim() > 1) ? 1 : 0);
719 fs << ", " << el->GetArrayLength() << ", \"" << el->GetName() << "\");" << std::endl;
720 continue;
721 }
722
738 TStreamerBasicPointer *elp = dynamic_cast<TStreamerBasicPointer *>(el);
739 if (elp == 0) {
740 std::cout << "fatal error with TStreamerBasicPointer" << std::endl;
741 continue;
742 }
743 fs << tab2 << "buf.WriteArray(" << ElementGetter(cl, el->GetName());
744 fs << ", " << ElementGetter(cl, elp->GetCountName()) << ", \"" << el->GetName() << "\", true);" << std::endl;
745 continue;
746 }
747
749 fs << tab2 << "buf.WriteCharStar(" << ElementGetter(cl, el->GetName()) << ", \"" << el->GetName() << "\");"
750 << std::endl;
751 continue;
752 }
753
755 fs << tab2 << GetStreamerName(el->GetClassPointer()) << "(buf, dynamic_cast<"
756 << el->GetClassPointer()->GetName() << "*>(obj), false);" << std::endl;
757 continue;
758 }
759
760 // Class* Class not derived from TObject and with comment field //->
763 if (el->GetArrayLength() > 0) {
764 fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
765 fs << ", " << el->GetArrayLength() << ", -1"
766 << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
767 } else {
768 fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName());
769 fs << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
770 }
771 continue;
772 }
773
774 // Class* Class not derived from TObject and no comment
777 if (el->GetArrayLength() > 0) {
778 fs << tab2 << "buf.WriteObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
779 fs << ", " << el->GetArrayLength() << ", \"" << el->GetName() << "\", "
780 << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
781 } else {
782 fs << tab2 << "buf.WriteObjectPtr(" << ElementGetter(cl, el->GetName());
783 fs << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
784 }
785 continue;
786 }
787
788 case TVirtualStreamerInfo::kAny: { // Class NOT derived from TObject
789 fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName(), 2);
790 fs << ", \"" << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
791 continue;
792 }
793
795 fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
796 fs << ", " << el->GetArrayLength() << ", sizeof(" << el->GetClassPointer()->GetName() << "), \""
797 << el->GetName() << "\", " << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
798 continue;
799 }
800
801 // container with no virtual table (stl) and no comment
806 TStreamerSTL *elstl = dynamic_cast<TStreamerSTL *>(el);
807 if (elstl == 0)
808 break; // to make skip
809
810 if (ProduceSTLstreamer(fs, cl, elstl, true))
811 continue;
812 fs << tab2 << "// STL type = " << elstl->GetSTLtype() << std::endl;
813 break;
814 }
815 }
816 fs << tab2 << "buf.MakeEmptyMember(\"" << el->GetName() << "\"); // sinfo type " << el->GetType()
817 << " of class " << el->GetClassPointer()->GetName() << " not supported" << std::endl;
818 }
819
820 fs << tab2 << "buf.EndClassNode();" << std::endl;
821
822 fs << tab1 << "}" << std::endl;
823 fs << tab1 << "return obj;" << std::endl;
824 fs << "}" << std::endl << std::endl;
825}
826
827////////////////////////////////////////////////////////////////////////////////
828/// Produce code to read argument of stl container from xml file
829
830void TXMLPlayer::ReadSTLarg(std::ostream &fs, TString &argname, int argtyp, Bool_t isargptr, TClass *argcl,
831 TString &tname, TString &ifcond)
832{
833 switch (argtyp) {
850 fs << tname << " " << argname << " = buf." << GetBasicTypeReaderMethodName(argtyp, tname.Data()) << "(0);"
851 << std::endl;
852 break;
853 }
854
856 fs << tname << (isargptr ? " " : " *") << argname << " = "
857 << "(" << argcl->GetName() << "*)"
858 << "buf.ReadObjectPtr(0, " << GetStreamerName(argcl) << ");" << std::endl;
859 if (!isargptr) {
860 if (ifcond.Length() > 0)
861 ifcond += " && ";
862 ifcond += argname;
863 TString buf = "*";
864 buf += argname;
865 argname = buf;
866 }
867 break;
868 }
869
871 fs << "string *" << argname << " = "
872 << "buf.ReadSTLstring();" << std::endl;
873 if (!isargptr) {
874 if (ifcond.Length() > 0)
875 ifcond += " && ";
876 ifcond += argname;
877 TString buf = "*";
878 buf += argname;
879 argname = buf;
880 }
881 break;
882 }
883
884 default: fs << "/* argument " << argname << " not supported */";
885 }
886}
887
888////////////////////////////////////////////////////////////////////////////////
889/// Produce code to write argument of stl container to xml file
890
891void TXMLPlayer::WriteSTLarg(std::ostream &fs, const char *accname, int argtyp, Bool_t isargptr, TClass *argcl)
892{
893 switch (argtyp) {
910 fs << "buf.WriteValue(" << accname << ", 0);" << std::endl;
911 break;
912 }
913
915 fs << "buf.WriteObjectPtr(";
916 if (isargptr)
917 fs << accname;
918 else
919 fs << "&(" << accname << ")";
920 fs << ", 0, " << GetStreamerName(argcl) << ");" << std::endl;
921 break;
922 }
923
925 fs << "buf.WriteSTLstring(";
926 if (isargptr)
927 fs << accname;
928 else
929 fs << "&(" << accname << ")";
930 fs << ");" << std::endl;
931 break;
932 }
933
934 default: fs << "/* argument not supported */" << std::endl;
935 }
936}
937
938////////////////////////////////////////////////////////////////////////////////
939/// Produce code of xml streamer for data member of stl type
940
941Bool_t TXMLPlayer::ProduceSTLstreamer(std::ostream &fs, TClass *cl, TStreamerSTL *el, Bool_t isWriting)
942{
943 if ((cl == 0) || (el == 0))
944 return false;
945
946 TClass *contcl = el->GetClassPointer();
947
948 Bool_t isstr = (el->GetSTLtype() == ROOT::kSTLstring);
949 Bool_t isptr = el->IsaPointer();
950 Bool_t isarr = (el->GetArrayLength() > 0);
951 Bool_t isparent = (strcmp(el->GetName(), contcl->GetName()) == 0);
952
953 int stltyp = -1;
954 int narg = 0;
955 int argtype[2];
956 Bool_t isargptr[2];
957 TClass *argcl[2];
958 TString argtname[2];
959
960 if (!isstr && contcl->GetCollectionType() != ROOT::kNotSTL) {
961 int nestedLoc = 0;
962 std::vector<std::string> splitName;
963 TClassEdit::GetSplit(contcl->GetName(), splitName, nestedLoc);
964
965 stltyp = contcl->GetCollectionType();
966 switch (stltyp) {
967 case ROOT::kSTLvector: narg = 1; break;
968 case ROOT::kSTLlist: narg = 1; break;
969 case ROOT::kSTLforwardlist: narg = 1; break;
970 case ROOT::kSTLdeque: narg = 1; break;
971 case ROOT::kSTLmap: narg = 2; break;
972 case ROOT::kSTLmultimap: narg = 2; break;
973 case ROOT::kSTLset: narg = 1; break;
974 case ROOT::kSTLmultiset: narg = 1; break;
975 case ROOT::kSTLunorderedset: narg = 1; break;
976 case ROOT::kSTLunorderedmultiset: narg = 1; break;
977 case ROOT::kSTLunorderedmap: narg = 2; break;
978 case ROOT::kSTLunorderedmultimap: narg = 2; break;
979
980 default: return false;
981 }
982
983 for (int n = 0; n < narg; n++) {
984 argtype[n] = -1;
985 isargptr[n] = false;
986 argcl[n] = 0;
987 argtname[n] = "";
988
989 TString buf = splitName[n + 1];
990
991 argtname[n] = buf;
992
993 // nested STL containers not yet supported
994 if (TClassEdit::IsSTLCont(buf.Data()))
995 return false;
996
997 int pstar = buf.Index("*");
998
999 if (pstar > 0) {
1000 isargptr[n] = true;
1001 pstar--;
1002 while ((pstar > 0) && (buf[pstar] == ' '))
1003 pstar--;
1004 buf.Remove(pstar + 1);
1005 } else
1006 isargptr[n] = false;
1007
1008 if (buf.Index("const ") == 0) {
1009 buf.Remove(0, 6);
1010 while ((buf.Length() > 0) && (buf[0] == ' '))
1011 buf.Remove(0, 1);
1012 }
1013
1014 TDataType *dt = (TDataType *)gROOT->GetListOfTypes()->FindObject(buf);
1015 if (dt)
1016 argtype[n] = dt->GetType();
1017 else if (buf == "string")
1019 else {
1020 argcl[n] = TClass::GetClass(buf);
1021 if (argcl[n] != 0)
1023 }
1024 if (argtype[n] < 0)
1025 stltyp = -1;
1026 } // for narg
1027
1028 if (stltyp < 0)
1029 return false;
1030 }
1031
1032 Bool_t akaarrayaccess = (narg == 1) && (argtype[0] < 20);
1033
1034 char tabs[30], tabs2[30];
1035
1036 if (isWriting) {
1037
1038 fs << tab2 << "if (buf.StartSTLnode(\"" << fXmlSetup.XmlGetElementName(el) << "\")) {" << std::endl;
1039
1040 fs << tab3 << contcl->GetName() << " ";
1041
1042 TString accname;
1043 if (isptr) {
1044 if (isarr) {
1045 fs << "**cont";
1046 accname = "(*cont)->";
1047 } else {
1048 fs << "*cont";
1049 accname = "cont->";
1050 }
1051 } else if (isarr) {
1052 fs << "*cont";
1053 accname = "cont->";
1054 } else {
1055 fs << "&cont";
1056 accname = "cont.";
1057 }
1058
1059 fs << " = ";
1060
1061 if (isparent)
1062 fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << std::endl;
1063 else
1064 fs << ElementGetter(cl, el->GetName()) << ";" << std::endl;
1065
1066 if (isarr && el->GetArrayLength()) {
1067 strlcpy(tabs, tab4, sizeof(tabs));
1068 fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << std::endl;
1069 } else
1070 strlcpy(tabs, tab3, sizeof(tabs));
1071
1072 strlcpy(tabs2, tabs, sizeof(tabs2));
1073
1074 if (isptr) {
1075 strlcat(tabs2, tab1, sizeof(tabs2));
1076 fs << tabs << "if (" << (isarr ? "*cont" : "cont") << "==0) {" << std::endl;
1077 fs << tabs2 << "buf.WriteSTLsize(0" << (isstr ? ",true);" : ");") << std::endl;
1078 fs << tabs << "} else {" << std::endl;
1079 }
1080
1081 fs << tabs2 << "buf.WriteSTLsize(" << accname << (isstr ? "length(), true);" : "size());") << std::endl;
1082
1083 if (isstr) {
1084 fs << tabs2 << "buf.WriteSTLstringData(" << accname << "c_str());" << std::endl;
1085 } else {
1086 if (akaarrayaccess) {
1087 fs << tabs2 << argtname[0] << "* arr = new " << argtname[0] << "[" << accname << "size()];" << std::endl;
1088 fs << tabs2 << "int k = 0;" << std::endl;
1089 }
1090
1091 fs << tabs2 << contcl->GetName() << "::const_iterator iter;" << std::endl;
1092 fs << tabs2 << "for (iter = " << accname << "begin(); iter != " << accname << "end(); iter++)";
1093 if (akaarrayaccess) {
1094 fs << std::endl << tabs2 << tab1 << "arr[k++] = *iter;" << std::endl;
1095 fs << tabs2 << "buf.WriteArray(arr, " << accname << "size(), 0, false);" << std::endl;
1096 fs << tabs2 << "delete[] arr;" << std::endl;
1097 } else if (narg == 1) {
1098 fs << std::endl << tabs2 << tab1;
1099 WriteSTLarg(fs, "*iter", argtype[0], isargptr[0], argcl[0]);
1100 } else if (narg == 2) {
1101 fs << " {" << std::endl;
1102 fs << tabs2 << tab1;
1103 WriteSTLarg(fs, "iter->first", argtype[0], isargptr[0], argcl[0]);
1104 fs << tabs2 << tab1;
1105 WriteSTLarg(fs, "iter->second", argtype[1], isargptr[1], argcl[1]);
1106 fs << tabs2 << "}" << std::endl;
1107 }
1108 } // if (isstr)
1109
1110 if (isptr)
1111 fs << tabs << "}" << std::endl;
1112
1113 if (isarr && el->GetArrayLength()) {
1114 if (isptr)
1115 fs << tabs << "cont++;" << std::endl;
1116 else
1117 fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << std::endl;
1118 fs << tab3 << "}" << std::endl;
1119 }
1120
1121 fs << tab3 << "buf.EndSTLnode();" << std::endl;
1122 fs << tab2 << "}" << std::endl;
1123
1124 } else {
1125
1126 fs << tab2 << "if (buf.VerifySTLnode(\"" << fXmlSetup.XmlGetElementName(el) << "\")) {" << std::endl;
1127
1128 fs << tab3 << contcl->GetName() << " ";
1129 TString accname, accptr;
1130 if (isptr) {
1131 if (isarr) {
1132 fs << "**cont";
1133 accname = "(*cont)->";
1134 accptr = "*cont";
1135 } else {
1136 fs << "*cont";
1137 accname = "cont->";
1138 accptr = "cont";
1139 }
1140 } else if (isarr) {
1141 fs << "*cont";
1142 accname = "cont->";
1143 } else {
1144 fs << "&cont";
1145 accname = "cont.";
1146 }
1147
1148 fs << " = ";
1149
1150 if (isparent)
1151 fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << std::endl;
1152 else
1153 fs << ElementGetter(cl, el->GetName()) << ";" << std::endl;
1154
1155 if (isarr && el->GetArrayLength()) {
1156 strlcpy(tabs, tab4, sizeof(tabs));
1157 fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << std::endl;
1158 } else
1159 strlcpy(tabs, tab3, sizeof(tabs));
1160
1161 fs << tabs << "int size = buf.ReadSTLsize(" << (isstr ? "true);" : ");") << std::endl;
1162
1163 if (isptr) {
1164 fs << tabs << "delete " << accptr << ";" << std::endl;
1165 fs << tabs << "if (size==0) " << accptr << " = 0;" << std::endl;
1166 fs << tabs << " else " << accptr << " = new " << contcl->GetName() << ";" << std::endl;
1167 if (!isarr) {
1168 char endch[5];
1169 fs << tabs << ElementSetter(cl, el->GetName(), endch);
1170 fs << "cont" << endch << ";" << std::endl;
1171 }
1172 } else {
1173 fs << tabs << accname << (isstr ? "erase();" : "clear();") << std::endl;
1174 }
1175
1176 if (isstr) {
1177 fs << tabs << "if (size>0) " << accname << "assign(buf.ReadSTLstringData(size));" << std::endl;
1178 } else {
1179 if (akaarrayaccess) {
1180 fs << tabs << argtname[0] << "* arr = new " << argtname[0] << "[size];" << std::endl;
1181 fs << tabs << "buf.ReadArray(arr, size, 0, false);" << std::endl;
1182 }
1183
1184 fs << tabs << "for(int k=0;k<size;k++)";
1185
1186 if (akaarrayaccess) {
1187 fs << std::endl << tabs << tab1 << accname;
1188 if ((stltyp == ROOT::kSTLset) || (stltyp == ROOT::kSTLmultiset))
1189 fs << "insert";
1190 else
1191 fs << "push_back";
1192 fs << "(arr[k]);" << std::endl;
1193 fs << tabs << "delete[] arr;" << std::endl;
1194 } else if (narg == 1) {
1195 TString arg1("arg"), ifcond;
1196 fs << " {" << std::endl << tabs << tab1;
1197 ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
1198 fs << tabs << tab1;
1199 if (ifcond.Length() > 0)
1200 fs << "if (" << ifcond << ") ";
1201 fs << accname;
1202 if ((stltyp == ROOT::kSTLset) || (stltyp == ROOT::kSTLmultiset))
1203 fs << "insert";
1204 else
1205 fs << "push_back";
1206 fs << "(" << arg1 << ");" << std::endl;
1207 fs << tabs << "}" << std::endl;
1208 } else if (narg == 2) {
1209 TString arg1("arg1"), arg2("arg2"), ifcond;
1210 fs << " {" << std::endl << tabs << tab1;
1211 ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
1212 fs << tabs << tab1;
1213 ReadSTLarg(fs, arg2, argtype[1], isargptr[1], argcl[1], argtname[1], ifcond);
1214 fs << tabs << tab1;
1215 if (ifcond.Length() > 0)
1216 fs << "if (" << ifcond << ") ";
1217 fs << accname << "insert(make_pair(" << arg1 << ", " << arg2 << "));" << std::endl;
1218 fs << tabs << "}" << std::endl;
1219 }
1220 }
1221
1222 if (isarr && el->GetArrayLength()) {
1223 if (isptr)
1224 fs << tabs << "cont++;" << std::endl;
1225 else
1226 fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << std::endl;
1227 fs << tab3 << "}" << std::endl;
1228 }
1229
1230 fs << tab3 << "buf.EndSTLnode();" << std::endl;
1231 fs << tab2 << "}" << std::endl;
1232 }
1233 return true;
1234}
int Int_t
Definition: RtypesCore.h:41
const Bool_t kFALSE
Definition: RtypesCore.h:88
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kTRUE
Definition: RtypesCore.h:87
#define ClassImp(name)
Definition: Rtypes.h:365
@ kFloat_t
Definition: TDataType.h:31
@ kULong64_t
Definition: TDataType.h:32
@ kInt_t
Definition: TDataType.h:30
@ kLong_t
Definition: TDataType.h:30
@ kDouble32_t
Definition: TDataType.h:31
@ kShort_t
Definition: TDataType.h:29
@ kBool_t
Definition: TDataType.h:32
@ kULong_t
Definition: TDataType.h:30
@ kLong64_t
Definition: TDataType.h:32
@ kUShort_t
Definition: TDataType.h:29
@ kDouble_t
Definition: TDataType.h:31
@ kChar_t
Definition: TDataType.h:29
@ kUChar_t
Definition: TDataType.h:29
@ kUInt_t
Definition: TDataType.h:30
@ kFloat16_t
Definition: TDataType.h:33
@ kIsPublic
Definition: TDictionary.h:74
@ kIsConstant
Definition: TDictionary.h:86
int type
Definition: TGX11.cxx:120
#define gROOT
Definition: TROOT.h:415
const char * tab1
Definition: TXMLPlayer.cxx:122
const char * tab3
Definition: TXMLPlayer.cxx:124
const char * tab2
Definition: TXMLPlayer.cxx:123
const char * tab4
Definition: TXMLPlayer.cxx:125
const char * names_xmlfileclass
Definition: TXMLPlayer.cxx:127
TClass instances represent classes, structs and namespaces in the ROOT type system.
Definition: TClass.h:75
TDataMember * GetDataMember(const char *datamember) const
Return pointer to datamember object with name "datamember".
Definition: TClass.cxx:3299
TVirtualStreamerInfo * GetStreamerInfo(Int_t version=0) const
returns a pointer to the TVirtualStreamerInfo object for version If the object does not exist,...
Definition: TClass.cxx:4440
ROOT::ESTLType GetCollectionType() const
Return the 'type' of the STL the TClass is representing.
Definition: TClass.cxx:2824
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2765
const char * GetDeclFileName() const
Return name of the file containing the declaration of this class.
Definition: TClass.cxx:3323
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:2906
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
TMethodCall * SetterMethod(TClass *cl)
Return a TMethodCall method responsible for setting the value of data member.
Long_t GetOffset() const
Get offset from "this".
Int_t GetArrayDim() const
Return number of array dimensions.
Bool_t IsEnum() const
Return true if data member is an enum.
Bool_t IsBasic() const
Return true if data member is a basic type, e.g. char, int, long...
Bool_t IsaPointer() const
Return true if data member is a pointer.
TDataType * GetDataType() const
Definition: TDataMember.h:74
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
TMethodCall * GetterMethod(TClass *cl=0)
Return a TMethodCall method responsible for getting the value of data member.
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Basic data type descriptor (datatype information is obtained from CINT).
Definition: TDataType.h:44
Int_t GetType() const
Definition: TDataType.h:68
TString GetTypeName()
Get basic type of typedef, e,g.
Definition: TDataType.cxx:149
Long_t Property() const
Get property description word. For meaning of bits see EProperty.
Definition: TFunction.cxx:183
void Reset()
Definition: TCollection.h:252
A doubly linked list.
Definition: TList.h:44
Method or function calling interface.
Definition: TMethodCall.h:37
const char * GetMethodName() const
Definition: TMethodCall.h:90
TFunction * GetMethod()
Returns the TMethod describing the method to be executed.
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
An array of TObjects.
Definition: TObjArray.h:37
void Add(TObject *obj)
Definition: TObjArray.h:74
virtual void Delete(Option_t *option="")
Remove all objects from the array AND delete all heap based objects.
Definition: TObjArray.cxx:355
virtual TObject * FindObject(const char *name) const
Find an object in this collection using its name.
Definition: TObjArray.cxx:414
Int_t GetLast() const
Return index of last object in array.
Definition: TObjArray.cxx:576
TObject * At(Int_t idx) const
Definition: TObjArray.h:166
Mother of all ROOT objects.
Definition: TObject.h:37
const char * GetCountName() const
Int_t GetType() const
virtual TClass * GetClassPointer() const
Returns a pointer to the TClass of this element.
Int_t GetArrayDim() const
Int_t GetArrayLength() const
const char * GetTypeNameBasic() const
Return type name of this element in case the type name is not a standard basic type,...
Int_t GetSTLtype() const
Bool_t IsaPointer() const
Return true if the data member is a pointer.
Basic string class.
Definition: TString.h:131
Ssiz_t Length() const
Definition: TString.h:405
const char * Data() const
Definition: TString.h:364
@ kIgnoreCase
Definition: TString.h:263
TString & Remove(Ssiz_t pos)
Definition: TString.h:668
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:634
Abstract Interface class describing Streamer information for one class.
virtual TObjArray * GetElements() const =0
virtual Int_t GetClassVersion() const =0
TString GetMemberTypeName(TDataMember *member)
returns name of simple data type for given data member
Definition: TXMLPlayer.cxx:220
Bool_t ProduceCode(TList *cllist, const char *filename)
Produce streamers for provide class list TList should include list of classes, for which code should ...
Definition: TXMLPlayer.cxx:165
TString GetStreamerName(TClass *cl)
returns streamer function name for given class
Definition: TXMLPlayer.cxx:148
TString fSetterName
buffer for name of getter method
Definition: TXMLPlayer.h:50
const char * ElementGetter(TClass *cl, const char *membername, int specials=0)
produce code to access member of given class.
Definition: TXMLPlayer.cxx:331
TXMLSetup fXmlSetup
buffer for name of setter method
Definition: TXMLPlayer.h:51
virtual ~TXMLPlayer()
destructor of TXMLPlayer object
Definition: TXMLPlayer.cxx:141
TString GetBasicTypeName(TStreamerElement *el)
return simple data types for given TStreamerElement object
Definition: TXMLPlayer.cxx:258
void ReadSTLarg(std::ostream &fs, TString &argname, int argtyp, Bool_t isargptr, TClass *argcl, TString &tname, TString &ifcond)
Produce code to read argument of stl container from xml file.
Definition: TXMLPlayer.cxx:830
TXMLPlayer()
default constructor
Definition: TXMLPlayer.cxx:134
TString GetBasicTypeReaderMethodName(Int_t type, const char *realname)
return functions name to read simple data type from xml file
Definition: TXMLPlayer.cxx:291
void ProduceStreamerSource(std::ostream &fs, TClass *cl, TList *cllist)
Produce source code of streamer function for specified class.
Definition: TXMLPlayer.cxx:427
TString fGetterName
Definition: TXMLPlayer.h:49
Bool_t ProduceSTLstreamer(std::ostream &fs, TClass *cl, TStreamerSTL *el, Bool_t isWriting)
Produce code of xml streamer for data member of stl type.
Definition: TXMLPlayer.cxx:941
const char * ElementSetter(TClass *cl, const char *membername, char *endch)
Produce code to set value to given data member.
Definition: TXMLPlayer.cxx:390
void WriteSTLarg(std::ostream &fs, const char *accname, int argtyp, Bool_t isargptr, TClass *argcl)
Produce code to write argument of stl container to xml file.
Definition: TXMLPlayer.cxx:891
const char * XmlGetElementName(const TStreamerElement *el)
return converted name for TStreamerElement
Definition: TXMLSetup.cxx:237
return c1
Definition: legend1.C:41
const Int_t n
Definition: legend1.C:16
@ kSTLmap
Definition: ESTLType.h:33
@ kSTLunorderedmultiset
Definition: ESTLType.h:43
@ kSTLstring
Definition: ESTLType.h:48
@ kSTLset
Definition: ESTLType.h:35
@ kSTLmultiset
Definition: ESTLType.h:36
@ kSTLdeque
Definition: ESTLType.h:32
@ kSTLvector
Definition: ESTLType.h:30
@ kSTLunorderedmultimap
Definition: ESTLType.h:45
@ kSTLunorderedset
Definition: ESTLType.h:42
@ kSTLlist
Definition: ESTLType.h:31
@ kSTLforwardlist
Definition: ESTLType.h:41
@ kSTLunorderedmap
Definition: ESTLType.h:44
@ kNotSTL
Definition: ESTLType.h:29
@ kSTLmultimap
Definition: ESTLType.h:34
ROOT::ESTLType IsSTLCont(std::string_view type)
type : type name: vector<list<classA,allocator>,allocator> result: 0 : not stl container code of cont...
int GetSplit(const char *type, std::vector< std::string > &output, int &nestedLoc, EModType mode=TClassEdit::kNone)
Stores in output (after emptying it) the split type.
Definition: TClassEdit.cxx:995
Definition: first.py:1