Chemical Data Processing Library C++ API - Version 1.2.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 
49  template <typename DataType>
50  class MultiFormatDataReader : public Base::DataReader<DataType>
51  {
52 
53  public:
54  typedef std::shared_ptr<MultiFormatDataReader> SharedPointer;
55 
56  MultiFormatDataReader(const std::string& file_name,
57  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
58 
59  MultiFormatDataReader(const std::string& file_name, const std::string& fmt,
60  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
61 
62  MultiFormatDataReader(const std::string& file_name, const Base::DataFormat& fmt,
63  std::ios_base::openmode mode = std::ios_base::in | std::ios_base::binary);
64 
65  MultiFormatDataReader(std::istream& is, const std::string& fmt);
66 
67  MultiFormatDataReader(std::istream& is, const Base::DataFormat& fmt);
68 
70 
72 
73  const Base::DataFormat& getDataFormat() const;
74 
75  MultiFormatDataReader& read(DataType& obj, bool overwrite = true);
76 
77  MultiFormatDataReader& read(std::size_t idx, DataType& obj, bool overwrite = true);
78 
80 
81  bool hasMoreData();
82 
83  std::size_t getRecordIndex() const;
84 
85  void setRecordIndex(std::size_t idx);
86 
87  std::size_t getNumRecords();
88 
89  operator const void*() const;
90 
91  bool operator!() const;
92 
93  void close();
94 
95  private:
96  void init();
97 
98  typedef typename Base::DataReader<DataType>::SharedPointer ReaderPtr;
99 
100  ReaderPtr readerPtr;
101  Base::DataFormat dataFormat;
102  };
103  } // namespace Util
104 } // namespace CDPL
105 
106 
107 // Implementation
108 
109 template <typename DataType>
110 CDPL::Util::MultiFormatDataReader<DataType>::MultiFormatDataReader(const std::string& file_name, std::ios_base::openmode mode)
111 {
112  const auto& handler = Base::DataIOManager<DataType>::getInputHandlerByFileName(file_name);
113 
114  if (!handler)
115  throw Base::IOError("MultiFormatDataReader: could not deduce data format of '" + file_name + "'");
116 
117  readerPtr = handler->createReader(file_name, mode);
118  dataFormat = handler->getDataFormat();
119 
120  init();
121 }
122 
123 template <typename DataType>
124 CDPL::Util::MultiFormatDataReader<DataType>::MultiFormatDataReader(const std::string& file_name, const std::string& fmt,
125  std::ios_base::openmode mode)
126 {
128 
129  if (!handler)
130  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt + "'");
131 
132  readerPtr = handler->createReader(file_name, mode);
133  dataFormat = handler->getDataFormat();
134 
135  init();
136 }
137 
138 template <typename DataType>
140  std::ios_base::openmode mode):
141  dataFormat(fmt)
142 {
144 
145  if (!handler)
146  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt.getName() + "'");
147 
148  readerPtr = handler->createReader(file_name, mode);
149 
150  init();
151 }
152 
153 template <typename DataType>
155 {
157 
158  if (!handler)
159  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt + "'");
160 
161  readerPtr = handler->createReader(is);
162  dataFormat = handler->getDataFormat();
163 
164  init();
165 }
166 
167 template <typename DataType>
169  dataFormat(fmt)
170 {
172 
173  if (!handler)
174  throw Base::IOError("MultiFormatDataReader: could not find handler for format '" + fmt.getName() + "'");
175 
176  readerPtr = handler->createReader(is);
177 
178  init();
179 }
180 
181 template <typename DataType>
183 {
184  return dataFormat;
185 }
186 
187 template <typename DataType>
190 {
191  readerPtr->read(obj, overwrite);
192  return *this;
193 }
194 
195 template <typename DataType>
197 CDPL::Util::MultiFormatDataReader<DataType>::read(std::size_t idx, DataType& obj, bool overwrite)
198 {
199  readerPtr->read(idx, obj, overwrite);
200  return *this;
201 }
202 
203 template <typename DataType>
206 {
207  readerPtr->skip();
208  return *this;
209 }
210 
211 template <typename DataType>
213 {
214  return readerPtr->hasMoreData();
215 }
216 
217 template <typename DataType>
219 {
220  return readerPtr->getRecordIndex();
221 }
222 
223 template <typename DataType>
225 {
226  readerPtr->setRecordIndex(idx);
227 }
228 
229 template <typename DataType>
231 {
232  return readerPtr->getNumRecords();
233 }
234 
235 template <typename DataType>
237 {
238  return readerPtr->operator const void*();
239 }
240 
241 template <typename DataType>
243 {
244  return readerPtr->operator!();
245 }
246 
247 template <typename DataType>
249 {
250  readerPtr->close();
251 }
252 
253 template <typename DataType>
255 {
256  readerPtr->setParent(this);
257  readerPtr->registerIOCallback(std::bind(&Base::DataIOBase::invokeIOCallbacks, this, std::placeholders::_2));
258 }
259 
260 #endif // CDPL_UTIL_MULTIFORMATDATAREADER_HPP
Definition of exception classes.
Definition of the 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.
A singleton class that serves as a global registry for Base::DataInputHandler and Base::DataOutputHan...
Definition: DataIOManager.hpp:104
static InputHandlerPointer getInputHandlerByFormat(const DataFormat &fmt)
Returns a pointer to a Base::DataInputHandler implementation instance registered for the specified da...
Definition: DataIOManager.hpp:580
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:591
An 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
MultiFormatDataReader.
Definition: MultiFormatDataReader.hpp:51
MultiFormatDataReader & read(DataType &obj, bool overwrite=true)
Reads the data record at the current record index and stores the read data in obj.
Definition: MultiFormatDataReader.hpp:189
bool operator!() const
Tells whether the reader is in a bad state.
Definition: MultiFormatDataReader.hpp:242
std::shared_ptr< MultiFormatDataReader > SharedPointer
Definition: MultiFormatDataReader.hpp:54
MultiFormatDataReader & skip()
Skips the data record at the current record index.
Definition: MultiFormatDataReader.hpp:205
const Base::DataFormat & getDataFormat() const
Definition: MultiFormatDataReader.hpp:182
std::size_t getRecordIndex() const
Returns the index of the current data record.
Definition: MultiFormatDataReader.hpp:218
MultiFormatDataReader(const MultiFormatDataReader &)=delete
void close()
Performs a reader specific shutdown operation (if required).
Definition: MultiFormatDataReader.hpp:248
MultiFormatDataReader & operator=(const MultiFormatDataReader &)=delete
void setRecordIndex(std::size_t idx)
Sets the index of the current data record to idx.
Definition: MultiFormatDataReader.hpp:224
bool hasMoreData()
Tells if there are any data records left to read.
Definition: MultiFormatDataReader.hpp:212
MultiFormatDataReader(const std::string &file_name, std::ios_base::openmode mode=std::ios_base::in|std::ios_base::binary)
Definition: MultiFormatDataReader.hpp:110
std::size_t getNumRecords()
Returns the total number of available data records.
Definition: MultiFormatDataReader.hpp:230
The namespace of the Chemical Data Processing Library.