Jpp test-rotations-new
the software that should make you happy
Loading...
Searching...
No Matches
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 <cstring>
7#include <typeinfo>
8#include <vector>
9
10#include <TDictionary.h>
11#include <TClass.h>
12#include <TDataMember.h>
13#include <TBaseClass.h>
14#include <TIterator.h>
15#include <TList.h>
16#include <TBranch.h>
17
18#include "JLang/JType.hh"
19#include "JLang/JException.hh"
20#include "JLang/JEquals.hh"
21
22#include "JROOT/JRoot.hh"
23
24
25/**
26 * \author mdejong
27 */
28
29namespace JROOT {}
30namespace JPP { using namespace JROOT; }
31
32namespace JROOT {
33
34 using JLANG::JEquals;
35 using JLANG::JType;
37
38
39 /**
40 * Auxiliary class to manage access to base classes and data members of ROOT class.
41 */
42 struct JRootClass :
43 public JEquals<JRootClass>
44 {
45 /**
46 * Constructor.
47 *
48 * \param type data type
49 */
50 template<class JType_t>
52 dictionary(TDictionary::GetDictionary(typeid(JType_t))),
53 offset(0)
54 {}
55
56
57 /**
58 * Constructor.
59 *
60 * \param pd pointer to C++ data member
61 */
62 template<class JType_t, class JClass_t>
63 JRootClass(JType_t JClass_t::*pd) :
64 dictionary(TDictionary::GetDictionary(typeid(JType_t))),
65 offset((char*) &(((JClass_t*) NULL)->*pd) - (char*) NULL)
66 {}
67
68
69 /**
70 * Constructor.
71 *
72 * \param dictionary pointer to dictionary
73 * \param offset offset
74 */
75 JRootClass(TDictionary* dictionary,
76 int offset = 0) :
79 {}
80
81
82 /**
83 * Get dictionary.
84 *
85 * \return pointer to dictionary
86 */
87 TDictionary* getDictionary() const
88 {
89 return dictionary;
90 }
91
92
93 /**
94 * Get offset of this class with respect to parent class.
95 *
96 * \return offset
97 */
98 int getOffset() const
99 {
100 return offset;
101 }
102
103
104 /**
105 * Get class.
106 *
107 * \return pointer to class
108 */
109 TClass* getClass() const
110 {
111 return dynamic_cast<TClass*>(dictionary);
112 }
113
114
115 /**
116 * Get type name.
117 *
118 * \return type name
119 */
120 const char* getTypename() const
121 {
122 if (dictionary != NULL)
123 return dictionary->GetName();
124 else
125 return NULL;
126 }
127
128
129 /**
130 * Check validity of this class.
131 *
132 * \return true if valid class; else false
133 */
134 bool is_valid() const
135 {
136 return (this->getDictionary() != NULL && JRoot::is_class(this->getTypename()));
137 }
138
139
140 /**
141 * Test equality of ROOT classes.
142 *
143 * \param object ROOT class
144 * \return true if both ROOT classes are same type; else false
145 */
146 bool equals(const JRootClass& object) const
147 {
148 return (this-> getTypename() != NULL &&
149 object.getTypename() != NULL &&
150 strcmp(this->getTypename(), object.getTypename()) == 0);
151 }
152
153
154 /**
155 * Find base class or data member with given name within current class.
156 *
157 * \param name name of base class or data member
158 * \param option case insensitive
159 * \return ROOT class
160 */
161 JRootClass find(const char* const name, const bool option = true) const
162 {
163 if (name != NULL && strlen(name) != 0) {
164
165 if (strcmp(getTypename(), name) == 0) {
166 return *this;
167 }
168
169 if (this->getClass() != NULL) {
170
171 // check for data members
172
173 for (TIter next(this->getClass()->GetListOfDataMembers(kFALSE)); const TDataMember *p = (const TDataMember*) next(); ) {
174 if (( option && strcmp (p->GetName(), name) == 0) ||
175 (!option && strcasecmp(p->GetName(), name) == 0)) {
176 return this->get(*p);
177 }
178 }
179
180 // check for base classes
181
182 for (TIter next(this->getClass()->GetListOfBases()); const TBaseClass *p = (const TBaseClass*) next(); ) {
183
184 if (JRoot::is_class(*p) && !JRoot::is_STLcontainer(*p)) {
185
186 JRootClass rcs = this->get(*p);
187
188 rcs = rcs.find(name, option);
189
190 if (rcs.is_valid()) {
191 return rcs;
192 }
193 }
194 }
195 }
196 }
197
198 return JRootClass(); // invalid value
199 }
200
201
202 /**
203 * Get ROOT class of given data member.
204 *
205 * \param object data member
206 * \return ROOT class
207 */
208 JRootClass get(const TDataMember& object) const
209 {
210 return JRootClass(TDictionary::GetDictionary(object.GetTypeName()),
211 this->getOffset() + object.GetOffset());
212 }
213
214
215 /**
216 * Get ROOT class of given base class
217 *
218 * \param object base class
219 * \return ROOT class
220 */
221 JRootClass get(const TBaseClass& object) const
222 {
223 return JRootClass(TDictionary::GetDictionary(object.GetName()),
224 this->getOffset() + const_cast<TBaseClass&>(object).GetDelta());
225 }
226
227
228 /**
229 * Print ROOT class information.
230 *
231 * \param out output stream
232 */
233 inline void print(std::ostream& out) const
234 {
235 print(out, getTypename());
236 }
237
238
239 protected:
240
241 TDictionary* dictionary; //!< pointer to ROOT dictionary
242 int offset; //!< offset with respect to data structure [B]
243
244
245 /**
246 * Default constructor.
247 */
249 dictionary(NULL),
250 offset(0)
251 {}
252
253
254 /**
255 * Print ROOT class information.
256 *
257 * \param out output stream
258 * \param prefix prefix
259 */
260 inline void print(std::ostream& out, const std::string& prefix) const
261 {
262 if (this->is_valid()) {
263
264 print(out, prefix, this->getTypename());
265
266 if (this->getClass() != NULL) {
267
268 for (TIter next(this->getClass()->GetListOfBases()); const TBaseClass *p = (const TBaseClass*) next(); ) {
269 if (!JRoot::is_STLcontainer(*p))
270 this->get(*p).print(out, prefix + "::" + p->GetName());
271 else
272 print(out, prefix + "::" + p->GetName(), this->get(*p).getTypename());
273 }
274
275 for (TIter next(this->getClass()->GetListOfDataMembers(kFALSE)); const TDataMember *p = (const TDataMember*) next(); ) {
277 this->get(*p).print(out, prefix + (JRoot::is_static(*p) ? "::" : ".") + p->GetName());
278 else
279 print(out, prefix + (JRoot::is_static(*p) ? "::" : ".") + p->GetName(), this->get(*p).getTypename());
280 }
281 }
282 }
283 }
284
285
286 /**
287 * Print ROOT class information.
288 *
289 * \param out output stream
290 * \param name name
291 * \param type type
292 */
293 inline static void print(std::ostream& out, const std::string& name, const std::string& type)
294 {
295 using namespace std;
296
297 out << name << " " << '(' << type << ')' << endl;
298 }
299 };
300
301
302 /**
303 * Get ROOT data member for given parent and member class.
304 *
305 * \param parent ROOT parent class
306 * \param member ROOT member class
307 * \return pointer to ROOT data member
308 */
309 inline const TDataMember* getDataMember(const JRootClass& parent,
310 const JRootClass& member)
311 {
312 if (parent.getClass() != NULL) {
313
314 for (TIter next(parent.getClass()->GetListOfDataMembers(kFALSE)); const TDataMember *p = (const TDataMember*) next(); ) {
315
316 const JRootClass abc = parent.get(*p);
317
318 if (abc == member && abc.getOffset() == member.getOffset()) {
319 return p;
320 }
321 }
322
323 for (TIter next(parent.getClass()->GetListOfBases()); const TBaseClass *p = (const TBaseClass*) next(); ) {
324
325 if (JRoot::is_class(*p) && !JRoot::is_STLcontainer(*p)) {
326
327 const TDataMember* q = getDataMember(parent.get(*p), member);
328
329 if (q != NULL) {
330 return q;
331 }
332 }
333 }
334 }
335
336 return NULL;
337 }
338
339
340 /**
341 * Get ROOT data member for given C++ data member.
342 *
343 * \param pd pointer to C++ data member
344 * \return pointer to ROOT data member
345 */
346 template<class JType_t, class JClass_t>
347 inline const TDataMember* getDataMember(JType_t JClass_t::*pd)
348 {
350 }
351
352
353 /**
354 * Get list of ROOT data members for given class.
355 */
356 template<class T>
358 {
359 static std::vector<TDataMember*> buffer;
360
361 if (buffer.empty()) {
362
363 TClass* rc = dynamic_cast<TClass*>(TDictionary::GetDictionary(typeid(T)));
364
365 if (rc != NULL) {
366 for (TIter next(rc->GetListOfDataMembers(kFALSE)); TDataMember *p = (TDataMember*) next(); ) {
367 if (JRoot::is_class(p->GetName())) {
368 buffer.push_back(p);
369 }
370 }
371 }
372 }
373
374 return buffer;
375 }
376
377
378 /**
379 * Auxiliary class to manage access to base classes and data members of ROOT class objects.
380 *
381 * This class augments the class JRootClass with addressing capabilities.
382 */
383 template<class JPointer_t>
385 public JRootClass
386 {
387 /**
388 * Type definition of address.
389 */
390 typedef JPointer_t pointer_type;
391
392 /**
393 * Constructor.
394 *
395 * \param object template object
396 */
397 template<class T>
399 JRootClass(JType<T>()),
400 address((pointer_type) &object)
401 {}
402
403
404 /**
405 * Get address.
406 *
407 * \return pointer to object
408 */
410 {
411 return this->address + getOffset();
412 }
413
414
415 /**
416 * Check validity of this addressable class.
417 *
418 * \return true if valid addressable class; else false
419 */
420 bool is_valid() const
421 {
422 return (JRootClass::is_valid() && this->address != NULL);
423 }
424
425
426 /**
427 * Find addressable base class or data member with given name within current class.
428 *
429 * \param name name of base class or data member
430 * \return ROOT addressable class
431 */
432 JRootAddressableClass find(const char* const name) const
433 {
435 }
436
437
438 /**
439 * Get addressable class of given data member.
440 *
441 * \param object data member
442 * \return ROOT addressable class
443 */
444 JRootAddressableClass get(const TDataMember& object) const
445 {
446 using namespace std;
447
448 if (object.IsaPointer()) {
449
450 char* po = NULL;
451
452 memcpy(&po, this->getAddress() + object.GetOffset(), sizeof(char*));
453
454 return JRootAddressableClass(JRootClass(TDictionary::GetDictionary(object.GetTypeName())), po);
455
456 } else if (strstr(object.GetTypeName(), "unique_ptr") != NULL) {
457
458 char* po = NULL;
459
460 memcpy(&po, this->getAddress() + object.GetOffset(), sizeof(char*));
461
462 string buffer(object.GetTypeName());
463
464 const string::size_type il = buffer.find_first_of("<");
465 const string::size_type ir = buffer.find_first_of(">,");
466
467 buffer = buffer.substr(il + 1, ir - il - 1);
468
469 return JRootAddressableClass(JRootClass(TDictionary::GetDictionary(buffer.c_str())), po);
470
471 } else {
472
473 return JRootAddressableClass(JRootClass::get(object), this->address);
474 }
475 }
476
477
478 /**
479 * Get addressable class of given base class
480 *
481 * \param object base class
482 * \return ROOT addressable class
483 */
484 JRootAddressableClass get(const TBaseClass& object) const
485 {
486 return JRootAddressableClass(JRootClass::get(object), this->address);
487 }
488
489
490 /**
491 * Find addressable base class or data member with given name within current class.
492 *
493 * \param name name of base class or data member
494 * \return ROOT addressable class
495 */
496 JRootAddressableClass operator[](const char* const name) const
497 {
498 return this->find(name);
499 }
500
501
502 protected:
503 /**
504 * Default constructor.
505 */
507 JRootClass(),
508 address(NULL)
509 {}
510
511
512 /**
513 * Constructor.
514 *
515 * \param rc ROOT class
516 * \param address address
517 */
522
524 };
525
526
527 /**
528 * ROOT class for reading into object.
529 */
531 public JRootAddressableClass<char *>
532 {
533 /**
534 * Default constructor.
535 */
539
540
541 /**
542 * Constructor.
543 *
544 * \param object template object
545 */
546 template<class T>
548 JRootAddressableClass<char *>(object)
549 {}
550
551
552 /**
553 * Copy constructor.
554 *
555 * \param rc ROOT addressable class
556 */
560
561
562 /**
563 * Constructor.
564 *
565 * \param dictionary pointer to dictionary
566 * \param address address
567 */
571
572
573 /**
574 * Type conversion operator.
575 *
576 * \return value
577 */
578 template<class T>
579 operator const T&() const
580 {
581 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
582 return * (const T*) this->getAddress();
583 } else {
584 THROW(JCastException, "JRootReadableClass::operator const T&");
585 }
586 }
587
588
589 /**
590 * Type conversion operator.
591 *
592 * \return value
593 */
594 template<class T>
595 operator T&()
596 {
597 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
598 return * (T*) this->getAddress();
599 } else {
600 THROW(JCastException, "JRootReadableClass::operator T&");
601 }
602 }
603 };
604
605
606 /**
607 * ROOT class for writing from object.
608 */
610 public JRootAddressableClass<const char*>
611 {
612 /**
613 * Default constructor.
614 */
616 JRootAddressableClass<const char *>()
617 {}
618
619
620 /**
621 * Constructor.
622 *
623 * \param object template object
624 */
625 template<class T>
626 JRootWritableClass(const T& object) :
627 JRootAddressableClass<const char *>(object)
628 {}
629
630
631 /**
632 * Copy constructor.
633 *
634 * \param rc ROOT addressable class
635 */
639
640
641 /**
642 * Constructor.
643 *
644 * \param dictionary pointer to dictionary
645 * \param address address
646 */
650
651
652 /**
653 * Type conversion operator.
654 *
655 * \return value
656 */
657 template<class T>
658 operator const T&() const
659 {
660 if (static_cast<const JRootClass&>(*this) == JRootClass(JType<T>())) {
661 return * (const T*) this->getAddress();
662 } else {
663 THROW(JCastException, "JRootWritableClass::operator const T&");
664 }
665 }
666 };
667
668
669 /**
670 * ROOT readable class for <tt>TBranch</tt>.
671 */
673 public JRootReadableClass
674 {
675 /**
676 * Default constructor.
677 */
681
682
683 /**
684 * Copy constructor.
685 *
686 * \param bc branch class
687 */
689 JRootReadableClass(static_cast<const JRootReadableClass&>(bc))
690 {
691 this->name = bc.name;
692 this->type = bc.type;
693
694 if (this->type != kOther_t) {
695 this->address = new char[TDataType::GetDataType(this->type)->Size()];
696 }
697 }
698
699
700 /**
701 * Constructor.
702 *
703 * \param pb pointer to branch
704 */
705 JBranchClass(TBranch* pb) :
707 {
708 if (pb != NULL) {
709
710 this->name = pb->GetName();
711
712 TClass* cs;
713
714 if (pb->GetExpectedType(cs, this->type) == 0) {
715
716 if (cs != NULL)
717 this->dictionary = cs;
718 else
719 this->dictionary = TDictionary::GetDictionary(TDataType::GetTypeName(this->type));
720
721 if (this->type != kOther_t) {
722 this->address = new char[TDataType::GetDataType(this->type)->Size()];
723 }
724 }
725 }
726 }
727
728
729 /**
730 * Destructor.
731 */
733 {
734 if (this->type != kOther_t) {
735 if (this->address != NULL) {
736 delete [] this->address;
737 }
738 }
739 }
740
741
742 /**
743 * Get name.
744 *
745 * \return name
746 */
747 const char* const getName() const
748 {
749 return this->name.c_str();
750 }
751
752
753 /**
754 * Get type.
755 *
756 * \return type
757 */
758 EDataType getType() const
759 {
760 return this->type;
761 }
762
763
764 /**
765 * Get branch address.
766 *
767 * \return address
768 */
770 {
771 return (type == kOther_t ? (void*) (&this->address) : (void*) this->address);
772 }
773
774 private:
775 std::string name;
776 EDataType type = kNoType_t;
777 };
778}
779
780#endif
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Exception for cast operation.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
std::vector< TDataMember * > getListOfDataMembers()
Get list of ROOT data members for given class.
const TDataMember * getDataMember(const JRootClass &parent, const JRootClass &member)
Get ROOT data member for given parent and member class.
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84
Auxiliary class for a type holder.
Definition JType.hh:19
ROOT readable class for TBranch.
JBranchClass()
Default constructor.
JBranchClass(const JBranchClass &bc)
Copy constructor.
EDataType getType() const
Get type.
JBranchClass(TBranch *pb)
Constructor.
void * getAddress()
Get branch address.
~JBranchClass()
Destructor.
const char *const getName() const
Get name.
Auxiliary class to manage access to base classes and data members of ROOT class objects.
JPointer_t pointer_type
Type definition of address.
bool is_valid() const
Check validity of this addressable class.
pointer_type getAddress() const
Get address.
JRootAddressableClass find(const char *const name) const
Find addressable base class or data member with given name within current class.
JRootAddressableClass operator[](const char *const name) const
Find addressable base class or data member with given name within current class.
JRootAddressableClass(const JRootClass &rc, pointer_type address)
Constructor.
JRootAddressableClass get(const TDataMember &object) const
Get addressable class of given data member.
JRootAddressableClass get(const TBaseClass &object) const
Get addressable class of given base class.
JRootAddressableClass()
Default constructor.
JRootAddressableClass(T &object)
Constructor.
Auxiliary class to manage access to base classes and data members of ROOT class.
Definition JRootClass.hh:44
TDictionary * getDictionary() const
Get dictionary.
Definition JRootClass.hh:87
JRootClass(const JType< JType_t > &type)
Constructor.
Definition JRootClass.hh:51
void print(std::ostream &out) const
Print ROOT class information.
TDictionary * dictionary
pointer to ROOT dictionary
const char * getTypename() const
Get type name.
bool is_valid() const
Check validity of this class.
JRootClass(JType_t JClass_t::*pd)
Constructor.
Definition JRootClass.hh:63
JRootClass()
Default constructor.
TClass * getClass() const
Get class.
void print(std::ostream &out, const std::string &prefix) const
Print ROOT class information.
int getOffset() const
Get offset of this class with respect to parent class.
Definition JRootClass.hh:98
JRootClass get(const TBaseClass &object) const
Get ROOT class of given base class.
int offset
offset with respect to data structure [B]
JRootClass find(const char *const name, const bool option=true) const
Find base class or data member with given name within current class.
static void print(std::ostream &out, const std::string &name, const std::string &type)
Print ROOT class information.
JRootClass get(const TDataMember &object) const
Get ROOT class of given data member.
JRootClass(TDictionary *dictionary, int offset=0)
Constructor.
Definition JRootClass.hh:75
bool equals(const JRootClass &object) const
Test equality of ROOT classes.
ROOT class for reading into object.
JRootReadableClass(const JRootAddressableClass< char * > &rc)
Copy constructor.
JRootReadableClass()
Default constructor.
JRootReadableClass(TDictionary *dictionary, pointer_type address)
Constructor.
JRootReadableClass(T &object)
Constructor.
ROOT class for writing from object.
JRootWritableClass(const JRootAddressableClass< const char * > &rc)
Copy constructor.
JRootWritableClass()
Default constructor.
JRootWritableClass(const T &object)
Constructor.
JRootWritableClass(TDictionary *dictionary, pointer_type address)
Constructor.
static bool is_class(const char *const name)
Check name of class against internal ROOT class names.
Definition JRoot.hh:30
static bool is_static(const TDataMember &object)
Check if data member is static.
Definition JRoot.hh:109
static bool is_STLcontainer(const TBaseClass &object)
Check if base class is STL container.
Definition JRoot.hh:72
static bool is_STLstring(const TDataMember &object)
Check if data member is STL string.
Definition JRoot.hh:96