Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-2019 The plumed team 3 : (see the PEOPLE file at the root of the distribution for a list of names) 4 : 5 : See http://www.plumed.org for more information. 6 : 7 : This file is part of plumed, version 2. 8 : 9 : plumed is free software: you can redistribute it and/or modify 10 : it under the terms of the GNU Lesser General Public License as published by 11 : the Free Software Foundation, either version 3 of the License, or 12 : (at your option) any later version. 13 : 14 : plumed is distributed in the hope that it will be useful, 15 : but WITHOUT ANY WARRANTY; without even the implied warranty of 16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 : GNU Lesser General Public License for more details. 18 : 19 : You should have received a copy of the GNU Lesser General Public License 20 : along with plumed. If not, see <http://www.gnu.org/licenses/>. 21 : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 22 : #include "FileBase.h" 23 : #include "Exception.h" 24 : #include "core/Action.h" 25 : #include "core/PlumedMain.h" 26 : #include "core/Value.h" 27 : #include "Communicator.h" 28 : #include "Tools.h" 29 : #include <cstdarg> 30 : #include <cstring> 31 : #include <cstdlib> 32 : 33 : #include <iostream> 34 : #include <string> 35 : 36 : #ifdef __PLUMED_HAS_ZLIB 37 : #include <zlib.h> 38 : #endif 39 : 40 : namespace PLMD { 41 : 42 728 : FileBase& FileBase::link(FILE*fp) { 43 728 : plumed_massert(!this->fp,"cannot link an already open file"); 44 728 : this->fp=fp; 45 728 : cloned=true; 46 728 : return *this; 47 : } 48 : 49 4250 : FileBase& FileBase::flush() { 50 4250 : if(fp) fflush(fp); 51 4250 : return *this; 52 : } 53 : 54 7179 : FileBase& FileBase::link(Communicator&comm) { 55 7179 : plumed_massert(!fp,"cannot link an already open file"); 56 7179 : this->comm=&comm; 57 7179 : return *this; 58 : } 59 : 60 4259 : FileBase& FileBase::link(PlumedMain&plumed) { 61 4259 : plumed_massert(!fp,"cannot link an already open file"); 62 4259 : this->plumed=&plumed; 63 4259 : link(plumed.comm); 64 4259 : return *this; 65 : } 66 : 67 3574 : FileBase& FileBase::link(Action&action) { 68 3574 : plumed_massert(!fp,"cannot link an already open file"); 69 3574 : this->action=&action; 70 3574 : link(action.plumed); 71 3574 : return *this; 72 : } 73 : 74 1551 : bool FileBase::FileExist(const std::string& path) { 75 : bool do_exist=false; 76 4653 : this->path=appendSuffix(path,getSuffix()); 77 1551 : mode="r"; 78 1551 : FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 79 1551 : if(!ff) { 80 : this->path=path; 81 515 : ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 82 : mode="r"; 83 : } 84 1551 : if(ff) {do_exist=true; fclose(ff);} 85 1551 : if(comm) comm->Barrier(); 86 1551 : return do_exist; 87 : } 88 : 89 9699 : bool FileBase::isOpen() { 90 : bool isopen=false; 91 9699 : if(fp) isopen=true; 92 9699 : return isopen; 93 : } 94 : 95 1918 : void FileBase::close() { 96 1918 : plumed_assert(!cloned); 97 1918 : eof=false; 98 1918 : err=false; 99 1918 : if(fp) std::fclose(fp); 100 : #ifdef __PLUMED_HAS_ZLIB 101 1918 : if(gzfp) gzclose(gzFile(gzfp)); 102 : #endif 103 1918 : fp=NULL; 104 1918 : gzfp=NULL; 105 1918 : } 106 : 107 8075 : FileBase::FileBase(): 108 : fp(NULL), 109 : gzfp(NULL), 110 : comm(NULL), 111 : plumed(NULL), 112 : action(NULL), 113 : cloned(false), 114 : eof(false), 115 : err(false), 116 : heavyFlush(false), 117 24225 : enforcedSuffix_(false) 118 : { 119 8075 : } 120 : 121 8075 : FileBase::~FileBase() 122 : { 123 8075 : if(plumed) plumed->eraseFile(*this); 124 8075 : if(!cloned && fp) fclose(fp); 125 : #ifdef __PLUMED_HAS_ZLIB 126 8075 : if(!cloned && gzfp) gzclose(gzFile(gzfp)); 127 : #endif 128 8075 : } 129 : 130 2945332 : FileBase::operator bool()const { 131 2945332 : return !eof; 132 : } 133 : 134 5990 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) { 135 5990 : if(path=="/dev/null") return path; // do not append a suffix to /dev/null 136 5749 : std::string ret=path; 137 5749 : std::string ext=Tools::extension(path); 138 : 139 : // These are the recognized extensions so far: 140 : // gz xtc trr 141 : // If a file name ends with one of these extensions, the suffix is added *before* 142 : // the extension. This is useful when extensions are conventionally used 143 : // to detect file type, so as to allow easier file manipulation. 144 : // Removing this line, any extension recognized by Tools::extension() would be considered 145 : // if(ext!="gz" && ext!="xtc" && ext!="trr") ext=""; 146 : 147 5749 : if(ext.length()>0) { 148 4211 : int l=path.length()-(ext.length()+1); 149 4211 : plumed_assert(l>=0); 150 8422 : ret=ret.substr(0,l); 151 : } 152 : ret+=suffix; 153 9960 : if(ext.length()>0)ret+="."+ext; 154 : return ret; 155 : } 156 : 157 230 : FileBase& FileBase::enforceSuffix(const std::string&suffix) { 158 230 : enforcedSuffix_=true; 159 230 : enforcedSuffix=suffix; 160 230 : return *this; 161 : } 162 : 163 4852 : std::string FileBase::getSuffix()const { 164 4852 : if(enforcedSuffix_) return enforcedSuffix; 165 4616 : if(plumed) return plumed->getSuffix(); 166 421 : return ""; 167 : } 168 : 169 5874 : }