zfstream.h
Go to the documentation of this file.
1 #ifndef _utl_zfstream_h_
2 #define _utl_zfstream_h_
3 
4 #include <utl/zstream.h>
5 #include <boost/iostreams/positioning.hpp>
6 #include <boost/iostreams/optimal_buffer_size.hpp>
7 #include <boost/shared_ptr.hpp>
8 #include <boost/iostreams/stream.hpp>
9 #include <boost/filesystem.hpp>
10 #include <fstream>
11 
12 
13 namespace utl {
14 
15  namespace detail {
16 
17  inline
18  bool
19  is_automatic(const zip_type ztype)
20  {
21  return static_cast<int>(ztype) & static_cast<int>(zip_type::automatic);
22  }
23 
24 
25  inline
26  zip_type
27  deduce_zip_type(const std::string& filename, const zip_type ztype)
28  {
29  if (!is_automatic(ztype))
30  return ztype;
31  const auto ext = boost::filesystem::extension(filename);
32  if (ext == ".bz2")
33  return zip_type::bzip2;
34  if (ext == ".gz")
35  return zip_type::gzip;
36  if (ext == ".xz")
37  return zip_type::xzip;
38  return zip_type::none;
39  }
40 
41  }
42 
43 
45  private:
46  struct impl {
47  void
48  init()
49  {
50  ++_n_open_calls;
51  _stream.close();
52  _stream.open(_filename.c_str(), _openmode);
53  _position = 0;
55  }
56 
57  unsigned int _n_open_calls = 0;
58  std::string _filename;
60  std::ios_base::openmode _openmode;
61  std::ifstream _stream;
62  std::size_t _position;
64  };
65 
66  public:
67  typedef char char_type;
68  struct category :
69  boost::iostreams::input_seekable,
70  boost::iostreams::device_tag,
71  boost::iostreams::closable_tag
72  { };
73 
75 
76  zfstream_source(const std::string& filename, const zip_type ztype)
77  { open(filename, ztype); }
78 
79  zfstream_source(const std::string& filename,
80  const std::ios_base::openmode openmode = std::ios_base::in,
81  const zip_type ztype = zip_type::automatic)
82  { open(filename, openmode, ztype); }
83 
84  void open(const std::string& filename, const zip_type ztype)
85  { open(filename, std::ios_base::in, ztype); }
86 
87  void
88  open(const std::string& filename,
89  const std::ios_base::openmode openmode = std::ios_base::in,
90  const zip_type ztype = zip_type::automatic)
91  {
92  _impl.reset(new impl);
93  _impl->_filename = filename;
94  _impl->_zip_type = detail::deduce_zip_type(filename, ztype);
95  _impl->_openmode = (_impl->_zip_type == zip_type::none ? openmode : std::ios_base::binary);
96  _impl->init();
97  }
98 
99  void close() { _impl.reset(); }
100 
101  std::streamsize
102  read(char* const s, const std::streamsize n)
103  {
104  const auto size = boost::iostreams::read(_impl->_filter, s, n);
105  if (size > 0)
106  _impl->_position += size;
107  return size;
108  }
109 
110  boost::iostreams::stream_offset
111  seek(const boost::iostreams::stream_offset off, const std::ios_base::seekdir way)
112  {
113  const auto old = _impl->_position;
114  // determine new value of fPosition
115  std::size_t next;
116  if (way == std::ios_base::beg) {
117  if (off < 0)
118  throw std::ios_base::failure("bad seek offset");
119  next = off;
120  } else if (way == std::ios_base::cur)
121  next = old + off;
122  else
123  throw std::ios_base::failure("bad seek direction");
124 
125  if (next == old)
126  return _impl->_position;
127 
128  std::size_t skip;
129 
130  if (next > old)
131  skip = next - old;
132  else {
133  _impl->_filter.reset();
134  _impl->_stream.close();
135  _impl->init();
136  skip = next;
137  }
138 
139  const std::streamsize chunk = boost::iostreams::optimal_buffer_size(_impl->_filter);
140  char buff[chunk];
141 
142  for (std::size_t i = 0, n = skip/chunk; i < n; ++i)
143  if (read(buff, chunk) != chunk)
144  return -1; // EOF
145 
146  const std::streamsize rest = skip % chunk;
147  if (rest && read(buff, rest) != rest)
148  return -1; // EOF
149 
150  if (_impl->_position != next)
151  throw std::ios_base::failure("bad seek result");
152 
153  return _impl->_position;
154  }
155 
156  std::size_t tellg() const { return _impl ? _impl->_position : 0; }
157 
158  int get_n_open_calls() const { return _impl ? _impl->_n_open_calls : -1; }
159 
160  bool is_complete() const { return _impl && _impl->_filter.is_complete(); }
161 
162  zip_type get_zip_type() const { return _impl->_zip_type; }
163 
164  private:
165  boost::shared_ptr<impl> _impl;
166  };
167 
168 
169  /*
170  \class zifstream zifstream.h "utl/zfstream.h"
171 
172  NB: the interface is the same as the usual std::istream type
173  in order for the class to be used as a drop-in replacement for
174  std::ifstream.
175 
176  Usage:
177  \code
178  {
179  zifstream ifs("foo.bz2");
180  string h;
181  ifs >> h;
182  int i;
183  ifs >> i;
184  }
185  \endcode
186 
187  \author Darko Veberic
188  \date 12 May 2010
189  \date 20 Oct 2011 redesign
190  */
191 
192  class zifstream : public boost::iostreams::stream<zfstream_source> {
193  private:
194  typedef boost::iostreams::stream<zfstream_source> base;
195 
196  public:
198 
199  zifstream(const std::string& filename, const zip_type ztype)
200  : base(zfstream_source(filename, ztype)) { }
201 
202  zifstream(const std::string& filename,
203  const std::ios_base::openmode om = std::ios_base::in,
204  const zip_type ztype = zip_type::automatic)
205  : base(zfstream_source(filename, om, ztype)) { }
206 
207  void open(const std::string& filename, const zip_type ztype)
208  { (**this).open(filename, std::ios_base::in, ztype); }
209 
210  void open(const std::string& filename,
211  const std::ios_base::openmode om = std::ios_base::in,
212  const zip_type ztype = zip_type::automatic)
213  { (**this).open(filename, om, ztype); }
214 
215  int get_n_open_calls() { return this->is_open() ? (**this).get_n_open_calls() : -1; }
216 
217  bool is_complete() { return this->is_open() && (**this).is_complete(); }
218 
219  zip_type get_zip_type() { return (**this).get_zip_type(); }
220  };
221 
222 
223  //
224 
225 
227  private:
228  struct impl {
229  impl(const std::string& filename,
230  const std::ios_base::openmode om,
231  const zip_type ztype)
232  : _stream(filename.c_str(), om), _filter(_stream, ztype), _zip_type(ztype) { }
233  std::ofstream _stream;
236  };
237 
238  public:
239  typedef char char_type;
240  struct category :
241  boost::iostreams::output,
242  boost::iostreams::device_tag,
243  boost::iostreams::closable_tag,
244  boost::iostreams::flushable_tag
245  { };
246 
248 
249  zfstream_sink(const std::string& filename, const zip_type ztype)
250  { open(filename, ztype); }
251 
252  zfstream_sink(const std::string& filename,
253  const std::ios_base::openmode om = std::ios_base::out,
254  const zip_type ztype = zip_type::automatic)
255  { open(filename, om, ztype); }
256 
257  void open(const std::string& filename, const zip_type ztype)
258  { open(filename, std::ios_base::out, ztype); }
259 
260  void
261  open(const std::string& filename,
262  const std::ios_base::openmode omode = std::ios_base::out,
264  {
265  ztype = detail::deduce_zip_type(filename, ztype);
266  const std::ios_base::openmode om =
267  (ztype == zip_type::none ? omode : std::ios_base::binary);
268  _impl.reset(new impl(filename, om, ztype));
269  }
270 
271  void close() { _impl.reset(); }
272 
273  std::streamsize write(const char* const s, const std::streamsize n)
274  { return boost::iostreams::write(_impl->_filter, s, n); }
275 
276  bool flush() { return bool(_impl->_filter.flush()); }
277 
278  bool is_complete() const { return _impl && _impl->_filter.is_complete(); }
279 
280  zip_type get_zip_type() const { return _impl->_zip_type; }
281 
282  private:
283  boost::shared_ptr<impl> _impl;
284  };
285 
286 
287  /*
288  \class zofstream zfstream.h "utl/zfstream.h"
289 
290  NB: the interface is the same as the usual std::ostream type
291  in order for the class to be used as a drop-in replacement for
292  std::ofstream.
293 
294  Usage:
295  \code
296  {
297  zofstream ofs("foo.bz2");
298  ofs << "hallo " << 13 << endl;
299  }
300  \endcode
301 
302  \author Darko Veberic
303  \date 12 May 2010
304  \date 20 Oct 2011 redesign
305  */
306 
307  class zofstream : public boost::iostreams::stream<zfstream_sink> {
308  private:
309  typedef boost::iostreams::stream<zfstream_sink> base;
310 
311  public:
313 
314  zofstream(const std::string& filename, const zip_type ztype)
315  : base(zfstream_sink(filename, ztype)) { }
316 
317  zofstream(const std::string& filename,
318  const std::ios_base::openmode omode = std::ios_base::out,
319  const zip_type ztype = zip_type::automatic)
320  : base(zfstream_sink(filename, omode, ztype)) { }
321 
322  void open(const std::string& filename, const zip_type ztype)
323  { (**this).open(filename, std::ios_base::out, ztype); }
324 
325  void open(const std::string& filename,
326  const std::ios_base::openmode omode = std::ios_base::out,
327  const zip_type ztype = zip_type::automatic)
328  { (**this).open(filename, omode, ztype); }
329 
330  bool is_complete() { return this->is_open() && (**this).is_complete(); }
331 
332  zip_type get_zip_type() { return (**this).get_zip_type(); }
333  };
334 
335 
336 }
337 
338 
339 #endif
bool is_complete()
Definition: zfstream.h:217
std::ofstream _stream
Definition: zfstream.h:233
int get_n_open_calls() const
Definition: zfstream.h:158
zip_type get_zip_type()
Definition: zfstream.h:219
void open(const std::string &filename, const std::ios_base::openmode omode=std::ios_base::out, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:325
zfstream_sink(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:249
std::ios_base::openmode _openmode
Definition: zfstream.h:60
unsigned int _n_open_calls
Definition: zfstream.h:57
boost::iostreams::stream_offset seek(const boost::iostreams::stream_offset off, const std::ios_base::seekdir way)
Definition: zfstream.h:111
boost::iostreams::stream< zfstream_source > base
Definition: zfstream.h:194
zifstream(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:199
zfstream_sink(const std::string &filename, const std::ios_base::openmode om=std::ios_base::out, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:252
zip_type get_zip_type()
Definition: zfstream.h:332
void open(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:207
zfstream_source(const std::string &filename, const std::ios_base::openmode openmode=std::ios_base::in, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:79
vector< t2list > out
output of the algorithm: a list of clusters
Definition: XbAlgo.cc:32
bool is_complete()
Definition: zfstream.h:330
detail::zifilter _filter
Definition: zfstream.h:63
bool is_complete() const
Definition: zfstream.h:160
void push(stream &strm, const zip_type ztype)
Definition: zstream.h:45
std::ifstream _stream
Definition: zfstream.h:61
zip_type deduce_zip_type(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:27
std::size_t tellg() const
Definition: zfstream.h:156
Iterator next(Iterator it)
bool is_complete() const
Definition: zfstream.h:278
boost::shared_ptr< impl > _impl
Definition: zfstream.h:283
constexpr double s
Definition: AugerUnits.h:163
int get_n_open_calls()
Definition: zfstream.h:215
void open(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:84
void open(const std::string &filename, const std::ios_base::openmode omode=std::ios_base::out, zip_type ztype=zip_type::automatic)
Definition: zfstream.h:261
zofstream(const std::string &filename, const std::ios_base::openmode omode=std::ios_base::out, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:317
void open(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:257
impl(const std::string &filename, const std::ios_base::openmode om, const zip_type ztype)
Definition: zfstream.h:229
void open(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:322
zip_type get_zip_type() const
Definition: zfstream.h:280
std::streamsize read(char *const s, const std::streamsize n)
Definition: zfstream.h:102
zofstream(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:314
bool is_automatic(const zip_type ztype)
Definition: zfstream.h:19
zip_type get_zip_type() const
Definition: zfstream.h:162
zfstream_source(const std::string &filename, const zip_type ztype)
Definition: zfstream.h:76
char * filename
Definition: dump1090.h:266
detail::zofilter _filter
Definition: zfstream.h:234
boost::shared_ptr< impl > _impl
Definition: zfstream.h:165
void open(const std::string &filename, const std::ios_base::openmode om=std::ios_base::in, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:210
std::streamsize write(const char *const s, const std::streamsize n)
Definition: zfstream.h:273
zifstream(const std::string &filename, const std::ios_base::openmode om=std::ios_base::in, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:202
boost::iostreams::stream< zfstream_sink > base
Definition: zfstream.h:309
zip_type
Definition: zstream.h:18
void open(const std::string &filename, const std::ios_base::openmode openmode=std::ios_base::in, const zip_type ztype=zip_type::automatic)
Definition: zfstream.h:88

, generated on Tue Sep 26 2023.