ArchiveOpener.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <boost/archive/text_oarchive.hpp>
00031 #include <boost/archive/text_iarchive.hpp>
00032
00033 #include <sstream>
00034 #include <iostream>
00035
00036 #include "ArchiveOpener.hpp"
00037 #include "ArchiveLocationInfo.hpp"
00038 #include "ProcessSpecificArchive.hpp"
00039 #include "Exception.hpp"
00040 #include "OutputFileHandler.hpp"
00041
00048 template<>
00049 ArchiveOpener<boost::archive::text_iarchive, std::ifstream>::ArchiveOpener(
00050 const FileFinder& rDirectory,
00051 const std::string& rFileNameBase,
00052 unsigned procId)
00053 : mpCommonStream(NULL),
00054 mpPrivateStream(NULL),
00055 mpCommonArchive(NULL),
00056 mpPrivateArchive(NULL)
00057 {
00058
00059 ArchiveLocationInfo::SetArchiveDirectory(rDirectory);
00060 std::string private_path = ArchiveLocationInfo::GetProcessUniqueFilePath(rFileNameBase, procId);
00061 std::stringstream common_path;
00062 common_path << ArchiveLocationInfo::GetArchiveDirectory() << rFileNameBase;
00063
00064
00065 mpCommonStream = new std::ifstream(common_path.str().c_str(), std::ios::binary);
00066 if (!mpCommonStream->is_open())
00067 {
00068 delete mpCommonStream;
00069 EXCEPTION("Cannot load main archive file: " + common_path.str());
00070 }
00071
00072 try
00073 {
00074 mpCommonArchive = new boost::archive::text_iarchive(*mpCommonStream);
00075 }
00076 catch (boost::archive::archive_exception& boost_exception)
00077 {
00078 if (boost_exception.code == boost::archive::archive_exception::unsupported_version)
00079 {
00080
00081 delete mpCommonArchive;
00082 delete mpCommonStream;
00083 EXCEPTION("Could not open Boost archive '" + common_path.str() + "' because it was written by a more recent Boost. Check process-specific archives too");
00084 }
00085 else
00086 {
00087
00088 #define COVERAGE_IGNORE
00089 throw boost_exception;
00090 #undef COVERAGE_IGNORE
00091 }
00092 }
00093
00094
00095 mpPrivateStream = new std::ifstream(private_path.c_str(), std::ios::binary);
00096 if (!mpPrivateStream->is_open())
00097 {
00098 delete mpPrivateStream;
00099 delete mpCommonArchive;
00100 delete mpCommonStream;
00101 EXCEPTION("Cannot load secondary archive file: " + private_path);
00102 }
00103 mpPrivateArchive = new boost::archive::text_iarchive(*mpPrivateStream);
00104 ProcessSpecificArchive<boost::archive::text_iarchive>::Set(mpPrivateArchive);
00105 }
00106
00107 template<>
00108 ArchiveOpener<boost::archive::text_iarchive, std::ifstream>::~ArchiveOpener()
00109 {
00110 ProcessSpecificArchive<boost::archive::text_iarchive>::Set(NULL);
00111 delete mpPrivateArchive;
00112 delete mpPrivateStream;
00113 delete mpCommonArchive;
00114 delete mpCommonStream;
00115 }
00116
00123 template<>
00124 ArchiveOpener<boost::archive::text_oarchive, std::ofstream>::ArchiveOpener(
00125 const FileFinder& rDirectory,
00126 const std::string& rFileNameBase,
00127 unsigned procId)
00128 : mpCommonStream(NULL),
00129 mpPrivateStream(NULL),
00130 mpCommonArchive(NULL),
00131 mpPrivateArchive(NULL)
00132 {
00133
00134 if (procId != PetscTools::GetMyRank())
00135 {
00136 EXCEPTION("Specifying the secondary archive file ID doesn't make sense when writing.");
00137 }
00138
00139
00140 ArchiveLocationInfo::SetArchiveDirectory(rDirectory);
00141 if (ArchiveLocationInfo::GetIsDirRelativeToChasteTestOutput())
00142 {
00143
00144 OutputFileHandler handler(ArchiveLocationInfo::GetArchiveRelativePath(), false);
00145 }
00146 std::string private_path = ArchiveLocationInfo::GetProcessUniqueFilePath(rFileNameBase);
00147 std::stringstream common_path;
00148 common_path << ArchiveLocationInfo::GetArchiveDirectory() << rFileNameBase;
00149
00150
00151 if (PetscTools::AmMaster())
00152 {
00153 mpCommonStream = new std::ofstream(common_path.str().c_str());
00154 if (!mpCommonStream->is_open())
00155 {
00156 delete mpCommonStream;
00157 EXCEPTION("Failed to open main archive file for writing: " + common_path.str());
00158 }
00159 }
00160 else
00161 {
00162
00163 mpCommonStream = new std::ofstream("/dev/null");
00164 #define COVERAGE_IGNORE
00165 if (!mpCommonStream->is_open())
00166 {
00167 delete mpCommonStream;
00168 EXCEPTION("Failed to open dummy archive file '/dev/null' for writing");
00169 }
00170 #undef COVERAGE_IGNORE
00171 }
00172 mpCommonArchive = new boost::archive::text_oarchive(*mpCommonStream);
00173
00174
00175 mpPrivateStream = new std::ofstream(private_path.c_str());
00176 if (!mpPrivateStream->is_open())
00177 {
00178 delete mpPrivateStream;
00179 delete mpCommonArchive;
00180 delete mpCommonStream;
00181 EXCEPTION("Failed to open secondary archive file for writing: " + private_path);
00182 }
00183 mpPrivateArchive = new boost::archive::text_oarchive(*mpPrivateStream);
00184 ProcessSpecificArchive<boost::archive::text_oarchive>::Set(mpPrivateArchive);
00185 }
00186
00187 template<>
00188 ArchiveOpener<boost::archive::text_oarchive, std::ofstream>::~ArchiveOpener()
00189 {
00190 ProcessSpecificArchive<boost::archive::text_oarchive>::Set(NULL);
00191 delete mpPrivateArchive;
00192 delete mpPrivateStream;
00193 delete mpCommonArchive;
00194 delete mpCommonStream;
00195
00196
00197
00198
00199
00200
00201 PetscTools::Barrier("~ArchiveOpener");
00202 }