Bayeux  3.4.1
Core Foundation library for SuperNEMO
writer-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_WRITER_INL_H
23 #define BRIO_WRITER_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 // ROOT can shadow CLHEP and vice versa, appears not to be serious
31 #pragma clang diagnostic ignored "-Wshadow"
32 #endif
33 #ifdef __GNUC__
34 #pragma GCC diagnostic push
35 // ROOT can shadow CLHEP and vice versa, appears not to be serious
36 #pragma GCC diagnostic ignored "-Wshadow"
37 #endif
38 #include <TTree.h>
39 #ifdef __GNUC__
40 #pragma GCC diagnostic pop
41 #endif
42 #ifdef __clang__
43 #pragma clang diagnostic pop
44 #endif
45 
46 namespace brio {
47 
48  template <typename T>
49  int writer::store(const T & data_, const std::string & label_)
50  {
51  DT_THROW_IF(!this->is_opened(),
52  std::logic_error,
53  "Operation prohibited; file is not opened !");
54  store_info *ptr_si = this->_get_store_info(label_);
55  if (!ptr_si) {
56  if (label_.empty()) {
57  // if we do not allow automatic store, this is a critical error:
58  DT_THROW_IF(!_allow_automatic_store_,
59  std::logic_error,
60  "No target store is selected nor target !");
62  data_.get_serial_tag(),
64  } else {
65  ptr_si = this->_add_store(label_, data_.get_serial_tag(),
67  }
68  }
69  // Final check:
70  DT_THROW_IF(ptr_si == 0,
71  std::logic_error,
72  "Could not determine any store to save data !");
74  "ptr_si = " << std::hex << ptr_si << std::dec);
76  "Using store with label '" << ptr_si->label << "'...");
78  ptr_si->tree->Print ();
79  }
80  return this->_at_store<T>(data_, ptr_si);
81  }
82 
83  template <typename T>
84  int writer::_at_store(const T & data_, store_info * store_info_)
85  {
86  DT_LOG_TRACE(this->get_logging_priority(),"Entering...");
87  store_info *ptr_si = store_info_;
88  // First serialized object sets the serialization tag for this store:
89  if (ptr_si->serialization_tag ==
91  ptr_si->serialization_tag = data_.get_serial_tag();
92  }
93  // Else if the store has a dedicated serialization tag:
94  else if (ptr_si->has_dedicated_serialization_tag()) {
95  // Check the data serialization tag matches that requested by the store:
96  DT_THROW_IF(data_.get_serial_tag() != ptr_si->get_serialization_tag(),
97  std::logic_error,
98  "Serialization tag mismatch ! "
99  << "Attempt to store an object with `"
100  << data_.get_serial_tag ()
101  << "' serialization tag "
102  << "in the store labelled '"
103  << ptr_si->label
104  << "' with dedicated `"
105  << ptr_si->get_serialization_tag ()
106  << "' serialization tag !");
107  }
108 
109  // Prepare the (std::vector<char>) buffer to host the binary archive
110  // as a sequence of bytes:
111  typedef std::vector<char> buffer_type;
112 
113  /* Clear the buffer of characters for streaming but
114  * intrinsic capacity is kept as is (this is a behaviour of vector
115  * class from the STL library):
116  */
117  if (!ptr_si->buffer.empty()) {
118  ptr_si->buffer.clear();
119  } else if (ptr_si->buffer.capacity() == 0) {
120  // Ensure minimum starting capacity of the buffer of characters for
121  // streaming in order to optimize possible memory reallocation:
123  }
124 
125  // Archiving is redirected to the buffer:
126  namespace io = boost::iostreams;
127  io::stream<io::back_insert_device<buffer_type> > output_stream(ptr_si->buffer);
128  // 2011-06-16 FM: restored
129  if (this->is_format_pba()) {
130  datatools::portable_oarchive oa(output_stream);
131  oa << data_;
132  }
133  if (is_format_text()) {
134  output_stream.imbue(*_locale);
135  boost::archive::text_oarchive oa(output_stream);
136  oa << data_;
137  }
138  output_stream.flush();
139 
140  // Now the buffer contains the final sequence of bytes corresponding to
141  // the serialized output binary archive:
143  "Buffer size = "
144  << ptr_si->buffer.size()
145  << " buffer capacity = "
146  << ptr_si->buffer.capacity());
147  // Prepare the container interface to be streamed using the ROOT I/O system:
148  ptr_si->record.fSerialTag = data_.get_serial_tag().c_str();
149  ptr_si->record.fVersionTag = 0; // not used
150  ptr_si->record.fDataBuffer.fN = ptr_si->buffer.size();
151  ptr_si->record.fDataBuffer.fArray = &(ptr_si->buffer[0]);
152  // Store this tree entry in the ROOT I/O system:
153  ptr_si->tree->Fill ();
154  // Reset the ROOT data buffer:
155  ptr_si->record.fDataBuffer.fN = 0;
156  ptr_si->record.fDataBuffer.fArray = 0;
157  // Update some counters:
158  ptr_si->number_of_entries = ptr_si->tree->GetEntries();
159  ptr_si->current_entry = ptr_si->number_of_entries - 1;
160  // Update the 'current store' pointer:
161  _current_store = ptr_si;
162  DT_LOG_TRACE(this->get_logging_priority(),"Exiting.");
163  return 0;
164  }
165 
166 } // namespace brio
167 
168 #endif // BRIO_READER_INL_H
169 
170 // Local Variables: --
171 // mode: c++ --
172 // c-file-style: "gnu" --
173 // tab-width: 2 --
174 // End: --
store_info * _get_store_info(const std::string &label_="")
store_info * _add_store(const std::string &label_, const std::string &serial_tag_, size_t buffer_size_)
const std::string & get_serialization_tag() const
static const std::string & automatic_store_label()
std::vector< char > buffer
the input buffer (used only by the writer)
Definition: utils.h:81
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
int _at_store(const T &dat, store_info *store_info_)
Definition: writer-inl.h:84
static size_t default_store_buffer_size()
TArrayCMod fDataBuffer
The buffer of bytes that contains the Boost archive associated to the serialized data.
Definition: brio_record.h:50
datatools::logger::priority get_logging_priority() const
TString fSerialTag
The serialization tag of the data class.
Definition: brio_record.h:48
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
#define DT_LOG_DEBUG(Priority, Message)
Log Message if Priority is greater or equal to PRIO_DEBUG.
Definition: logger_macros.h:147
static const std::string & postponed_dedicated_serial_tag_label()
UInt_t fVersionTag
The serialization version number of the data class.
Definition: brio_record.h:49
std::string label
the label (name) of the store
Definition: utils.h:75
bool is_format_pba() const
int64_t number_of_entries
the number of entries in the store
Definition: utils.h:82
std::string serialization_tag
the serialization tag associated to the object stored in the store
Definition: utils.h:76
static size_t default_stream_buffer_size()
brio_record record
the current brio record to be (de)serialized
Definition: utils.h:79
A debugging message.
Definition: logger.h:91
bool has_dedicated_serialization_tag() const
#define DT_THROW_IF(Condition, ExceptionType, Message)
Definition: exception.h:76
#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
int store(const T &data_, const std::string &label_="")
Definition: writer-inl.h:49
bool is_format_text() const
Top-level namespace of the Bayeux/brio module library.
Definition: base_io.h:37