Jpp  master_rocky-37-gf0c5bc59d
the software that should make you happy
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"
12 #include "JLang/JEquationFacet.hh"
14 #include "JLang/JBool.hh"
15 #include "JLang/JRedirectString.hh"
16 #include "JLang/JRedirectStream.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  */
29 namespace JROOT {}
30 namespace JPP { using namespace JROOT; }
31 
32 namespace JROOT {
33 
34  using JLANG::JEquation;
36  using JLANG::JBool;
37  using JLANG::JStreamState;
38  using JLANG::JException;
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  */
59  class JRootReader :
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>
158  JRootReader& getObject(T& object)
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  */
292  class JRootWriter :
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,
306  const JRootDictionary_t& dictionary) :
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>
593  struct JRootStreamer {
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.
Definition: JException.hh:712
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.
Definition: JStreamState.hh:23
Forward declaration of writer object.
JObjectStreamer class.
virtual JRootWriter & put(JRootWriter &out, const std::string &prefix, const void *address) const
Stream output.
virtual JRootWriter & putObject(JRootWriter &out, const void *address) const
Stream output.
virtual JRootReader & getObject(JRootReader &in, void *address) const
Stream input.
Implementation for ASCII input of objects with ROOT dictionary.
const JRootDictionary_t & dictionary
JRootReader & get(T &object)
Read object according equation format.
JRootReader & getObject(const JRootReadableClass &cls)
Read ROOT class.
JRootReader & getObject(T &object, const JBool< true > &option)
Read object.
JRootReader & getObject(T &object)
Read object.
JRootReader & getObject(T &object, const JBool< false > &option)
Read object.
JRootReader & getObject(std::vector< JElement_t, JAllocator_t > &object, const JBool< false > &option)
Read object.
const JRootDictionary_t & getDictionary() const
Get dictionary.
JRootReader(std::istream &in, const JEquationParameters &parameters, const JRootDictionary_t &dictionary)
Constructor.
JRootReader & getObject(JRootReadableClass &cls)
Read ROOT class.
JRootReader & get(const JRootReadableClass &cls)
Read ROOT class according equation format.
Implementation for ASCII output of objects with ROOT dictionary.
JRootWriter & putObject(const T &object, const JBool< false > &option)
Write object.
JRootWriter & put(JRootWritableClass &cls)
Write ROOT class according equation format.
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 & 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 JRootWritableClass &cls)
Write ROOT class.
JRootWriter & put(const JRootWritableClass &cls)
Write ROOT class according equation format.
JRootWriter & put(const std::string &prefix, const JRootWritableClass &cls, bool eol)
Write ROOT class according equation format.
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 & putObject(const T &object, const JBool< true > &option)
Write object.
const JRootDictionary_t & dictionary
Test availability of stream operators.
std::ostream & white_space(std::ostream &out)
Print white space.
bool fail(std::istream &in)
Check for stream state.
Definition: JParser.hh:98
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Auxiliary classes and methods for ROOT I/O.
bool putObject(TDirectory &dir, const TObject &object)
Write object to ROOT directory.
const int n
Definition: JPolint.hh:786
Definition: JSTDTypes.hh:14
Auxiliary template class for type bool.
Definition: JBool.hh:21
bool is_valid() const
Check validity of this addressable class.
Definition: JRootClass.hh:471
pointer_type getAddress() const
Get address.
Definition: JRootClass.hh:460
JRootAddressableClass get(const TDataMember &data_member) const
Get addressable class of given data member.
Definition: JRootClass.hh:495
JRootAddressableClass find(const char *const name) const
Find addressable base class or data member with given name within current class.
Definition: JRootClass.hh:483
static bool is_static(const TDataMember &data_member)
Check if data member is static.
Definition: JRootClass.hh:128
TClass * getClass() const
Get class.
Definition: JRootClass.hh:194
const char * getTypename() const
Get type name.
Definition: JRootClass.hh:205
Type definition of ROOT based dictionary for ASCII I/O.
ROOT class for reading object.
Definition: JRootClass.hh:544
Auxiliary template class to define default implementation of the ROOT streamer.
static JRootWriter & putObject(JRootWriter &writer, const T &object)
Write object.
static JRootReader & getObject(JRootReader &reader, T &object)
Read object.
static JRootWriter & put(JRootWriter &writer, const std::string &key, const T &value)
Write given key and value according equation format.
ROOT class for writing object.
Definition: JRootClass.hh:604