MFEM  v4.1.0
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
zstr.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------
2 // Copyright 2015 Ontario Institute for Cancer Research
3 // Written by Matei David (matei@cs.toronto.edu)
4 //---------------------------------------------------------
5 
6 // Original version, https://github.com/mateidavid/zstr, distributed under MIT
7 // license. This file is a combination of the zstr.hpp and strict_fstream.hpp
8 // files in the original src/ directory with additional MFEM modifactions.
9 
10 // The MIT License (MIT)
11 //
12 // Copyright (c) 2015 Matei David, Ontario Institute for Cancer Research
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to deal
16 // in the Software without restriction, including without limitation the rights
17 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18 // copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included in all
22 // copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 // SOFTWARE.
31 
32 // Reference:
33 // http://stackoverflow.com/questions/14086417/how-to-write-custom-input-stream-in-c
34 
35 #ifndef __ZSTR_HPP
36 #define __ZSTR_HPP
37 
38 #include <cassert>
39 #include <fstream>
40 #include <sstream>
41 #include <cstring>
42 #include <string>
43 
44 #ifdef MFEM_USE_ZLIB
45 #include <zlib.h>
46 #endif
47 
48 // The section below is a modified content of the src/strict_fstream.hpp
49 // file from https://github.com/mateidavid/zstr.
50 
51 /**
52  * This namespace defines wrappers for std::ifstream, std::ofstream, and
53  * std::fstream objects. The wrappers perform the following steps:
54  * - check the open modes make sense
55  * - check that the call to open() is successful
56  * - (for input streams) check that the opened file is peek-able
57  * - turn on the badbit in the exception mask
58  */
59 namespace strict_fstream
60 {
61 
62 /// Overload of error-reporting function, to enable use with VS.
63 /// Ref: http://stackoverflow.com/a/901316/717706
64 static std::string strerror()
65 {
66  std::string buff(80, '\0');
67 #ifdef _WIN32
68  if (strerror_s(&buff[0], buff.size(), errno) != 0)
69  {
70  buff = "Unknown error";
71  }
72 #elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && ! _GNU_SOURCE || defined(__APPLE__)
73  // XSI-compliant strerror_r()
74  if (strerror_r(errno, &buff[0], buff.size()) != 0)
75  {
76  buff = "Unknown error";
77  }
78 #else
79  // GNU-specific strerror_r()
80  auto p = strerror_r(errno, &buff[0], buff.size());
81  std::string tmp(p, std::strlen(p));
82  std::swap(buff, tmp);
83 #endif
84  buff.resize(buff.find('\0'));
85  return buff;
86 }
87 
88 /// Exception class thrown by failed operations.
89 class Exception
90  : public std::exception
91 {
92 public:
93  Exception(const std::string& msg) : _msg(msg) {}
94  const char * what() const noexcept { return _msg.c_str(); }
95 private:
96  std::string _msg;
97 }; // class Exception
98 
99 namespace detail
100 {
101 
103 {
104  static std::string mode_to_string(std::ios_base::openmode mode)
105  {
106  static const int n_modes = 6;
107  static const std::ios_base::openmode mode_val_v[n_modes] =
108  {
109  std::ios_base::in,
111  std::ios_base::app,
112  std::ios_base::ate,
113  std::ios_base::trunc,
114  std::ios_base::binary
115  };
116 
117  static const char * mode_name_v[n_modes] =
118  {
119  "in",
120  "out",
121  "app",
122  "ate",
123  "trunc",
124  "binary"
125  };
126  std::string res;
127  for (int i = 0; i < n_modes; ++i)
128  {
129  if (mode & mode_val_v[i])
130  {
131  res += (! res.empty()? "|" : "");
132  res += mode_name_v[i];
133  }
134  }
135  if (res.empty()) { res = "none"; }
136  return res;
137  }
138  static void check_mode(const std::string& filename,
139  std::ios_base::openmode mode)
140  {
141  if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out))
142  {
143  throw Exception(std::string("strict_fstream: open('") + filename +
144  "'): mode error: trunc and not out");
145  }
146  else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out))
147  {
148  throw Exception(std::string("strict_fstream: open('") + filename +
149  "'): mode error: app and not out");
150  }
151  else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app))
152  {
153  throw Exception(std::string("strict_fstream: open('") + filename +
154  "'): mode error: trunc and app");
155  }
156  }
157  static void check_open(std::ios * s_p, const std::string& filename,
158  std::ios_base::openmode mode)
159  {
160  if (s_p->fail())
161  {
162  throw Exception(std::string("strict_fstream: open('")
163  + filename + "'," + mode_to_string(mode) + "): open failed: "
164  + strerror());
165  }
166  }
167  static void check_peek(std::istream * is_p, const std::string& filename,
168  std::ios_base::openmode mode)
169  {
170  bool peek_failed = true;
171  try
172  {
173  is_p->peek();
174  peek_failed = is_p->fail();
175  }
176  catch (std::ios_base::failure &e) {}
177  if (peek_failed)
178  {
179  throw Exception(std::string("strict_fstream: open('")
180  + filename + "'," + mode_to_string(mode) + "): peek failed: "
181  + strerror());
182  }
183  is_p->clear();
184  }
185 }; // struct static_method_holder
186 
187 } // namespace detail
188 
189 class ifstream
190  : public std::ifstream
191 {
192 public:
193  ifstream() = default;
194  ifstream(const std::string& filename,
195  std::ios_base::openmode mode = std::ios_base::in)
196  {
197  open(filename, mode);
198  }
199  void open(const std::string& filename,
200  std::ios_base::openmode mode = std::ios_base::in)
201  {
202  mode |= std::ios_base::in;
203  exceptions(std::ios_base::badbit);
205  std::ifstream::open(filename, mode);
206  detail::static_method_holder::check_open(this, filename, mode);
207  detail::static_method_holder::check_peek(this, filename, mode);
208  }
209 }; // class ifstream
210 
211 class ofstream
212  : public std::ofstream
213 {
214 public:
215  ofstream() = default;
216  ofstream(const std::string& filename,
217  std::ios_base::openmode mode = std::ios_base::out)
218  {
219  open(filename, mode);
220  }
221  void open(const std::string& filename,
222  std::ios_base::openmode mode = std::ios_base::out)
223  {
224  mode |= std::ios_base::out;
225  exceptions(std::ios_base::badbit);
227  std::ofstream::open(filename, mode);
228  detail::static_method_holder::check_open(this, filename, mode);
229  }
230 }; // class ofstream
231 
232 class fstream
233  : public std::fstream
234 {
235 public:
236  fstream() = default;
237  fstream(const std::string& filename,
238  std::ios_base::openmode mode = std::ios_base::in)
239  {
240  open(filename, mode);
241  }
242  void open(const std::string& filename,
243  std::ios_base::openmode mode = std::ios_base::in)
244  {
245  if (! (mode & std::ios_base::out)) { mode |= std::ios_base::in; }
246  exceptions(std::ios_base::badbit);
248  std::fstream::open(filename, mode);
249  detail::static_method_holder::check_open(this, filename, mode);
250  detail::static_method_holder::check_peek(this, filename, mode);
251  }
252 }; // class fstream
253 
254 } // namespace strict_fstream
255 
256 
257 // The section below is a modified content of the src/zstr.hpp file from
258 // https://github.com/mateidavid/zstr.
259 
260 namespace zstr
261 {
262 #ifdef MFEM_USE_ZLIB
263 /// Exception class thrown by failed zlib operations.
265  : public std::exception
266 {
267 public:
268  Exception(z_stream *zstrm_p, int ret)
269  : _msg("zlib: ")
270  {
271  switch (ret)
272  {
273  case Z_STREAM_ERROR:
274  _msg += "Z_STREAM_ERROR: ";
275  break;
276  case Z_DATA_ERROR:
277  _msg += "Z_DATA_ERROR: ";
278  break;
279  case Z_MEM_ERROR:
280  _msg += "Z_MEM_ERROR: ";
281  break;
282  case Z_VERSION_ERROR:
283  _msg += "Z_VERSION_ERROR: ";
284  break;
285  case Z_BUF_ERROR:
286  _msg += "Z_BUF_ERROR: ";
287  break;
288  default:
289  std::ostringstream oss;
290  oss << ret;
291  _msg += "[" + oss.str() + "]: ";
292  break;
293  }
294  _msg += zstrm_p->msg;
295  }
296  Exception(const std::string msg) : _msg(msg) {}
297  const char *what() const noexcept { return _msg.c_str(); }
298 
299 private:
300  std::string _msg;
301 }; // class Exception
302 #endif
303 
304 #ifdef MFEM_USE_ZLIB
305 namespace detail
306 {
308  : public z_stream
309 {
310 public:
311  z_stream_wrapper(bool _is_input = true, int _level = Z_DEFAULT_COMPRESSION)
312  : is_input(_is_input)
313  {
314  this->zalloc = Z_NULL;
315  this->zfree = Z_NULL;
316  this->opaque = Z_NULL;
317  int ret;
318  if (is_input)
319  {
320  this->avail_in = 0;
321  this->next_in = Z_NULL;
322  ret = inflateInit2(this, 15 + 32);
323  }
324  else
325  {
326  ret = deflateInit2(this, _level, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
327  }
328  if (ret != Z_OK)
329  {
330  throw Exception(this, ret);
331  }
332  }
334  {
335  if (is_input)
336  {
337  inflateEnd(this);
338  }
339  else
340  {
341  deflateEnd(this);
342  }
343  }
344 
345 private:
346  bool is_input;
347 }; // class z_stream_wrapper
348 
349 } // namespace detail
350 
352  : public std::streambuf
353 {
354 public:
355  istreambuf(std::streambuf *_sbuf_p,
356  std::size_t _buff_size = default_buff_size, bool _auto_detect = true)
357  : sbuf_p(_sbuf_p),
358  zstrm_p(nullptr),
359  buff_size(_buff_size),
360  auto_detect(_auto_detect),
361  auto_detect_run(false),
362  is_text(false)
363  {
364  assert(sbuf_p);
365  in_buff = new char[buff_size];
366  in_buff_start = in_buff;
367  in_buff_end = in_buff;
368  out_buff = new char[buff_size];
369  setg(out_buff, out_buff, out_buff);
370  }
371 
372  istreambuf(const istreambuf &) = delete;
373  istreambuf(istreambuf &&) = default;
374  istreambuf &operator=(const istreambuf &) = delete;
375  istreambuf &operator=(istreambuf &&) = default;
376 
377  virtual ~istreambuf()
378  {
379  delete[] in_buff;
380  delete[] out_buff;
381  if (zstrm_p)
382  {
383  delete zstrm_p;
384  }
385  }
386 
387  virtual std::streambuf::int_type underflow()
388  {
389  if (this->gptr() == this->egptr())
390  {
391  // pointers for free region in output buffer
392  char *out_buff_free_start = out_buff;
393  do
394  {
395  // read more input if none available
396  if (in_buff_start == in_buff_end)
397  {
398  // empty input buffer: refill from the start
399  in_buff_start = in_buff;
400  std::streamsize sz = sbuf_p->sgetn(in_buff, buff_size);
401  in_buff_end = in_buff + sz;
402  if (in_buff_end == in_buff_start)
403  {
404  break;
405  } // end of input
406  }
407  // auto detect if the stream contains text or deflate data
408  if (auto_detect && !auto_detect_run)
409  {
410  auto_detect_run = true;
411  unsigned char b0 = *reinterpret_cast<unsigned char *>(in_buff_start);
412  unsigned char b1 = *reinterpret_cast<unsigned char *>(in_buff_start + 1);
413  // Ref:
414  // http://en.wikipedia.org/wiki/Gzip
415  // http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like
416  is_text = !(in_buff_start + 2 <= in_buff_end && ((b0 == 0x1F &&
417  b1 == 0x8B) // gzip header
418  || (b0 == 0x78 && (b1 == 0x01 // zlib header
419  || b1 == 0x9C || b1 == 0xDA))));
420  }
421  if (is_text)
422  {
423  // simply swap in_buff and out_buff, and adjust pointers
424  assert(in_buff_start == in_buff);
425  std::swap(in_buff, out_buff);
426  out_buff_free_start = in_buff_end;
427  in_buff_start = in_buff;
428  in_buff_end = in_buff;
429  }
430  else
431  {
432  // run inflate() on input
433  if (!zstrm_p)
434  {
435  zstrm_p = new detail::z_stream_wrapper(true);
436  }
437  zstrm_p->next_in = reinterpret_cast<decltype(zstrm_p->next_in)>(in_buff_start);
438  zstrm_p->avail_in = in_buff_end - in_buff_start;
439  zstrm_p->next_out = reinterpret_cast<decltype(zstrm_p->next_out)>
440  (out_buff_free_start);
441  zstrm_p->avail_out = (out_buff + buff_size) - out_buff_free_start;
442  int ret = inflate(zstrm_p, Z_NO_FLUSH);
443  // process return code
444  if (ret != Z_OK && ret != Z_STREAM_END)
445  {
446  throw Exception(zstrm_p, ret);
447  }
448  // update in&out pointers following inflate()
449  in_buff_start = reinterpret_cast<decltype(in_buff_start)>(zstrm_p->next_in);
450  in_buff_end = in_buff_start + zstrm_p->avail_in;
451  out_buff_free_start = reinterpret_cast<decltype(out_buff_free_start)>
452  (zstrm_p->next_out);
453  assert(out_buff_free_start + zstrm_p->avail_out == out_buff + buff_size);
454  // if stream ended, deallocate inflator
455  if (ret == Z_STREAM_END)
456  {
457  delete zstrm_p;
458  zstrm_p = nullptr;
459  }
460  }
461  }
462  while (out_buff_free_start == out_buff);
463  // 2 exit conditions:
464  // - end of input: there might or might not be output available
465  // - out_buff_free_start != out_buff: output available
466  this->setg(out_buff, out_buff, out_buff_free_start);
467  }
468  return this->gptr() == this->egptr()
469  ? traits_type::eof()
470  : traits_type::to_int_type(*this->gptr());
471  }
472 
473 private:
474  std::streambuf *sbuf_p;
475  char *in_buff;
476  char *in_buff_start;
477  char *in_buff_end;
478  char *out_buff;
479  detail::z_stream_wrapper *zstrm_p;
480  std::size_t buff_size;
481  bool auto_detect;
482  bool auto_detect_run;
483  bool is_text;
484 
485  static const std::size_t default_buff_size = (std::size_t)1 << 20;
486 }; // class istreambuf
487 
489  : public std::streambuf
490 {
491 public:
492  ostreambuf(std::streambuf *_sbuf_p,
493  std::size_t _buff_size = default_buff_size, int _level = Z_DEFAULT_COMPRESSION)
494  : sbuf_p(_sbuf_p),
495  zstrm_p(new detail::z_stream_wrapper(false, _level)),
496  buff_size(_buff_size)
497  {
498  assert(sbuf_p);
499  in_buff = new char[buff_size];
500  out_buff = new char[buff_size];
501  setp(in_buff, in_buff + buff_size);
502  }
503 
504  ostreambuf(const ostreambuf &) = delete;
505  ostreambuf(ostreambuf &&) = default;
506  ostreambuf &operator=(const ostreambuf &) = delete;
507  ostreambuf &operator=(ostreambuf &&) = default;
508 
509  int deflate_loop(int flush)
510  {
511  while (true)
512  {
513  zstrm_p->next_out = reinterpret_cast<decltype(zstrm_p->next_out)>(out_buff);
514  zstrm_p->avail_out = buff_size;
515  int ret = deflate(zstrm_p, flush);
516  if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
517  {
518  throw Exception(zstrm_p, ret);
519  }
520  std::streamsize sz = sbuf_p->sputn(out_buff,
521  reinterpret_cast<decltype(out_buff)>(zstrm_p->next_out) - out_buff);
522  if (sz != reinterpret_cast<decltype(out_buff)>(zstrm_p->next_out) - out_buff)
523  {
524  // there was an error in the sink stream
525  return -1;
526  }
527  if (ret == Z_STREAM_END || ret == Z_BUF_ERROR || sz == 0)
528  {
529  break;
530  }
531  }
532  return 0;
533  }
534 
535  virtual ~ostreambuf()
536  {
537  // flush the zlib stream
538  //
539  // NOTE: Errors here (sync() return value not 0) are ignored, because we
540  // cannot throw in a destructor. This mirrors the behaviour of
541  // std::basic_filebuf::~basic_filebuf(). To see an exception on error,
542  // close the ofstream with an explicit call to close(), and do not rely
543  // on the implicit call in the destructor.
544  //
545  sync();
546  delete[] in_buff;
547  delete[] out_buff;
548  delete zstrm_p;
549  }
550  virtual std::streambuf::int_type overflow(std::streambuf::int_type c =
551  traits_type::eof())
552  {
553  zstrm_p->next_in = reinterpret_cast<decltype(zstrm_p->next_in)>(pbase());
554  zstrm_p->avail_in = pptr() - pbase();
555  while (zstrm_p->avail_in > 0)
556  {
557  int r = deflate_loop(Z_NO_FLUSH);
558  if (r != 0)
559  {
560  setp(nullptr, nullptr);
561  return traits_type::eof();
562  }
563  }
564  setp(in_buff, in_buff + buff_size);
565  return traits_type::eq_int_type(c,
566  traits_type::eof())
567  ? traits_type::eof()
568  : sputc(c);
569  }
570  virtual int sync()
571  {
572  // first, call overflow to clear in_buff
573  overflow();
574  if (!pptr())
575  {
576  return -1;
577  }
578  // then, call deflate asking to finish the zlib stream
579  zstrm_p->next_in = nullptr;
580  zstrm_p->avail_in = 0;
581  if (deflate_loop(Z_FINISH) != 0)
582  {
583  return -1;
584  }
585  deflateReset(zstrm_p);
586  return 0;
587  }
588 
589 private:
590  std::streambuf *sbuf_p;
591  char *in_buff;
592  char *out_buff;
593  detail::z_stream_wrapper *zstrm_p;
594  std::size_t buff_size;
595 
596  static const std::size_t default_buff_size = (std::size_t)1 << 20;
597 }; // class ostreambuf
598 
599 class istream
600  : public std::istream
601 {
602 public:
603  istream(std::istream &is)
604  : std::istream(new istreambuf(is.rdbuf()))
605  {
606  exceptions(std::ios_base::badbit);
607  }
608  explicit istream(std::streambuf *sbuf_p)
609  : std::istream(new istreambuf(sbuf_p))
610  {
611  exceptions(std::ios_base::badbit);
612  }
613  virtual ~istream()
614  {
615  delete rdbuf();
616  }
617 }; // class istream
618 
619 class ostream
620  : public std::ostream
621 {
622 public:
623  ostream(std::ostream &os)
624  : std::ostream(new ostreambuf(os.rdbuf()))
625  {
626  exceptions(std::ios_base::badbit);
627  }
628  explicit ostream(std::streambuf *sbuf_p)
629  : std::ostream(new ostreambuf(sbuf_p))
630  {
631  exceptions(std::ios_base::badbit);
632  }
633  virtual ~ostream()
634  {
635  delete rdbuf();
636  }
637 }; // class ostream
638 #endif
639 
640 namespace detail
641 {
642 
643 template <typename FStream_Type>
645 {
646  strict_fstream_holder(const std::string &filename,
647  std::ios_base::openmode mode = std::ios_base::in)
648  : _fs(filename, mode)
649  {
650  }
651  FStream_Type _fs;
652 }; // class strict_fstream_holder
653 
654 } // namespace detail
655 
656 #ifdef MFEM_USE_ZLIB
657 class ifstream
658  : private detail::strict_fstream_holder<strict_fstream::ifstream>,
659  public std::istream
660 {
661 public:
662  explicit ifstream(const std::string &filename,
663  std::ios_base::openmode mode = std::ios_base::in)
664  : detail::strict_fstream_holder<strict_fstream::ifstream>(filename, mode),
665  std::istream(new istreambuf(_fs.rdbuf()))
666  {
667  exceptions(std::ios_base::badbit);
668  }
669  virtual ~ifstream()
670  {
671  if (rdbuf())
672  {
673  delete rdbuf();
674  }
675  }
676 }; // class ifstream
677 
678 class ofstream
679  : private detail::strict_fstream_holder<strict_fstream::ofstream>,
680  public std::ostream
681 {
682 public:
683  explicit ofstream(const std::string &filename,
684  std::ios_base::openmode mode = std::ios_base::out)
685  : detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
686  mode | std::ios_base::binary),
687  std::ostream(new ostreambuf(_fs.rdbuf()))
688  {
689  exceptions(std::ios_base::badbit);
690  }
691  virtual ~ofstream()
692  {
693  if (rdbuf())
694  {
695  delete rdbuf();
696  }
697  }
698 }; // class ofstream
699 #endif
700 
701 } // namespace zstr
702 
703 
704 // The section below contains MFEM-specific additions.
705 
706 namespace mfem
707 {
708 
710  : private zstr::detail::strict_fstream_holder<strict_fstream::ofstream>,
711  public std::ostream
712 {
713 public:
714  explicit ofgzstream(const std::string &filename,
715  bool compression = false)
716  : zstr::detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
717  std::ios_base::binary),
718  std::ostream(nullptr)
719  {
720 #ifdef MFEM_USE_ZLIB
721  if (compression)
722  {
723  strbuf = new zstr::ostreambuf(_fs.rdbuf());
724  rdbuf(strbuf);
725  }
726  else
727 #endif
728  {
729  rdbuf(_fs.rdbuf());
730  }
731  exceptions(std::ios_base::badbit);
732  }
733 
734  explicit ofgzstream(const std::string &filename,
735  char const *open_mode_chars)
736  : zstr::detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
737  std::ios_base::binary),
738  std::ostream(nullptr)
739  {
740 #ifdef MFEM_USE_ZLIB
741  // If open_mode_chars contains any combination of open mode chars
742  // containing the 'z' char, compression is enabled. This preserves the
743  // behavior of the old interface but ignores the choice of the compression
744  // level (it is always set to 6).
745  if (std::string(open_mode_chars).find('z') != std::string::npos)
746  {
747  strbuf = new zstr::ostreambuf(_fs.rdbuf());
748  rdbuf(strbuf);
749  }
750  else
751 #endif
752  {
753  rdbuf(_fs.rdbuf());
754  }
755  exceptions(std::ios_base::badbit);
756  }
757 
758  virtual ~ofgzstream()
759  {
760  delete strbuf;
761  }
762 
763  std::streambuf *strbuf = nullptr;
764 };
765 
767  : private zstr::detail::strict_fstream_holder<strict_fstream::ifstream>,
768  public std::istream
769 {
770 public:
771  explicit ifgzstream(const std::string &filename)
772  : zstr::detail::strict_fstream_holder<strict_fstream::ifstream>(filename,
773  std::ios_base::in),
774  std::istream(nullptr)
775  {
776 #ifdef MFEM_USE_ZLIB
777  strbuf = new zstr::istreambuf(_fs.rdbuf());
778  rdbuf(strbuf);
779 #else
780  rdbuf(_fs.rdbuf());
781 #endif
782  exceptions(std::ios_base::badbit);
783  }
784 
785  virtual ~ifgzstream()
786  {
787  delete strbuf;
788  }
789 
790  std::streambuf *strbuf = nullptr;
791 };
792 
793 /// Input file stream that remembers the input file name (useful for example
794 /// when reading NetCDF meshes) and supports optional zlib decompression.
796 {
797 public:
798  named_ifgzstream(const std::string &mesh_name) : ifgzstream(mesh_name),
799  filename(mesh_name) {}
800 
801  const std::string filename;
802 };
803 
804 } // namespace mfem
805 
806 #endif
static void check_peek(std::istream *is_p, const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:167
const char * what() const noexcept
Definition: zstr.hpp:297
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:216
std::streambuf * strbuf
Definition: zstr.hpp:763
const char * what() const noexcept
Definition: zstr.hpp:94
virtual std::streambuf::int_type underflow()
Definition: zstr.hpp:387
virtual ~ifstream()
Definition: zstr.hpp:669
virtual int sync()
Definition: zstr.hpp:570
ifgzstream(const std::string &filename)
Definition: zstr.hpp:771
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:199
istream(std::istream &is)
Definition: zstr.hpp:603
ostreambuf(std::streambuf *_sbuf_p, std::size_t _buff_size=default_buff_size, int _level=Z_DEFAULT_COMPRESSION)
Definition: zstr.hpp:492
Exception class thrown by failed zlib operations.
Definition: zstr.hpp:264
fstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:237
std::streambuf * strbuf
Definition: zstr.hpp:790
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:194
virtual ~istream()
Definition: zstr.hpp:613
Exception(z_stream *zstrm_p, int ret)
Definition: zstr.hpp:268
named_ifgzstream(const std::string &mesh_name)
Definition: zstr.hpp:798
virtual ~ostream()
Definition: zstr.hpp:633
virtual ~ostreambuf()
Definition: zstr.hpp:535
ostreambuf & operator=(const ostreambuf &)=delete
ostream(std::streambuf *sbuf_p)
Definition: zstr.hpp:628
Exception(const std::string &msg)
Definition: zstr.hpp:93
int deflate_loop(int flush)
Definition: zstr.hpp:509
z_stream_wrapper(bool _is_input=true, int _level=Z_DEFAULT_COMPRESSION)
Definition: zstr.hpp:311
static void check_mode(const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:138
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:221
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:242
ostream(std::ostream &os)
Definition: zstr.hpp:623
istreambuf & operator=(const istreambuf &)=delete
virtual ~istreambuf()
Definition: zstr.hpp:377
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:662
virtual std::streambuf::int_type overflow(std::streambuf::int_type c=traits_type::eof())
Definition: zstr.hpp:550
virtual ~ifgzstream()
Definition: zstr.hpp:785
ofgzstream(const std::string &filename, bool compression=false)
Definition: zstr.hpp:714
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:683
static std::string mode_to_string(std::ios_base::openmode mode)
Definition: zstr.hpp:104
Exception(const std::string msg)
Definition: zstr.hpp:296
istream(std::streambuf *sbuf_p)
Definition: zstr.hpp:608
virtual ~ofstream()
Definition: zstr.hpp:691
strict_fstream_holder(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:646
istreambuf(std::streambuf *_sbuf_p, std::size_t _buff_size=default_buff_size, bool _auto_detect=true)
Definition: zstr.hpp:355
const std::string filename
Definition: zstr.hpp:801
Exception class thrown by failed operations.
Definition: zstr.hpp:89
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition: globals.hpp:66
virtual ~ofgzstream()
Definition: zstr.hpp:758
ofgzstream(const std::string &filename, char const *open_mode_chars)
Definition: zstr.hpp:734
static void check_open(std::ios *s_p, const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:157