Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
gzip_util.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file utility/file/gzip_util.cc
11 /// @brief gzip utility functions
12 /// @author David Kim (dekim@u.washington.edu)
13 
14 // Unit header
16 
17 // Project headers
18 // This has to come before boinc_util.hh or we get this error on VC++
19 // '_read' : is not a member of 'std::basic_istream<_Elem,_Traits>'
20 #include <utility/io/izstream.hh>
21 
22 // Boinc headers
23 // This has to come before some/all other headers or we get this error on Mac:
24 // /System/Library/Frameworks/CoreFoundation.framework/Headers/CFMessagePort.h:34: error: storage class specifiers invalid in parameter declarations
25 // /System/Library/Frameworks/CoreFoundation.framework/Headers/CFMessagePort.h:34: error: storage class specified for parameter 'parameter'
26 // /System/Library/Frameworks/CoreFoundation.framework/Headers/CFMessagePort.h:55: error: storage class specifiers invalid in parameter declarations
27 // /System/Library/Frameworks/CoreFoundation.framework/Headers/CFMessagePort.h:55: error: storage class specified for parameter 'parameter'
28 #ifdef BOINC
30 #endif // BOINC
31 
33 #include <utility/io/ozstream.hh>
34 
35 
36 namespace utility {
37 namespace file {
38 
39 
40 /// @brief gzip: file compression
41 long
43  std::string const & uncompressedfile,
44  bool overwrite
45 )
46 {
47  using std::cout;
48  using std::cerr;
49  using std::endl;
50  using std::ifstream;
51  using std::ios_base;
52  using std::string;
54 
55  string compressed = uncompressedfile + ".gz";
56  string resolved_compressed = compressed;
57 
58 #ifdef BOINC
59  // Files that are not temporary need to have resolved names.
60  boinc::resolve_filename( resolved_compressed );
61 #endif // BOINC
62 
63  if ( file_extension( uncompressedfile ) == "gz" ) {
64  cout << "WARNING! attempt to gzip file " << uncompressedfile << " failed: already has .gz suffix -- unchanged." << endl;
65  cerr << "WARNING! attempt to gzip file " << uncompressedfile << " failed: already has .gz suffix -- unchanged." << endl;
66  return 0;
67  }
68 
69  // Check if it exists alread
70  if ( !overwrite && file_exists( resolved_compressed ) ) {
71  cout << "WARNING! attempt to gzip file " << uncompressedfile << " failed: file " << resolved_compressed << " already exists." << endl;
72  cerr << "WARNING! attempt to gzip file " << uncompressedfile << " failed: file " << resolved_compressed << " already exists." << endl;
73  return 0;
74  }
75 
76  // Check if uncompressed file exists
77  if ( !file_exists( uncompressedfile ) ) {
78  cout << "WARNING! attempt to gzip file " << uncompressedfile << " failed: file does not exist." << endl;
79  cerr << "WARNING! attempt to gzip file " << uncompressedfile << " failed: file does not exist." << endl;
80  return 0;
81  }
82 
83  // Get uncompressed ifstream
84  ifstream f_stream;
85  trytry_ifstream_open( f_stream, uncompressedfile, ios_base::in|ios_base::binary );
86  if ( !f_stream ) {
87  cout << "WARNING! attempt to gzip file " << uncompressedfile << " failed: cannot read file." << endl;
88  cerr << "WARNING! attempt to gzip file " << uncompressedfile << " failed: cannot read file." << endl;
89  f_stream.close();
90  return 0;
91  }
92 
93  // Write compressed file
94  // Use compressed and not resolved_compressed since ozstream
95  // resolves filenames for BOINC
96  ozstream zf_stream( compressed );
97  if ( !zf_stream || zf_stream.uncompressed() ) {
98  cout << "WARNING! attempt to create gzipped file " << resolved_compressed << " failed." << endl;
99  cerr << "WARNING! attempt to create gzipped file " << resolved_compressed << " failed." << endl;
100  f_stream.close();
101  zf_stream.close();
102  return 0;
103  }
104 
105  // Write to ozstream
106  zf_stream << f_stream.rdbuf();
107  if ( zf_stream().fail() ) {
108  cout << "WARNING! cannot write gzipped stream to file " << resolved_compressed << endl;
109  cerr << "WARNING! cannot write gzipped stream to file " << resolved_compressed << endl;
110  f_stream.close();
111  zf_stream.close();
112  return 0;
113  }
114  // Flush all buffers (must do for gzip)
115  zf_stream.zflush();
116 
117  // Check for success and then delete uncompressed file
118  long in_size = zf_stream.get_in_size();
119  long out_size = zf_stream.get_out_size();
120  long crc = zf_stream.get_crc();
121  long uncompressedfile_size = file_size( uncompressedfile );
122  f_stream.close();
123  zf_stream.close();
124  if ( in_size && out_size && crc && in_size == uncompressedfile_size ) {
125  // gzipped file created so remove uncompressed file
126  if ( file_delete( uncompressedfile ) == -1 ) {
127  cout << "WARNING! error deleting file " << uncompressedfile << endl;
128  cerr << "WARNING! error deleting file " << uncompressedfile << endl;
129  }
130  return out_size;
131  }
132  cout << "WARNING! gzip failed to create file " << resolved_compressed << endl;
133  return 0;
134 }
135 
136 
137 /// @brief gunzip: file decompression
138 long
140  std::string const & compressedfile,
141  bool overwrite
142 )
143 {
144  using std::cout;
145  using std::cerr;
146  using std::endl;
147  using std::ios_base;
148  using std::ofstream;
149  using std::string;
150  using utility::io::izstream;
151 
152  // Check if compressedfile ends with .gz
153  if ( file_extension( compressedfile ) != "gz" ) {
154  cout << "WARNING! attempt to gunzip file " << compressedfile << " failed: unknown suffix -- ignored." << endl;
155  cerr << "WARNING! attempt to gunzip file " << compressedfile << " failed: unknown suffix -- ignored." << endl;
156  return 0;
157  }
158 
159  // Get uncompressed file name
160  string uncompressed( compressedfile );
161  uncompressed.replace( uncompressed.rfind(".gz", uncompressed.length()), 3, "" );
162  string resolved_uncompressed( uncompressed );
163 
164 #ifdef BOINC
165  // Files that are not temporary need to have resolved names.
166  boinc::resolve_filename( resolved_uncompressed );
167 #endif // BOINC
168 
169  // Check if uncompressed file exists alread
170  if ( !overwrite && file_exists( resolved_uncompressed ) ) {
171  cout << "WARNING! attempt to gunzip file " << compressedfile << " failed: file " << resolved_uncompressed << " already exists." << std::endl;
172  cerr << "WARNING! attempt to gunzip file " << compressedfile << " failed: file " << resolved_uncompressed << " already exists." << std::endl;
173  return 0;
174  }
175 
176  // Check if compressed file exists
177  if ( !file_exists( compressedfile ) ) {
178  cout << "WARNING! attempt to gzip file " << compressedfile << " failed: file does not exist." << endl;
179  cerr << "WARNING! attempt to gzip file " << compressedfile << " failed: file does not exist." << endl;
180  return 0;
181  }
182 
183  // Get compressed zipstream
184  izstream zf_stream( compressedfile );
185  if ( !zf_stream ) {
186  cout << "WARNING! attempt to gunzip file " << compressedfile << " failed: cannot read file." << endl;
187  cerr << "WARNING! attempt to gunzip file " << compressedfile << " failed: cannot read file." << endl;
188  zf_stream.close();
189  return 0;
190  }
191  if ( !zf_stream.is_gzip() ) {
192  cout << "WARNING! attempt to gunzip file " << compressedfile << " failed: unknown file type." << endl;
193  cerr << "WARNING! attempt to gunzip file " << compressedfile << " failed: unknown file type." << endl;
194  zf_stream.close();
195  return 0;
196  }
197  // Write uncompressed file
198  // Use uncompressed and not resolved_uncompressed since trytry_ofstream_open
199  // Resolves filenames for BOINC
200  ofstream o_stream;
201  trytry_ofstream_open( o_stream, uncompressed, ios_base::out|ios_base::binary );
202  if ( !o_stream ) {
203  cout << "WARNING! attempt to create unzipped file " << uncompressed << " failed." << endl;
204  cerr << "WARNING! attempt to create unzipped file " << uncompressed << " failed." << endl;
205  o_stream.close();
206  return 0;
207  }
208  o_stream << zf_stream.rdbuf(); // write to ozstream
209  if ( o_stream.fail() ) {
210  cout << "WARNING! cannot write gunzipped stream to file " << resolved_uncompressed << endl;
211  cerr << "WARNING! cannot write gunzipped stream to file " << resolved_uncompressed << endl;
212  o_stream.close();
213  zf_stream.close();
214  return 0;
215  }
216 
217  long in_size = zf_stream.get_in_size();
218  long out_size = zf_stream.get_out_size();
219  long crc = zf_stream.get_crc();
220  o_stream.close();
221  zf_stream.close();
222  if ( in_size && out_size && crc ) {
223  // gunzipped file created so remove compressed file
224  if ( file_delete( compressedfile ) == -1 ) {
225  cout << "WARNING! error deleting file " << compressedfile << endl;
226  cerr << "WARNING! error deleting file " << compressedfile << endl;
227  }
228  return out_size;
229  }
230  cout << "WARNING! gunzip failed to create file " << resolved_uncompressed << endl;
231  cerr << "WARNING! gunzip failed to create file " << resolved_uncompressed << endl;
232  return 0;
233 }
234 
235 
236 } // namespace file
237 } // namespace utility
ocstream cerr(std::cerr)
Wrapper around std::cerr.
Definition: ocstream.hh:290
Wrappers to make BOINC work.
Platform independent operations on files (except I/O)
bool trytry_ofstream_open(std::ofstream &ofstream_, std::string const &name, std::ios_base::openmode open_mode)
Try to open file a few times just in case it is locked (from BOINC LIB)
long gzip(std::string const &uncompressedfile, bool overwrite)
gzip: file compression
Definition: gzip_util.cc:42
long file_size(std::string const &filename)
Platform independent way of getting file size.
izstream: Input file stream wrapper for uncompressed and compressed files
Definition: izstream.hh:44
Input file stream wrapper for uncompressed and compressed files.
std::string file_extension(std::string const &filename)
Extension of a File Name.
int file_delete(std::string const &path)
Delete File.
Output file stream wrapper for uncompressed and compressed files.
std::streambuf * rdbuf() const
Pointer to the stream buffer.
Definition: ocstream.hh:201
gzip utility functions
bool trytry_ifstream_open(std::ifstream &ifstream_, std::string const &name, std::ios_base::openmode open_mode)
Try to open file a few times just in case it is locked (from BOINC LIB)
ocstream cout(std::cout)
Wrapper around std::cout.
Definition: ocstream.hh:287
long gunzip(std::string const &compressedfile, bool overwrite)
gunzip: file decompression
Definition: gzip_util.cc:139
bool file_exists(std::string const &path)
Does File Exist?
ozstream: Output file stream wrapper for uncompressed and compressed files
Definition: ozstream.hh:53