A toolkit for working with phylogenetic data.
v0.18.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
input_source.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_IO_INPUT_SOURCE_H_
2 #define GENESIS_UTILS_IO_INPUT_SOURCE_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2017 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program 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
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lucas.czech@h-its.org>
23  Exelixis Lab, Heidelberg Institute for Theoretical Studies
24  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
25 */
26 
35 
36 #include <cstdio>
37 #include <cstring>
38 #include <istream>
39 #include <stdexcept>
40 #include <string>
41 
42 namespace genesis {
43 namespace utils {
44 
45 // =================================================================================================
46 // Base Input Source
47 // =================================================================================================
48 
55 {
56 public:
57 
58  // -------------------------------------------------------------
59  // Constructors and Rule of Five
60  // -------------------------------------------------------------
61 
62  BaseInputSource() = default;
63 
64  BaseInputSource( BaseInputSource const& ) = default;
65  BaseInputSource( BaseInputSource&& ) = default;
66 
67  BaseInputSource& operator= ( BaseInputSource const& ) = default;
69 
70  virtual ~BaseInputSource()
71  {}
72 
73  // -------------------------------------------------------------
74  // Members
75  // -------------------------------------------------------------
76 
80  size_t read( char* buffer, size_t size )
81  {
82  // Non-virtual interface.
83  return read_( buffer, size );
84  }
85 
89  std::string source_name() const
90  {
91  // Non-virtual interface.
92  return source_name_();
93  }
94 
95  // -------------------------------------------------------------
96  // Internal Members
97  // -------------------------------------------------------------
98 
99 private:
100 
101  virtual size_t read_( char* buffer, size_t size ) = 0;
102 
103  virtual std::string source_name_() const = 0;
104 
105 };
106 
107 // =================================================================================================
108 // String Input Source
109 // =================================================================================================
110 
122 {
123 public:
124 
125  // -------------------------------------------------------------
126  // Constructors and Rule of Five
127  // -------------------------------------------------------------
128 
132  StringInputSource( char const* str, size_t size )
133  : in_str_( str )
134  , cursor_( str )
135  , in_size_( size )
136  , rest_size_( size )
137  {}
138 
142  StringInputSource( std::string const& str )
143  : in_str_( str.c_str() )
144  , cursor_( str.c_str() )
145  , in_size_( str.size() )
146  , rest_size_( str.size() )
147  {}
148 
149  StringInputSource( StringInputSource const& ) = default;
150  StringInputSource( StringInputSource&& ) = default;
151 
152  StringInputSource& operator= ( StringInputSource const& ) = default;
154 
156  {}
157 
158  // -------------------------------------------------------------
159  // Special Members
160  // -------------------------------------------------------------
161 
165  void rewind()
166  {
167  cursor_ = in_str_;
168  rest_size_ = in_size_;
169  }
170 
171  // -------------------------------------------------------------
172  // Overloaded Internal Members
173  // -------------------------------------------------------------
174 
175 private:
176 
180  size_t read_( char* buffer, size_t size ) override
181  {
182  // Don't overshoot.
183  if( size > rest_size_ ) {
184  size = rest_size_;
185  }
186 
187  // Read.
188  std::memcpy( buffer, cursor_, size );
189  cursor_ += size;
190  rest_size_ -= size;
191  return size;
192  }
193 
197  std::string source_name_() const override
198  {
199  return "input string";
200  }
201 
202  // -------------------------------------------------------------
203  // Member Variables
204  // -------------------------------------------------------------
205 
206  // Original and current string position pointer.
207  char const* in_str_;
208  char const* cursor_;
209 
210  // Original and current (remaining) string size.
211  size_t in_size_;
212  size_t rest_size_;
213 
214 };
215 
216 // =================================================================================================
217 // Stream Input Source
218 // =================================================================================================
219 
228 {
229 public:
230 
231  // -------------------------------------------------------------
232  // Constructors and Rule of Five
233  // -------------------------------------------------------------
234 
238  explicit StreamInputSource( std::istream& in )
239  : in_( in )
240  {}
241 
242  StreamInputSource( StreamInputSource const& ) = default;
243  StreamInputSource( StreamInputSource&& ) = default;
244 
245  StreamInputSource& operator= ( StreamInputSource const& ) = default;
247 
249  {}
250 
251  // -------------------------------------------------------------
252  // Overloaded Internal Members
253  // -------------------------------------------------------------
254 
255 private:
256 
260  size_t read_( char* buffer, size_t size ) override
261  {
262  in_.read( buffer, size );
263  return in_.gcount();
264  }
265 
269  std::string source_name_() const override
270  {
271  return "input stream";
272  }
273 
274  // -------------------------------------------------------------
275  // Member Variables
276  // -------------------------------------------------------------
277 
278  std::istream& in_;
279 };
280 
281 // =================================================================================================
282 // File Input Source
283 // =================================================================================================
284 
294 {
295 public:
296 
297  // -------------------------------------------------------------
298  // Constructors and Rule of Five
299  // -------------------------------------------------------------
300 
304  explicit FileInputSource( std::string const& file_name )
305  : file_name_( file_name )
306  {
307  if( ! file_exists( file_name ) ) {
308  throw std::runtime_error( "File does not exists: " + file_name );
309  }
310 
311  file_ = std::fopen( file_name.c_str(), "rb" );
312 
313  if( file_ == nullptr ) {
314  // TODO use errno here.
315  throw std::runtime_error( "Cannot open file: " + file_name );
316  }
317 
318  // We do our own buffering.
319  std::setvbuf( file_, 0, _IONBF, 0 );
320  }
321 
326  explicit FileInputSource( std::string const& file_name, FILE* file )
327  : file_( file )
328  , file_name_( file_name )
329  {
330  // We do our own buffering.
331  std::setvbuf( file_, 0, _IONBF, 0 );
332  }
333 
334  FileInputSource( FileInputSource const& ) = default;
335  FileInputSource( FileInputSource&& ) = default;
336 
337  FileInputSource& operator= ( FileInputSource const& ) = default;
339 
341  {
342  std::fclose( file_ );
343  }
344 
345  // -------------------------------------------------------------
346  // Special Members
347  // -------------------------------------------------------------
348 
352  void rewind()
353  {
354  std::rewind( file_ );
355  }
356 
357  // -------------------------------------------------------------
358  // Overloaded Internal Members
359  // -------------------------------------------------------------
360 
361 private:
362 
366  size_t read_( char* buffer, size_t size ) override
367  {
368  return std::fread( buffer, 1, size, file_ );
369  }
370 
374  std::string source_name_() const override
375  {
376  return "input file " + file_name_;
377  }
378 
379  // -------------------------------------------------------------
380  // Member Variables
381  // -------------------------------------------------------------
382 
383  FILE* file_;
384  std::string file_name_;
385 };
386 
387 } // namespace utils
388 } // namespace genesis
389 
390 #endif // include guard
BaseInputSource & operator=(BaseInputSource const &)=default
StreamInputSource & operator=(StreamInputSource const &)=default
bool file_exists(std::string const &filename)
Return true iff the file exists.
Definition: fs.cpp:69
Input source for reading byte data from a file.
FileInputSource & operator=(FileInputSource const &)=default
StringInputSource(std::string const &str)
Construct the input source from a std::string.
StringInputSource(char const *str, size_t size)
Construct the input source from a char array.
size_t read(char *buffer, size_t size)
Read size many bytes into the char buffer.
Provides functions for accessing the file system.
Abstract base class for reading byte data from input sources.
FileInputSource(std::string const &file_name)
Construct the input source from a file with the given file name.
std::string source_name() const
Get a name of the input source. Mainly interesting for user output.
void rewind()
Rewind the source to its start, so that it can be re-read.
void rewind()
Rewind the source to its start, so that it can be re-read.
StringInputSource & operator=(StringInputSource const &)=default
FileInputSource(std::string const &file_name, FILE *file)
Construct the input source from a FILE pointer. The file_name is used for the source_name() function ...
Input source for reading byte data from a string.
StreamInputSource(std::istream &in)
Construct the input source from an std::istream.
Input source for reading byte data from an istream.