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