From 5d79eff2cd55cdfa4057d2c613fdfabe84363e7e Mon Sep 17 00:00:00 2001 From: Matthias Volk Date: Tue, 14 Feb 2017 18:25:26 +0100 Subject: [PATCH] Wrapper for file opening --- .../modelchecker/dft/DFTASFChecker.cpp | 23 +++--- src/storm-dft/parser/DFTGalileoParser.cpp | 17 ++-- src/storm-dft/parser/DFTJsonParser.cpp | 14 +--- src/storm-gspn-cli/storm-gspn.cpp | 8 +- src/storm-gspn/storm-gspn.h | 20 ++--- src/storm-pgcl-cli/storm-pgcl.cpp | 11 +-- src/storm-pgcl/parser/PgclParser.cpp | 9 ++- src/storm/abstraction/MenuGameAbstractor.cpp | 5 +- src/storm/cli/entrypoints.h | 8 +- .../modelchecker/region/ParameterRegion.cpp | 5 +- .../AtomicPropositionLabelingParser.cpp | 5 -- .../DeterministicSparseTransitionParser.cpp | 5 -- src/storm/parser/FormulaParser.cpp | 9 ++- src/storm/parser/JaniParser.cpp | 14 +--- src/storm/parser/MappedFile.cpp | 18 ++--- src/storm/parser/MappedFile.h | 8 -- .../MarkovAutomatonSparseTransitionParser.cpp | 5 -- ...NondeterministicSparseTransitionParser.cpp | 5 -- src/storm/parser/PrismParser.cpp | 10 +-- .../parser/SparseChoiceLabelingParser.cpp | 5 -- src/storm/parser/SparseStateRewardParser.cpp | 5 -- src/storm/settings/SettingsManager.cpp | 8 +- src/storm/solver/SmtlibSmtSolver.cpp | 13 +-- src/storm/storage/dd/Odd.cpp | 6 +- src/storm/storage/jani/JSONExporter.cpp | 18 ++--- src/storm/utility/export.h | 15 +--- src/storm/utility/file.h | 81 +++++++++++++++++++ src/storm/utility/storm.h | 13 +-- src/test/parser/MappedFileTest.cpp | 7 +- 29 files changed, 188 insertions(+), 182 deletions(-) create mode 100644 src/storm/utility/file.h diff --git a/src/storm-dft/modelchecker/dft/DFTASFChecker.cpp b/src/storm-dft/modelchecker/dft/DFTASFChecker.cpp index 0d6cf2e31..55d968a2c 100644 --- a/src/storm-dft/modelchecker/dft/DFTASFChecker.cpp +++ b/src/storm-dft/modelchecker/dft/DFTASFChecker.cpp @@ -1,5 +1,6 @@ #include "DFTASFChecker.h" #include +#include "storm/utility/file.h" namespace storm { @@ -394,24 +395,22 @@ namespace storm { } void DFTASFChecker::toFile(std::string const& filename) { - std::ofstream ofs; - std::cout << "Writing to " << filename << std::endl; - ofs.open(filename); - ofs << "; time point variables" << std::endl; + std::ofstream stream; + storm::utility::openFile(filename, stream); + stream << "; time point variables" << std::endl; for (auto const& timeVarEntry : timePointVariables) { - ofs << "(declare-fun " << varNames[timeVarEntry.second] << "() Int)" << std::endl; + stream << "(declare-fun " << varNames[timeVarEntry.second] << "() Int)" << std::endl; } - ofs << "; claim variables" << std::endl; + stream << "; claim variables" << std::endl; for (auto const& claimVarEntry : claimVariables) { - ofs << "(declare-fun " << varNames[claimVarEntry.second] << "() Int)" << std::endl; + stream << "(declare-fun " << varNames[claimVarEntry.second] << "() Int)" << std::endl; } for (auto const& constraint : constraints) { - ofs << "; " << constraint->description() << std::endl; - ofs << "(assert " << constraint->toSmtlib2(varNames) << ")" << std::endl; + stream << "; " << constraint->description() << std::endl; + stream << "(assert " << constraint->toSmtlib2(varNames) << ")" << std::endl; } - ofs << "(check-sat)" << std::endl; - ofs.close(); - + stream << "(check-sat)" << std::endl; + storm::utility::closeFile(stream); } } } diff --git a/src/storm-dft/parser/DFTGalileoParser.cpp b/src/storm-dft/parser/DFTGalileoParser.cpp index f872f4526..c5a88716c 100644 --- a/src/storm-dft/parser/DFTGalileoParser.cpp +++ b/src/storm-dft/parser/DFTGalileoParser.cpp @@ -10,6 +10,7 @@ #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/utility/macros.h" +#include "storm/utility/file.h" namespace storm { namespace parser { @@ -49,18 +50,10 @@ namespace storm { std::string parametricToken = "param"; std::ifstream file; - file.exceptions ( std::ifstream::failbit ); - try { - file.open(filename); - } - catch (std::ifstream::failure e) { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << filename << "."); - return; - } - file.exceptions( std::ifstream::goodbit ); - + storm::utility::openFile(filename, file); std::string line; - while(std::getline(file, line)) { + + while (std::getline(file, line)) { bool success = true; STORM_LOG_TRACE("Parsing: " << line); size_t commentstarts = line.find("//"); @@ -143,7 +136,7 @@ namespace storm { if(!builder.setTopLevel(toplevelId)) { STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Top level id unknown."); } - file.close(); + storm::utility::closeFile(file); } template diff --git a/src/storm-dft/parser/DFTJsonParser.cpp b/src/storm-dft/parser/DFTJsonParser.cpp index 9a5c5d047..faff4a099 100644 --- a/src/storm-dft/parser/DFTJsonParser.cpp +++ b/src/storm-dft/parser/DFTJsonParser.cpp @@ -10,6 +10,7 @@ #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" #include "storm/utility/macros.h" +#include "storm/utility/file.h" namespace storm { namespace parser { @@ -52,19 +53,10 @@ namespace storm { STORM_LOG_DEBUG("Parsing from JSON"); std::ifstream file; - file.exceptions ( std::ifstream::failbit ); - try { - file.open(filename); - } - catch (std::ifstream::failure e) { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << filename << "."); - return; - } - file.exceptions( std::ifstream::goodbit ); - + storm::utility::openFile(filename, file); json parsedJson; parsedJson << file; - file.close(); + storm::utility::closeFile(file); // Start by building mapping from ids to names std::map nameMapping; diff --git a/src/storm-gspn-cli/storm-gspn.cpp b/src/storm-gspn-cli/storm-gspn.cpp index 2dd98e645..bbff2c9cc 100644 --- a/src/storm-gspn-cli/storm-gspn.cpp +++ b/src/storm-gspn-cli/storm-gspn.cpp @@ -56,19 +56,19 @@ void initializeSettings() { std::unordered_map parseCapacitiesList(std::string const& filename) { std::unordered_map map; - std::ifstream ifs; - ifs.open(filename); + std::ifstream stream; + storm::utility::openFile(filename, stream); std::string line; - while( std::getline(ifs, line) ) { + while ( std::getline(stream, line) ) { std::vector strs; boost::split(strs, line, boost::is_any_of("\t ")); STORM_LOG_THROW(strs.size() == 2, storm::exceptions::WrongFormatException, "Expect key value pairs"); std::cout << std::stoll(strs[1]) << std::endl; map[strs[0]] = std::stoll(strs[1]); } + storm::utility::closeFile(stream); return map; - } diff --git a/src/storm-gspn/storm-gspn.h b/src/storm-gspn/storm-gspn.h index de3811109..d043ce53d 100644 --- a/src/storm-gspn/storm-gspn.h +++ b/src/storm-gspn/storm-gspn.h @@ -8,6 +8,8 @@ #include "storm/settings/SettingsManager.h" #include "storm/settings/modules/GSPNExportSettings.h" +#include "storm/utility/file.h" + namespace storm { /** * Builds JANI model from GSPN. @@ -21,23 +23,23 @@ namespace storm { storm::settings::modules::GSPNExportSettings const& exportSettings = storm::settings::getModule(); if (exportSettings.isWriteToDotSet()) { std::ofstream fs; - fs.open(exportSettings.getWriteToDotFilename()); + storm::utility::openFile(exportSettings.getWriteToDotFilename(), fs); gspn.writeDotToStream(fs); - fs.close(); + storm::utility::closeFile(fs); } if (exportSettings.isWriteToPnproSet()) { std::ofstream fs; - fs.open(exportSettings.getWriteToPnproFilename()); + storm::utility::openFile(exportSettings.getWriteToPnproFilename(), fs); gspn.toPnpro(fs); - fs.close(); + storm::utility::closeFile(fs); } if (exportSettings.isWriteToPnmlSet()) { std::ofstream fs; - fs.open(exportSettings.getWriteToPnmlFilename()); + storm::utility::openFile(exportSettings.getWriteToPnmlFilename(), fs); gspn.toPnml(fs); - fs.close(); + storm::utility::closeFile(fs); } if (exportSettings.isDisplayStatsSet()) { @@ -48,13 +50,13 @@ namespace storm { if (exportSettings.isWriteStatsToFileSet()) { std::ofstream fs; - fs.open(exportSettings.getWriteStatsFilename()); + storm::utility::openFile(exportSettings.getWriteStatsFilename(), fs); gspn.writeStatsToStream(fs); - fs.close(); + storm::utility::closeFile(fs); } } -} \ No newline at end of file +} diff --git a/src/storm-pgcl-cli/storm-pgcl.cpp b/src/storm-pgcl-cli/storm-pgcl.cpp index 6a6707177..2fa9385a2 100644 --- a/src/storm-pgcl-cli/storm-pgcl.cpp +++ b/src/storm-pgcl-cli/storm-pgcl.cpp @@ -47,13 +47,10 @@ void handleJani(storm::jani::Model& model) { void programGraphToDotFile(storm::ppg::ProgramGraph const& prog) { std::string filepath = storm::settings::getModule().getProgramGraphDotOutputFilename(); - std::ofstream ofs; - ofs.open(filepath, std::ofstream::out ); - if (ofs.is_open()) { - prog.printDot(ofs); - } else { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Cannot open " << filepath); - } + std::ofstream stream; + storm::utility::openFile(filepath, stream); + prog.printDot(stream); + storm::utility::closeFile(stream); } int main(const int argc, const char** argv) { diff --git a/src/storm-pgcl/parser/PgclParser.cpp b/src/storm-pgcl/parser/PgclParser.cpp index ca264de5f..6ecde3054 100755 --- a/src/storm-pgcl/parser/PgclParser.cpp +++ b/src/storm-pgcl/parser/PgclParser.cpp @@ -1,6 +1,7 @@ #include "PgclParser.h" // If the parser fails due to ill-formed data, this exception is thrown. #include "storm/exceptions/WrongFormatException.h" +#include "storm/utility/file.h" namespace storm { namespace parser { @@ -9,8 +10,8 @@ namespace storm { storm::pgcl::PgclProgram result; // Open file and initialize result. - std::ifstream inputFileStream(filename, std::ios::in); - STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'."); + std::ifstream inputFileStream; + storm::utility::openFile(filename, inputFileStream); // Now try to parse the contents of the file. try { @@ -18,12 +19,12 @@ namespace storm { result = parseFromString(fileContent, filename); } catch(std::exception& e) { // In case of an exception properly close the file before passing exception. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); throw e; } // Close the stream in case everything went smoothly and return result. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); return result; } diff --git a/src/storm/abstraction/MenuGameAbstractor.cpp b/src/storm/abstraction/MenuGameAbstractor.cpp index 164802c2b..9a0071571 100644 --- a/src/storm/abstraction/MenuGameAbstractor.cpp +++ b/src/storm/abstraction/MenuGameAbstractor.cpp @@ -7,6 +7,7 @@ #include "storm/storage/dd/Add.h" #include "storm/storage/dd/Bdd.h" #include "storm/utility/dd.h" +#include "storm/utility/file.h" #include "storm-config.h" #include "storm/adapters/CarlAdapter.h" @@ -47,7 +48,8 @@ namespace storm { template void MenuGameAbstractor::exportToDot(storm::abstraction::MenuGame const& currentGame, std::string const& filename, storm::dd::Bdd const& highlightStatesBdd, storm::dd::Bdd const& filter) const { - std::ofstream out(filename); + std::ofstream out; + storm::utility::openFile(filename, out); AbstractionInformation const& abstractionInformation = this->getAbstractionInformation(); storm::dd::Add filteredTransitions = filter.template toAdd() * currentGame.getTransitionMatrix(); @@ -130,6 +132,7 @@ namespace storm { } out << "}" << std::endl; + storm::utility::closeFile(out); } template class MenuGameAbstractor; diff --git a/src/storm/cli/entrypoints.h b/src/storm/cli/entrypoints.h index 3d1a9397e..79b030fb8 100644 --- a/src/storm/cli/entrypoints.h +++ b/src/storm/cli/entrypoints.h @@ -324,10 +324,10 @@ namespace storm { // And export if required. if(storm::settings::getModule().isExportExplicitSet()) { - std::ofstream ofs; - ofs.open(storm::settings::getModule().getExportExplicitFilename(), std::ofstream::out); - storm::exporter::explicitExportSparseModel(ofs, sparseModel, model.getParameterNames()); - ofs.close(); + std::ofstream stream; + storm::utility::openFile(storm::settings::getModule().getExportExplicitFilename(), stream); + storm::exporter::explicitExportSparseModel(stream, sparseModel, model.getParameterNames()); + storm::utility::closeFile(stream); } } diff --git a/src/storm/modelchecker/region/ParameterRegion.cpp b/src/storm/modelchecker/region/ParameterRegion.cpp index 27b683e8b..d328831fc 100644 --- a/src/storm/modelchecker/region/ParameterRegion.cpp +++ b/src/storm/modelchecker/region/ParameterRegion.cpp @@ -7,7 +7,8 @@ #include "storm/settings/modules/RegionSettings.h" #include "storm/exceptions/InvalidSettingsException.h" #include "storm/exceptions/InvalidArgumentException.h" -#include "utility/constants.h" +#include "storm/utility/constants.h" +#include "storm/utility/file.h" namespace storm { namespace modelchecker { @@ -283,7 +284,7 @@ namespace storm { } else{ //if we reach this point we can assume that the region is given as a file. - STORM_LOG_THROW(storm::parser::MappedFile::fileExistsAndIsReadable(storm::settings::getModule().getRegionFilePath().c_str()), storm::exceptions::InvalidSettingsException, "The path to the file in which the regions are specified is not valid."); + STORM_LOG_THROW(storm::utility::fileExistsAndIsReadable(storm::settings::getModule().getRegionFilePath()), storm::exceptions::InvalidSettingsException, "The path to the file in which the regions are specified is not valid."); storm::parser::MappedFile mf(storm::settings::getModule().getRegionFilePath().c_str()); regionsString = std::string(mf.getData(),mf.getDataSize()); } diff --git a/src/storm/parser/AtomicPropositionLabelingParser.cpp b/src/storm/parser/AtomicPropositionLabelingParser.cpp index bbb555460..4d55b4fe8 100644 --- a/src/storm/parser/AtomicPropositionLabelingParser.cpp +++ b/src/storm/parser/AtomicPropositionLabelingParser.cpp @@ -24,11 +24,6 @@ namespace storm { storm::models::sparse::StateLabeling AtomicPropositionLabelingParser::parseAtomicPropositionLabeling(uint_fast64_t stateCount, std::string const & filename) { // Open the given file. - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process."); - throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": The supplied Labeling input file does not exist or is not readable by this process."; - } - MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/parser/DeterministicSparseTransitionParser.cpp b/src/storm/parser/DeterministicSparseTransitionParser.cpp index 7b53415cb..9aacb7e4c 100644 --- a/src/storm/parser/DeterministicSparseTransitionParser.cpp +++ b/src/storm/parser/DeterministicSparseTransitionParser.cpp @@ -41,11 +41,6 @@ namespace storm { // Enforce locale where decimal point is '.'. setlocale(LC_NUMERIC, "C"); - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); - throw storm::exceptions::FileIoException() << "The supplied Transition input file \"" << filename << "\" does not exist or is not readable by this process."; - } - // Open file. MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/parser/FormulaParser.cpp b/src/storm/parser/FormulaParser.cpp index 6bb1687dc..e592f141c 100644 --- a/src/storm/parser/FormulaParser.cpp +++ b/src/storm/parser/FormulaParser.cpp @@ -15,6 +15,7 @@ #include "storm/storage/expressions/ExpressionEvaluator.h" #include "FormulaParserGrammar.h" #include "storm/storage/expressions/ExpressionManager.h" +#include "storm/utility/file.h" namespace storm { namespace parser { @@ -65,8 +66,8 @@ namespace storm { std::vector FormulaParser::parseFromFile(std::string const& filename) const { // Open file and initialize result. - std::ifstream inputFileStream(filename, std::ios::in); - STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'."); + std::ifstream inputFileStream; + storm::utility::openFile(filename, inputFileStream); std::vector properties; @@ -76,12 +77,12 @@ namespace storm { properties = parseFromString(fileContent); } catch(std::exception& e) { // In case of an exception properly close the file before passing exception. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); throw e; } // Close the stream in case everything went smoothly and return result. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); return properties; } diff --git a/src/storm/parser/JaniParser.cpp b/src/storm/parser/JaniParser.cpp index c8f0c15e8..826c8075b 100644 --- a/src/storm/parser/JaniParser.cpp +++ b/src/storm/parser/JaniParser.cpp @@ -18,6 +18,7 @@ #include #include "storm/utility/macros.h" +#include "storm/utility/file.h" namespace storm { namespace parser { @@ -64,18 +65,9 @@ namespace storm { void JaniParser::readFile(std::string const &path) { std::ifstream file; - file.exceptions ( std::ifstream::failbit ); - try { - file.open(path); - } - catch (std::ifstream::failure e) { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Exception during file opening on " << path << "."); - return; - } - file.exceptions( std::ifstream::goodbit ); - + storm::utility::openFile(path, file); parsedStructure << file; - file.close(); + storm::utility::closeFile(file); } std::pair> JaniParser::parseModel(bool parseProperties) { diff --git a/src/storm/parser/MappedFile.cpp b/src/storm/parser/MappedFile.cpp index e731ebf18..5b9f02714 100644 --- a/src/storm/parser/MappedFile.cpp +++ b/src/storm/parser/MappedFile.cpp @@ -15,10 +15,14 @@ #include "storm/exceptions/FileIoException.h" #include "storm/utility/macros.h" +#include "storm/utility/file.h" + namespace storm { namespace parser { MappedFile::MappedFile(const char* filename) { + STORM_LOG_THROW(storm::utility::fileExistsAndIsReadable(filename), storm::exceptions::FileIoException, "Error while reading " << filename << ": The file does not exist or is not readable."); + #if defined LINUX || defined MACOSX // Do file mapping for reasonable systems. @@ -29,15 +33,11 @@ namespace storm { #else if (stat64(filename, &(this->st)) != 0) { #endif - STORM_LOG_ERROR("Error in stat(" << filename << "): Probably, this file does not exist."); - throw exceptions::FileIoException() << "MappedFile Error in stat(): Probably, this file does not exist."; + STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Error in stat(" << filename << "): Probably, this file does not exist."); } this->file = open(filename, O_RDONLY); - if (this->file < 0) { - STORM_LOG_ERROR("Error in open(" << filename << "): Probably, we may not read this file."); - throw exceptions::FileIoException() << "MappedFile Error in open(): Probably, we may not read this file."; - } + STORM_LOG_THROW(this->file >= 0, storm::exceptions::FileIoException, "Error in open(" << filename << "): Probably, we may not read this file."); this->data = static_cast(mmap(NULL, this->st.st_size, PROT_READ, MAP_PRIVATE, this->file, 0)); if (this->data == MAP_FAILED) { @@ -90,12 +90,6 @@ namespace storm { #endif } - bool MappedFile::fileExistsAndIsReadable(const char* filename) { - // Test by opening an input file stream and testing the stream flags. - std::ifstream fin(filename); - return fin.good(); - } - char const* MappedFile::getData() const { return data; } diff --git a/src/storm/parser/MappedFile.h b/src/storm/parser/MappedFile.h index f1be7f83c..aeeb7fa6f 100644 --- a/src/storm/parser/MappedFile.h +++ b/src/storm/parser/MappedFile.h @@ -49,14 +49,6 @@ namespace storm { */ ~MappedFile(); - /*! - * Tests whether the given file exists and is readable. - *qi - * @param filename Path and name of the file to be tested. - * @return True iff the file exists and is readable. - */ - static bool fileExistsAndIsReadable(const char* filename); - /*! * Returns a pointer to the beginning of the mapped file data. * diff --git a/src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp b/src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp index 271f22516..25b62a2e2 100644 --- a/src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp +++ b/src/storm/parser/MarkovAutomatonSparseTransitionParser.cpp @@ -294,11 +294,6 @@ namespace storm { // Set the locale to correctly recognize floating point numbers. setlocale(LC_NUMERIC, "C"); - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); - throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; - } - // Open file and prepare pointer to buffer. MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/parser/NondeterministicSparseTransitionParser.cpp b/src/storm/parser/NondeterministicSparseTransitionParser.cpp index a9e1b53b1..f9a1947b9 100644 --- a/src/storm/parser/NondeterministicSparseTransitionParser.cpp +++ b/src/storm/parser/NondeterministicSparseTransitionParser.cpp @@ -39,11 +39,6 @@ namespace storm { // Enforce locale where decimal point is '.'. setlocale(LC_NUMERIC, "C"); - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); - throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; - } - // Open file. MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/parser/PrismParser.cpp b/src/storm/parser/PrismParser.cpp index 436d27c5d..62ef9eebe 100644 --- a/src/storm/parser/PrismParser.cpp +++ b/src/storm/parser/PrismParser.cpp @@ -7,6 +7,7 @@ #include "storm/exceptions/InvalidArgumentException.h" #include "storm/exceptions/InvalidTypeException.h" #include "storm/utility/macros.h" +#include "storm/utility/file.h" #include "storm/exceptions/WrongFormatException.h" #include "storm/storage/expressions/ExpressionManager.h" @@ -17,9 +18,8 @@ namespace storm { namespace parser { storm::prism::Program PrismParser::parse(std::string const& filename) { // Open file and initialize result. - std::ifstream inputFileStream(filename); - STORM_LOG_THROW(inputFileStream.good(), storm::exceptions::WrongFormatException, "Unable to read from file '" << filename << "'."); - + std::ifstream inputFileStream; + storm::utility::openFile(filename, inputFileStream); storm::prism::Program result; // Now try to parse the contents of the file. @@ -28,12 +28,12 @@ namespace storm { result = parseFromString(fileContent, filename); } catch(std::exception& e) { // In case of an exception properly close the file before passing exception. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); throw e; } // Close the stream in case everything went smoothly and return result. - inputFileStream.close(); + storm::utility::closeFile(inputFileStream); return result; } diff --git a/src/storm/parser/SparseChoiceLabelingParser.cpp b/src/storm/parser/SparseChoiceLabelingParser.cpp index c73d1def4..26395d057 100644 --- a/src/storm/parser/SparseChoiceLabelingParser.cpp +++ b/src/storm/parser/SparseChoiceLabelingParser.cpp @@ -13,11 +13,6 @@ namespace storm { std::vector SparseChoiceLabelingParser::parseChoiceLabeling(std::vector const& nondeterministicChoiceIndices, std::string const& filename) { // Open file. - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); - throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; - } - MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/parser/SparseStateRewardParser.cpp b/src/storm/parser/SparseStateRewardParser.cpp index d010265a8..3df355578 100644 --- a/src/storm/parser/SparseStateRewardParser.cpp +++ b/src/storm/parser/SparseStateRewardParser.cpp @@ -17,11 +17,6 @@ namespace storm { template std::vector SparseStateRewardParser::parseSparseStateReward(uint_fast64_t stateCount, std::string const& filename) { // Open file. - if (!MappedFile::fileExistsAndIsReadable(filename.c_str())) { - STORM_LOG_ERROR("Error while parsing " << filename << ": File does not exist or is not readable."); - throw storm::exceptions::FileIoException() << "Error while parsing " << filename << ": File does not exist or is not readable."; - } - MappedFile file(filename.c_str()); char const* buf = file.getData(); diff --git a/src/storm/settings/SettingsManager.cpp b/src/storm/settings/SettingsManager.cpp index 8fefca91c..bbd514c57 100644 --- a/src/storm/settings/SettingsManager.cpp +++ b/src/storm/settings/SettingsManager.cpp @@ -39,6 +39,7 @@ #include "storm/settings/modules/JitBuilderSettings.h" #include "storm/settings/modules/MultiObjectiveSettings.h" #include "storm/utility/macros.h" +#include "storm/utility/file.h" #include "storm/settings/Option.h" namespace storm { @@ -394,8 +395,8 @@ namespace storm { std::map> SettingsManager::parseConfigFile(std::string const& filename) const { std::map> result; - std::ifstream input(filename); - STORM_LOG_THROW(input.good(), storm::exceptions::OptionParserException, "Could not read from config file '" << filename << "'."); + std::ifstream input; + storm::utility::openFile(filename, input); bool globalScope = true; std::string activeModule = ""; @@ -480,7 +481,8 @@ namespace storm { } } } - + + storm::utility::closeFile(input); return result; } diff --git a/src/storm/solver/SmtlibSmtSolver.cpp b/src/storm/solver/SmtlibSmtSolver.cpp index de33d4f0b..a9da13e4e 100644 --- a/src/storm/solver/SmtlibSmtSolver.cpp +++ b/src/storm/solver/SmtlibSmtSolver.cpp @@ -16,9 +16,10 @@ #include "storm/exceptions/InvalidStateException.h" #include "storm/exceptions/IllegalArgumentException.h" #include "storm/exceptions/IllegalFunctionCallException.h" -#include "utility/macros.h" -#include "adapters/CarlAdapter.h" -#include "exceptions/UnexpectedException.h" +#include "storm/utility/macros.h" +#include "storm/utility/file.h" +#include "storm/adapters/CarlAdapter.h" +#include "storm/exceptions/UnexpectedException.h" namespace storm { namespace solver { @@ -245,9 +246,9 @@ namespace storm { if (storm::settings::getModule().isExportSmtLibScriptSet()){ STORM_LOG_DEBUG("The SMT-LIBv2 commands are exportet to the given file"); - commandFile.open(storm::settings::getModule().getExportSmtLibScriptPath(), std::ios::trunc); - isCommandFileOpen=commandFile.is_open(); - STORM_LOG_THROW(isCommandFileOpen, storm::exceptions::InvalidArgumentException, "The file where the smt2commands should be written to could not be opened"); + storm::utility::openFile(storm::settings::getModule().getExportSmtLibScriptPath(), commandFile); + isCommandFileOpen = true; + // TODO also close file } //some initial commands diff --git a/src/storm/storage/dd/Odd.cpp b/src/storm/storage/dd/Odd.cpp index 23443a760..469b590b6 100644 --- a/src/storm/storage/dd/Odd.cpp +++ b/src/storm/storage/dd/Odd.cpp @@ -6,6 +6,7 @@ #include "storm/utility/macros.h" #include "storm/exceptions/InvalidArgumentException.h" +#include "storm/utility/file.h" namespace storm { namespace dd { @@ -86,7 +87,7 @@ namespace storm { void Odd::exportToDot(std::string const& filename) const { std::ofstream dotFile; - dotFile.open (filename); + storm::utility::openFile(filename, dotFile); // Print header. dotFile << "digraph \"ODD\" {" << std::endl << "center=true;" << std::endl << "edge [dir = none];" << std::endl; @@ -129,8 +130,7 @@ namespace storm { } dotFile << "}" << std::endl; - - dotFile.close(); + storm::utility::closeFile(dotFile); } void Odd::addToLevelToOddNodesMap(std::map>>& levelToOddNodesMap, uint_fast64_t level) const { diff --git a/src/storm/storage/jani/JSONExporter.cpp b/src/storm/storage/jani/JSONExporter.cpp index 834ce8623..c39a6b79b 100644 --- a/src/storm/storage/jani/JSONExporter.cpp +++ b/src/storm/storage/jani/JSONExporter.cpp @@ -5,6 +5,7 @@ #include #include "storm/utility/macros.h" +#include "storm/utility/file.h" #include "storm/exceptions/FileIoException.h" #include "storm/exceptions/NotSupportedException.h" @@ -510,20 +511,11 @@ namespace storm { return modernjson::json(expression.getValueAsDouble()); } - - - - - - void JsonExporter::toFile(storm::jani::Model const& janiModel, std::vector const& formulas, std::string const& filepath, bool checkValid) { - std::ofstream ofs; - ofs.open (filepath, std::ofstream::out ); - if(ofs.is_open()) { - toStream(janiModel, formulas, ofs, checkValid); - } else { - STORM_LOG_THROW(false, storm::exceptions::FileIoException, "Cannot open " << filepath); - } + std::ofstream stream; + storm::utility::openFile(filepath, stream); + toStream(janiModel, formulas, stream, checkValid); + storm::utility::closeFile(stream); } void JsonExporter::toStream(storm::jani::Model const& janiModel, std::vector const& formulas, std::ostream& os, bool checkValid) { diff --git a/src/storm/utility/export.h b/src/storm/utility/export.h index 3a6891780..b4f5020c0 100644 --- a/src/storm/utility/export.h +++ b/src/storm/utility/export.h @@ -12,7 +12,7 @@ #include #include "storm/utility/macros.h" -#include "storm/exceptions/FileIoException.h" +#include "storm/utility/file.h" //#include "storm/storage/parameters.h" //#include "storm/settings/modules/ParametricSettings.h" @@ -40,19 +40,11 @@ namespace storm { filestream.close(); } */ - - inline void exportStringToFile(std::string const& str, std::string filepath) { - std::ofstream filestream; - filestream.open(filepath); - STORM_LOG_THROW(filestream.is_open(), storm::exceptions::FileIoException , "Could not open file " << filepath << "."); - filestream << str; - } template inline void exportDataToCSVFile(std::string filepath, std::vector> const& data, boost::optional> const& columnHeaders) { std::ofstream filestream; - filestream.open(filepath); - STORM_LOG_THROW(filestream.is_open(), storm::exceptions::FileIoException , "Could not open file " << filepath << "."); + storm::utility::openFile(filepath, filestream); if(columnHeaders) { for(auto columnIt = columnHeaders->begin(); columnIt != columnHeaders->end(); ++columnIt) { @@ -73,10 +65,9 @@ namespace storm { } filestream << std::endl; } + storm::utility::closeFile(filestream); } } } - - #endif diff --git a/src/storm/utility/file.h b/src/storm/utility/file.h new file mode 100644 index 000000000..4e234dee5 --- /dev/null +++ b/src/storm/utility/file.h @@ -0,0 +1,81 @@ +/** + * @file: file.h + * @author: Sebastian Junges + * + * @since October 7, 2014 + */ + +#ifndef STORM_UTILITY_FILE_H_ +#define STORM_UTILITY_FILE_H_ + +#include + +#include "storm/utility/macros.h" +#include "storm/exceptions/FileIoException.h" + +namespace storm { + namespace utility { + + /*! + * Open the given file for writing. + * + * @param filename Path and name of the file to be tested. + * @param filestream Contains the file handler afterwards. + * @param append If true, the new content is appended instead of clearing the existing content. + */ + inline void openFile(std::string const& filepath, std::ofstream& filestream, bool append = false) { + if (append) { + filestream.open(filepath, std::ios::app); + } else { + filestream.open(filepath); + } + STORM_LOG_THROW(filestream, storm::exceptions::FileIoException , "Could not open file " << filepath << "."); + STORM_PRINT_AND_LOG("Write to file " << filepath << "." << std::endl); + } + + /*! + * Open the given file for reading. + * + * @param filename Path and name of the file to be tested. + * @param filestream Contains the file handler afterwards. + */ + inline void openFile(std::string const& filepath, std::ifstream& filestream) { + filestream.open(filepath); + STORM_LOG_THROW(filestream, storm::exceptions::FileIoException , "Could not open file " << filepath << "."); + } + + /*! + * Close the given file after writing. + * + * @param filestream Contains the file handler to close. + */ + inline void closeFile(std::ofstream& stream) { + stream.close(); + } + + /*! + * Close the given file after reading. + * + * @param filestream Contains the file handler to close. + */ + inline void closeFile(std::ifstream& stream) { + stream.close(); + } + + /*! + * Tests whether the given file exists and is readable. + * + * @param filename Path and name of the file to be tested. + * @return True iff the file exists and is readable. + */ + inline bool fileExistsAndIsReadable(std::string const& filename) { + // Test by opening an input file stream and testing the stream flags. + std::ifstream filestream; + filestream.open(filename); + return filestream.good(); + } + + } +} + +#endif diff --git a/src/storm/utility/storm.h b/src/storm/utility/storm.h index ef4785c1a..3aca0dbe2 100644 --- a/src/storm/utility/storm.h +++ b/src/storm/utility/storm.h @@ -97,6 +97,7 @@ #include "storm/exceptions/NotSupportedException.h" #include "storm/utility/Stopwatch.h" +#include "storm/utility/file.h" namespace storm { @@ -434,7 +435,7 @@ namespace storm { inline void exportParametricResultToFile(storm::RationalFunction const& result, storm::models::sparse::Dtmc::ConstraintCollector const& constraintCollector, std::string const& path) { std::ofstream filestream; - filestream.open(path); + storm::utility::openFile(path, filestream); // TODO: add checks. filestream << "!Parameters: "; std::set vars = result.gatherVariables(); @@ -445,7 +446,7 @@ namespace storm { std::copy(constraintCollector.getWellformedConstraints().begin(), constraintCollector.getWellformedConstraints().end(), std::ostream_iterator>(filestream, "\n")); filestream << "!Graph-preserving Constraints: " << std::endl; std::copy(constraintCollector.getGraphPreservingConstraints().begin(), constraintCollector.getGraphPreservingConstraints().end(), std::ostream_iterator>(filestream, "\n")); - filestream.close(); + storm::utility::closeFile(filestream); } template<> @@ -623,10 +624,10 @@ namespace storm { template void exportMatrixToFile(std::shared_ptr> model, std::string const& filepath) { STORM_LOG_THROW(model->getType() != storm::models::ModelType::Ctmc, storm::exceptions::NotImplementedException, "This functionality is not yet implemented." ); - std::ofstream ofs; - ofs.open (filepath, std::ofstream::out); - model->getTransitionMatrix().printAsMatlabMatrix(ofs); - ofs.close(); + std::ofstream stream; + storm::utility::openFile(filepath, stream); + model->getTransitionMatrix().printAsMatlabMatrix(stream); + storm::utility::closeFile(stream); } } diff --git a/src/test/parser/MappedFileTest.cpp b/src/test/parser/MappedFileTest.cpp index 3e8affe52..f33ee3aa2 100644 --- a/src/test/parser/MappedFileTest.cpp +++ b/src/test/parser/MappedFileTest.cpp @@ -11,6 +11,7 @@ #include #include "storm/parser/MappedFile.h" #include "storm/utility/cstring.h" +#include "storm/utility/file.h" #include "storm/exceptions/FileIoException.h" TEST(MappedFileTest, NonExistingFile) { @@ -41,12 +42,12 @@ TEST(MappedFileTest, ExistsAndReadble) { // Test the fileExistsAndIsReadable() method under various circumstances. // File exists and is readable. - ASSERT_TRUE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/txt/testStringFile.txt")); + ASSERT_TRUE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/txt/testStringFile.txt")); // File does not exist. - ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/nonExistingFile.not")); + ASSERT_FALSE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/nonExistingFile.not")); // File exists but is not readable. // TODO: Find portable solution to providing a situation in which a file exists but is not readable. - //ASSERT_FALSE(storm::parser::MappedFile::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/parser/unreadableFile.txt")); + //ASSERT_FALSE(storm::utility::fileExistsAndIsReadable(STORM_TEST_RESOURCES_DIR "/parser/unreadableFile.txt")); }