A toolkit for working with phylogenetic data.
v0.24.0
deserializer.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_IO_DESERIALIZER_H_
2 #define GENESIS_UTILS_IO_DESERIALIZER_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2019 Lucas Czech and HITS gGmbH
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 
39 
40 #include <algorithm>
41 #include <cstring>
42 #include <fstream>
43 #include <iostream>
44 #include <stdexcept>
45 #include <string>
46 
47 namespace genesis {
48 namespace utils {
49 
50 // =================================================================================================
51 // Deserializer
52 // =================================================================================================
53 
58 {
59 public:
60 
61  // -------------------------------------------------------------------------
62  // Constructor and Destructor
63  // -------------------------------------------------------------------------
64 
65  explicit Deserializer( std::string const& file_name )
66  : buffer_( std::make_shared< FileInputSource >( file_name ) )
67  {
68  if( ! buffer_ ) {
69  throw std::runtime_error("Creating Deserializer from file failed.");
70  }
71  }
72 
73  explicit Deserializer( std::istream& instream )
74  : buffer_( std::make_shared< StreamInputSource >( instream ) )
75  {
76  if( ! buffer_ ) {
77  throw std::runtime_error("Creating Deserializer from stream failed.");
78  }
79  }
80 
81  // -------------------------------------------------------------------------
82  // Stream Status
83  // -------------------------------------------------------------------------
84 
85  inline operator bool() const
86  {
87  return buffer_;
88  }
89 
90  // inline bool good() const
91  // {
92  // return instream.good();
93  // }
94  //
95  // inline bool eof() const
96  // {
97  // return instream.eof();
98  // }
99  //
100  // inline bool fail() const
101  // {
102  // return instream.fail();
103  // }
104  //
105  // inline bool bad() const
106  // {
107  // return instream.bad();
108  // }
109  //
110  // inline bool succeeded() const
111  // {
112  // return !instream.eof() && instream.peek() == EOF;
113  // }
114 
115  inline bool finished() const
116  {
117  return ! buffer_;
118  }
119 
120  // -------------------------------------------------------------------------
121  // File Status
122  // -------------------------------------------------------------------------
123 
124  // inline bool is_open() const
125  // {
126  // return infile.is_open();
127  // }
128  //
129  // inline void close()
130  // {
131  // infile.close();
132  // }
133 
134  // -------------------------------------------------------------------------
135  // Deserialization
136  // -------------------------------------------------------------------------
137 
143  void get_raw(char* buffer, size_t n)
144  {
145  size_t const got = buffer_.read(buffer, n);
146  if( got != n ) {
147  throw std::runtime_error(
148  "Could only read " + std::to_string(got) + " bytes instead of n=" +
149  std::to_string( n ) + " bytes from Deserializer input."
150  );
151  }
152  }
153 
157  bool get_null (size_t n)
158  {
159  char* buffer = new char[n];
160  get_raw( buffer, n );
161 
162  bool ret = true;
163  for (size_t i = 0; i < n; ++i) {
164  ret &= (buffer[i] == '\0');
165  }
166 
167  delete[] buffer;
168  return ret;
169  }
170 
174  std::string get_raw_string(size_t n)
175  {
176  char* buffer = new char[n];
177  get_raw( buffer, n );
178 
179  std::string str (buffer, n);
180  delete[] buffer;
181  return str;
182  }
183 
188  std::string get_string ()
189  {
190  size_t len = get_int<size_t>();
191  return get_raw_string(len);
192  }
193 
194  // TODO maybe trailing return types is a solution to make this work without having to specify the template parameters? (also for the othter, similar methods in this class)
199  template<typename T>
201  {
202  T res;
203  get_raw( reinterpret_cast<char*>( &res ), sizeof(T) );
204  return res;
205  }
206 
211  template<typename T>
212  void get_plain (T& res)
213  {
214  get_raw( reinterpret_cast<char*>( &res ), sizeof(T) );
215  }
216 
220  template<typename T>
221  T get_int ()
222  {
223  return get_plain<T>();
224  }
225 
229  template<typename T>
230  void get_int (T& res)
231  {
232  res = get_plain<T>();
233  }
234 
238  template<typename T>
240  {
241  return get_plain<T>();
242  }
243 
247  template<typename T>
248  void get_float (T& res)
249  {
250  res = get_plain<T>();
251  }
252 
253  // -------------------------------------------------------------------------
254  // Data Members
255  // -------------------------------------------------------------------------
256 
257 private:
258 
259  InputBuffer buffer_;
260 
261 };
262 
263 } // namespace utils
264 } // namespace genesis
265 
266 #endif // include guard
T get_plain()
Read as many bytes from the stream as the type T holds, and return them in form of a value of type T...
void get_float(T &res)
Read an floating point number from the stream and store it in the result.
Deserializer(std::string const &file_name)
Input source for reading byte data from a file.
STL namespace.
std::string get_string()
Read a string from the stream, provided that its length it written preceding it, as done by put_strin...
Container namespace for all symbols of genesis in order to keep them separate when used as a library...
void get_int(T &res)
Read an integer number from the stream and store it in the result.
Provides some valuable additions to STD.
std::string get_raw_string(size_t n)
Read n bytes from the stream and return them as a string.
Deserializer(std::istream &instream)
bool get_null(size_t n)
Reads n bytes from the stream and returns whether all of them are \0 bytes.
std::shared_ptr< BaseOutputTarget > to_string(std::string &target_string)
Obtain an output target for writing to a string.
void get_plain(T &res)
Read as many bytes from the stream as the type T holds, and put them in the result value of type T...
void get_raw(char *buffer, size_t n)
Read n bytes from the stream and store them in the buffer.
T get_int()
Read an integer number from the stream and return it.
size_t read(char *target, size_t size)
T get_float()
Read a floating point number from the stream and return it.
Input source for reading byte data from an istream.