Chemical Data Processing Library C++ API - Version 1.4.0
MultiFormatDataReader.hpp
Go to the documentation of this file.
1 /*
2  * MultiFormatDataReader.hpp
3  *
4  * This file is part of the Chemical Data Processing Toolkit
5  *
6  * Copyright (C) 2003 Thomas Seidel <thomas.seidel@univie.ac.at>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this library; see the file COPYING. If not, write to
20  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21  * Boston, MA 02111-1307, USA.
22  */
23 
29 #ifndef CDPL_UTIL_MULTIFORMATDATAREADER_HPP
30 #define CDPL_UTIL_MULTIFORMATDATAREADER_HPP
31 
32 #include <string>
33 #include <functional>
34 #include <memory>
35 
37 #include "CDPL/Base/Exceptions.hpp"
38 
39 
40 namespace CDPL
41 {
42 
43  namespace Util
44  {
45 
55  template <typename DataType>
56  class MultiFormatDataReader : public Base::DataReader<DataType>
57  {
58 
59  public:
63  typedef std::shared_ptr<MultiFormatDataReader> SharedPointer;
64 
71  MultiFormatDataReader(const std::string& file_name,
72  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
73 
81  MultiFormatDataReader(const std::string& file_name, const std::string& fmt,
82  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
83 
91  MultiFormatDataReader(const std::string& file_name, const Base::DataFormat& fmt,
92  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
93 
100  MultiFormatDataReader(std::istream& is, const std::string& fmt);
101 
108  MultiFormatDataReader(std::istream& is, const Base::DataFormat& fmt);
109 
111 
113 
118  const Base::DataFormat& getDataFormat() const;
119 
126  MultiFormatDataReader& read(DataType& obj, bool overwrite = true);
127 
135  MultiFormatDataReader& read(std::size_t idx, DataType& obj, bool overwrite = true);
136 
142 
147  bool hasMoreData();
148 
153  std::size_t getRecordIndex() const;
154 
159  void setRecordIndex(std::size_t idx);
160 
165  std::size_t getNumRecords();
166 
171  operator const void*() const;
172 
177  bool operator!() const;
178 
182  void close();
183 
184  private:
185  void init();
186 
187  typedef typename Base::DataReader<DataType>::SharedPointer ReaderPtr;
188 
189  ReaderPtr readerPtr;
190  Base::DataFormat dataFormat;
191  };
192  } // namespace Util
193 } // namespace CDPL
194 
195 
196 // Implementation
197 
198 template <typename DataType>
199 CDPL::Util::MultiFormatDataReader<DataType>::MultiFormatDataReader(const std::string& file_name, std::ios_base::openmode mode)
200 {
201  const auto& handler = Base::DataIOManager<DataType>::getInputHandlerByFileName(file_name);
202 
203  if (!handler)
204  throw Base::IOError("MultiFormatDataReader: could not deduce data format of '" + file_name + "'");
205 
206  readerPtr = handler->createReader(file_name, mode);
207  dataFormat = handler->getDataFormat();
208 
209  init();
210 }
211 
212 template <typename DataType>
213 CDPL::Util::MultiFormatDataReader<DataType>::MultiFormatDataReader(const std::string& file_name, const std::string& fmt,
214  std::ios_base::openmode mode)
215 {
217 
218  if (!handler)
219  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt + "'");
220 
221  readerPtr = handler->createReader(file_name, mode);
222  dataFormat = handler->getDataFormat();
223 
224  init();
225 }
226 
227 template <typename DataType>
229  std::ios_base::openmode mode):
230  dataFormat(fmt)
231 {
233 
234  if (!handler)
235  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt.getName() + "'");
236 
237  readerPtr = handler->createReader(file_name, mode);
238 
239  init();
240 }
241 
242 template <typename DataType>
244 {
246 
247  if (!handler)
248  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt + "'");
249 
250  readerPtr = handler->createReader(is);
251  dataFormat = handler->getDataFormat();
252 
253  init();
254 }
255 
256 template <typename DataType>
258  dataFormat(fmt)
259 {
261 
262  if (!handler)
263  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt.getName() + "'");
264 
265  readerPtr = handler->createReader(is);
266 
267  init();
268 }
269 
270 template <typename DataType>
272 {
273  return dataFormat;
274 }
275 
276 template <typename DataType>
279 {
280  readerPtr->read(obj, overwrite);
281  return *this;
282 }
283 
284 template <typename DataType>
286 CDPL::Util::MultiFormatDataReader<DataType>::read(std::size_t idx, DataType& obj, bool overwrite)
287 {
288  readerPtr->read(idx, obj, overwrite);
289  return *this;
290 }
291 
292 template <typename DataType>
295 {
296  readerPtr->skip();
297  return *this;
298 }
299 
300 template <typename DataType>
302 {
303  return readerPtr->hasMoreData();
304 }
305 
306 template <typename DataType>
308 {
309  return readerPtr->getRecordIndex();
310 }
311 
312 template <typename DataType>
314 {
315  readerPtr->setRecordIndex(idx);
316 }
317 
318 template <typename DataType>
320 {
321  return readerPtr->getNumRecords();
322 }
323 
324 template <typename DataType>
326 {
327  return readerPtr->operator const void*();
328 }
329 
330 template <typename DataType>
332 {
333  return readerPtr->operator!();
334 }
335 
336 template <typename DataType>
338 {
339  readerPtr->close();
340 }
341 
342 template <typename DataType>
344 {
345  readerPtr->setParent(this);
346  readerPtr->registerIOCallback(std::bind(&Base::DataIOBase::invokeIOCallbacks, this, std::placeholders::_2));
347 }
348 
349 #endif // CDPL_UTIL_MULTIFORMATDATAREADER_HPP
Definition of exception classes.
Definition of class CDPL::Base::DataIOManager.
void setParent(const ControlParameterContainer *cntnr)
Sets or removes the parent control-parameter container used to resolve requests for missing entries.
Provides meta-information about a particular data storage format.
Definition: Base/DataFormat.hpp:49
const std::string & getName() const
Returns the short-name of the data format.
void invokeIOCallbacks(double progress) const
Invokes all registered I/O callback functions with the argument *this.
Singleton class that serves as a global registry for Base::DataInputHandler and Base::DataOutputHandl...
Definition: DataIOManager.hpp:110
static InputHandlerPointer getInputHandlerByFormat(const DataFormat &fmt)
Returns a pointer to a Base::DataInputHandler implementation instance registered for the specified da...
Definition: DataIOManager.hpp:588
static InputHandlerPointer getInputHandlerByFileExtension(const std::string &file_ext)
Returns a pointer to a Base::DataInputHandler implementation instance registered for the data format ...
Definition: DataIOManager.hpp:599
Interface for reading data objects of a given type from an arbitrary data source.
Definition: DataReader.hpp:73
std::shared_ptr< DataReader > SharedPointer
A reference-counted smart pointer [SHPTR] for dynamically allocated DataReader instances.
Definition: DataReader.hpp:84
DataType DataType
The type of the read data objects.
Definition: DataReader.hpp:79
Thrown to indicate that an I/O operation has failed because of physical (e.g. broken pipe) or logical...
Definition: Base/Exceptions.hpp:250
Reader that auto-dispatches to a format-specific reader registered with Base::DataIOManager.
Definition: MultiFormatDataReader.hpp:57
MultiFormatDataReader & read(DataType &obj, bool overwrite=true)
Reads the next data record into obj.
Definition: MultiFormatDataReader.hpp:278
bool operator!() const
Tells whether the reader is in a bad state.
Definition: MultiFormatDataReader.hpp:331
std::shared_ptr< MultiFormatDataReader > SharedPointer
A reference-counted smart pointer [SHPTR] for dynamically allocated MultiFormatDataReader instances.
Definition: MultiFormatDataReader.hpp:63
MultiFormatDataReader & skip()
Skips the next data record.
Definition: MultiFormatDataReader.hpp:294
const Base::DataFormat & getDataFormat() const
Returns the data format the wrapped reader was instantiated for.
Definition: MultiFormatDataReader.hpp:271
std::size_t getRecordIndex() const
Returns the index of the current data record.
Definition: MultiFormatDataReader.hpp:307
MultiFormatDataReader(const MultiFormatDataReader &)=delete
void close()
Closes the underlying reader.
Definition: MultiFormatDataReader.hpp:337
MultiFormatDataReader & operator=(const MultiFormatDataReader &)=delete
void setRecordIndex(std::size_t idx)
Sets the index of the next data record to be read.
Definition: MultiFormatDataReader.hpp:313
bool hasMoreData()
Tells whether more records are available.
Definition: MultiFormatDataReader.hpp:301
MultiFormatDataReader(const std::string &file_name, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::binary)
Constructs a reader for the file file_name with format detected from its extension.
Definition: MultiFormatDataReader.hpp:199
std::size_t getNumRecords()
Returns the total number of records in the input source.
Definition: MultiFormatDataReader.hpp:319
The namespace of the Chemical Data Processing Library.