Jpp master_rocky-44-g75b7c4f75
the software that should make you happy
Loading...
Searching...
No Matches
JRootStreamer.hh
Go to the documentation of this file.
1#ifndef __JROOT__JROOTSTREAMER__
2#define __JROOT__JROOTSTREAMER__
3
4#include <string>
5#include <istream>
6#include <ostream>
7#include <sstream>
8#include <memory>
9
10#include "JLang/JEquation.hh"
14#include "JLang/JBool.hh"
17#include "JLang/JStreamState.hh"
19#include "JROOT/JRootClass.hh"
21
22
23/**
24 * \file
25 *
26 * ASCII I/O of objects with ROOT dictionary.
27 * \author mdejong
28 */
29namespace JROOT {}
30namespace JPP { using namespace JROOT; }
31
32namespace JROOT {
33
34 using JLANG::JEquation;
36 using JLANG::JBool;
39
40
41 /**
42 * Implementation for ASCII input of objects with ROOT dictionary.
43 *
44 * The method JRootReader::get is compatible with equation formatting, i.e:
45 *
46 * <pre><key>[<division><key>]<separator><value>[<white space><value>]*<end of line></pre>
47 *
48 * In this, the key corresponds to the name of a data member,
49 * which can be recursively parsed via a division character.\n
50 * \n
51 * The method JRootReader::getObject relates to simple formatting, i.e:
52 *
53 * <pre><value>[<white space><value>]*</pre>
54 *
55 * The default format for input of <tt>std::vector<T></tt> is
56 *
57 * <pre><number of elements>[<white space><value>]*</pre>
58 */
60 public std::istream,
61 private JStreamState
62 {
63 public:
64 /**
65 * Constructor.
66 *
67 * \param in input stream
68 * \param parameters equation parameters
69 * \param dictionary dictionary
70 */
71 JRootReader(std::istream& in,
72 const JEquationParameters& parameters,
74 std::istream(in.rdbuf()),
75 JStreamState(in, static_cast<std::istream&>(*this)),
77 {
78 imbue(std::locale(in.getloc(), new JLANG::JEquationFacet(parameters)));
79 }
80
81
82 /**
83 * Get dictionary.
84 *
85 * \return dictionary
86 */
88 {
89 return dictionary;
90 }
91
92
93 /**
94 * Read object according equation format.
95 *
96 * \param object object
97 * \return this ROOT reader
98 */
99 template<class T>
100 JRootReader& get(T& object)
101 {
102 return this->get(JRootReadableClass(object));
103 }
104
105
106 /**
107 * Read ROOT class according equation format.
108 *
109 * \param cls ROOT class
110 * \return this ROOT reader
111 */
113 {
114 using namespace std;
115 using namespace JPP;
116
117 if (cls.is_valid()) {
118
119 const JEquationFacet& facet = use_facet<JEquationFacet>(this->getloc());
120
121 for (JEquation equation; *this >> equation; ) {
122
123 const JRootReadableClass abc = cls.find(equation.getKey().c_str());
124
125 bool status = abc.is_valid();
126
127 if (status) {
128
129 JRedirectString redirect(*this, equation.getValue());
130
131 if (facet.isDivision (equation.getSeparator()))
132 this->get(abc);
133 else if (facet.isSeparator(equation.getSeparator()))
134 this->getObject(abc);
135 else
136 status = false;
137
138 status &= (!this->fail() || this->eof());
139 }
140
141 if (!status) {
142 THROW(JException, "Error parsing: " << equation);
143 }
144 }
145 }
146
147 return *this;
148 }
149
150
151 /**
152 * Read object.
153 *
154 * \param object object
155 * \return this ROOT reader
156 */
157 template<class T>
159 {
160 return this->getObject(object, JBool<JStreamAvailable<T>::has_istream>());
161 }
162
163
164 /**
165 * Read ROOT class.
166 *
167 * \param cls ROOT class
168 * \return this ROOT reader
169 */
171 {
172 if (cls.is_valid()) {
173
174 JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
175
176 if (i != this->getDictionary().end()) {
177
178 i->second->getObject(*this, cls.getAddress());
179
180 } else if (cls.getClass() != NULL) {
181
182 if (cls.getClass()->GetListOfBases() != NULL) {
183
184 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfBases()->MakeIterator());
185
186 for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL && (bool) (*this); ) {
187 this->getObject(cls.get(*p));
188 }
189 }
190
191 if (cls.getClass()->GetListOfDataMembers() != NULL) {
192
193 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfDataMembers()->MakeIterator());
194
195 for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL && (bool) (*this); ) {
196 this->getObject(cls.get(*p));
197 }
198 }
199 }
200 }
201
202 return *this;
203 }
204
205
206 /**
207 * Read ROOT class.
208 *
209 * \param cls ROOT class
210 * \return this ROOT reader
211 */
213 {
214 return getObject(const_cast<const JRootReadableClass&>(cls));
215 }
216
217 private:
218 /**
219 * Read object.
220 *
221 * \param object object
222 * \param option true
223 * \return this ROOT reader
224 */
225 template<class T>
226 JRootReader& getObject(T& object, const JBool<true>& option)
227 {
228 *this >> object;
229
230 return *this;
231 }
232
233
234 /**
235 * Read object.
236 *
237 * \param object object
238 * \param option false
239 * \return this ROOT reader
240 */
241 template<class T>
242 JRootReader& getObject(T& object, const JBool<false>& option)
243 {
244 return this->getObject(JRootReadableClass(object));
245 }
246
247
248 /**
249 * Read object.
250 *
251 * \param object object
252 * \param option false
253 * \return this ROOT reader
254 */
255 template<class JElement_t, class JAllocator_t>
257 {
258 int n = 0;
259
260 this->getObject(n);
261
262 for (JElement_t element; n != 0 && this->getObject(element); --n) {
263 object.push_back(element);
264 }
265
266 return *this;
267 }
268
269
271 };
272
273
274 /**
275 * Implementation for ASCII output of objects with ROOT dictionary.
276 *
277 * The method JRootWriter::put is compatible with equation formatting, i.e:
278 *
279 * <pre><key>[<division><key>]<separator><value>[<white space><value>]*<end of line></pre>
280 *
281 * In this, the key corresponds to the name of a data member
282 * which can be recursively parsed via a division character.\n
283 * \n
284 * The method JRootWriter::putObject relates to simple formatting, i.e:
285 *
286 * <pre><value>[<white space><value>]*</pre>
287 *
288 * The default format for output of <tt>std::vector<T></tt> is
289 *
290 * <pre><number of elements>[<white space><value>]*</pre>
291 */
293 public std::ostream,
294 private JStreamState
295 {
296 public:
297 /**
298 * Constructor.
299 *
300 * \param out output stream
301 * \param parameters equation parameters
302 * \param dictionary dictionary
303 */
304 JRootWriter(std::ostream& out,
305 const JEquationParameters& parameters,
307 std::ostream(out.rdbuf()),
308 JStreamState(out, static_cast<std::ostream&>(*this)),
310 {
311 imbue(std::locale(out.getloc(), new JLANG::JEquationFacet(parameters)));
312
313 flags (out.flags());
314 width (out.width());
315 precision(out.precision());
316 }
317
318
319 /**
320 * Get dictictionary.
321 *
322 * \return dictionary
323 */
325 {
326 return dictionary;
327 }
328
329
330 /**
331 * Write object according equation format.
332 *
333 * \param object object
334 * \return this ROOT writer
335 */
336 template<class T>
337 JRootWriter& put(const T& object)
338 {
339 return this->put(JRootWritableClass(object));
340 }
341
342
343 /**
344 * Write given key and value according equation format.
345 *
346 * \param key key
347 * \param value value
348 * \return this ROOT writer
349 */
350 template<class T>
351 JRootWriter& put(const std::string& key, const T& value)
352 {
353 using namespace std;
354 using namespace JPP;
355
356 ostringstream os;
357
358 {
359 JRedirectStream redirect(*this, os);
360
361 this->putObject(value);
362 }
363
364 return this->put(JEquation(key, os.str()));
365 }
366
367
368 /**
369 * Write ROOT class according equation format.
370 *
371 * \param cls ROOT class
372 * \return this ROOT writer
373 */
375 {
376 return this->put("", cls, false);
377 }
378
379
380 /**
381 * Write ROOT class according equation format.
382 *
383 * \param cls ROOT class
384 * \return this ROOT writer
385 */
387 {
388 return this->put(const_cast<const JRootWritableClass&>(cls));
389 }
390
391
392 /**
393 * Write ROOT class according equation format.
394 *
395 * \param prefix prefix
396 * \param cls ROOT class
397 * \param eol end-of-line
398 * \return object output
399 */
400 JRootWriter& put(const std::string& prefix, const JRootWritableClass& cls, bool eol)
401 {
402 using namespace std;
403 using namespace JPP;
404
405 if (cls.is_valid()) {
406
407 const JEquationFacet& facet = use_facet<JEquationFacet>(this->getloc());
408
409 JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
410
411 if (i != this->getDictionary().end()) {
412
413 i->second->put(*this, prefix, cls.getAddress());
414
415 } else if (eol) {
416
417 ostringstream os;
418
419 {
420 JRedirectStream redirect(*this, os);
421
422 this->putObject(cls);
423 }
424
425 this->put(JEquation(prefix, os.str()));
426
427 } else if (cls.getClass() != NULL) {
428
429 if (cls.getClass()->GetListOfBases() != NULL) {
430
431 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfBases()->MakeIterator());
432
433 for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
434 this->put(prefix, cls.get(*p), false);
435 }
436 }
437
438 if (cls.getClass()->GetListOfDataMembers() != NULL) {
439
440 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfDataMembers()->MakeIterator());
441
442 for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
443 if (!JRootClass::is_static(*p)) {
444 this->put(facet.getPrefix(prefix,p->GetName()), cls.get(*p), false);
445 }
446 }
447 }
448 }
449 }
450
451 return *this;
452 }
453
454
455 /**
456 * Write equation.
457 *
458 * \param equation equation
459 * \return this ROOT writer
460 */
461 virtual JRootWriter& put(const JEquation& equation)
462 {
463 *this << equation;
464
465 return *this;
466 }
467
468
469 /**
470 * Write object.
471 *
472 * \param object object
473 * \return this ROOT writer
474 */
475 template<class T>
476 JRootWriter& putObject(const T& object)
477 {
478 return this->putObject(object, JBool<JStreamAvailable<T>::has_ostream>());
479 }
480
481
482 /**
483 * Write ROOT class.
484 *
485 * \param cls ROOT class
486 * \return object output
487 */
489 {
490 using namespace std;
491
492 if (cls.is_valid()) {
493
494 JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
495
496 if (i != this->getDictionary().end()) {
497
498 i->second->putObject(*this, cls.getAddress());
499
500 } else if (cls.getClass() != NULL) {
501
502 if (cls.getClass()->GetListOfBases() != NULL) {
503
504 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfBases()->MakeIterator());
505
506 for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
507 this->putObject(cls.get(*p));
508 }
509 }
510
511 if (cls.getClass()->GetListOfDataMembers() != NULL) {
512
513 std::unique_ptr<TIterator> i(cls.getClass()->GetListOfDataMembers()->MakeIterator());
514
515 for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
516 if (!JRootClass::is_static(*p)) {
517 this->putObject(cls.get(*p));
518 }
519 }
520 }
521 }
522 }
523
524 return *this;
525 }
526
527 private:
528 /**
529 * Write object.
530 *
531 * \param object object
532 * \param option true
533 * \return this ROOT writer
534 */
535 template<class T>
536 JRootWriter& putObject(const T& object, const JBool<true>& option)
537 {
538 using namespace JPP;
539
540 *this << white_space;
541 *this << object;
542
543 return *this;
544 }
545
546
547 /**
548 * Write object.
549 *
550 * \param object object
551 * \param option false
552 * \return this ROOT writer
553 */
554 template<class T>
555 JRootWriter& putObject(const T& object, const JBool<false>& option)
556 {
557 return this->putObject(JRootWritableClass(object));
558 }
559
560
561 /**
562 * Write object.
563 *
564 * \param object object
565 * \param option false
566 * \return this ROOT writer
567 */
568 template<class JElement_t, class JAllocator_t>
570 {
571 this->putObject(object.size());
572
573 for (typename std::vector<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
574 this->putObject(*i);
575 }
576
577 return *this;
578 }
579
580
582 };
583
584
585 /**
586 * Auxiliary template class to define default implementation of the ROOT streamer.
587 *
588 * This class transfers the I/O functionality to the JRootReader or JRootWriter class.\n
589 * For a custom implementation of the I/O a given class, this class should be specialised.\n
590 * The class should also be added to the dictionary in use (method JRootDictionary::add).
591 */
592 template<class T>
594 /**
595 * Read object.
596 *
597 * \param reader ROOT reader
598 * \param object object
599 * \return ROOT reader
600 */
601 static JRootReader& getObject(JRootReader& reader, T& object)
602 {
603 return reader.getObject(object);
604 }
605
606
607 /**
608 * Write object.
609 *
610 * \param writer ROOT writer
611 * \param object object
612 * \return ROOT writer
613 */
614 static JRootWriter& putObject(JRootWriter& writer, const T& object)
615 {
616 return writer.putObject(object);
617 }
618
619
620 /**
621 * Write given key and value according equation format.
622 *
623 * \param writer ROOT writer
624 * \param key key
625 * \param value value
626 * \return ROOT writer
627 */
628 static JRootWriter& put(JRootWriter& writer, const std::string& key, const T& value)
629 {
630 return writer.put(key, value);
631 }
632 };
633
634
635 /**
636 * JObjectStreamer class.
637 *
638 * This class implements the JROOT::JAstractStreamer interface for the given template class.\n
639 * The I/O functionality is transferred first to the JRootStreamer class and
640 * subsequently -by default- to the JRootReader and JRootWriter class.\n
641 */
642 template<class T>
644 public JAbstractStreamer
645 {
646 public:
647 /**
648 * Stream input.
649 *
650 * \param in object reader
651 * \param address pointer to object
652 * \return object reader
653 */
654 virtual JRootReader& getObject(JRootReader& in, void* address) const
655 {
656 return JRootStreamer<T>::getObject(in, * ((T*) address));
657 }
658
659
660 /**
661 * Stream output.
662 *
663 * \param out object writer
664 * \param address pointer to object
665 * \return object writer
666 */
667 virtual JRootWriter& putObject(JRootWriter& out, const void* address) const
668 {
669 return JRootStreamer<T>::putObject(out, * ((const T*) address));
670 }
671
672
673 /**
674 * Stream output.
675 *
676 * \param out object writer
677 * \param prefix prefix
678 * \param address pointer to object
679 * \return object writer
680 */
681 virtual JRootWriter& put(JRootWriter& out, const std::string& prefix, const void* address) const
682 {
683 return JRootStreamer<T>::put(out, prefix, * ((const T*) address));
684 }
685 };
686}
687
688#endif
This file contains the basic interface for ASCII I/O of ROOT objects.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
const std::string getPrefix(const std::string &prefix, const std::string &name) const
Get combined prefix for output.
Simple data structure to support I/O of equations (see class JLANG::JEquation).
bool isSeparator(const char c) const
Test for separator character.
bool isDivision(const char c) const
Test for division character.
General purpose equation class.
Definition JEquation.hh:47
General exception.
Definition JException.hh:24
This class can be used to temporarily redirect one output (input) stream to another output (input) st...
This class can be used to temporarily redirect an input stream to an input string.
This class can be used to temporarily exchange the states between streams.
Forward declaration of writer object.
JObjectStreamer class.
virtual JRootReader & getObject(JRootReader &in, void *address) const
Stream input.
virtual JRootWriter & putObject(JRootWriter &out, const void *address) const
Stream output.
virtual JRootWriter & put(JRootWriter &out, const std::string &prefix, const void *address) const
Stream output.
Implementation for ASCII input of objects with ROOT dictionary.
const JRootDictionary_t & dictionary
JRootReader & getObject(JRootReadableClass &cls)
Read ROOT class.
JRootReader & getObject(const JRootReadableClass &cls)
Read ROOT class.
JRootReader & getObject(T &object, const JBool< false > &option)
Read object.
JRootReader & get(const JRootReadableClass &cls)
Read ROOT class according equation format.
JRootReader & getObject(T &object)
Read object.
JRootReader & getObject(std::vector< JElement_t, JAllocator_t > &object, const JBool< false > &option)
Read object.
JRootReader(std::istream &in, const JEquationParameters &parameters, const JRootDictionary_t &dictionary)
Constructor.
JRootReader & getObject(T &object, const JBool< true > &option)
Read object.
const JRootDictionary_t & getDictionary() const
Get dictionary.
JRootReader & get(T &object)
Read object according equation format.
Implementation for ASCII output of objects with ROOT dictionary.
JRootWriter & put(const std::string &prefix, const JRootWritableClass &cls, bool eol)
Write ROOT class according equation format.
JRootWriter & putObject(const T &object, const JBool< false > &option)
Write object.
const JRootDictionary_t & getDictionary() const
Get dictictionary.
JRootWriter(std::ostream &out, const JEquationParameters &parameters, const JRootDictionary_t &dictionary)
Constructor.
virtual JRootWriter & put(const JEquation &equation)
Write equation.
JRootWriter & put(const std::string &key, const T &value)
Write given key and value according equation format.
JRootWriter & putObject(const T &object)
Write object.
JRootWriter & put(JRootWritableClass &cls)
Write ROOT class according equation format.
JRootWriter & putObject(const std::vector< JElement_t, JAllocator_t > &object, const JBool< false > option)
Write object.
JRootWriter & put(const T &object)
Write object according equation format.
JRootWriter & putObject(const T &object, const JBool< true > &option)
Write object.
JRootWriter & putObject(const JRootWritableClass &cls)
Write ROOT class.
JRootWriter & put(const JRootWritableClass &cls)
Write ROOT class according equation format.
const JRootDictionary_t & dictionary
Test availability of stream operators.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
Auxiliary template class for type bool.
Definition JBool.hh:21
bool is_valid() const
Check validity of this addressable class.
pointer_type getAddress() const
Get address.
JRootAddressableClass get(const TDataMember &data_member) const
Get addressable class of given data member.
JRootAddressableClass find(const char *const name) const
Find addressable base class or data member with given name within current class.
const char * getTypename() const
Get type name.
static bool is_static(const TDataMember &data_member)
Check if data member is static.
TClass * getClass() const
Get class.
Type definition of ROOT based dictionary for ASCII I/O.
ROOT class for reading object.
Auxiliary template class to define default implementation of the ROOT streamer.
static JRootWriter & put(JRootWriter &writer, const std::string &key, const T &value)
Write given key and value according equation format.
static JRootReader & getObject(JRootReader &reader, T &object)
Read object.
static JRootWriter & putObject(JRootWriter &writer, const T &object)
Write object.
ROOT class for writing object.