Jpp
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
JRootStreamer.hh
Go to the documentation of this file.
1 #ifndef __JROOTSTREAMER__
2 #define __JROOTSTREAMER__
3 
4 #include <string>
5 #include <istream>
6 #include <ostream>
7 #include <iostream>
8 #include <map>
9 
10 #include "JLang/JEquation.hh"
12 #include "JLang/JEquationFacet.hh"
14 #include "JLang/JBool.hh"
15 #include "JLang/JSharedPointer.hh"
16 #include "JLang/JRedirectString.hh"
17 #include "JLang/JStreamState.hh"
19 #include "JROOT/JRootClass.hh"
20 
21 
22 /**
23  * \file
24  *
25  * ASCII I/O of objects with ROOT dictionary.
26  * \author mdejong
27  */
28 namespace JROOT {}
29 namespace JPP { using namespace JROOT; }
30 
31 namespace JROOT {
32 
34  using JLANG::JBool;
36  using JLANG::JStreamState;
37  using JLANG::JException;
38 
39 
40  /**
41  * Type definition of ROOT dictionary.
42  */
44 
45 
46  /**
47  * Implementation for ASCII input of objects with ROOT dictionary.
48  *
49  * The method JRootReader::get is compatible with equation formatting, i.e:
50  *
51  * <pre><key><separator><value>[<white space><value>]*<end of line></pre>
52  *
53  * and method JRootReader::getObject with simple formatting, i.e:
54  *
55  * <pre><value>[<white space><value>]*</pre>
56  *
57  * The default format for input of <tt>std::vector<T></tt> is
58  *
59  * <pre><number of elements>[<white space><value>]*</pre>
60  */
61  class JRootReader :
62  public std::istream,
63  private JStreamState
64  {
65  private:
66  /**
67  * Default helper class for formatting.
68  */
69  template<class T>
70  struct JDefaultHelper {
71  /**
72  * Read object.
73  *
74  * This method transfers the reading of the given object to the given JRootReader.
75  *
76  * \param reader ROOT reader
77  * \param object object
78  * \return ROOT reader
79  */
80  static JRootReader& getObject(JRootReader& reader, T& object)
81  {
82  return reader.getObject(object);
83  }
84  };
85 
86  public:
87  /**
88  * Helper class for user formatting.
89  *
90  * This class should be specialised for implementing a different format.
91  */
92  template<class T>
93  struct JHelper :
94  public JDefaultHelper<T>
95  {};
96 
97 
98  /**
99  * Constructor.
100  *
101  * \param in input stream
102  * \param parameters equation parameters
103  * \param dictionary dictionary
104  */
105  JRootReader(std::istream& in,
106  const JEquationParameters& parameters,
107  const JRootDictionary_t& dictionary) :
108  std::istream(in.rdbuf()),
109  JStreamState(in, static_cast<std::istream&>(*this)),
110  dictionary(dictionary)
111  {
112  imbue(std::locale(in.getloc(), new JLANG::JEquationFacet(parameters)));
113  }
114 
115 
116  /**
117  * Get dictionary.
118  *
119  * \return dictionary
120  */
122  {
123  return dictionary;
124  }
125 
126 
127  /**
128  * Read object.
129  *
130  * This method transfers the reading of the given object to the template JHelper class
131  * so that the default format can be changed through specialisation of this class.
132  *
133  * \param reader ROOT reader
134  * \param object object
135  * \return ROOT reader
136  */
137  template<class T>
138  static JRootReader& getObject(JRootReader& reader, T& object)
139  {
140  return JRootReader::JHelper<T>::getObject(reader, object);
141  }
142 
143 
144  /**
145  * Read object according equation format.
146  *
147  * \param object object
148  * \return this ROOT reader
149  */
150  template<class T>
151  JRootReader& get(T& object)
152  {
153  return this->get(JRootClassReader(object));
154  }
155 
156 
157  /**
158  * Read object.
159  *
160  * \param object object
161  * \return this ROOT reader
162  */
163  template<class T>
164  JRootReader& getObject(T& object)
165  {
166  return this->getObject(object, JBool<JRedirectAvailable<T>::has_istream>());
167  }
168 
169 
170  /**
171  * Read ROOT class according equation format.
172  *
173  * \param cls ROOT class
174  * \return this ROOT reader
175  */
176  JRootReader& get(const JRootClassReader& cls)
177  {
178  using namespace std;
179  using namespace JLANG;
180 
181  if (cls.is_valid()) {
182 
183  const JEquationFacet& facet = use_facet<JEquationFacet>(this->getloc());
184 
185  for (JEquation equation; *this >> equation; ) {
186 
187  const JRootClassReader abc = cls.find(equation.getKey().c_str());
188 
189  bool okay = abc.is_valid();
190 
191  if (okay) {
192 
193  JRedirectString redirect(*this, equation.getValue());
194 
195  if (facet.isDivision (equation.getSeparator()))
196  this->get(abc);
197  else if (facet.isSeparator(equation.getSeparator()))
198  this->getObject(abc);
199  else
200  okay = false;
201 
202  okay &= (!this->fail() || this->eof());
203  }
204 
205  if (!okay) {
206  throw JException("Error parsing: " + equation.toString());
207  }
208  }
209  }
210 
211  return *this;
212  }
213 
214 
215  /**
216  * Read ROOT class.
217  *
218  * \param cls ROOT class
219  * \return this ROOT reader
220  */
222  {
223  if (cls.is_valid()) {
224 
225  JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
226 
227  if (i != this->getDictionary().end()) {
228 
229  i->second->getObject(*this, cls.getAddress());
230 
231  } else if (cls.getClass() != NULL) {
232 
233  if (cls.getClass()->GetListOfBases() != NULL) {
234 
235  TIterator* i = cls.getClass()->GetListOfBases()->MakeIterator();
236 
237  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL && (bool) (*this); ) {
238  this->getObject(cls.get(*p));
239  }
240  }
241 
242  if (cls.getClass()->GetListOfDataMembers() != NULL) {
243 
244  TIterator* i = cls.getClass()->GetListOfDataMembers()->MakeIterator();
245 
246  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL && (bool) (*this); ) {
247  this->getObject(cls.get(*p));
248  }
249  }
250  }
251  }
252 
253  return *this;
254  }
255 
256 
257  protected:
258  /**
259  * Read object.
260  *
261  * \param object object
262  * \param option true
263  * \return this ROOT reader
264  */
265  template<class T>
266  JRootReader& getObject(T& object, const JBool<true>& option)
267  {
268  *this >> object;
269 
270  return *this;
271  }
272 
273 
274  /**
275  * Read object.
276  *
277  * \param object object
278  * \param option false
279  * \return this ROOT reader
280  */
281  template<class T>
282  JRootReader& getObject(T& object, const JBool<false>& option)
283  {
284  return this->getObject(JRootClassReader(object));
285  }
286 
287 
288  /**
289  * Read object.
290  *
291  * \param object object
292  * \param option false
293  * \return this ROOT reader
294  */
295  template<class JElement_t, class JAllocator_t>
297  {
298  int n = 0;
299 
300  this->getObject(n);
301 
302  for (JElement_t element; n != 0 && this->getObject(element); --n) {
303  object.push_back(element);
304  }
305 
306  return *this;
307  }
308 
309 
311  };
312 
313 
314  /**
315  * Implementation for ASCII output of objects with ROOT dictionary.
316  *
317  * The method JRootReader::put is compatible with equation formatting, i.e:
318  *
319  * <pre><key><separator><value>[<white space><value>]*<end of line></pre>
320  *
321  * and method JRootReader::putObject with simple formatting, i.e:
322  *
323  * <pre><value>[<white space><value>]*</pre>
324  *
325  * The default format for input of <tt>std::vector<T></tt> is
326  *
327  * <pre><number of elements>[<white space><value>]*</pre>
328  */
329  class JRootWriter :
330  public std::ostream,
331  private JStreamState
332  {
333  private:
334  /**
335  * Default helper class for formatting.
336  */
337  template<class T>
338  struct JDefaultHelper {
339  /**
340  * Write object.
341  *
342  * This method transfers the writing of the given object to the given JRootWriter.
343  *
344  * \param writer ROOT writer
345  * \param object object
346  * \return ROOT writer
347  */
348  static JRootWriter& putObject(JRootWriter& writer, const T& object)
349  {
350  return writer.putObject(object);
351  }
352 
353 
354  /**
355  * Write given key and value according equation format.
356  *
357  * \param writer ROOT writer
358  * \param key key
359  * \param value value
360  * \return ROOT writer
361  */
362  static JRootWriter& put(JRootWriter& writer, const std::string& key, const T& value)
363  {
364  return writer.put(key, value);
365  }
366  };
367 
368  public:
369  /**
370  * Helper class for user formatting.
371  *
372  * This class should be specialised for implementing a different format.
373  */
374  template<class T>
375  struct JHelper :
376  public JDefaultHelper<T>
377  {};
378 
379 
380  /**
381  * Constructor.
382  *
383  * \param out output stream
384  * \param parameters equation parameters
385  * \param dictionary dictionary
386  */
387  JRootWriter(std::ostream& out,
388  const JEquationParameters& parameters,
389  const JRootDictionary_t& dictionary) :
390  std::ostream(out.rdbuf()),
391  JStreamState(out, static_cast<std::ostream&>(*this)),
392  dictionary(dictionary)
393  {
394  imbue(std::locale(out.getloc(), new JLANG::JEquationFacet(parameters)));
395  }
396 
397 
398  /**
399  * Get dictictionary.
400  *
401  * \return dictionary
402  */
404  {
405  return dictionary;
406  }
407 
408 
409  /**
410  * Write object.
411  *
412  * This method transfers the writing of the given object to the template JHelper class
413  * so that the default format can be changed through specialisation of this class.
414  *
415  * \param writer ROOT writer
416  * \param object object
417  * \return ROOT writer
418  */
419  template<class T>
420  static JRootWriter& putObject(JRootWriter& writer, const T& object)
421  {
422  return JRootWriter::JHelper<T>::putObject(writer, object);
423  }
424 
425 
426  /**
427  * Write given key and value according equation format.
428  *
429  * \param writer ROOT writer
430  * \param key key
431  * \param value value
432  * \return ROOT writer
433  */
434  template<class T>
435  static JRootWriter& put(JRootWriter& writer, const std::string& key, const T& value)
436  {
437  return JRootWriter::JHelper<T>::put(writer, key, value);
438  }
439 
440 
441  /**
442  * Write object according equation format.
443  *
444  * \param object object
445  * \return this ROOT writer
446  */
447  template<class T>
448  JRootWriter& put(const T& object)
449  {
450  return this->put("", JRootClassWriter(object), false);
451  }
452 
453 
454  /**
455  * Write object.
456  *
457  * \param object object
458  * \return this ROOT writer
459  */
460  template<class T>
461  JRootWriter& putObject(const T& object)
462  {
463  return this->putObject(object, JBool<JRedirectAvailable<T>::has_ostream>());
464  }
465 
466 
467  /**
468  * ROOT class output.
469  *
470  * \param prefix prefix
471  * \param cls ROOT class
472  * \param eol end-of-line
473  * \return object output
474  */
475  JRootWriter& put(const std::string& prefix, const JRootClassWriter& cls, bool eol)
476  {
477  using namespace std;
478  using namespace JLANG;
479 
480  if (cls.is_valid()) {
481 
482  const JEquationFacet& facet = use_facet<JEquationFacet>(this->getloc());
483 
484  JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
485 
486  if (i != this->getDictionary().end()) {
487 
488  i->second->put(*this, prefix, cls.getAddress());
489 
490  } else if (eol) {
491 
492  *this << prefix;
493  *this << separator;
494 
495  this->putObject(cls);
496 
497  *this << end_of_line;
498 
499  } else if (cls.getClass() != NULL) {
500 
501  if (cls.getClass()->GetListOfBases() != NULL) {
502 
503  TIterator* i = cls.getClass()->GetListOfBases()->MakeIterator();
504 
505  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
506  this->put(prefix, cls.get(*p), false);
507  }
508  }
509 
510  if (cls.getClass()->GetListOfDataMembers() != NULL) {
511 
512  TIterator* i = cls.getClass()->GetListOfDataMembers()->MakeIterator();
513 
514  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
515  if (!JRootClass::is_static(*p)) {
516  this->put(facet.getPrefix(prefix,p->GetName()), cls.get(*p), false);
517  }
518  }
519  }
520  }
521  }
522 
523  return *this;
524  }
525 
526 
527  /**
528  * ROOT class output.
529  *
530  * \param cls ROOT class
531  * \return object output
532  */
534  {
535  using namespace std;
536 
537  if (cls.is_valid()) {
538 
539  JRootDictionary_t::const_iterator i = this->getDictionary().find(cls.getTypename());
540 
541  if (i != this->getDictionary().end()) {
542 
543  i->second->putObject(*this, cls.getAddress());
544 
545  } else if (cls.getClass() != NULL) {
546 
547  if (cls.getClass()->GetListOfBases() != NULL) {
548 
549  TIterator* i = cls.getClass()->GetListOfBases()->MakeIterator();
550 
551  for (const TBaseClass* p; (p = (const TBaseClass*) i->Next()) != NULL; ) {
552  this->putObject(cls.get(*p));
553  }
554  }
555 
556  if (cls.getClass()->GetListOfDataMembers() != NULL) {
557 
558  TIterator* i = cls.getClass()->GetListOfDataMembers()->MakeIterator();
559 
560  for (const TDataMember* p; (p = (const TDataMember*) i->Next()) != NULL; ) {
561  if (!JRootClass::is_static(*p)) {
562  this->putObject(cls.get(*p));
563  }
564  }
565  }
566  }
567  }
568 
569  return *this;
570  }
571 
572 
573  /**
574  * Write given key and value according equation format.
575  *
576  * \param key key
577  * \param value value
578  * \return this ROOT writer
579  */
580  template<class T>
581  JRootWriter& put(const std::string& key, const T& value)
582  {
583  return this->put(key, value, JLANG::JBool<JRedirectAvailable<T>::has_ostream>());
584  }
585 
586 
587  /**
588  * Write given key and value according equation format.
589  *
590  * \param key key
591  * \param value value
592  * \param option true
593  * \return this ROOT writer
594  */
595  template<class T>
596  JRootWriter& put(const std::string& key, const T& value, const JBool<true> option)
597  {
598  using namespace JLANG;
599 
600  *this << key;
601  *this << separator;
602  *this << white_space;
603  *this << value;
604  *this << end_of_line;
605 
606  return *this;
607  }
608 
609 
610  /**
611  * Write given key and value according equation format.
612  *
613  * \param key key
614  * \param value value
615  * \param option false
616  * \return this ROOT writer
617  */
618  template<class T>
619  JRootWriter& put(const std::string& key, const T& value, const JBool<false> option)
620  {
621  using namespace JLANG;
622 
623  *this << key;
624  *this << separator;
625 
626  this->putObject(value);
627 
628  *this << end_of_line;
629 
630  return *this;
631  }
632 
633 
634  /**
635  * Write given key and value according equation format.
636  *
637  * \param key key
638  * \param value value
639  * \param option false
640  * \return this ROOT writer
641  */
642  template<class JElement_t, class JAllocator_t>
643  JRootWriter& put(const std::string& key, const std::vector<JElement_t, JAllocator_t>& value, const JBool<false> option)
644  {
645  for (typename std::vector<JElement_t, JAllocator_t>::const_iterator i = value.begin(); i != value.end(); ++i) {
646  this->put(key, *i);
647  }
648 
649  return *this;
650  }
651 
652 
653  /**
654  * Write object.
655  *
656  * \param object object
657  * \param option true
658  * \return this ROOT writer
659  */
660  template<class T>
661  JRootWriter& putObject(const T& object, const JBool<true>& option)
662  {
663  using namespace JLANG;
664 
665  *this << white_space;
666  *this << object;
667 
668  return *this;
669  }
670 
671 
672  /**
673  * Write object.
674  *
675  * \param object object
676  * \param option false
677  * \return this ROOT writer
678  */
679  template<class T>
680  JRootWriter& putObject(const T& object, const JBool<false>& option)
681  {
682  return this->putObject(JRootClassWriter(object));
683  }
684 
685 
686  /**
687  * Write object.
688  *
689  * \param object object
690  * \param option false
691  * \return this ROOT writer
692  */
693  template<class JElement_t, class JAllocator_t>
695  {
696  this->putObject(object.size());
697 
698  for (typename std::vector<JElement_t, JAllocator_t>::const_iterator i = object.begin(); i != object.end(); ++i) {
699  this->putObject(*i);
700  }
701 
702  return *this;
703  }
704 
705 
707  };
708 
709 
710  /**
711  * JObjectStreamer class.
712  *
713  * This class implements the JAstractStreamer interface for the given template class.
714  * The I/O functionality is transferred to the JRootReader and JRootWriter class, respectively.
715  */
716  template<class T>
718  public JAbstractStreamer
719  {
720  public:
721  /**
722  * Stream input.
723  *
724  * \param in object reader
725  * \param address pointer to object
726  * \return object reader
727  */
728  virtual JRootReader& getObject(JRootReader& in, void* address) const
729  {
730  return JRootReader::getObject(in, * ((T*) address));
731  }
732 
733 
734  /**
735  * Stream output.
736  *
737  * \param out object writer
738  * \param address pointer to object
739  * \return object writer
740  */
741  virtual JRootWriter& putObject(JRootWriter& out, const void* address) const
742  {
743  return JRootWriter::putObject(out, * ((const T*) address));
744  }
745 
746 
747  /**
748  * Stream output.
749  *
750  * \param out object writer
751  * \param prefix prefix
752  * \param address pointer to object
753  * \return object writer
754  */
755  virtual JRootWriter& put(JRootWriter& out, const std::string& prefix, const void* address) const
756  {
757  return JRootWriter::put(out, prefix, * ((const T*) address));
758  }
759  };
760 
761 
762  /**
763  * Write content to output.
764  *
765  * \param out output stream
766  * \param object object
767  * \param key '.' separated list of data member names
768  * \param dicttionary dictionary
769  */
770  template<class T>
771  inline void print(std::ostream& out,
772  const T& object,
773  const std::string& key,
775  {
776  using namespace std;
777  using namespace JPP;
778 
779  const char separator = '.';
780 
781  JRootWriter writer(out, JEquationParameters("=", "\n", ".", ""), dictionary);
782 
783  JRootClassWriter cls(object);
784 
785  if (key != "") {
786  for (string::size_type i = 0, j = 0; j != string::npos && cls.is_valid(); i = j + 1) {
787  j = key.substr(i).find(separator);
788  cls = cls.find(key.substr(i, j - i).c_str());
789  }
790  }
791 
792  if (cls.is_valid()) {
793  if (writer.getDictionary().find(cls.getTypename()) != writer.getDictionary().end())
794  writer.putObject(cls);
795  else
796  writer.put(cls);
797  }
798  }
799 }
800 
801 #endif
const JRootDictionary_t & getDictionary() const
Get dictictionary.
JRootWriter & put(const std::string &key, const T &value)
Write given key and value according equation format.
General exception.
Definition: JException.hh:40
JRootWriter & putObject(const T &object, const JBool< true > &option)
Write object.
JRootReader & getObject(T &object, const JBool< false > &option)
Read object.
Facet class to specify parsing of equations in currect locale (see class JLANG::JEquation).
Implementation for ASCII output of objects with ROOT dictionary.
Helper class for user formatting.
JObjectStreamer class.
const char * getTypename() const
Get type name.
Definition: JRootClass.hh:178
const std::string getPrefix(const std::string &prefix, const std::string &name) const
Get combined prefix for output.
Default helper class for formatting.
pointer_type getAddress() const
Get address.
Definition: JRootClass.hh:411
This class can be used to temporarily exchange the states between streams.
Definition: JStreamState.hh:23
std::ostream & white_space(std::ostream &out)
Print white space.
static JRootWriter & putObject(JRootWriter &writer, const T &object)
Write object.
Simple data structure to support I/O of equations (see class JLANG::JEquation).
virtual JRootReader & getObject(JRootReader &in, void *address) const
Stream input.
JRootWriter & putObject(const JRootClassWriter &cls)
ROOT class output.
Forward declaration of writer object.
virtual JRootWriter & putObject(JRootWriter &out, const void *address) const
Stream output.
static JRootReader & getObject(JRootReader &reader, T &object)
Read object.
JRootWriter & putObject(const T &object)
Write object.
bool is_valid() const
Check validity of this addressable class.
Definition: JRootClass.hh:422
JRootWriter & put(const std::string &key, const T &value, const JBool< false > option)
Write given key and value according equation format.
General purpose equation class.
Definition: JEquation.hh:47
ROOT class for writing object.
Definition: JRootClass.hh:568
void print(const TH1 &h1, std::ostream &out)
Print histogram parameters.
virtual JRootWriter & put(JRootWriter &out, const std::string &prefix, const void *address) const
Stream output.
static JRootWriter & put(JRootWriter &writer, const std::string &key, const T &value)
Write given key and value according equation format.
Implementation for ASCII input of objects with ROOT dictionary.
Auxiliary template class for type bool.
Definition: JBool.hh:20
The template JSharedPointer class can be used to share a pointer to an object.
const JRootDictionary_t & dictionary
std::ostream & separator(std::ostream &out)
Print separator.
ROOT class for reading object.
Definition: JRootClass.hh:478
static JRootWriter & put(JRootWriter &writer, const std::string &key, const T &value)
Write given key and value according equation format.
JRootWriter(std::ostream &out, const JEquationParameters &parameters, const JRootDictionary_t &dictionary)
Constructor.
JRootReader(std::istream &in, const JEquationParameters &parameters, const JRootDictionary_t &dictionary)
Constructor.
JRootWriter & put(const std::string &key, const std::vector< JElement_t, JAllocator_t > &value, const JBool< false > option)
Write given key and value according equation format.
JRootReader & getObject(T &object)
Read object.
Default helper class for formatting.
JRootReader & getObject(std::vector< JElement_t, JAllocator_t > &object, const JBool< false > &option)
Read object.
JRootAddressableClass get(const TDataMember &data_member) const
Get addressable class of given data member.
Definition: JRootClass.hh:444
bool fail(std::istream &in)
Check for stream state.
Definition: JParser.hh:93
This file contains the basic interface for ASCII I/O of ROOT objects.
JRootWriter & putObject(const T &object, const JBool< false > &option)
Write object.
JRootWriter & put(const std::string &prefix, const JRootClassWriter &cls, bool eol)
ROOT class output.
TClass * getClass() const
Get class.
Definition: JRootClass.hh:167
static JRootReader & getObject(JRootReader &reader, T &object)
Read object.
bool isSeparator(const char c) const
Test for separator character.
static const JLANG::JEndOfLine end_of_line
Print end of line.
bool isDivision(const char c) const
Test for division character.
static JRootWriter & putObject(JRootWriter &writer, const T &object)
Write object.
JRootReader & getObject(T &object, const JBool< true > &option)
Read object.
std::map< std::string, JSharedPointer< JAbstractStreamer > > JRootDictionary_t
Type definition of ROOT dictionary.
const JRootDictionary_t & dictionary
Helper class for user formatting.
JRootWriter & put(const T &object)
Write object according equation format.
JRootReader & getObject(const JRootClassReader &cls)
Read ROOT class.
JRootAddressableClass find(const char *name) const
Find addressable base class or data member with given name within current class.
Definition: JRootClass.hh:433
JRootWriter & put(const std::string &key, const T &value, const JBool< true > option)
Write given key and value according equation format.
This class can be used to temporarily redirect an input stream to an input string.
const JRootDictionary_t & getDictionary() const
Get dictionary.
Test availability of redirect operators.
static bool is_static(const TDataMember &data_member)
Check if data member is static.
Definition: JRootClass.hh:122
bool putObject(TDirectory *dir, const T &object)
Write object to ROOT directory.
JRootWriter & putObject(const std::vector< JElement_t, JAllocator_t > &object, const JBool< false > option)
Write object.