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