Logo ROOT   6.10/09
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 steramers, 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 // retrived 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://www-linux.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 apropriate 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 offeset 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-linux.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) 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 
165 Bool_t TXMLPlayer::ProduceCode(TList* cllist, const char* filename)
166 {
167  if ((cllist==0) || (filename==0)) return kFALSE;
168 
169  std::ofstream fh(TString(filename)+".h");
170  std::ofstream fs(TString(filename)+".cxx");
171 
172  fh << "// generated header file" << std::endl << std::endl;
173  fh << "#ifndef " << filename << "_h" << std::endl;
174  fh << "#define " << filename << "_h" << std::endl << std::endl;
175 
176  fh << "#include \"" << names_xmlfileclass << ".h\"" << std::endl << std::endl;
177 
178  fs << "// generated source file" << std::endl << std::endl;
179  fs << "#include \"" << filename << ".h\"" << std::endl << std::endl;
180 
181  // produce appropriate include for all classes
182 
183  TObjArray inclfiles;
184  TIter iter(cllist);
185  TClass* cl = 0;
186  while ((cl = (TClass*) iter()) != 0) {
187  if (inclfiles.FindObject(cl->GetDeclFileName())==0) {
188  fs << "#include \"" << cl->GetDeclFileName() << "\"" << std::endl;
189  inclfiles.Add(new TNamed(cl->GetDeclFileName(),""));
190  }
191  }
192  inclfiles.Delete();
193 
194  fh << std::endl;
195  fs << std::endl;
196 
197  // produce streamers declarations and implementations
198 
199  iter.Reset();
200 
201  while ((cl = (TClass*) iter()) != 0) {
202 
203  fh << "extern void* " << GetStreamerName(cl) << "("
204  << names_xmlfileclass << " &buf, void* ptr = 0, bool checktypes = true);" << std::endl << std::endl;
205 
206  ProduceStreamerSource(fs, cl, cllist);
207  }
208 
209  fh << "#endif" << std::endl << std::endl;
210  fs << std::endl << std::endl;
211 
212  return kTRUE;
213 }
214 
215 ////////////////////////////////////////////////////////////////////////////////
216 /// returns name of simple data type for given data member
217 
219 {
220  if (member==0) return "int";
221 
222  if (member->IsBasic())
223  switch (member->GetDataType()->GetType()) {
224  case kChar_t: return "char";
225  case kShort_t: return "short";
226  case kInt_t: return "int";
227  case kLong_t: return "long";
228  case kLong64_t: return "long long";
229  case kFloat16_t:
230  case kFloat_t: return "float";
231  case kDouble32_t:
232  case kDouble_t: return "double";
233  case kUChar_t: {
234  char first = member->GetDataType()->GetTypeName()[0];
235  if ((first=='B') || (first=='b')) return "bool";
236  return "unsigned char";
237  }
238  case kBool_t: return "bool";
239  case kUShort_t: return "unsigned short";
240  case kUInt_t: return "unsigned int";
241  case kULong_t: return "unsigned long";
242  case kULong64_t: return "unsigned long long";
243  }
244 
245  if (member->IsEnum()) return "int";
246 
247  return member->GetTypeName();
248 }
249 
250 ////////////////////////////////////////////////////////////////////////////////
251 /// return simple data types for given TStreamerElement object
252 
254 {
255  if (el->GetType() == TVirtualStreamerInfo::kCounter) return "int";
256 
257  switch (el->GetType() % 20) {
258  case TVirtualStreamerInfo::kChar: return "char";
259  case TVirtualStreamerInfo::kShort: return "short";
260  case TVirtualStreamerInfo::kInt: return "int";
261  case TVirtualStreamerInfo::kLong: return "long";
262  case TVirtualStreamerInfo::kLong64: return "long long";
264  case TVirtualStreamerInfo::kFloat: return "float";
266  case TVirtualStreamerInfo::kDouble: return "double";
268  char first = el->GetTypeNameBasic()[0];
269  if ((first=='B') || (first=='b')) return "bool";
270  return "unsigned char";
271  }
272  case TVirtualStreamerInfo::kBool: return "bool";
273  case TVirtualStreamerInfo::kUShort: return "unsigned short";
274  case TVirtualStreamerInfo::kUInt: return "unsigned int";
275  case TVirtualStreamerInfo::kULong: return "unsigned long";
276  case TVirtualStreamerInfo::kULong64: return "unsigned long long";
277  }
278  return "int";
279 }
280 
281 ////////////////////////////////////////////////////////////////////////////////
282 /// return functions name to read simple data type from xml file
283 
285 {
286  if (type == TVirtualStreamerInfo::kCounter) return "ReadInt";
287 
288  switch (type % 20) {
289  case TVirtualStreamerInfo::kChar: return "ReadChar";
290  case TVirtualStreamerInfo::kShort: return "ReadShort";
291  case TVirtualStreamerInfo::kInt: return "ReadInt";
292  case TVirtualStreamerInfo::kLong: return "ReadLong";
293  case TVirtualStreamerInfo::kLong64: return "ReadLong64";
295  case TVirtualStreamerInfo::kFloat: return "ReadFloat";
297  case TVirtualStreamerInfo::kDouble: return "ReadDouble";
299  Bool_t isbool = false;
300  if (realname!=0)
301  isbool = (TString(realname).Index("bool",0, TString::kIgnoreCase)>=0);
302  if (isbool) return "ReadBool";
303  return "ReadUChar";
304  }
305  case TVirtualStreamerInfo::kBool: return "ReadBool";
306  case TVirtualStreamerInfo::kUShort: return "ReadUShort";
307  case TVirtualStreamerInfo::kUInt: return "ReadUInt";
308  case TVirtualStreamerInfo::kULong: return "ReadULong";
309  case TVirtualStreamerInfo::kULong64: return "ReadULong64";
310  }
311  return "ReadValue";
312 }
313 
314 ////////////////////////////////////////////////////////////////////////////////
315 /// produce code to access member of given class.
316 /// Parameter specials has following meaning:
317 /// 0 - nothing special
318 /// 1 - cast to data type
319 /// 2 - produce pointer on given member
320 /// 3 - skip casting when produce pointer by buf.P() function
321 
322 const char* TXMLPlayer::ElementGetter(TClass* cl, const char* membername, int specials)
323 {
324  TClass* membercl = cl ? cl->GetBaseDataMember(membername) : 0;
325  TDataMember* member = membercl ? membercl->GetDataMember(membername) : 0;
326  TMethodCall* mgetter = member ? member->GetterMethod(0) : 0;
327 
328  if ((mgetter!=0) && (mgetter->GetMethod()->Property() & kIsPublic)) {
329  fGetterName = "obj->";
330  fGetterName += mgetter->GetMethodName();
331  fGetterName += "()";
332  } else
333  if ((member==0) || ((member->Property() & kIsPublic) != 0)) {
334  fGetterName = "obj->";
335  fGetterName += membername;
336  } else {
337  fGetterName = "";
338  Bool_t deref = (member->GetArrayDim()==0) && (specials!=2);
339  if (deref) fGetterName += "*(";
340  if (specials!=3) {
341  fGetterName += "(";
342  if (member->Property() & kIsConstant) fGetterName += "const ";
343  fGetterName += GetMemberTypeName(member);
344  if (member->IsaPointer()) fGetterName+="*";
345  fGetterName += "*) ";
346  }
347  fGetterName += "buf.P(obj,";
348  fGetterName += member->GetOffset();
349  fGetterName += ")";
350  if (deref) fGetterName += ")";
351  specials = 0;
352  }
353 
354  if ((specials==1) && (member!=0)) {
355  TString cast = "(";
356  cast += GetMemberTypeName(member);
357  if (member->IsaPointer() || (member->GetArrayDim()>0)) cast += "*";
358  cast += ") ";
359  cast += fGetterName;
360  fGetterName = cast;
361  }
362 
363  if ((specials==2) && (member!=0)) {
364  TString buf = "&(";
365  buf += fGetterName;
366  buf += ")";
367  fGetterName = buf;
368  }
369 
370  return fGetterName.Data();
371 }
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 /// Produce code to set value to given data member.
375 /// endch should be output after value is specified.
376 
377 const char* TXMLPlayer::ElementSetter(TClass* cl, const char* membername, char* endch)
378 {
379  strcpy(endch,"");
380 
381  TClass* membercl = cl ? cl->GetBaseDataMember(membername) : 0;
382  TDataMember* member = membercl ? membercl->GetDataMember(membername) : 0;
383  TMethodCall* msetter = member ? member->SetterMethod(cl) : 0;
384 
385  if ((msetter!=0) && (msetter->GetMethod()->Property() & kIsPublic)) {
386  fSetterName = "obj->";
387  fSetterName += msetter->GetMethodName();
388  fSetterName += "(";
389  strcpy(endch,")");
390  } else
391  if ((member==0) || (member->Property() & kIsPublic) != 0) {
392  fSetterName = "obj->";
393  fSetterName += membername;
394  fSetterName += " = ";
395  } else {
396  fSetterName = "";
397  if (member->GetArrayDim()==0) fSetterName += "*";
398  fSetterName += "((";
399  if (member->Property() & kIsConstant) fSetterName += "const ";
400  fSetterName += GetMemberTypeName(member);
401  if (member->IsaPointer()) fSetterName += "*";
402  fSetterName += "*) buf.P(obj,";
403  fSetterName += member->GetOffset();
404  fSetterName += ")) = ";
405  }
406  return fSetterName.Data();
407 }
408 
409 ////////////////////////////////////////////////////////////////////////////////
410 /// Produce source code of streamer function for specified class
411 
412 void TXMLPlayer::ProduceStreamerSource(std::ostream& fs, TClass* cl, TList* cllist)
413 {
414  if (cl==0) return;
416  TObjArray* elements = info->GetElements();
417  if (elements==0) return;
418 
419  fs << "//__________________________________________________________________________" << std::endl;
420  fs << "void* " << GetStreamerName(cl) << "("
421  << names_xmlfileclass << " &buf, void* ptr, bool checktypes)" << std::endl;
422  fs << "{" << std::endl;
423  fs << tab1 << cl->GetName() << " *obj = (" << cl->GetName() << "*) ptr;" << std::endl;
424 
425  fs << tab1 << "if (buf.IsReading()) { " << std::endl;
426 
427  TIter iter(cllist);
428  TClass* c1 = 0;
429  Bool_t firstchild = true;
430 
431  while ((c1 = (TClass*) iter()) != 0) {
432  if (c1==cl) continue;
433  if (c1->GetListOfBases()->FindObject(cl->GetName())==0) continue;
434  if (firstchild) {
435  fs << tab2 << "if (checktypes) {" << std::endl;
436  fs << tab3 << "void* ";
437  firstchild = false;
438  } else
439  fs << tab3;
440  fs << "res = " << GetStreamerName(c1)
441  << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));" << std::endl;
442  fs << tab3 << "if (res) return dynamic_cast<" << cl->GetName()
443  << "*>(("<< c1->GetName() << " *) res);" << std::endl;
444  }
445  if (!firstchild) fs << tab2 << "}" << std::endl;
446 
447  fs << tab2 << "if (!buf.CheckClassNode(\"" << cl->GetName() << "\", "
448  << info->GetClassVersion() << ")) return 0;" << std::endl;
449 
450  fs << tab2 << "if (obj==0) obj = new " << cl->GetName() << ";" << std::endl;
451 
452  int n;
453  for (n=0;n<=elements->GetLast();n++) {
454 
455  TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n));
456  if (el==0) continue;
457 
458  Int_t typ = el->GetType();
459 
460  switch (typ) {
461  // basic types
478  char endch[5];
479  fs << tab2 << ElementSetter(cl, el->GetName(), endch);
480  fs << "buf." << GetBasicTypeReaderMethodName(el->GetType(), 0)
481  << "(\"" << el->GetName() << "\")" << endch << ";" << std::endl;
482  continue;
483  }
484 
485  // array of basic types like bool[10]
501  fs << tab2 << "buf.ReadArray("
502  << ElementGetter(cl, el->GetName(), (el->GetArrayDim()>1) ? 1 : 0);
503  fs << ", " << el->GetArrayLength()
504  << ", \"" << el->GetName() << "\");" << std::endl;
505  continue;
506  }
507 
508  // array of basic types like bool[n]
524  TStreamerBasicPointer* elp = dynamic_cast<TStreamerBasicPointer*> (el);
525  if (elp==0) {
526  std::cout << "fatal error with TStreamerBasicPointer" << std::endl;
527  continue;
528  }
529  char endch[5];
530 
531  fs << tab2 << ElementSetter(cl, el->GetName(), endch);
532  fs << "buf.ReadArray(" << ElementGetter(cl, el->GetName());
533  fs << ", " << ElementGetter(cl, elp->GetCountName());
534  fs << ", \"" << el->GetName() << "\", true)" << endch << ";" << std::endl;
535  continue;
536  }
537 
539  char endch[5];
540  fs << tab2 << ElementSetter(cl, el->GetName(), endch);
541  fs << "buf.ReadCharStar(" << ElementGetter(cl, el->GetName());
542  fs << ", \"" << el->GetName() << "\")" << endch << ";" << std::endl;
543  continue;
544  }
545 
547  fs << tab2 << GetStreamerName(el->GetClassPointer())
548  << "(buf, dynamic_cast<" << el->GetClassPointer()->GetName()
549  << "*>(obj), false);" << std::endl;
550  continue;
551  }
552 
553  // Class* Class not derived from TObject and with comment field //->
556  if (el->GetArrayLength()>0) {
557  fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
558  fs << ", " << el->GetArrayLength() << ", -1"
559  << ", \"" << el->GetName() << "\", "
560  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
561  } else {
562  fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName());
563  fs << ", \"" << el->GetName() << "\", "
564  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
565  }
566  continue;
567  }
568 
569  // Class* Class not derived from TObject and no comment
572  if (el->GetArrayLength()>0) {
573  fs << tab2 << "for (int n=0;n<" << el->GetArrayLength() << ";n++) "
574  << "delete (" << ElementGetter(cl, el->GetName()) << ")[n];" << std::endl;
575  fs << tab2 << "buf.ReadObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
576  fs << ", " << el->GetArrayLength()
577  << ", \"" << el->GetName() << "\", "
578  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
579  } else {
580  char endch[5];
581 
582  fs << tab2 << "delete " << ElementGetter(cl, el->GetName()) << ";" << std::endl;
583  fs << tab2 << ElementSetter(cl, el->GetName(), endch);
584  fs << "(" << el->GetClassPointer()->GetName()
585  << "*) buf.ReadObjectPtr(\"" << el->GetName() << "\", "
587  << ")" <<endch << ";" << std::endl;
588  }
589  continue;
590  }
591 
592  // Class NOT derived from TObject
594  fs << tab2 << "buf.ReadObject(" << ElementGetter(cl, el->GetName(), 2);
595  fs << ", \"" << el->GetName() << "\", "
596  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
597  continue;
598  }
599 
600  // Class NOT derived from TObject, array
602  fs << tab2 << "buf.ReadObjectArr(" << ElementGetter(cl, el->GetName());
603  fs << ", " << el->GetArrayLength()
604  << ", sizeof(" << el->GetClassPointer()->GetName()
605  << "), \"" << el->GetName() << "\", "
606  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
607  continue;
608  }
609 
610  // container with no virtual table (stl) and no comment
615  TStreamerSTL* elstl = dynamic_cast<TStreamerSTL*> (el);
616  if (elstl==0) break; // to make skip
617 
618  if (ProduceSTLstreamer(fs, cl, elstl, false)) continue;
619 
620  fs << tab2 << "// STL type = " << elstl->GetSTLtype() << std::endl;
621  break;
622  }
623  }
624  fs << tab2 << "buf.SkipMember(\"" << el->GetName()
625  << "\"); // sinfo type " << el->GetType()
626  << " of class " << el->GetClassPointer()->GetName()
627  << " not supported" << std::endl;
628  }
629 
630  fs << tab2 << "buf.EndClassNode();" << std::endl;
631 
632  fs << tab1 << "} else {" << std::endl;
633 
634  // generation of writing part of class streamer
635 
636  fs << tab2 << "if (obj==0) return 0;" << std::endl;
637 
638  firstchild = true;
639  iter.Reset();
640  while ((c1 = (TClass*) iter()) != 0) {
641  if (c1==cl) continue;
642  if (c1->GetListOfBases()->FindObject(cl->GetName())==0) continue;
643  if (firstchild) {
644  firstchild = false;
645  fs << tab2 << "if (checktypes) {" << std::endl;
646  }
647  fs << tab3 << "if (dynamic_cast<" << c1->GetName() << "*>(obj))" << std::endl;
648  fs << tab4 << "return " << GetStreamerName(c1) << "(buf, dynamic_cast<" << c1->GetName() << "*>(obj));" << std::endl;
649  }
650  if (!firstchild) fs << tab2 << "}" << std::endl;
651 
652  fs << tab2 << "buf.StartClassNode(\"" << cl->GetName() << "\", "
653  << info->GetClassVersion() << ");" << std::endl;
654 
655  for (n=0;n<=elements->GetLast();n++) {
656 
657  TStreamerElement* el = dynamic_cast<TStreamerElement*> (elements->At(n));
658  if (el==0) continue;
659 
660  Int_t typ = el->GetType();
661 
662  switch (typ) {
663  // write basic types
680  fs << tab2 << "buf.WriteValue(";
682  fs <<"(unsigned char) " << ElementGetter(cl, el->GetName());
683  else
684  fs << ElementGetter(cl, el->GetName());
685  fs << ", \"" << el->GetName() << "\");" << std::endl;
686  continue;
687  }
688 
689  // array of basic types
705  fs << tab2 << "buf.WriteArray("
706  << ElementGetter(cl, el->GetName(), (el->GetArrayDim()>1) ? 1 : 0);
707  fs << ", " << el->GetArrayLength()
708  << ", \"" << el->GetName() << "\");" << std::endl;
709  continue;
710  }
711 
727  TStreamerBasicPointer* elp = dynamic_cast<TStreamerBasicPointer*> (el);
728  if (elp==0) {
729  std::cout << "fatal error with TStreamerBasicPointer" << std::endl;
730  continue;
731  }
732  fs << tab2 << "buf.WriteArray(" << ElementGetter(cl, el->GetName());
733  fs << ", " << ElementGetter(cl, elp->GetCountName())
734  << ", \"" << el->GetName() << "\", true);" << std::endl;
735  continue;
736  }
737 
739  fs << tab2 << "buf.WriteCharStar(" << ElementGetter(cl, el->GetName())
740  << ", \"" << el->GetName() << "\");" << std::endl;
741  continue;
742  }
743 
745  fs << tab2 << GetStreamerName(el->GetClassPointer())
746  << "(buf, dynamic_cast<" << el->GetClassPointer()->GetName()
747  << "*>(obj), false);" << std::endl;
748  continue;
749  }
750 
751  // Class* Class not derived from TObject and with comment field //->
754  if (el->GetArrayLength()>0) {
755  fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
756  fs << ", " << el->GetArrayLength() << ", -1"
757  << ", \"" << el->GetName() << "\", "
758  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
759  } else {
760  fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName());
761  fs << ", \"" << el->GetName() << "\", "
762  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
763  }
764  continue;
765  }
766 
767  // Class* Class not derived from TObject and no comment
770  if (el->GetArrayLength()>0) {
771  fs << tab2 << "buf.WriteObjectPtrArr((void**) " << ElementGetter(cl, el->GetName(), 3);
772  fs << ", " << el->GetArrayLength()
773  << ", \"" << el->GetName() << "\", "
774  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
775  } else {
776  fs << tab2 << "buf.WriteObjectPtr(" << ElementGetter(cl, el->GetName());
777  fs << ", \"" << el->GetName() << "\", "
778  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
779  }
780  continue;
781  }
782 
783  case TVirtualStreamerInfo::kAny: { // Class NOT derived from TObject
784  fs << tab2 << "buf.WriteObject(" << ElementGetter(cl, el->GetName(), 2);
785  fs << ", \"" << el->GetName() << "\", "
786  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
787  continue;
788  }
789 
791  fs << tab2 << "buf.WriteObjectArr(" << ElementGetter(cl, el->GetName());
792  fs << ", " << el->GetArrayLength()
793  << ", sizeof(" << el->GetClassPointer()->GetName()
794  << "), \"" << el->GetName() << "\", "
795  << GetStreamerName(el->GetClassPointer()) << ");" << std::endl;
796  continue;
797  }
798 
799  // container with no virtual table (stl) and no comment
804  TStreamerSTL* elstl = dynamic_cast<TStreamerSTL*> (el);
805  if (elstl==0) break; // to make skip
806 
807  if (ProduceSTLstreamer(fs, cl, elstl, true)) continue;
808  fs << tab2 << "// STL type = " << elstl->GetSTLtype() << std::endl;
809  break;
810  }
811 
812  }
813  fs << tab2 << "buf.MakeEmptyMember(\"" << el->GetName()
814  << "\"); // sinfo type " << el->GetType()
815  << " of class " << el->GetClassPointer()->GetName()
816  << " not supported" << std::endl;
817  }
818 
819  fs << tab2 << "buf.EndClassNode();" << std::endl;
820 
821  fs << tab1 << "}" << std::endl;
822  fs << tab1 << "return obj;" << std::endl;
823  fs << "}" << std::endl << std::endl;
824 }
825 
826 ////////////////////////////////////////////////////////////////////////////////
827 /// Produce code to read argument of stl container from xml file
828 
829 void TXMLPlayer::ReadSTLarg(std::ostream& fs,
830  TString& argname,
831  int argtyp,
832  Bool_t isargptr,
833  TClass* argcl,
834  TString& tname,
835  TString& ifcond)
836 {
837  switch(argtyp) {
854  fs << tname << " " << argname << " = buf."
855  << GetBasicTypeReaderMethodName(argtyp, tname.Data()) << "(0);" << std::endl;
856  break;
857  }
858 
860  fs << tname << (isargptr ? " ": " *") << argname << " = "
861  << "(" << argcl->GetName() << "*)"
862  << "buf.ReadObjectPtr(0, "
863  << GetStreamerName(argcl) << ");" << std::endl;
864  if (!isargptr) {
865  if (ifcond.Length()>0) ifcond+=" && ";
866  ifcond += argname;
867  TString buf = "*";
868  buf += argname;
869  argname = buf;
870  }
871  break;
872  }
873 
875  fs << "string *" << argname << " = "
876  << "buf.ReadSTLstring();" << std::endl;
877  if (!isargptr) {
878  if (ifcond.Length()>0) ifcond+=" && ";
879  ifcond += argname;
880  TString buf = "*";
881  buf += argname;
882  argname = buf;
883  }
884  break;
885  }
886 
887  default:
888  fs << "/* argument " << argname << " not supported */";
889  }
890 }
891 
892 ////////////////////////////////////////////////////////////////////////////////
893 /// Produce code to write argument of stl container to xml file
894 
895 void TXMLPlayer::WriteSTLarg(std::ostream& fs, const char* accname, int argtyp, Bool_t isargptr, TClass* argcl)
896 {
897  switch(argtyp) {
914  fs << "buf.WriteValue(" << accname << ", 0);" << std::endl;
915  break;
916  }
917 
919  fs << "buf.WriteObjectPtr(";
920  if (isargptr)
921  fs << accname;
922  else
923  fs << "&(" << accname << ")";
924  fs << ", 0, " << GetStreamerName(argcl) << ");" << std::endl;
925  break;
926  }
927 
929  fs << "buf.WriteSTLstring(";
930  if (isargptr)
931  fs << accname;
932  else
933  fs << "&(" << accname << ")";
934  fs << ");" << std::endl;
935  break;
936  }
937 
938  default:
939  fs << "/* argument not supported */" << std::endl;
940  }
941 }
942 
943 ////////////////////////////////////////////////////////////////////////////////
944 /// Produce code of xml streamer for data member of stl type
945 
946 Bool_t TXMLPlayer::ProduceSTLstreamer(std::ostream& fs, TClass* cl, TStreamerSTL* el, Bool_t isWriting)
947 {
948  if ((cl==0) || (el==0)) return false;
949 
950  TClass* contcl = el->GetClassPointer();
951 
952  Bool_t isstr = (el->GetSTLtype() == ROOT::kSTLstring);
953  Bool_t isptr = el->IsaPointer();
954  Bool_t isarr = (el->GetArrayLength()>0);
955  Bool_t isparent = (strcmp(el->GetName(), contcl->GetName())==0);
956 
957  int stltyp = -1;
958  int narg = 0;
959  int argtype[2];
960  Bool_t isargptr[2];
961  TClass* argcl[2];
962  TString argtname[2];
963 
964  if (!isstr && contcl->GetCollectionType() != ROOT::kNotSTL) {
965  int nestedLoc = 0;
966  std::vector<std::string> splitName;
967  TClassEdit::GetSplit(contcl->GetName(), splitName, nestedLoc);
968 
969  stltyp = contcl->GetCollectionType();
970  switch (stltyp) {
971  case ROOT::kSTLvector : narg = 1; break;
972  case ROOT::kSTLlist : narg = 1; break;
973  case ROOT::kSTLforwardlist : narg = 1; break;
974  case ROOT::kSTLdeque : narg = 1; break;
975  case ROOT::kSTLmap : narg = 2; break;
976  case ROOT::kSTLmultimap : narg = 2; break;
977  case ROOT::kSTLset : narg = 1; break;
978  case ROOT::kSTLmultiset : narg = 1; break;
979  case ROOT::kSTLunorderedset : narg = 1; break;
980  case ROOT::kSTLunorderedmultiset : narg = 1; break;
981  case ROOT::kSTLunorderedmap : narg = 2; break;
982  case ROOT::kSTLunorderedmultimap : narg = 2; break;
983 
984  default: return false;
985  }
986 
987  for(int n=0;n<narg;n++) {
988  argtype[n] = -1;
989  isargptr[n] = false;
990  argcl[n] = 0;
991  argtname[n] = "";
992 
993  TString buf = splitName[n+1];
994 
995  argtname[n] = buf;
996 
997  // nested STL containers not yet supported
998  if (TClassEdit::IsSTLCont(buf.Data())) return false;
999 
1000  int pstar = buf.Index("*");
1001 
1002  if (pstar>0) {
1003  isargptr[n] = true;
1004  pstar--;
1005  while ((pstar>0) && (buf[pstar]==' ')) pstar--;
1006  buf.Remove(pstar+1);
1007  } else
1008  isargptr[n] = false;
1009 
1010  if (buf.Index("const ")==0) {
1011  buf.Remove(0,6);
1012  while ((buf.Length()>0) && (buf[0]==' ')) buf.Remove(0,1);
1013  }
1014 
1015  TDataType *dt = (TDataType*)gROOT->GetListOfTypes()->FindObject(buf);
1016  if (dt) argtype[n] = dt->GetType(); else
1017  if (buf=="string")
1019  else {
1020  argcl[n] = TClass::GetClass(buf);
1021  if (argcl[n]!=0) argtype[n]=TVirtualStreamerInfo::kObject;
1022  }
1023  if (argtype[n]<0) stltyp = -1;
1024  } // for narg
1025 
1026  if (stltyp<0) return false;
1027  }
1028 
1029  Bool_t akaarrayaccess = (narg==1) && (argtype[0]<20);
1030 
1031  char tabs[30], tabs2[30];
1032 
1033  if (isWriting) {
1034 
1035  fs << tab2 << "if (buf.StartSTLnode(\""
1036  << fXmlSetup.XmlGetElementName(el) << "\")) {" << std::endl;
1037 
1038  fs << tab3 << contcl->GetName() << " ";
1039 
1040  TString accname;
1041  if (isptr) {
1042  if (isarr) { fs << "**cont"; accname = "(*cont)->"; }
1043  else { fs << "*cont"; accname = "cont->"; }
1044  } else
1045  if (isarr) { fs << "*cont"; accname = "cont->"; }
1046  else { fs << "&cont"; accname = "cont."; }
1047 
1048  fs << " = ";
1049 
1050  if (isparent)
1051  fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << std::endl;
1052  else
1053  fs << ElementGetter(cl, el->GetName()) << ";" << std::endl;
1054 
1055  if (isarr && el->GetArrayLength()) {
1056  strlcpy(tabs, tab4, sizeof(tabs));
1057  fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << std::endl;
1058  } else
1059  strlcpy(tabs, tab3, sizeof(tabs));
1060 
1061  strlcpy(tabs2, tabs, sizeof(tabs2));
1062 
1063  if (isptr) {
1064  strlcat(tabs2, tab1, sizeof(tabs2));
1065  fs << tabs << "if (" << (isarr ? "*cont" : "cont") << "==0) {" << std::endl;
1066  fs << tabs2 << "buf.WriteSTLsize(0" << (isstr ? ",true);" : ");") << std::endl;
1067  fs << tabs << "} else {" << std::endl;
1068  }
1069 
1070  fs << tabs2 << "buf.WriteSTLsize(" << accname
1071  << (isstr ? "length(), true);" : "size());") << std::endl;
1072 
1073  if (isstr) {
1074  fs << tabs2 << "buf.WriteSTLstringData(" << accname << "c_str());" << std::endl;
1075  } else {
1076  if (akaarrayaccess) {
1077  fs << tabs2 << argtname[0] << "* arr = new " << argtname[0]
1078  << "[" << accname << "size()];" << std::endl;
1079  fs << tabs2 << "int k = 0;" << std::endl;
1080  }
1081 
1082  fs << tabs2 << contcl->GetName() << "::const_iterator iter;" << std::endl;
1083  fs << tabs2 << "for (iter = " << accname << "begin(); iter != "
1084  << accname << "end(); iter++)";
1085  if (akaarrayaccess) {
1086  fs << std::endl << tabs2 << tab1 << "arr[k++] = *iter;" << std::endl;
1087  fs << tabs2 << "buf.WriteArray(arr, " << accname << "size(), 0, false);" << std::endl;
1088  fs << tabs2 << "delete[] arr;" << std::endl;
1089  } else
1090  if (narg==1) {
1091  fs << std::endl << tabs2 << tab1;
1092  WriteSTLarg(fs, "*iter", argtype[0], isargptr[0], argcl[0]);
1093  } else
1094  if (narg==2) {
1095  fs << " {" << std::endl;
1096  fs << tabs2 << tab1;
1097  WriteSTLarg(fs, "iter->first", argtype[0], isargptr[0], argcl[0]);
1098  fs << tabs2 << tab1;
1099  WriteSTLarg(fs, "iter->second", argtype[1], isargptr[1], argcl[1]);
1100  fs << tabs2 << "}" << std::endl;
1101  }
1102  } // if (isstr)
1103 
1104  if (isptr) fs << tabs << "}" << std::endl;
1105 
1106  if (isarr && el->GetArrayLength()) {
1107  if (isptr)
1108  fs << tabs << "cont++;" << std::endl;
1109  else
1110  fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << std::endl;
1111  fs << tab3 << "}" << std::endl;
1112  }
1113 
1114  fs << tab3 << "buf.EndSTLnode();" << std::endl;
1115  fs << tab2 << "}" << std::endl;
1116 
1117  } else {
1118 
1119 
1120  fs << tab2 << "if (buf.VerifySTLnode(\""
1121  << fXmlSetup.XmlGetElementName(el) << "\")) {" << std::endl;
1122 
1123  fs << tab3 << contcl->GetName() << " ";
1124  TString accname, accptr;
1125  if (isptr) {
1126  if (isarr) { fs << "**cont"; accname = "(*cont)->"; accptr = "*cont"; }
1127  else { fs << "*cont"; accname = "cont->"; accptr = "cont"; }
1128  } else
1129  if (isarr) { fs << "*cont"; accname = "cont->"; }
1130  else { fs << "&cont"; accname = "cont."; }
1131 
1132  fs << " = ";
1133 
1134  if (isparent)
1135  fs << "*dynamic_cast<" << contcl->GetName() << "*>(obj);" << std::endl;
1136  else
1137  fs << ElementGetter(cl, el->GetName()) << ";" << std::endl;
1138 
1139  if (isarr && el->GetArrayLength()) {
1140  strlcpy(tabs, tab4, sizeof(tabs));
1141  fs << tab3 << "for(int n=0;n<" << el->GetArrayLength() << ";n++) {" << std::endl;
1142  } else
1143  strlcpy(tabs, tab3, sizeof(tabs));
1144 
1145  fs << tabs << "int size = buf.ReadSTLsize(" << (isstr ? "true);" : ");") << std::endl;
1146 
1147  if (isptr) {
1148  fs << tabs << "delete " << accptr << ";" << std::endl;
1149  fs << tabs << "if (size==0) " << accptr << " = 0;" << std::endl;
1150  fs << tabs << " else " << accptr << " = new " << contcl->GetName() << ";" << std::endl;
1151  if (!isarr) {
1152  char endch[5];
1153  fs << tabs << ElementSetter(cl, el->GetName(), endch);
1154  fs << "cont" << endch << ";" << std::endl;
1155  }
1156  } else {
1157  fs << tabs << accname << (isstr ? "erase();" : "clear();") << std::endl;
1158  }
1159 
1160  if (isstr) {
1161  fs << tabs << "if (size>0) " << accname << "assign(buf.ReadSTLstringData(size));" << std::endl;
1162  } else {
1163  if (akaarrayaccess) {
1164  fs << tabs << argtname[0] << "* arr = new " << argtname[0] << "[size];" << std::endl;
1165  fs << tabs << "buf.ReadArray(arr, size, 0, false);" << std::endl;
1166  }
1167 
1168  fs << tabs << "for(int k=0;k<size;k++)";
1169 
1170  if (akaarrayaccess) {
1171  fs << std::endl << tabs << tab1 << accname;
1172  if ((stltyp==ROOT::kSTLset) || (stltyp==ROOT::kSTLmultiset))
1173  fs << "insert"; else fs << "push_back";
1174  fs << "(arr[k]);" << std::endl;
1175  fs << tabs << "delete[] arr;" << std::endl;
1176  } else
1177  if (narg==1) {
1178  TString arg1("arg"), ifcond;
1179  fs << " {" << std::endl << tabs << tab1;
1180  ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
1181  fs << tabs << tab1;
1182  if (ifcond.Length()>0) fs << "if (" << ifcond << ") ";
1183  fs << accname;
1184  if ((stltyp==ROOT::kSTLset) || (stltyp==ROOT::kSTLmultiset))
1185  fs << "insert";
1186  else
1187  fs << "push_back";
1188  fs << "(" << arg1 << ");" << std::endl;
1189  fs << tabs << "}" << std::endl;
1190  } else
1191  if (narg==2) {
1192  TString arg1("arg1"), arg2("arg2"), ifcond;
1193  fs << " {" << std::endl << tabs << tab1;
1194  ReadSTLarg(fs, arg1, argtype[0], isargptr[0], argcl[0], argtname[0], ifcond);
1195  fs << tabs << tab1;
1196  ReadSTLarg(fs, arg2, argtype[1], isargptr[1], argcl[1], argtname[1], ifcond);
1197  fs << tabs << tab1;
1198  if (ifcond.Length()>0) fs << "if (" << ifcond << ") ";
1199  fs << accname << "insert(make_pair("
1200  << arg1 << ", " << arg2 << "));" << std::endl;
1201  fs << tabs << "}" << std::endl;
1202  }
1203  }
1204 
1205  if (isarr && el->GetArrayLength()) {
1206  if (isptr) fs << tabs << "cont++;" << std::endl;
1207  else fs << tabs << "(void*) cont = (char*) cont + sizeof(" << contcl->GetName() << ");" << std::endl;
1208  fs << tab3 << "}" << std::endl;
1209  }
1210 
1211  fs << tab3 << "buf.EndSTLnode();" << std::endl;
1212  fs << tab2 << "}" << std::endl;
1213  }
1214  return true;
1215 }
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:3452
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
TXMLSetup fXmlSetup
buffer for name of setter method
Definition: TXMLPlayer.h:51
const char * GetDeclFileName() const
Definition: TClass.h:376
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:329
return c1
Definition: legend1.C:41
All ROOT classes may have RTTI (run time type identification) support added.
Definition: TDataMember.h:31
void ProduceStreamerSource(std::ostream &fs, TClass *cl, TList *cllist)
Produce source code of streamer function for specified class.
Definition: TXMLPlayer.cxx:412
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:4360
const char * GetTypeName() const
Get type of data member, e,g.: "class TDirectory*" -> "TDirectory".
Int_t GetSTLtype() const
#define gROOT
Definition: TROOT.h:375
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition: TString.h:587
Basic string class.
Definition: TString.h:129
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:284
void Reset()
Definition: TCollection.h:156
Bool_t IsaPointer() const
Return true if the data member is a pointer.
virtual TObject * FindObject(const char *name) const
Find an object in this list using its name.
Definition: TList.cxx:501
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:946
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:396
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:72
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:377
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 GetBasicTypeName(TStreamerElement *el)
return simple data types for given TStreamerElement object
Definition: TXMLPlayer.cxx:253
A doubly linked list.
Definition: TList.h:43
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:528
const char * XmlGetElementName(const TStreamerElement *el)
return converted name for TStreamerElement
Definition: TXMLSetup.cxx:247
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:829
Ssiz_t Length() const
Definition: TString.h:388
Int_t GetArrayDim() const
Return number of array dimensions.
The ROOT global object gROOT contains a list of all defined classes.
Definition: TClass.h:71
TClass * GetBaseDataMember(const char *datamember)
Return pointer to (base) class that contains datamember.
Definition: TClass.cxx:2744
ROOT::ESTLType GetCollectionType() const
Return the &#39;type&#39; of the STL the TClass is representing.
Definition: TClass.cxx:2803
Long_t GetOffset() const
Get offset from "this".
const Bool_t kFALSE
Definition: RtypesCore.h:92
TString & Remove(Ssiz_t pos)
Definition: TString.h:621
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:336
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:895
const char * ElementGetter(TClass *cl, const char *membername, int specials=0)
produce code to access member of given class.
Definition: TXMLPlayer.cxx:322
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:2885
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:218
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:3225
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:91
Int_t GetType() const
const Int_t n
Definition: legend1.C:16
const char * Data() const
Definition: TString.h:347