MFEM  v4.5.1
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 modifications.
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 // Overloaded error checks to handle POSIX and GNU strerror_r
63 inline char* check_strerror_r(int r, char* buff, size_t buff_size)
64 {
65  if (r) { snprintf(buff, buff_size, "unknown error: %d", r); }
66  return buff;
67 }
68 
69 inline char* check_strerror_r(char* r, char*, int)
70 {
71  return r;
72 }
73 
74 /// Overload of error-reporting function, to enable use with VS.
75 /// Ref: http://stackoverflow.com/a/901316/717706
76 static std::string strerror()
77 {
78  std::string buff(80, '\0');
79 #ifdef _WIN32
80  if (strerror_s(&buff[0], buff.size(), errno) != 0)
81  {
82  buff = "Unknown error";
83  }
84 #else
85  char* p = check_strerror_r(strerror_r(errno, &buff[0], buff.size()), &buff[0],
86  buff.size());
87  std::string tmp(p, std::strlen(p));
88  std::swap(buff, tmp);
89 #endif
90  buff.resize(buff.find('\0'));
91  return buff;
92 }
93 
94 /// Exception class thrown by failed operations.
95 class Exception
96  : public std::exception
97 {
98 public:
99  Exception(const std::string& msg_) : msg(msg_) {}
100  const char * what() const noexcept { return msg.c_str(); }
101 private:
102  std::string msg;
103 }; // class Exception
104 
105 namespace detail
106 {
107 
109 {
110  static std::string mode_to_string(std::ios_base::openmode mode)
111  {
112  static const int n_modes = 6;
113  static const std::ios_base::openmode mode_val_v[n_modes] =
114  {
115  std::ios_base::in,
117  std::ios_base::app,
118  std::ios_base::ate,
119  std::ios_base::trunc,
120  std::ios_base::binary
121  };
122 
123  static const char * mode_name_v[n_modes] =
124  {
125  "in",
126  "out",
127  "app",
128  "ate",
129  "trunc",
130  "binary"
131  };
132  std::string res;
133  for (int i = 0; i < n_modes; ++i)
134  {
135  if (mode & mode_val_v[i])
136  {
137  res += (! res.empty()? "|" : "");
138  res += mode_name_v[i];
139  }
140  }
141  if (res.empty()) { res = "none"; }
142  return res;
143  }
144  static void check_mode(const std::string& filename,
145  std::ios_base::openmode mode)
146  {
147  if ((mode & std::ios_base::trunc) && ! (mode & std::ios_base::out))
148  {
149  throw Exception(std::string("strict_fstream: open('") + filename +
150  "'): mode error: trunc and not out");
151  }
152  else if ((mode & std::ios_base::app) && ! (mode & std::ios_base::out))
153  {
154  throw Exception(std::string("strict_fstream: open('") + filename +
155  "'): mode error: app and not out");
156  }
157  else if ((mode & std::ios_base::trunc) && (mode & std::ios_base::app))
158  {
159  throw Exception(std::string("strict_fstream: open('") + filename +
160  "'): mode error: trunc and app");
161  }
162  }
163  static void check_open(std::ios * s_p, const std::string& filename,
164  std::ios_base::openmode mode)
165  {
166  if (s_p->fail())
167  {
168  throw Exception(std::string("strict_fstream: open('")
169  + filename + "'," + mode_to_string(mode) + "): open failed: "
170  + strerror());
171  }
172  }
173  static void check_peek(std::istream * is_p, const std::string& filename,
174  std::ios_base::openmode mode)
175  {
176  bool peek_failed = true;
177  try
178  {
179  is_p->peek();
180  peek_failed = is_p->fail();
181  }
182  catch (std::ios_base::failure&) {}
183  if (peek_failed)
184  {
185  throw Exception(std::string("strict_fstream: open('")
186  + filename + "'," + mode_to_string(mode) + "): peek failed: "
187  + strerror());
188  }
189  is_p->clear();
190  }
191 }; // struct static_method_holder
192 
193 } // namespace detail
194 
195 class ifstream
196  : public std::ifstream
197 {
198 public:
199  ifstream() = default;
200  ifstream(const std::string& filename,
201  std::ios_base::openmode mode = std::ios_base::in)
202  {
203  open(filename, mode);
204  }
205  void open(const std::string& filename,
206  std::ios_base::openmode mode = std::ios_base::in)
207  {
208  mode |= std::ios_base::in;
209  exceptions(std::ios_base::badbit);
210  // detail::static_method_holder::check_mode(filename, mode);
211  std::ifstream::open(filename, mode);
212  // detail::static_method_holder::check_open(this, filename, mode);
213  // detail::static_method_holder::check_peek(this, filename, mode);
214  }
215 }; // class ifstream
216 
217 class ofstream
218  : public std::ofstream
219 {
220 public:
221  ofstream() = default;
222  ofstream(const std::string& filename,
223  std::ios_base::openmode mode = std::ios_base::out)
224  {
225  open(filename, mode);
226  }
227  void open(const std::string& filename,
228  std::ios_base::openmode mode = std::ios_base::out)
229  {
230  mode |= std::ios_base::out;
231  exceptions(std::ios_base::badbit);
232  // detail::static_method_holder::check_mode(filename, mode);
233  std::ofstream::open(filename, mode);
234  // detail::static_method_holder::check_open(this, filename, mode);
235  }
236 }; // class ofstream
237 
238 class fstream
239  : public std::fstream
240 {
241 public:
242  fstream() = default;
243  fstream(const std::string& filename,
244  std::ios_base::openmode mode = std::ios_base::in)
245  {
246  open(filename, mode);
247  }
248  void open(const std::string& filename,
249  std::ios_base::openmode mode = std::ios_base::in)
250  {
251  if (! (mode & std::ios_base::out)) { mode |= std::ios_base::in; }
252  exceptions(std::ios_base::badbit);
253  // detail::static_method_holder::check_mode(filename, mode);
254  std::fstream::open(filename, mode);
255  // detail::static_method_holder::check_open(this, filename, mode);
256  // detail::static_method_holder::check_peek(this, filename, mode);
257  }
258 }; // class fstream
259 
260 } // namespace strict_fstream
261 
262 
263 // The section below is a modified content of the src/zstr.hpp file from
264 // https://github.com/mateidavid/zstr.
265 
266 namespace zstr
267 {
268 #ifdef MFEM_USE_ZLIB
269 /// Exception class thrown by failed zlib operations.
271  : public std::exception
272 {
273 public:
274  Exception(z_stream *zstrm_p, int ret)
275  : msg("zlib: ")
276  {
277  switch (ret)
278  {
279  case Z_STREAM_ERROR:
280  msg += "Z_STREAM_ERROR: ";
281  break;
282  case Z_DATA_ERROR:
283  msg += "Z_DATA_ERROR: ";
284  break;
285  case Z_MEM_ERROR:
286  msg += "Z_MEM_ERROR: ";
287  break;
288  case Z_VERSION_ERROR:
289  msg += "Z_VERSION_ERROR: ";
290  break;
291  case Z_BUF_ERROR:
292  msg += "Z_BUF_ERROR: ";
293  break;
294  default:
295  std::ostringstream oss;
296  oss << ret;
297  msg += "[" + oss.str() + "]: ";
298  break;
299  }
300  msg += zstrm_p->msg;
301  }
302  Exception(const std::string msg_) : msg(msg_) {}
303  const char *what() const noexcept { return msg.c_str(); }
304 
305 private:
306  std::string msg;
307 }; // class Exception
308 #endif
309 
310 #ifdef MFEM_USE_ZLIB
311 namespace detail
312 {
314  : public z_stream
315 {
316 public:
317  z_stream_wrapper(bool is_input_ = true, int level_ = Z_DEFAULT_COMPRESSION)
318  : is_input(is_input_)
319  {
320  this->zalloc = Z_NULL;
321  this->zfree = Z_NULL;
322  this->opaque = Z_NULL;
323  int ret;
324  if (is_input)
325  {
326  this->avail_in = 0;
327  this->next_in = Z_NULL;
328  ret = inflateInit2(this, 15 + 32);
329  }
330  else
331  {
332  ret = deflateInit2(this, level_, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
333  }
334  if (ret != Z_OK)
335  {
336  throw Exception(this, ret);
337  }
338  }
340  {
341  if (is_input)
342  {
343  inflateEnd(this);
344  }
345  else
346  {
347  deflateEnd(this);
348  }
349  }
350 
351 private:
352  bool is_input;
353 }; // class z_stream_wrapper
354 
355 } // namespace detail
356 
358  : public std::streambuf
359 {
360 public:
361  istreambuf(std::streambuf *sbuf_p_,
362  std::size_t buff_size_ = default_buff_size, bool auto_detect_ = true)
363  : sbuf_p(sbuf_p_),
364  zstrm_p(nullptr),
365  buff_size(buff_size_),
366  auto_detect(auto_detect_),
367  auto_detect_run(false),
368  is_text(false)
369  {
370  assert(sbuf_p);
371  in_buff = new char[buff_size];
372  in_buff_start = in_buff;
373  in_buff_end = in_buff;
374  out_buff = new char[buff_size];
375  setg(out_buff, out_buff, out_buff);
376  }
377 
378  istreambuf(const istreambuf &) = delete;
379  istreambuf(istreambuf &&) = default;
380  istreambuf &operator=(const istreambuf &) = delete;
381  istreambuf &operator=(istreambuf &&) = default;
382 
383  virtual ~istreambuf()
384  {
385  delete[] in_buff;
386  delete[] out_buff;
387  if (zstrm_p)
388  {
389  delete zstrm_p;
390  }
391  }
392 
393  virtual std::streambuf::int_type underflow()
394  {
395  if (this->gptr() == this->egptr())
396  {
397  // pointers for free region in output buffer
398  char *out_buff_free_start = out_buff;
399  do
400  {
401  // read more input if none available
402  if (in_buff_start == in_buff_end)
403  {
404  // empty input buffer: refill from the start
405  in_buff_start = in_buff;
406  std::streamsize sz = sbuf_p->sgetn(in_buff, buff_size);
407  in_buff_end = in_buff + sz;
408  if (in_buff_end == in_buff_start)
409  {
410  break;
411  } // end of input
412  }
413  // auto detect if the stream contains text or deflate data
414  if (auto_detect && !auto_detect_run)
415  {
416  auto_detect_run = true;
417  unsigned char b0 = *reinterpret_cast<unsigned char *>(in_buff_start);
418  unsigned char b1 = *reinterpret_cast<unsigned char *>(in_buff_start + 1);
419  // Ref:
420  // http://en.wikipedia.org/wiki/Gzip
421  // http://stackoverflow.com/questions/9050260/what-does-a-zlib-header-look-like
422  is_text = !(in_buff_start + 2 <= in_buff_end && ((b0 == 0x1F &&
423  b1 == 0x8B) // gzip header
424  || (b0 == 0x78 && (b1 == 0x01 // zlib header
425  || b1 == 0x9C || b1 == 0xDA))));
426  }
427  if (is_text)
428  {
429  // simply swap in_buff and out_buff, and adjust pointers
430  assert(in_buff_start == in_buff);
431  std::swap(in_buff, out_buff);
432  out_buff_free_start = in_buff_end;
433  in_buff_start = in_buff;
434  in_buff_end = in_buff;
435  }
436  else
437  {
438  // run inflate() on input
439  if (!zstrm_p)
440  {
441  zstrm_p = new detail::z_stream_wrapper(true);
442  }
443  zstrm_p->next_in = reinterpret_cast<decltype(zstrm_p->next_in)>(in_buff_start);
444  zstrm_p->avail_in = in_buff_end - in_buff_start;
445  zstrm_p->next_out = reinterpret_cast<decltype(zstrm_p->next_out)>
446  (out_buff_free_start);
447  zstrm_p->avail_out = (out_buff + buff_size) - out_buff_free_start;
448  int ret = inflate(zstrm_p, Z_NO_FLUSH);
449  // process return code
450  if (ret != Z_OK && ret != Z_STREAM_END)
451  {
452  throw Exception(zstrm_p, ret);
453  }
454  // update in&out pointers following inflate()
455  in_buff_start = reinterpret_cast<decltype(in_buff_start)>(zstrm_p->next_in);
456  in_buff_end = in_buff_start + zstrm_p->avail_in;
457  out_buff_free_start = reinterpret_cast<decltype(out_buff_free_start)>
458  (zstrm_p->next_out);
459  assert(out_buff_free_start + zstrm_p->avail_out == out_buff + buff_size);
460  // if stream ended, deallocate inflator
461  if (ret == Z_STREAM_END)
462  {
463  delete zstrm_p;
464  zstrm_p = nullptr;
465  }
466  }
467  }
468  while (out_buff_free_start == out_buff);
469  // 2 exit conditions:
470  // - end of input: there might or might not be output available
471  // - out_buff_free_start != out_buff: output available
472  this->setg(out_buff, out_buff, out_buff_free_start);
473  }
474  return this->gptr() == this->egptr()
475  ? traits_type::eof()
476  : traits_type::to_int_type(*this->gptr());
477  }
478 
479 private:
480  std::streambuf *sbuf_p;
481  char *in_buff;
482  char *in_buff_start;
483  char *in_buff_end;
484  char *out_buff;
485  detail::z_stream_wrapper *zstrm_p;
486  std::size_t buff_size;
487  bool auto_detect;
488  bool auto_detect_run;
489  bool is_text;
490 
491  static const std::size_t default_buff_size = (std::size_t)1 << 20;
492 }; // class istreambuf
493 
495  : public std::streambuf
496 {
497 public:
498  ostreambuf(std::streambuf *sbuf_p_,
499  std::size_t buff_size_ = default_buff_size, int level_ = Z_DEFAULT_COMPRESSION)
500  : sbuf_p(sbuf_p_),
501  zstrm_p(new detail::z_stream_wrapper(false, level_)),
502  buff_size(buff_size_)
503  {
504  assert(sbuf_p);
505  in_buff = new char[buff_size];
506  out_buff = new char[buff_size];
507  setp(in_buff, in_buff + buff_size);
508  }
509 
510  ostreambuf(const ostreambuf &) = delete;
511  ostreambuf(ostreambuf &&) = default;
512  ostreambuf &operator=(const ostreambuf &) = delete;
513  ostreambuf &operator=(ostreambuf &&) = default;
514 
515  int deflate_loop(int flush)
516  {
517  while (true)
518  {
519  zstrm_p->next_out = reinterpret_cast<decltype(zstrm_p->next_out)>(out_buff);
520  zstrm_p->avail_out = buff_size;
521  int ret = deflate(zstrm_p, flush);
522  if (ret != Z_OK && ret != Z_STREAM_END && ret != Z_BUF_ERROR)
523  {
524  throw Exception(zstrm_p, ret);
525  }
526  std::streamsize sz = sbuf_p->sputn(out_buff,
527  reinterpret_cast<decltype(out_buff)>(zstrm_p->next_out) - out_buff);
528  if (sz != reinterpret_cast<decltype(out_buff)>(zstrm_p->next_out) - out_buff)
529  {
530  // there was an error in the sink stream
531  return -1;
532  }
533  if (ret == Z_STREAM_END || ret == Z_BUF_ERROR || sz == 0)
534  {
535  break;
536  }
537  }
538  return 0;
539  }
540 
541  virtual ~ostreambuf()
542  {
543  // flush the zlib stream
544  //
545  // NOTE: Errors here (sync() return value not 0) are ignored, because we
546  // cannot throw in a destructor. This mirrors the behaviour of
547  // std::basic_filebuf::~basic_filebuf(). To see an exception on error,
548  // close the ofstream with an explicit call to close(), and do not rely
549  // on the implicit call in the destructor.
550  //
551  sync();
552  delete[] in_buff;
553  delete[] out_buff;
554  delete zstrm_p;
555  }
556  virtual std::streambuf::int_type overflow(std::streambuf::int_type c =
557  traits_type::eof())
558  {
559  zstrm_p->next_in = reinterpret_cast<decltype(zstrm_p->next_in)>(pbase());
560  zstrm_p->avail_in = pptr() - pbase();
561  while (zstrm_p->avail_in > 0)
562  {
563  int r = deflate_loop(Z_NO_FLUSH);
564  if (r != 0)
565  {
566  setp(nullptr, nullptr);
567  return traits_type::eof();
568  }
569  }
570  setp(in_buff, in_buff + buff_size);
571  return traits_type::eq_int_type(c,
572  traits_type::eof())
573  ? traits_type::eof()
574  : sputc(c);
575  }
576  virtual int sync()
577  {
578  // first, call overflow to clear in_buff
579  overflow();
580  if (!pptr())
581  {
582  return -1;
583  }
584  // then, call deflate asking to finish the zlib stream
585  zstrm_p->next_in = nullptr;
586  zstrm_p->avail_in = 0;
587  if (deflate_loop(Z_FINISH) != 0)
588  {
589  return -1;
590  }
591  deflateReset(zstrm_p);
592  return 0;
593  }
594 
595 private:
596  std::streambuf *sbuf_p;
597  char *in_buff;
598  char *out_buff;
599  detail::z_stream_wrapper *zstrm_p;
600  std::size_t buff_size;
601 
602  static const std::size_t default_buff_size = (std::size_t)1 << 20;
603 }; // class ostreambuf
604 
605 class istream
606  : public std::istream
607 {
608 public:
609  istream(std::istream &is)
610  : std::istream(new istreambuf(is.rdbuf()))
611  {
612  exceptions(std::ios_base::badbit);
613  }
614  explicit istream(std::streambuf *sbuf_p)
615  : std::istream(new istreambuf(sbuf_p))
616  {
617  exceptions(std::ios_base::badbit);
618  }
619  virtual ~istream()
620  {
621  delete rdbuf();
622  }
623 }; // class istream
624 
625 class ostream
626  : public std::ostream
627 {
628 public:
629  ostream(std::ostream &os)
630  : std::ostream(new ostreambuf(os.rdbuf()))
631  {
632  exceptions(std::ios_base::badbit);
633  }
634  explicit ostream(std::streambuf *sbuf_p)
635  : std::ostream(new ostreambuf(sbuf_p))
636  {
637  exceptions(std::ios_base::badbit);
638  }
639  virtual ~ostream()
640  {
641  delete rdbuf();
642  }
643 }; // class ostream
644 #endif
645 
646 namespace detail
647 {
648 
649 template <typename FStream_Type>
651 {
652  strict_fstream_holder(const std::string &filename,
653  std::ios_base::openmode mode = std::ios_base::in)
654  : fs_(filename, mode)
655  {
656  }
657  FStream_Type fs_;
658 }; // class strict_fstream_holder
659 
660 } // namespace detail
661 
662 #ifdef MFEM_USE_ZLIB
663 class ifstream
664  : private detail::strict_fstream_holder<strict_fstream::ifstream>,
665  public std::istream
666 {
667 public:
668  explicit ifstream(const std::string &filename,
669  std::ios_base::openmode mode = std::ios_base::in)
670  : detail::strict_fstream_holder<strict_fstream::ifstream>(filename, mode),
671  std::istream(new istreambuf(fs_.rdbuf()))
672  {
673  exceptions(std::ios_base::badbit);
674  }
675  virtual ~ifstream()
676  {
677  if (rdbuf())
678  {
679  delete rdbuf();
680  }
681  }
682 }; // class ifstream
683 
684 class ofstream
685  : private detail::strict_fstream_holder<strict_fstream::ofstream>,
686  public std::ostream
687 {
688 public:
689  explicit ofstream(const std::string &filename,
690  std::ios_base::openmode mode = std::ios_base::out)
691  : detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
692  mode | std::ios_base::binary),
693  std::ostream(new ostreambuf(fs_.rdbuf()))
694  {
695  exceptions(std::ios_base::badbit);
696  }
697  virtual ~ofstream()
698  {
699  if (rdbuf())
700  {
701  delete rdbuf();
702  }
703  }
704 }; // class ofstream
705 #endif
706 
707 } // namespace zstr
708 
709 
710 // The section below contains MFEM-specific additions.
711 
712 namespace mfem
713 {
714 
716  : private zstr::detail::strict_fstream_holder<strict_fstream::ofstream>,
717  public std::ostream
718 {
719 public:
720  explicit ofgzstream(const std::string &filename,
721  bool compression = false)
722  : zstr::detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
723  std::ios_base::binary),
724  std::ostream(nullptr)
725  {
726 #ifdef MFEM_USE_ZLIB
727  if (compression)
728  {
729  strbuf = new zstr::ostreambuf(fs_.rdbuf());
730  rdbuf(strbuf);
731  }
732  else
733 #endif
734  {
735  rdbuf(fs_.rdbuf());
736  }
737  exceptions(std::ios_base::badbit);
738  }
739 
740  explicit ofgzstream(const std::string &filename,
741  char const *open_mode_chars)
742  : zstr::detail::strict_fstream_holder<strict_fstream::ofstream>(filename,
743  std::ios_base::binary),
744  std::ostream(nullptr)
745  {
746 #ifdef MFEM_USE_ZLIB
747  // If open_mode_chars contains any combination of open mode chars
748  // containing the 'z' char, compression is enabled. This preserves the
749  // behavior of the old interface but ignores the choice of the compression
750  // level (it is always set to 6).
751  if (std::string(open_mode_chars).find('z') != std::string::npos)
752  {
753  strbuf = new zstr::ostreambuf(fs_.rdbuf());
754  rdbuf(strbuf);
755  }
756  else
757 #endif
758  {
759  rdbuf(fs_.rdbuf());
760  }
761  setstate(fs_.rdstate());
762  exceptions(std::ios_base::badbit);
763  }
764 
765  virtual ~ofgzstream()
766  {
767  delete strbuf;
768  }
769 
770  std::streambuf *strbuf = nullptr;
771 };
772 
774  : private zstr::detail::strict_fstream_holder<strict_fstream::ifstream>,
775  public std::istream
776 {
777 public:
778  explicit ifgzstream(const std::string &filename)
779  : zstr::detail::strict_fstream_holder<strict_fstream::ifstream>(filename,
780  std::ios_base::in),
781  std::istream(nullptr)
782  {
783 #ifdef MFEM_USE_ZLIB
784  strbuf = new zstr::istreambuf(fs_.rdbuf());
785  rdbuf(strbuf);
786 #else
787  rdbuf(fs_.rdbuf());
788 #endif
789  setstate(fs_.rdstate());
790  exceptions(std::ios_base::badbit);
791  }
792 
793  virtual ~ifgzstream()
794  {
795  delete strbuf;
796  }
797 
798  std::streambuf *strbuf = nullptr;
799 };
800 
801 /// Input file stream that remembers the input file name (useful for example
802 /// when reading NetCDF meshes) and supports optional zlib decompression.
804 {
805 public:
806  named_ifgzstream(const std::string &mesh_name) : ifgzstream(mesh_name),
807  filename(mesh_name) {}
808 
809  const std::string filename;
810 };
811 
812 } // namespace mfem
813 
814 #endif
char * check_strerror_r(int r, char *buff, size_t buff_size)
Definition: zstr.hpp:63
static void check_peek(std::istream *is_p, const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:173
const char * what() const noexcept
Definition: zstr.hpp:303
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:222
std::streambuf * strbuf
Definition: zstr.hpp:770
const char * what() const noexcept
Definition: zstr.hpp:100
virtual std::streambuf::int_type underflow()
Definition: zstr.hpp:393
virtual ~ifstream()
Definition: zstr.hpp:675
virtual int sync()
Definition: zstr.hpp:576
ifgzstream(const std::string &filename)
Definition: zstr.hpp:778
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:205
istream(std::istream &is)
Definition: zstr.hpp:609
Exception class thrown by failed zlib operations.
Definition: zstr.hpp:270
ostreambuf(std::streambuf *sbuf_p_, std::size_t buff_size_=default_buff_size, int level_=Z_DEFAULT_COMPRESSION)
Definition: zstr.hpp:498
fstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:243
std::streambuf * strbuf
Definition: zstr.hpp:798
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:200
virtual ~istream()
Definition: zstr.hpp:619
Exception(z_stream *zstrm_p, int ret)
Definition: zstr.hpp:274
named_ifgzstream(const std::string &mesh_name)
Definition: zstr.hpp:806
istreambuf(std::streambuf *sbuf_p_, std::size_t buff_size_=default_buff_size, bool auto_detect_=true)
Definition: zstr.hpp:361
virtual ~ostream()
Definition: zstr.hpp:639
virtual ~ostreambuf()
Definition: zstr.hpp:541
ostreambuf & operator=(const ostreambuf &)=delete
Exception(const std::string msg_)
Definition: zstr.hpp:302
ostream(std::streambuf *sbuf_p)
Definition: zstr.hpp:634
int deflate_loop(int flush)
Definition: zstr.hpp:515
static void check_mode(const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:144
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:227
void open(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:248
ostream(std::ostream &os)
Definition: zstr.hpp:629
istreambuf & operator=(const istreambuf &)=delete
virtual ~istreambuf()
Definition: zstr.hpp:383
ifstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:668
virtual std::streambuf::int_type overflow(std::streambuf::int_type c=traits_type::eof())
Definition: zstr.hpp:556
virtual ~ifgzstream()
Definition: zstr.hpp:793
ofgzstream(const std::string &filename, bool compression=false)
Definition: zstr.hpp:720
ofstream(const std::string &filename, std::ios_base::openmode mode=std::ios_base::out)
Definition: zstr.hpp:689
Exception(const std::string &msg_)
Definition: zstr.hpp:99
static std::string mode_to_string(std::ios_base::openmode mode)
Definition: zstr.hpp:110
istream(std::streambuf *sbuf_p)
Definition: zstr.hpp:614
virtual ~ofstream()
Definition: zstr.hpp:697
z_stream_wrapper(bool is_input_=true, int level_=Z_DEFAULT_COMPRESSION)
Definition: zstr.hpp:317
strict_fstream_holder(const std::string &filename, std::ios_base::openmode mode=std::ios_base::in)
Definition: zstr.hpp:652
const std::string filename
Definition: zstr.hpp:809
Exception class thrown by failed operations.
Definition: zstr.hpp:95
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:765
ofgzstream(const std::string &filename, char const *open_mode_chars)
Definition: zstr.hpp:740
static void check_open(std::ios *s_p, const std::string &filename, std::ios_base::openmode mode)
Definition: zstr.hpp:163