Rosetta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ozstream.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/io/ozstream.cc
11 /// @brief Output file stream wrapper for uncompressed and compressed files
12 /// @author Stuart G. Mentzer (Stuart_Mentzer@objexx.com)
13 /// @author David Kim (dekim@u.washington.edu)
14 /// @author Yih-En Andrew Ban (yab@u.washington.edu)
15 
16 
17 // Unit header
18 #include <utility/io/ozstream.hh>
19 
20 // Project headers
22 #if defined( USE_FILE_PROVIDER )
24 #endif
25 #include <utility/exit.hh>
26 
27 // C++ headers
28 #include <cstdlib>
29 
30 
31 namespace utility {
32 namespace io {
33 
34 /// @detail special "atomic" method to open a stream and print a header if it is new. This is necessary to avoid process competition when
35 /// checking for existance to decided whether or not to write a header.
36 void
37 ozstream::open_append_if_existed( std::string const& filename_a, std::stringstream& preprinted_header ) {
38  // Close the file if open and reset the state
39  close();
40  filename_ = filename_a;
41 #ifdef USEMPI
42  // std::cout << "MPI_Reroute " << (bMPI_reroute_stream_ ? " active " : " not-active ") << std::endl;
43  if ( bMPI_reroute_stream_ ) { // this is switched via call to static function enable_MPI_reroute()
44  mpi_stream_p_ = new mpi_stream::mpi_ostream( filename_a, mpi_FileBuf_master_rank_, preprinted_header, true );
45  if ( ( !mpi_stream_p_ ) || ( !( *mpi_stream_p_ ) ) ) {
47  } else compression_ = UNCOMPRESSED;
48  return;
49  }
50 #endif
51 
52  if ( !utility::file::file_exists( filename_a ) ) {
53  open( filename_a );
54  if ( good() ) ( *this) << preprinted_header.str();
55  } else {
56  open_append( filename_a );
57  }
58 }
59 
60 /// @brief Open a file
61 void
63  std::string const & filename_a,
64  std::ios_base::openmode open_mode // Ignored for gzip files
65 )
66 {
67  using std::ios;
68  using std::ios_base;
72 
73 
74  // #if defined( USE_FILE_PROVIDER )
75  // utility::Inline_File_Provider *provider = utility::Inline_File_Provider::get_instance();
76  //
77  // if(!provider->get_ostream( filename_a , &file_provider_stream )){
78  // std::cerr << "Cannot find inline file: " << filename_a << std::endl;
79  // file_provider_stream = &bad_stream;
80  // file_provider_stream->setstate( ios_base::failbit | ios_base::badbit );
81  // }
82  //
83  // if (file_provider_stream->good() ){
84  // return;
85  // }
86  // #endif
87 
88  // Close the file if open and reset the state
89  close();
90 
91  // Open the ofstream and set the compression state and file name
92  filename_ = filename_a;
93 
94 #ifdef USEMPI
95  // std::cout << "MPI_Reroute " << (bMPI_reroute_stream_ ? " active " : " not-active ") << std::endl;
96  if ( bMPI_reroute_stream_ ) {
97  std::stringstream no_header;
98  mpi_stream_p_ = new mpi_stream::mpi_ostream( filename_, mpi_FileBuf_master_rank_, no_header, open_mode & ios::app );
99  if ( ( !mpi_stream_p_ ) || ( !( *mpi_stream_p_ ) ) ) {
100  compression_ = NONE;
101  } else {
103  }
104  return;
105  }
106 #endif
107  if ( ( open_mode & ios::ate ) || ( open_mode & ios::app )
108  || ( ( open_mode & ios::in ) && ( open_mode & ios::out ) ) ) {
109 
110  // prepare new character buffer -- must do this before file is opened
112 
113  // Unsupported for gzip files: Use ofstream
114  trytry_ofstream_open( of_stream_, filename_a, open_mode );
115 
117 
118  } else if ( file_extension( filename_a ) == "gz" ) { // gzip file
119 
120  trytry_ofstream_open( of_stream_, filename_a, ios_base::out|ios_base::binary );
121  if ( of_stream_ ) { // Open succeeded
122  compression_ = GZIP;
123  } else { // Leave stream state so that failure can be detected
124  compression_ = NONE;
125  }
126 
127  } else { // Uncompressed file
128 
129  // prepare new character buffer -- must do this before file is opened
131 
132  trytry_ofstream_open( of_stream_, filename_a, ios_base::out );
133  if ( of_stream_ ) { // Open succeeded
135  } else { // Leave stream state so that failure can be detected
136  compression_ = NONE;
137  }
138 
139  }
140 
141  // Attach zip_ostream to ofstream if gzip file
142  if ( compression_ == GZIP ) {
143  // zip_stream_p_ deleted by close() above so don't have to here
144  zip_stream_p_ = new zip_ostream( of_stream_, true, static_cast< size_t >( Z_DEFAULT_COMPRESSION ), zlib_stream::DefaultStrategy, 15, 8, buffer_size_ );
145  if ( ( !zip_stream_p_ ) || ( !( *zip_stream_p_ ) ) ||
146  ( !zip_stream_p_->is_gzip() ) ) { // zip_stream not in good state
147  if ( zip_stream_p_ ) delete zip_stream_p_;
148  zip_stream_p_ = 0;
149  of_stream_.close();
150  // Set failbit so failure can be detected
151  of_stream_.setstate( ios_base::failbit );
152  }
153  }
154 }
155 
156 
157 /// @brief Open a text file or gzip'd file for appending
158 void
159 ozstream::open_append( std::string const & filename_a )
160 {
161  using std::cout;
162  using std::endl;
163  using std::exit;
164  using std::ios_base;
168 
169  // Close the file if open and reset the state
170  close();
171 
172  // Open the ofstream and set the compression state and file name
173  filename_ = filename_a;
174 
175 #ifdef USEMPI
176  // std::cout << "MPI_Reroute " << (bMPI_reroute_stream_ ? " active " : " not-active ") << std::endl;
177  if ( bMPI_reroute_stream_ ) {
178  std::stringstream no_header;
180  if ( ( !mpi_stream_p_ ) || ( !( *mpi_stream_p_ ) ) ) {
181  compression_ = NONE;
182  } else compression_ = UNCOMPRESSED;
183  return;
184  }
185 #endif
186 
187  if ( file_extension( filename_a ) == "gz" ) { // gzip file
188 
189  trytry_ofstream_open( of_stream_, filename_a, ios_base::out|ios_base::binary|ios_base::app );
190  if ( of_stream_ ) { // Open succeeded
191  compression_ = GZIP;
192  } else { // Leave stream state so that failure can be detected
193  compression_ = NONE;
194  }
195 
196  } else { // Uncompressed file
197 
198  // prepare new character buffer -- must do this before file is opened
200 
201  trytry_ofstream_open( of_stream_, filename_a, ios_base::out|ios_base::app );
202  if ( of_stream_ ) { // Open succeeded
204  } else { // Leave stream state so that failure can be detected
205  compression_ = NONE;
206  }
207 
208  }
209 
210  // Attach zip_ostream to ofstream if gzip file
211  if ( compression_ == GZIP ) {
212  // zip_stream_p_ deleted by close() above so don't have to here
213  zip_stream_p_ = new zip_ostream( of_stream_, true, static_cast< size_t >( Z_DEFAULT_COMPRESSION ), zlib_stream::DefaultStrategy, 15, 8, buffer_size_ );
214  if ( ( !zip_stream_p_ ) || ( !( *zip_stream_p_ ) ) ||
215  ( !zip_stream_p_->is_gzip() ) ) { // zip_stream not in good state
216  delete zip_stream_p_; zip_stream_p_ = 0;
217  of_stream_.close();
218  // Set failbit so failure can be detected
219  of_stream_.setstate( ios_base::failbit );
220  }
221  }
222 }
223 
224 #ifndef USEMPI
226  utility_exit_with_message( "enable_MPI_reroute called in non-mpi version of mini ");
227 }
228 #endif
229 
230 #ifdef USEMPI
231 void ozstream::enable_MPI_reroute( int min_rank, int master_rank ) {
232  int my_rank;
233  MPI_Comm_rank (MPI_COMM_WORLD, &my_rank);/* get current process id */
234  if ( my_rank >= min_rank ) bMPI_reroute_stream_ = true;
235  mpi_FileBuf_master_rank_ = master_rank;
236 }
237 #endif
238 
239 bool ozstream::bMPI_reroute_stream_( false );
241 
242 } // namespace io
243 } // namespace utility
#define utility_exit_with_message(m)
Exit with file + line + message.
Definition: exit.hh:47
bool good() const
Good?
Definition: ozstream.hh:549
basic_zip_ostream< char > zip_ostream
Definition: zipstream.hpp:645
bool allocate_assign_char_buffer()
if character buffer does not exist, create it and assign it to internal ofstream
Definition: ozstream.hh:690
std::streamsize buffer_size_
size of buffer (in bytes)
Definition: ozstream.hh:748
Compression compression_
Compression state.
Definition: ozstream.hh:736
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)
bool is_gzip() const
returns true if it is a gzip
Definition: zipstream.hpp:451
static bool bMPI_reroute_stream_
Definition: ozstream.hh:759
basic_mpi_ostream< char > mpi_ostream
Definition: mpistream.hh:339
void open_append_if_existed(std::string const &filename_a, std::stringstream &preprinted_header)
open file as append if it exists, return true if file existed before, false if it is new...
Definition: ozstream.cc:37
zlib_stream::zip_ostream * zip_stream_p_
Zip file stream pointer (owning)
Definition: ozstream.hh:754
Program exit functions and macros.
mpi_stream::mpi_ostream * mpi_stream_p_
Definition: ozstream.hh:757
std::string file_extension(std::string const &filename)
Extension of a File Name.
std::string filename_
File name.
Definition: ozstream.hh:742
static void enable_MPI_reroute(int min_client_rank, int master_rank)
Definition: ozstream.cc:225
void open_append(std::string const &filename_a)
Open a text file for appending.
Definition: ozstream.cc:159
Output file stream wrapper for uncompressed and compressed files.
void close()
Close the ofstream and reset the state.
Definition: ozstream.hh:430
static int mpi_FileBuf_master_rank_
Definition: ozstream.hh:760
ocstream cout(std::cout)
Wrapper around std::cout.
Definition: ocstream.hh:287
BooleanOptionKey const exit("options:exit")
Definition: OptionKeys.hh:51
bool file_exists(std::string const &path)
Does File Exist?
void open(std::string const &filename_a, std::ios_base::openmode open_mode=std::ios_base::out)
Open a file.
Definition: ozstream.cc:62
std::ofstream of_stream_
File stream.
Definition: ozstream.hh:739