Chemical Data Processing Library C++ API - Version 1.0.0
CompoundDataReader.hpp
Go to the documentation of this file.
1 /*
2  * CompoundDataReader.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_COMPOUNDDATAREADER_HPP
30 #define CDPL_UTIL_COMPOUNDDATAREADER_HPP
31 
32 #include <vector>
33 #include <algorithm>
34 #include <functional>
35 
36 #include "CDPL/Base/DataReader.hpp"
37 #include "CDPL/Base/Exceptions.hpp"
38 
39 
40 namespace CDPL
41 {
42 
43  namespace Util
44  {
45 
49  template <typename DataType>
50  class CompoundDataReader : public Base::DataReader<DataType>
51  {
52 
53  public:
54  typedef std::shared_ptr<CompoundDataReader> SharedPointer;
55 
58 
60 
62 
64 
66 
67  void addReader(const ReaderPointer& reader);
68 
69  void removeReader(std::size_t idx);
70 
71  std::size_t getNumReaders();
72 
73  void clear();
74 
75  std::size_t getReaderIDForRecordIndex(std::size_t idx) const;
76 
77  const ReaderPointer& getReader(std::size_t idx) const;
78 
79  CompoundDataReader& read(DataType& obj, bool overwrite = true);
80  CompoundDataReader& read(std::size_t idx, DataType& obj, bool overwrite = true);
81 
83 
84  bool hasMoreData();
85 
86  std::size_t getRecordIndex() const;
87  void setRecordIndex(std::size_t idx);
88 
89  std::size_t getNumRecords();
90 
91  operator const void*() const;
92  bool operator!() const;
93 
94  private:
95  ReaderType* getReaderForRecordIndex(std::size_t& idx) const;
96 
97  typedef std::vector<ReaderPointer> ReaderArray;
98  typedef std::vector<std::size_t> RecordIndexArray;
99 
100  ReaderArray readers;
101  bool state;
102  RecordIndexArray recordIdxBounds;
103  std::size_t recordIdx;
104  std::size_t numRecords;
105  };
106  } // namespace Util
107 } // namespace CDPL
108 
109 
110 // Implementation
111 
112 template <typename DataType>
114  state(false), recordIdx(0), numRecords(0)
115 {}
116 
117 template <typename DataType>
119 {
120  clear();
121 }
122 
123 template <typename DataType>
125 {
126  std::for_each(readers.begin(), readers.end(),
127  std::bind(&ReaderType::setParent, std::placeholders::_1,
128  static_cast<CompoundDataReader*>(0)));
129  readers.clear();
130  recordIdxBounds.clear();
131 
132  numRecords = 0;
133  state = false;
134  recordIdx = 0;
135 }
136 
137 template <typename DataType>
139 {
140  readers.reserve(readers.size() + 1);
141  recordIdxBounds.reserve(readers.size() + 1);
142 
143  reader->setParent(this);
144 
145  std::size_t num_recs = reader->getNumRecords();
146 
147  readers.push_back(reader);
148  numRecords += num_recs;
149  recordIdxBounds.push_back(numRecords);
150 
151  state |= static_cast<bool>(reader->operator const void*());
152 }
153 
154 template <typename DataType>
156 {
157  if (idx >= readers.size())
158  throw Base::IndexError("CompoundDataReader: reader index out of bounds");
159 
160  std::size_t num_lost_records = readers[idx]->getNumRecords();
161 
162  readers[idx]->setParent(0);
163 
164  readers.erase(readers.begin() + idx);
165  recordIdxBounds.erase(recordIdxBounds.begin() + idx);
166 
167  for (; idx < readers.size(); idx++)
168  recordIdxBounds[idx] -= num_lost_records;
169 
170  numRecords -= num_lost_records;
171 }
172 
173 template <typename DataType>
175 {
176  return readers.size();
177 }
178 
179 template <typename DataType>
182 {
183  if (idx >= readers.size())
184  throw Base::IndexError("CompoundDataReader: reader index out of bounds");
185 
186  return readers[idx];
187 }
188 
189 template <typename DataType>
192 {
193  state = false;
194 
195  std::size_t idx = recordIdx;
196  ReaderType* reader = getReaderForRecordIndex(idx);
197 
198  if (reader && (state = reader->read(idx, obj, overwrite))) {
199  recordIdx++;
200  this->invokeIOCallbacks(1.0);
201  }
202 
203  return *this;
204 }
205 
206 template <typename DataType>
208 CDPL::Util::CompoundDataReader<DataType>::read(std::size_t idx, DataType& obj, bool overwrite)
209 {
210  setRecordIndex(idx);
211 
212  return read(obj, overwrite);
213 }
214 
215 template <typename DataType>
218 {
219  state = false;
220 
221  if (recordIdx >= numRecords)
222  return *this;
223 
224  recordIdx++;
225  state = true;
226 
227  this->invokeIOCallbacks(1.0);
228 
229  return *this;
230 }
231 
232 template <typename DataType>
234 {
235  return (recordIdx < numRecords);
236 }
237 
238 template <typename DataType>
240 {
241  return recordIdx;
242 }
243 
244 template <typename DataType>
246 {
247  if (idx >= numRecords)
248  throw Base::IndexError("CompoundDataReader: record index out of bounds");
249 
250  recordIdx = idx;
251 }
252 
253 template <typename DataType>
255 {
256  return numRecords;
257 }
258 
259 template <typename DataType>
261 {
262  return (state ? this : 0);
263 }
264 
265 template <typename DataType>
267 {
268  return !state;
269 }
270 
271 template <typename DataType>
273 {
274  for (std::size_t i = 0; i < readers.size(); i++) {
275  if (idx < recordIdxBounds[i])
276  return (i + 1);
277  }
278 
279  return 0;
280 }
281 
282 template <typename DataType>
285 {
286  for (std::size_t i = 0; i < readers.size(); i++) {
287  if (idx < recordIdxBounds[i]) {
288  idx -= (i == 0 ? std::size_t(0) : recordIdxBounds[i - 1]);
289  return readers[i].get();
290  }
291  }
292 
293  return 0;
294 }
295 
296 #endif // CDPL_UTIL_COMPOUNDDATAREADER_HPP
CDPL::Util::CompoundDataReader::SharedPointer
std::shared_ptr< CompoundDataReader > SharedPointer
Definition: CompoundDataReader.hpp:54
CDPL::Util::CompoundDataReader::getNumReaders
std::size_t getNumReaders()
Definition: CompoundDataReader.hpp:174
CDPL::Base::DataReader::read
virtual DataReader & read(DataType &obj, bool overwrite=true)=0
Reads the data record at the current record index and stores the read data in obj.
CDPL::Util::CompoundDataReader::~CompoundDataReader
~CompoundDataReader()
Definition: CompoundDataReader.hpp:118
CDPL::Base::DataReader< DataType >::DataType
DataType DataType
The type of the read data objects.
Definition: DataReader.hpp:79
CDPL::Util::CompoundDataReader
CompoundDataReader.
Definition: CompoundDataReader.hpp:51
DataReader.hpp
Definition of the class CDPL::Base::DataReader.
CDPL::Util::CompoundDataReader::read
CompoundDataReader & read(DataType &obj, bool overwrite=true)
Reads the data record at the current record index and stores the read data in obj.
Definition: CompoundDataReader.hpp:191
CDPL::Util::CompoundDataReader::operator=
CompoundDataReader & operator=(const CompoundDataReader &)=delete
CDPL::Util::CompoundDataReader::skip
CompoundDataReader & skip()
Skips the data record at the current record index.
Definition: CompoundDataReader.hpp:217
CDPL::Util::CompoundDataReader::CompoundDataReader
CompoundDataReader()
Definition: CompoundDataReader.hpp:113
CDPL::Base::IndexError
Thrown to indicate that an index is out of range.
Definition: Base/Exceptions.hpp:152
CDPL::Util::CompoundDataReader::getReaderIDForRecordIndex
std::size_t getReaderIDForRecordIndex(std::size_t idx) const
Definition: CompoundDataReader.hpp:272
CDPL::Util::CompoundDataReader::ReaderType
Base::DataReader< DataType > ReaderType
Definition: CompoundDataReader.hpp:56
CDPL::Base::DataReader
An interface for reading data objects of a given type from an arbitrary data source.
Definition: DataReader.hpp:73
CDPL::Util::CompoundDataReader::clear
void clear()
Definition: CompoundDataReader.hpp:124
CDPL::Util::CompoundDataReader::ReaderPointer
ReaderType::SharedPointer ReaderPointer
Definition: CompoundDataReader.hpp:57
CDPL::Util::CompoundDataReader::addReader
void addReader(const ReaderPointer &reader)
Definition: CompoundDataReader.hpp:138
Exceptions.hpp
Definition of exception classes.
CDPL::Util::CompoundDataReader::hasMoreData
bool hasMoreData()
Tells if there are any data records left to read.
Definition: CompoundDataReader.hpp:233
CDPL::Base::DataReader< DataType >::SharedPointer
std::shared_ptr< DataReader > SharedPointer
A reference-counted smart pointer [SHPTR] for dynamically allocated DataReader instances.
Definition: DataReader.hpp:84
CDPL::Util::CompoundDataReader::getNumRecords
std::size_t getNumRecords()
Returns the total number of available data records.
Definition: CompoundDataReader.hpp:254
CDPL::Util::CompoundDataReader::CompoundDataReader
CompoundDataReader(const CompoundDataReader &)=delete
CDPL
The namespace of the Chemical Data Processing Library.
CDPL::Util::CompoundDataReader::getReader
const ReaderPointer & getReader(std::size_t idx) const
Definition: CompoundDataReader.hpp:181
CDPL::Util::CompoundDataReader::operator!
bool operator!() const
Definition: CompoundDataReader.hpp:266
CDPL::Util::CompoundDataReader::getRecordIndex
std::size_t getRecordIndex() const
Definition: CompoundDataReader.hpp:239
CDPL::Util::CompoundDataReader::setRecordIndex
void setRecordIndex(std::size_t idx)
Sets the index of the current data record to idx.
Definition: CompoundDataReader.hpp:245
CDPL::Util::CompoundDataReader::removeReader
void removeReader(std::size_t idx)
Definition: CompoundDataReader.hpp:155