Bayeux  3.4.1
Core Foundation library for SuperNEMO
reader-inl.h
Go to the documentation of this file.
1 //
4 // Copyright (c) 2013 by Ben Morgan <bmorgan.warwick@gmail.com>
5 // Copyright (c) 2013 by The University of Warwick
6 //
7 // This file is part of brio.
8 //
9 // brio is free software: you can redistribute it and/or modify
10 // it under the terms of the GNU General Public License as published by
11 // the Free Software Foundation, either version 3 of the License, or
12 // (at your option) any later version.
13 //
14 // brio is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 // GNU General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with brio. If not, see <http://www.gnu.org/licenses/>.
21 
22 #ifndef BRIO_READER_INL_H
23 #define BRIO_READER_INL_H
24 
25 // Third Party:
26 // - ROOT:
27 #ifdef __clang__
28 #pragma clang diagnostic push
29 #pragma clang diagnostic ignored "-Wc++11-long-long"
30 #endif
31 #include <TTree.h>
32 #ifdef __clang__
33 #pragma clang diagnostic pop
34 #endif
35 
36 namespace brio {
37 
38  template<typename T>
39  int reader::load_next(T & data_, const std::string & label_)
40  {
41  int64_t entry = this->get_current_entry(label_);
42  return this->load<T>(data_, label_, entry + 1);
43  }
44 
45  template<typename T>
46  int reader::load_previous(T & data_, const std::string & label_)
47  {
48  int64_t entry = this->get_current_entry(label_);
49  return this->load<T>(data_, label_, entry - 1);
50  }
51 
52  template<typename T>
53  int reader::load(T& data_, int64_t nentry_)
54  {
55  return this->load<T>(data_, "", nentry_);
56  }
57 
58  template<typename T>
59  int reader::load(T & data_, const std::string & label_, int64_t nentry_)
60  {
61  DT_THROW_IF(!this->is_opened(),
62  std::logic_error,
63  "Operation prohibited; file is not opened !");
64 
65  store_info *ptr_si = this->_get_store_info(label_);
66  if (!ptr_si) {
67  DT_THROW_IF(!label_.empty (),
68  std::logic_error,
69  "No source store with label '" << label_ << "' !");
70  // if we do not allow automatic store, this is a critical error:
71  DT_THROW_IF(!_allow_automatic_store_,
72  std::logic_error,
73  "No source store is selected nor default store is available !");
74  ptr_si = _automatic_store_;
75  }
76  return this->_at_load<T>(data_, ptr_si, nentry_);
77  }
78 
79  template<class T>
80  int reader::_at_load(T & data_, store_info * ptr_si_, int64_t nentry_)
81  {
82  DT_LOG_TRACE(this->get_logging_priority(),"Entering...");
83  store_info & si = *ptr_si_;
84 
85  if (_check_serial_tag_) {
86  // We check if the serialization tag from the store matches the
87  // data's one:
89  // 2013-02-19 FM : change the way we check the serial tag :
90  //if (data_.get_serial_tag () != si.get_serialization_tag ())
91  DT_THROW_IF(!datatools::check_serial_tag<T>(si.get_serialization_tag ()),
92  std::logic_error,
93  "Data serialization tag '" << data_.get_serial_tag()
94  << "' does not match source store's serialization tag '" << si.get_serialization_tag () << "' !");
95  }
96  }
97 
99  std::logic_error,
100  "Source store '" << si.label << "' has no entry !");
101  int64_t nentry = nentry_;
102  if (nentry >= 0) {
103  // check overflow:
104  DT_THROW_IF(nentry_ >= si.number_of_entries,
105  std::logic_error,
106  "Source store '" << si.label << "' has "
107  << "no serialized entry at index '" << nentry_ << "' !");
108  } else {
109  // if nentry_ < 0: use entry index relative to the current entry
110  // position
111  if (si.current_entry < 0) {// at rewind position
112  // start with first entry:
113  nentry = 0;
114  } else {
115  // try next entry:
116  nentry = si.current_entry + 1;
117  }
118  }
119 
120  // read this tree entry in the ROOT I/O system:
121  si.record.reset();
122  int ret = si.tree->GetEntry(nentry, 1); // -> 1 for all branches
123  if (!ret) {
124  DT_THROW_IF(true,
125  std::logic_error,
126  "No entry '"
127  << nentry << "' at entry # " << nentry
128  << " in source store labelled '" << si.label.c_str()
129  << "' from file '" << _filename << "' !");
130  } else if (ret == -1) {
131  DT_THROW_IF(true,
132  std::logic_error,
133  "An I/O error occurs from entry '"
134  << nentry
135  << "' in source store labelled '" << si.label.c_str()
136  << "' from file '" << _filename << "' !");
137  } else {
138  si.current_entry = nentry;
139  }
140 
141  if (_check_serial_tag_) {
142  /* We may be confused with stores without dedicated serialization tag.
143  * Here we test if data and the entry's serial tags match:
144  */
146  // check serial tag associated to the buffered binary archive:
147  std::string serial_tag = si.record.fSerialTag.Data();
148  // 2013-02-19 FM : change the way we check
149  // if (data_.get_serial_tag () != serial_tag)
150  DT_THROW_IF(!datatools::check_serial_tag<T>(serial_tag),
151  std::logic_error,
152  "Entry '" << nentry
153  << "' with serial tag '" << serial_tag
154  << "' in (mixed) source store labelled '" << si.label.c_str()
155 
156  << "' from file '" << _filename
157  << "' does not match the requested '"
158  << data_.get_serial_tag() << "' data type !");
159  }
160  }
161 
162  // Deserialize from the archive:
163  boost::iostreams::stream<boost::iostreams::array_source>
164  input_stream(si.record.fDataBuffer.fArray,si.record.fDataBuffer.fN);
165  // 2011-06-16 FM: restored
166  if (this->is_format_pba()) {
167  datatools::portable_iarchive ia(input_stream);
168  ia >> data_;
169  }
170  if (this->is_format_text()) {
171  input_stream.imbue(*_locale);
172  boost::archive::text_iarchive ia(input_stream);
173  ia >> data_;
174  }
175 
176  _current_store = &si;
177  DT_LOG_TRACE(this->get_logging_priority(),"Exiting.");
178  return 0;
179  }
180 
181 } // namespace brio
182 
183 #endif // BRIO_READER_INL_H
184 
185 // Local Variables: --
186 // mode: c++ --
187 // c-file-style: "gnu" --
188 // tab-width: 2 --
189 // End: --
store_info * _get_store_info(const std::string &label_="")
const std::string & get_serialization_tag() const
A class that contains internal dynamic informations for a given store.
Definition: utils.h:33
TTree * tree
the embedded ROOT tree
Definition: utils.h:78
TArrayCMod fDataBuffer
The buffer of bytes that contains the Boost archive associated to the serialized data.
Definition: brio_record.h:50
int load(T &data_, int64_t nentry_=-1)
Load template method for arbitrary entry.
Definition: reader-inl.h:53
datatools::logger::priority get_logging_priority() const
TString fSerialTag
The serialization tag of the data class.
Definition: brio_record.h:48
void reset()
Reset the internal data.
int64_t current_entry
the current entry number in the store
Definition: utils.h:83
virtual bool is_opened() const
store_info * _current_store
Handle to the current active store (if any)
Definition: base_io.h:156
std::string label
the label (name) of the store
Definition: utils.h:75
int load_next(T &data_, const std::string &label_="")
Load template method for next entry.
Definition: reader-inl.h:39
bool is_format_pba() const
int64_t number_of_entries
the number of entries in the store
Definition: utils.h:82
brio_record record
the current brio record to be (de)serialized
Definition: utils.h:79
bool has_dedicated_serialization_tag() const
int _at_load(T &data_, store_info *ptr_si_, int64_t nentry_)
Definition: reader-inl.h:80
#define DT_THROW_IF(Condition, ExceptionType, Message)
Definition: exception.h:76
int load_previous(T &data_, const std::string &label_="")
Load template method for previous entry.
Definition: reader-inl.h:46
std::string _filename
Name of the current I/O file (extensions are .brio or .trio)
Definition: base_io.h:153
#define DT_LOG_TRACE(Priority, Message)
Log Message if Priority is greater or equal to PRIO_TRACE.
Definition: logger_macros.h:227
Char_t * fArray
Array of bytes.
Definition: TArrayCMod.h:31
std::locale * _locale
I/O locale (for portable streams)
Definition: base_io.h:159
int64_t get_current_entry(const std::string &label_="") const
bool is_format_text() const
Top-level namespace of the Bayeux/brio module library.
Definition: base_io.h:37
const std::string & serial_tag()