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