A library for working with phylogenetic and population genetic data.
v0.32.0
output_stream.hpp
Go to the documentation of this file.
1 #ifndef GENESIS_UTILS_IO_OUTPUT_STREAM_H_
2 #define GENESIS_UTILS_IO_OUTPUT_STREAM_H_
3 
4 /*
5  Genesis - A toolkit for working with phylogenetic data.
6  Copyright (C) 2014-2023 Lucas Czech
7 
8  This program is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with this program. If not, see <http://www.gnu.org/licenses/>.
20 
21  Contact:
22  Lucas Czech <lczech@carnegiescience.edu>
23  Department of Plant Biology, Carnegie Institution For Science
24  260 Panama Street, Stanford, CA 94305, USA
25 */
26 
37 
38 #include <cerrno>
39 #include <cstdio>
40 #include <cstring>
41 #include <fstream>
42 #include <sstream>
43 #include <stdexcept>
44 #include <string>
45 
46 namespace genesis {
47 namespace utils {
48 
49 // =================================================================================================
50 // Output Stream
51 // =================================================================================================
52 
72 inline void file_output_stream(
73  std::string const& file_name,
74  std::ofstream& out_stream,
75  std::ios_base::openmode mode = std::ios_base::out,
76  bool create_dirs = true
77 ) {
78  // Make sure that we are only overwriting if we are allowed to.
79  if( ! Options::get().allow_file_overwriting() && utils::path_exists( file_name ) ) {
80  throw ExistingFileError(
81  "Output path '" + file_name + "' already exists. If you want to allow overwriting of "
82  "existing files, activate genesis::utils::Options::get().allow_file_overwriting() first.",
83  file_name
84  );
85  }
86 
87  // Create all parent dirs, if needed.
88  if( create_dirs ) {
89  auto const path = file_path( file_name );
90  dir_create( path );
91  }
92 
93  // Now prepare the stream and check that this worked.
94  errno = 0;
95  out_stream.open( file_name, mode );
96  if( !out_stream.is_open() || out_stream.fail() ) {
97  throw std::runtime_error(
98  "Cannot open output file '" + file_name + "': " + std::string( strerror( errno ))
99  );
100  }
101 }
102 
103 } // namespace utils
104 } // namespace genesis
105 
106 #endif // include guard
genesis::utils::ExistingFileError
Exception class that is thrown if trying to write to an existing file.
Definition: exception.hpp:109
fs.hpp
Provides functions for accessing the file system.
genesis::utils::dir_create
void dir_create(std::string const &path, bool with_parents)
Create a directory.
Definition: fs.cpp:236
genesis::utils::file_path
std::string file_path(std::string const &filename)
Return the path leading to a file.
Definition: fs.cpp:776
genesis::tree::path
utils::Range< IteratorPath< true > > path(ElementType const &start, ElementType const &finish)
Definition: path.hpp:337
genesis::utils::file_output_stream
void file_output_stream(std::string const &file_name, std::ofstream &out_stream, std::ios_base::openmode mode=std::ios_base::out, bool create_dirs=true)
Helper function to obtain an output stream to a file.
Definition: output_stream.hpp:72
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::path_exists
bool path_exists(std::string const &path)
Return whether a path exists, i.e., is a file or directory.
Definition: fs.cpp:74
options.hpp
exception.hpp
genesis::utils::Options::get
static Options & get()
Returns a single instance of this class.
Definition: options.hpp:68