1 /* -*- c++ -*- ----------------------------------------------------------
2    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3    https://www.lammps.org/, Sandia National Laboratories
4    Steve Plimpton, sjplimp@sandia.gov
5 
6    Copyright (2003) Sandia Corporation.  Under the terms of Contract
7    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
8    certain rights in this software.  This software is distributed under
9    the GNU General Public License.
10 
11    See the README file in the top-level LAMMPS directory.
12 ------------------------------------------------------------------------- */
13 
14 /* ----------------------------------------------------------------------
15    Contributing author: Richard Berger (Temple U)
16 ------------------------------------------------------------------------- */
17 
18 #include "gz_file_writer.h"
19 #include "fmt/format.h"
20 #include <cstdio>
21 
22 using namespace LAMMPS_NS;
23 
GzFileWriter()24 GzFileWriter::GzFileWriter() : FileWriter(), compression_level(Z_BEST_COMPRESSION), gzFp(nullptr) {}
25 
26 /* ---------------------------------------------------------------------- */
27 
~GzFileWriter()28 GzFileWriter::~GzFileWriter()
29 {
30   GzFileWriter::close();
31 }
32 
33 /* ---------------------------------------------------------------------- */
34 
open(const std::string & path,bool append)35 void GzFileWriter::open(const std::string &path, bool append)
36 {
37   if (isopen()) return;
38 
39   std::string mode;
40   if (append) {
41     mode = fmt::format("ab{}", mode, compression_level);
42   } else {
43     mode = fmt::format("wb{}", mode, compression_level);
44   }
45 
46   gzFp = gzopen(path.c_str(), mode.c_str());
47 
48   if (gzFp == nullptr) throw FileWriterException(fmt::format("Could not open file '{}'", path));
49 }
50 
51 /* ---------------------------------------------------------------------- */
52 
write(const void * buffer,size_t length)53 size_t GzFileWriter::write(const void *buffer, size_t length)
54 {
55   if (!isopen()) return 0;
56 
57   return gzwrite(gzFp, buffer, length);
58 }
59 
60 /* ---------------------------------------------------------------------- */
61 
flush()62 void GzFileWriter::flush()
63 {
64   if (!isopen()) return;
65 
66   gzflush(gzFp, Z_SYNC_FLUSH);
67 }
68 
69 /* ---------------------------------------------------------------------- */
70 
close()71 void GzFileWriter::close()
72 {
73   if (!GzFileWriter::isopen()) return;
74 
75   gzclose(gzFp);
76   gzFp = nullptr;
77 }
78 
79 /* ---------------------------------------------------------------------- */
80 
isopen() const81 bool GzFileWriter::isopen() const
82 {
83   return gzFp;
84 }
85 
86 /* ---------------------------------------------------------------------- */
87 
setCompressionLevel(int level)88 void GzFileWriter::setCompressionLevel(int level)
89 {
90   if (isopen())
91     throw FileWriterException("Compression level can not be changed while file is open");
92 
93   const int min_level = Z_DEFAULT_COMPRESSION;
94   const int max_level = Z_BEST_COMPRESSION;
95 
96   if (level < min_level || level > max_level)
97     throw FileWriterException(
98         fmt::format("Compression level must in the range of [{}, {}]", min_level, max_level));
99 
100   compression_level = level;
101 }
102