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 mpPrivateStream = new std::ifstream(private_path.c_str(), std::ios::binary);
00095 if (!mpPrivateStream->is_open())
00096 {
00097 delete mpPrivateStream;
00098 delete mpCommonArchive;
00099 delete mpCommonStream;
00100 EXCEPTION("Cannot load secondary archive file: " + private_path);
00101 }
00102 mpPrivateArchive = new boost::archive::text_iarchive(*mpPrivateStream);
00103 ProcessSpecificArchive<boost::archive::text_iarchive>::Set(mpPrivateArchive);
00104 }
00105
00106 template<>
00107 ArchiveOpener<boost::archive::text_iarchive, std::ifstream>::~ArchiveOpener()
00108 {
00109 ProcessSpecificArchive<boost::archive::text_iarchive>::Set(NULL);
00110 delete mpPrivateArchive;
00111 delete mpPrivateStream;
00112 delete mpCommonArchive;
00113 delete mpCommonStream;
00114 }
00115
00122 template<>
00123 ArchiveOpener<boost::archive::text_oarchive, std::ofstream>::ArchiveOpener(
00124 const FileFinder& rDirectory,
00125 const std::string& rFileNameBase,
00126 unsigned procId)
00127 : mpCommonStream(NULL),
00128 mpPrivateStream(NULL),
00129 mpCommonArchive(NULL),
00130 mpPrivateArchive(NULL)
00131 {
00132
00133 if (procId != PetscTools::GetMyRank())
00134 {
00135 EXCEPTION("Specifying the secondary archive file ID doesn't make sense when writing.");
00136 }
00137
00138 ArchiveLocationInfo::SetArchiveDirectory(rDirectory);
00139 if (ArchiveLocationInfo::GetIsDirRelativeToChasteTestOutput())
00140 {
00141
00142 OutputFileHandler handler(ArchiveLocationInfo::GetArchiveRelativePath(), false);
00143 }
00144 std::string private_path = ArchiveLocationInfo::GetProcessUniqueFilePath(rFileNameBase);
00145 std::stringstream common_path;
00146 common_path << ArchiveLocationInfo::GetArchiveDirectory() << rFileNameBase;
00147
00148
00149 if (PetscTools::AmMaster())
00150 {
00151 mpCommonStream = new std::ofstream(common_path.str().c_str());
00152 if (!mpCommonStream->is_open())
00153 {
00154 delete mpCommonStream;
00155 EXCEPTION("Failed to open main archive file for writing: " + common_path.str());
00156 }
00157 }
00158 else
00159 {
00160
00161
00162 mpCommonStream = new std::ofstream("/dev/null");
00163 #define COVERAGE_IGNORE
00164 if (!mpCommonStream->is_open())
00165 {
00166 delete mpCommonStream;
00167 EXCEPTION("Failed to open dummy archive file '/dev/null' for writing");
00168 }
00169 #undef COVERAGE_IGNORE
00170 }
00171 mpCommonArchive = new boost::archive::text_oarchive(*mpCommonStream);
00172
00173
00174 mpPrivateStream = new std::ofstream(private_path.c_str());
00175 if (!mpPrivateStream->is_open())
00176 {
00177 delete mpPrivateStream;
00178 delete mpCommonArchive;
00179 delete mpCommonStream;
00180 EXCEPTION("Failed to open secondary archive file for writing: " + private_path);
00181 }
00182 mpPrivateArchive = new boost::archive::text_oarchive(*mpPrivateStream);
00183 ProcessSpecificArchive<boost::archive::text_oarchive>::Set(mpPrivateArchive);
00184 }
00185
00186 template<>
00187 ArchiveOpener<boost::archive::text_oarchive, std::ofstream>::~ArchiveOpener()
00188 {
00189 ProcessSpecificArchive<boost::archive::text_oarchive>::Set(NULL);
00190 delete mpPrivateArchive;
00191 delete mpPrivateStream;
00192 delete mpCommonArchive;
00193 delete mpCommonStream;
00194
00195
00196
00197
00198
00199
00200 PetscTools::Barrier("~ArchiveOpener");
00201 }
00202
00203
00204