Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JRootClass.hh
Go to the documentation of this file.
1 #ifndef __JROOT__JROOTCLASS__
2 #define __JROOT__JROOTCLASS__
3 
4 #include <string>
5 #include <ostream>
6 #include <string.h>
7 #include <typeinfo>
8 
9 #include <TDictionary.h>
10 #include <TClass.h>
11 #include <TDataMember.h>
12 #include <TBaseClass.h>
13 #include <TIterator.h>
14 #include <TList.h>
15 
16 #include "JLang/JType.hh"
17 #include "JLang/JException.hh"
18 #include "JLang/JEquals.hh"
19 
20 
21 /**
22  * \author mdejong
23  */
24 
25 namespace JROOT {}
26 namespace JPP { using namespace JROOT; }
27 
28 namespace JROOT {
29 
30  using JLANG::JEquals;
31  using JLANG::JType;
32  using JLANG::getType;
34 
35 
36  /**
37  * Auxiliary class to manage access to base classes and data members of ROOT class.
38  */
39  struct JRootClass :
40  public JEquals<JRootClass>
41  {
42  /**
43  * Check class name against ROOT class names.
44  *
45  * \param class_name class name
46  * \return true if valid class name; else false
47  */
48  static inline bool is_class(const char* const class_name)
49  {
50  return (class_name != NULL &&
51  strcmp(class_name, TClass ::Class()->GetName()) != 0 &&
52  strcmp(class_name, TObject::Class()->GetName()) != 0 &&
53  strcmp(class_name, "_Rb_tree_node_base") != 0 &&
54  strcmp(class_name, "fgIsA") != 0 &&
55  strcmp(class_name, "atomic<TClass*>") != 0);
56  }
57 
58 
59  /**
60  * Check base class against ROOT class names.
61  *
62  * \param base_class base class
63  * \return true if valid class name; else false
64  */
65  static inline bool is_class(const TBaseClass& base_class)
66  {
67  return is_class(base_class.GetName());
68  }
69 
70 
71  /**
72  * Check data member against ROOT class names.
73  *
74  * \param data_member data member
75  * \return true if valid class name; else false
76  */
77  static inline bool is_class(const TDataMember& data_member)
78  {
79  return is_class(data_member.GetTypeName());
80  }
81 
82 
83  /**
84  * Check if base class is STL container.
85  *
86  * \param base_class base class
87  * \return true if STL congtainer; else false
88  */
89  static inline bool is_STLcontainer(const TBaseClass& base_class)
90  {
91  return (const_cast<TBaseClass&>(base_class).IsSTLContainer() != ROOT::kNotSTL);
92  }
93 
94 
95  /**
96  * Check if data member is STL container.
97  *
98  * \param data_member data member
99  * \return true if STL congtainer; else false
100  */
101  static inline bool is_STLcontainer(const TDataMember& data_member)
102  {
103  return (const_cast<TDataMember&>(data_member).IsSTLContainer() != ROOT::kNotSTL);
104  }
105 
106 
107  /**
108  * Check if data member is STL string.
109  *
110  * \param data_member data member
111  * \return true if STL string; else false
112  */
113  static inline bool is_STLstring(const TDataMember& data_member)
114  {
115  return (strcmp(data_member.GetFullTypeName(), "string") == 0 ||
116  strcmp(data_member.GetFullTypeName(), "const string") == 0);
117  }
118 
119 
120  /**
121  * Check if data member is static.
122  *
123  * \param data_member data member
124  * \return true if static; else false
125  */
126  static inline bool is_static(const TDataMember& data_member)
127  {
128  return (data_member.Property() & kIsStatic);
129  }
130 
131 
132  /**
133  * Constructor.
134  *
135  * \param type data type
136  */
137  template<class JType_t>
138  JRootClass(const JType<JType_t>& type) :
139  dictionary(TDictionary::GetDictionary(typeid(JType_t))),
140  offset(0)
141  {}
142 
143 
144  /**
145  * Constructor.
146  *
147  * \param pd pointer to C++ data member
148  */
149  template<class JType_t, class JClass_t>
150  JRootClass(JType_t JClass_t::*pd) :
151  dictionary(TDictionary::GetDictionary(typeid(JType_t))),
152  offset((char*) &(((JClass_t*) NULL)->*pd) - (char*) NULL)
153  {}
154 
155 
156  /**
157  * Get dictionary.
158  *
159  * \return pointer to dictionary
160  */
161  TDictionary* getDictionary() const
162  {
163  return dictionary;
164  }
165 
166 
167  /**
168  * Get offset of this class with respect to parent class.
169  *
170  * \return offset
171  */
172  int getOffset() const
173  {
174  return offset;
175  }
176 
177 
178  /**
179  * Get class.
180  *
181  * \return pointer to class
182  */
183  TClass* getClass() const
184  {
185  return dynamic_cast<TClass*>(dictionary);
186  }
187 
188 
189  /**
190  * Get type name.
191  *
192  * \return type name
193  */
194  const char* getTypename() const
195  {
196  if (dictionary != NULL)
197  return dictionary->GetName();
198  else
199  return NULL;
200  }
201 
202 
203  /**
204  * Check validity of this class.
205  *
206  * \return true if valid class; else false
207  */
208  bool is_valid() const
209  {
210  return (this->getDictionary() != NULL && is_class(this->getTypename()));
211  }
212 
213 
214  /**
215  * Test equality of ROOT classes.
216  *
217  * \param object ROOT class
218  * \return true if both ROOT classes are same type; else false
219  */
220  bool equals(const JRootClass& object) const
221  {
222  return (this-> getTypename() != NULL &&
223  object.getTypename() != NULL &&
224  strcmp(this->getTypename(), object.getTypename()) == 0);
225  }
226 
227 
228  /**
229  * Find base class or data member with given name within current class.
230  *
231  * \param name name of base class or data member
232  */
233  JRootClass find(const char* name) const
234  {
235  if (name != NULL && strlen(name) != 0) {
236 
237  if (strcmp(getTypename(), name) == 0) {
238  return *this;
239  }
240 
241  if (this->getClass() != NULL) {
242 
243  // check for data member
244 
245  const TDataMember* p = this->getClass()->GetDataMember(name);
246 
247  if (p != NULL) {
248  return this->get(*p);
249  }
250 
251  // check for base classes
252 
253  TIterator* i = this->getClass()->GetListOfBases()->MakeIterator();
254 
255  for (TBaseClass* p; (p = (TBaseClass*) i->Next()) != NULL; ) {
256 
257  if (is_class(*p) && !is_STLcontainer(*p)) {
258 
259  JRootClass rcs = this->get(*p);
260 
261  rcs = rcs.find(name);
262 
263  if (rcs.is_valid()) {
264  return rcs;
265  }
266  }
267  }
268  }
269  }
270 
271  return JRootClass(); // invalid value
272  }
273 
274 
275  /**
276  * Get ROOT class of given data member.
277  *
278  * \param data_member data member
279  */
280  JRootClass get(const TDataMember& data_member) const
281  {
282  return JRootClass(TDictionary::GetDictionary(data_member.GetTypeName()),
283  this->getOffset() + data_member.GetOffset());
284  }
285 
286 
287  /**
288  * Get ROOT class of given base class
289  *
290  * \param base_class base class
291  */
292  JRootClass get(const TBaseClass& base_class) const
293  {
294  return JRootClass(TDictionary::GetDictionary(base_class.GetName()),
295  this->getOffset() + const_cast<TBaseClass&>(base_class).GetDelta());
296  }
297 
298 
299  /**
300  * Print ROOT class information.
301  *
302  * \param out output stream
303  */
304  inline void print(std::ostream& out) const
305  {
306  print(out, getTypename());
307  }
308 
309 
310  protected:
311 
312  TDictionary* dictionary; //!< pointer to ROOT dictionary
313  int offset; //!< offset with respect to data structure [B]
314 
315 
316  /**
317  * Default constructor.
318  */
320  dictionary(NULL),
321  offset(0)
322  {}
323 
324 
325  /**
326  * Constructor.
327  *
328  * \param dictionary pointer to dictionary
329  * \param offset offset
330  */
331  JRootClass(TDictionary* dictionary,
332  int offset) :
333  dictionary(dictionary),
334  offset (offset)
335  {}
336 
337 
338  /**
339  * Print ROOT class information.
340  *
341  * \param out output stream
342  * \param prefix prefix
343  */
344  inline void print(std::ostream& out, const std::string& prefix) const
345  {
346  if (this->is_valid()) {
347 
348  print(out, prefix, this->getTypename());
349 
350  if (this->getClass() != NULL) {
351 
352  if (this->getClass()->GetListOfBases() != NULL) {
353 
354  TIterator* i = this->getClass()->GetListOfBases()->MakeIterator();
355 
356  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
357  if (!is_STLcontainer(*p))
358  this->get(*p).print(out, prefix + "::" + p->GetName());
359  else
360  print(out, prefix + "::" + p->GetName(), this->get(*p).getTypename());
361  }
362  }
363 
364  if (this->getClass()->GetListOfDataMembers() != NULL) {
365 
366  TIterator* i = this->getClass()->GetListOfDataMembers()->MakeIterator();
367 
368  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
369  if (!is_STLstring(*p) && !is_STLcontainer(*p))
370  this->get(*p).print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName());
371  else
372  print(out, prefix + (is_static(*p) ? "::" : ".") + p->GetName(), this->get(*p).getTypename());
373  }
374  }
375  }
376  }
377  }
378 
379 
380  /**
381  * Print ROOT class information.
382  *
383  * \param out output stream
384  * \param name name
385  * \param type type
386  */
387  inline static void print(std::ostream& out, const std::string& name, const std::string& type)
388  {
389  using namespace std;
390 
391  out << name << " " << '(' << type << ')' << endl;
392  }
393  };
394 
395 
396  /**
397  * Simple address wrapper.
398  */
399  template<class JPointer_t>
400  struct JAddress
401  {
402  /**
403  * Type definition of address.
404  */
405  typedef JPointer_t pointer_type;
406 
407  /**
408  * Constructor.
409  *
410  * \param p pointer to object
411  */
413  address(p)
414  {}
415 
417  };
418 
419 
420  /**
421  * Auxiliary class to manage access to base classes and data members of ROOT class objects.
422  *
423  * This class augments the class JRootClass with addressing capabilities.
424  */
425  template<class JPointer_t>
427  public JRootClass,
428  public JAddress<JPointer_t>
429  {
432 
433  /**
434  * Constructor.
435  *
436  * \param object template object
437  */
438  template<class T>
440  JRootClass(JType<T>()),
441  JAddress_t((pointer_type) &object)
442  {}
443 
444 
445  /**
446  * Get address.
447  *
448  * \return pointer to object
449  */
451  {
452  return this->address + getOffset();
453  }
454 
455 
456  /**
457  * Check validity of this addressable class.
458  *
459  * \return true if valid addressable class; else false
460  */
461  bool is_valid() const
462  {
463  return (JRootClass::is_valid() && this->address != NULL);
464  }
465 
466 
467  /**
468  * Find addressable base class or data member with given name within current class.
469  *
470  * \param name name of base class or data member
471  */
472  JRootAddressableClass find(const char* name) const
473  {
474  return JRootAddressableClass(JRootClass::find(name), this->address);
475  }
476 
477 
478  /**
479  * Get addressable class of given data member.
480  *
481  * \param data_member data member
482  */
483  JRootAddressableClass get(const TDataMember& data_member) const
484  {
485  return JRootAddressableClass(JRootClass::get(data_member), this->address);
486  }
487 
488 
489  /**
490  * Get addressable class of given base class
491  *
492  * \param base_class base class
493  */
494  JRootAddressableClass get(const TBaseClass& base_class) const
495  {
496  return JRootAddressableClass(JRootClass::get(base_class), this->address);
497  }
498 
499 
500  /**
501  * Find addressable base class or data member with given name within current class.
502  *
503  * \param name name of base class or data member
504  */
506  {
507  return this->find(name);
508  }
509 
510 
511  protected:
512  /**
513  * Constructor.
514  *
515  * \param rc ROOT class
516  * \param address address
517  */
519  JRootClass(rc),
520  JAddress_t(address)
521  {}
522  };
523 
524 
525  /**
526  * ROOT class for reading object.
527  */
529  public JRootAddressableClass<char *>
530  {
531  /**
532  * Constructor.
533  *
534  * \param object template object
535  */
536  template<class T>
538  JRootAddressableClass<char *>(object)
539  {}
540 
541 
542  /**
543  * Copy constructor.
544  *
545  * \param rc ROOT addressable class
546  */
548  JRootAddressableClass<char *>(rc)
549  {}
550 
551 
552  /**
553  * Type conversion operator.
554  *
555  * \return value
556  */
557  template<class T>
558  operator const T&() const
559  {
560  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
561  return * (const T*) this->getAddress();
562  } else {
563  THROW(JCastException, "JRootReadableClass::operator const T&");
564  }
565  }
566 
567 
568  /**
569  * Type conversion operator.
570  *
571  * \return value
572  */
573  template<class T>
574  operator T&()
575  {
576  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
577  return * (T*) this->getAddress();
578  } else {
579  THROW(JCastException, "JRootReadableClass::operator T&");
580  }
581  }
582  };
583 
584 
585  /**
586  * ROOT class for writing object.
587  */
589  public JRootAddressableClass<const char*>
590  {
591  /**
592  * Constructor.
593  *
594  * \param object template object
595  */
596  template<class T>
597  JRootWritableClass(const T& object) :
598  JRootAddressableClass<const char *>(object)
599  {}
600 
601 
602  /**
603  * Copy constructor.
604  *
605  * \param rc ROOT addressable class
606  */
608  JRootAddressableClass<const char *>(rc)
609  {}
610 
611 
612  /**
613  * Type conversion operator.
614  *
615  * \return value
616  */
617  template<class T>
618  operator const T&() const
619  {
620  if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
621  return * (const T*) this->getAddress();
622  } else {
623  THROW(JCastException, "JRootWritableClass::operator const T&");
624  }
625  }
626  };
627 
628 
629  /**
630  * Get ROOT data member for given parent and member class.
631  *
632  * \param parent ROOT class
633  * \param member ROOT class
634  * \return pointer to ROOT data member
635  */
636  inline const TDataMember* getDataMember(const JRootClass& parent,
637  const JRootClass& member)
638  {
639  if (parent.getClass() != NULL) {
640 
641  TIterator* i = NULL;
642 
643  i = parent.getClass()->GetListOfDataMembers()->MakeIterator();
644 
645  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
646 
647  const JRootClass abc = parent.get(*p);
648 
649  if (abc == member && abc.getOffset() == member.getOffset()) {
650  return p;
651  }
652  }
653 
654  i = parent.getClass()->GetListOfBases()->MakeIterator();
655 
656  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
657 
659 
660  const TDataMember* q = getDataMember(parent.get(*p), member);
661 
662  if (q != NULL) {
663  return q;
664  }
665  }
666  }
667  }
668 
669  return NULL;
670  }
671 
672 
673  /**
674  * Get ROOT data member for given C++ data member.
675  *
676  * \param pd pointer to C++ data member
677  * \return pointer to ROOT data member
678  */
679  template<class JType_t, class JClass_t>
680  inline const TDataMember* getDataMember(JType_t JClass_t::*pd)
681  {
682  return getDataMember(JRootClass(getType<JClass_t>()), JRootClass(pd));
683  }
684 }
685 
686 #endif
void print(std::ostream &out, const std::string &prefix) const
Print ROOT class information.
Definition: JRootClass.hh:344
Exceptions.
ROOT class for reading object.
Definition: JRootClass.hh:528
JRootAddressableClass find(const char *name) const
Find addressable base class or data member with given name within current class.
Definition: JRootClass.hh:472
pointer_type address
Definition: JRootClass.hh:416
JAddress_t::pointer_type pointer_type
Definition: JRootClass.hh:431
int getOffset() const
Get offset of this class with respect to parent class.
Definition: JRootClass.hh:172
JRootAddressableClass(const JRootClass &rc, pointer_type address)
Constructor.
Definition: JRootClass.hh:518
JRootClass(JType_t JClass_t::*pd)
Constructor.
Definition: JRootClass.hh:150
const TDataMember * getDataMember(const JRootClass &parent, const JRootClass &member)
Get ROOT data member for given parent and member class.
Definition: JRootClass.hh:636
static bool is_STLcontainer(const TBaseClass &base_class)
Check if base class is STL container.
Definition: JRootClass.hh:89
void print(std::ostream &out) const
Print ROOT class information.
Definition: JRootClass.hh:304
JRootClass(const JType< JType_t > &type)
Constructor.
Definition: JRootClass.hh:138
static bool is_class(const char *const class_name)
Check class name against ROOT class names.
Definition: JRootClass.hh:48
const char * getTypename() const
Get type name.
Definition: JRootClass.hh:194
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Definition: JException.hh:670
JRootClass()
Default constructor.
Definition: JRootClass.hh:319
JRootAddressableClass(T &object)
Constructor.
Definition: JRootClass.hh:439
JRootWritableClass(const JRootAddressableClass< const char * > &rc)
Copy constructor.
Definition: JRootClass.hh:607
Auxiliary class for a type holder.
Definition: JType.hh:19
static bool is_STLcontainer(const TDataMember &data_member)
Check if data member is STL container.
Definition: JRootClass.hh:101
JRootWritableClass(const T &object)
Constructor.
Definition: JRootClass.hh:597
Auxiliary class to manage access to base classes and data members of ROOT class objects.
Definition: JRootClass.hh:426
static bool is_STLstring(const TDataMember &data_member)
Check if data member is STL string.
Definition: JRootClass.hh:113
JRootClass get(const TDataMember &data_member) const
Get ROOT class of given data member.
Definition: JRootClass.hh:280
JRootAddressableClass operator[](const char *name) const
Find addressable base class or data member with given name within current class.
Definition: JRootClass.hh:505
TDictionary * getDictionary() const
Get dictionary.
Definition: JRootClass.hh:161
static bool is_class(const TBaseClass &base_class)
Check base class against ROOT class names.
Definition: JRootClass.hh:65
pointer_type getAddress() const
Get address.
Definition: JRootClass.hh:450
do set_variable OUTPUT_DIRECTORY $WORKDIR T
Template definition of auxiliary base class for comparison of data structures.
Definition: JEquals.hh:24
bool equals(const JRootClass &object) const
Test equality of ROOT classes.
Definition: JRootClass.hh:220
bool is_valid() const
Check validity of this class.
Definition: JRootClass.hh:208
JRootReadableClass(T &object)
Constructor.
Definition: JRootClass.hh:537
static void print(std::ostream &out, const std::string &name, const std::string &type)
Print ROOT class information.
Definition: JRootClass.hh:387
Exception for cast operation.
Definition: JException.hh:234
then echo n User name
Definition: JCookie.sh:45
TDictionary * dictionary
pointer to ROOT dictionary
Definition: JRootClass.hh:312
JPointer_t pointer_type
Type definition of address.
Definition: JRootClass.hh:405
bool is_valid() const
Check validity of this addressable class.
Definition: JRootClass.hh:461
JAddress< JPointer_t > JAddress_t
Definition: JRootClass.hh:430
static bool is_class(const TDataMember &data_member)
Check data member against ROOT class names.
Definition: JRootClass.hh:77
TClass * getClass() const
Get class.
Definition: JRootClass.hh:183
JAddress(pointer_type p)
Constructor.
Definition: JRootClass.hh:412
JType< T > getType()
Get type.
Definition: JType.hh:31
JRootClass(TDictionary *dictionary, int offset)
Constructor.
Definition: JRootClass.hh:331
Simple address wrapper.
Definition: JRootClass.hh:400
Auxiliary class to manage access to base classes and data members of ROOT class.
Definition: JRootClass.hh:39
JRootClass find(const char *name) const
Find base class or data member with given name within current class.
Definition: JRootClass.hh:233
int offset
offset with respect to data structure [B]
Definition: JRootClass.hh:313
JRootReadableClass(const JRootAddressableClass< char * > &rc)
Copy constructor.
Definition: JRootClass.hh:547
static bool is_static(const TDataMember &data_member)
Check if data member is static.
Definition: JRootClass.hh:126
ROOT class for writing object.
Definition: JRootClass.hh:588