Branch data Line data Source code
1 : : // ***************************************************************************** 2 : : /*! 3 : : \file src/Base/Writer.cpp 4 : : \copyright 2012-2015 J. Bakosi, 5 : : 2016-2018 Los Alamos National Security, LLC., 6 : : 2019-2021 Triad National Security, LLC., 7 : : 2022-2024 J. Bakosi 8 : : All rights reserved. See the LICENSE file for details. 9 : : \brief Writer base class definition 10 : : \details Writer base class definition. Writer base serves as a base class 11 : : for various file writers. It does generic low-level I/O, e.g., opening and 12 : : closing a file, and associated error handling. 13 : : */ 14 : : // ***************************************************************************** 15 : : 16 : : #include <string> 17 : : #include <exception> 18 : : #include <cstdio> 19 : : 20 : : #include "Writer.hpp" 21 : : #include "Exception.hpp" 22 : : 23 : : using tk::Writer; 24 : : 25 : 6040 : Writer::Writer( const std::string& filename, std::ios_base::openmode mode ) : 26 [ + - ]: 6040 : m_filename( filename ), m_outFile() 27 : : // ***************************************************************************** 28 : : // Constructor: Acquire file handle 29 : : //! \param[in] filename Name of file to open for writing 30 : : //! \param[in] mode Open mode, see 31 : : //! http://en.cppreference.com/w/cpp/io/ios_base/openmode 32 : : // ***************************************************************************** 33 : : { 34 : : // Doing this if-test gives the derived class an option to pass an empty 35 : : // string in case the file does not need to be opened, because e.g., there is 36 : : // no data that needs to be written, without contaminating client-code with 37 : : // this if-test. 38 [ + + ]: 6040 : if (!m_filename.empty()) { 39 [ + - ]: 6039 : m_outFile.open( m_filename, mode ); 40 [ + - ][ - + ]: 6039 : ErrChk( m_outFile.good(), "Failed to open file: " + m_filename ); [ - - ][ - - ] [ - - ] 41 : : } 42 : 6040 : } 43 : : 44 : 12080 : Writer::~Writer() noexcept 45 : : // ***************************************************************************** 46 : : // Destructor: Release file handle 47 : : //! \details Exception safety: no-throw guarantee: never throws exceptions. 48 : : //! Error handling, while done by throwing and catching exceptions, results in 49 : : //! warnings to terminal. We use C-style printf, since that will not throw 50 : : //! exceptions. 51 : : // ***************************************************************************** 52 : : { 53 [ + + ]: 6040 : if (!m_filename.empty()) { 54 : : try { 55 : : 56 [ + - ]: 6039 : m_outFile.close(); 57 : : 58 [ + - ][ - + ]: 6039 : if ( m_outFile.fail() ) 59 [ - - ]: 0 : printf( ">>> WARNING: Failed to close file: %s\n", m_filename.c_str() ); 60 : : 61 : : } // emit only a warning on error 62 [ - - ][ - ]: 0 : catch ( Exception& e ) { 63 : 0 : e.handleException(); 64 : 0 : } 65 : 0 : catch ( std::exception& e ) { 66 : 0 : printf( ">>> WARNING: std::exception in Writer destructor: %s\n", 67 : 0 : e.what() ); 68 : 0 : } 69 : 0 : catch (...) { 70 : 0 : printf( ">>> WARNING: UNKNOWN EXCEPTION in Writer destructor\n" ); 71 : 0 : } 72 : : } 73 : 6040 : }