/** * \file file.cpp * \brief Get directories used by IMP. * * Copyright 2007-2013 IMP Inventors. All rights reserved. * */ #include #include #include #include //#include #include #ifdef _MSC_VER #include #endif IMPBASE_BEGIN_NAMESPACE namespace { template struct LazyFileStorage: public internal::IOStorage { typedef internal::IOStorage P; std::string name_; bool open_; bool append_; FileStream stream_; LazyFileStorage(std::string name, bool append=false): P(name), open_(false), append_(append){} BaseStream& get_stream() { if (!open_) { if (append_) { stream_.open(P::get_name().c_str(), std::fstream::app); } else { stream_.open(P::get_name().c_str()); } if (!stream_) { IMP_THROW("Unable to open file " << P::get_name(), IOException); } open_=true; } return stream_; } }; template struct FileStorage: public internal::IOStorage { typedef internal::IOStorage P; FileStream stream_; FileStorage(std::string name): P(name), stream_(name.c_str()){ if (!stream_) { IMP_THROW("Unable to open file " << name, IOException); } } BaseStream& get_stream() { return stream_; } }; template struct StreamStorage: public internal::IOStorage { typedef internal::IOStorage P; BaseStream &stream_; StreamStorage(BaseStream &stream, std::string name): P(name), stream_(stream){} BaseStream& get_stream() { return stream_; } }; template struct OwnedStreamStorage: public internal::IOStorage{ typedef internal::IOStorage P; BaseStream &stream_; OwnerPointer ref_; OwnedStreamStorage(BaseStream &stream, Object*o): P("python stream"), stream_(stream), ref_(o){} BaseStream& get_stream() { return stream_; } }; } TextOutput::TextOutput(const char *c, bool append): out_(new LazyFileStorage(c, append)){} TextOutput::TextOutput(std::string c, bool append): out_(new LazyFileStorage(c, append)){} TextOutput::TextOutput(std::ostream &in, std::string name): out_(new StreamStorage(in, name)){} TextOutput::TextOutput(TextProxy out): out_(new OwnedStreamStorage(*out.str_, out.ptr_)){} TextOutput::TextOutput(int) { IMP_THROW("Wrong argument type", IOException); } TextOutput::TextOutput(double) { IMP_THROW("Wrong argument type", IOException); } TextInput::TextInput(const char *c): in_(new LazyFileStorage(c)){} TextInput::TextInput(std::string c): in_(new LazyFileStorage(c)){} TextInput::TextInput(std::istream &in, std::string name): in_(new StreamStorage(in, name)){} TextInput::TextInput(TextProxy out): in_(new OwnedStreamStorage(*out.str_, out.ptr_)){} TextInput::TextInput(int) { IMP_THROW("Wrong argument type", IOException); } TextInput::TextInput(double) { IMP_THROW("Wrong argument type", IOException); } namespace { #ifndef __clang__ void testf(TextInput) { } void testcall() { testf(std::string("filename")); std::ifstream inf("infile"); testf(inf); } #endif } TextOutput create_temporary_file(std::string prefix, std::string suffix) { return TextOutput(create_temporary_file_name(prefix, suffix)); } std::string create_temporary_file_name(std::string prefix, std::string suffix) { char *env = getenv("IMP_BUILD_ROOT"); std::string imp_tmp; if (env) { imp_tmp= internal::get_concatenated_path(env, "build/tmp"); } #if defined _MSC_VER std::string tpathstr; if (imp_tmp.empty()) { TCHAR tpath[MAX_PATH]; DWORD dwRetVal = GetTempPath(MAX_PATH,tpath); if (dwRetVal > MAX_PATH || (dwRetVal == 0)) { IMP_THROW("Unable to find temporary path", IOException); } tpathstr=tpath; } else { tpathstr= imp_tmp; } char filename[MAX_PATH]; if (GetTempFileName(tpathstr.c_str(), prefix.c_str(), 0, filename)==0) { IMP_THROW("Unable to create temp file in " << tpathstr, IOException); } return std::string(filename)+suffix; #else std::string pathprefix; if (imp_tmp.empty()) { pathprefix="/tmp"; } else { pathprefix=imp_tmp; } std::string templ=internal::get_concatenated_path(pathprefix, prefix+".XXXXXX"); boost::scoped_array filename; filename.reset(new char[templ.size()+suffix.size()+1]); std::copy(templ.begin(), templ.end(), filename.get()); #ifdef __APPLE__ std::copy(suffix.begin(), suffix.end(), filename.get()+templ.size()); filename[templ.size()+ suffix.size()]='\0'; int fd = mkstemps(filename.get(), suffix.size()); if (fd == -1) { IMP_THROW("Unable to create temporary file: " << filename.get(), IOException); } close(fd); #else filename[templ.size()]='\0'; int fd = mkstemp(filename.get()); if (fd == -1) { IMP_THROW("Unable to create temporary file: " << filename.get(), IOException); } close(fd); std::copy(suffix.begin(), suffix.end(), filename.get()+templ.size()); filename[templ.size()+ suffix.size()]='\0'; #endif return std::string(filename.get()); #endif } std::string get_relative_path(std::string base, std::string relative) { std::string dir= internal::get_directory_path(base); return internal::get_concatenated_path(dir, relative); } IMPBASE_END_NAMESPACE