Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-2023 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 20867 : FileBase& FileBase::link(FILE*fp) { 43 20867 : plumed_massert(!this->fp,"cannot link an already open file"); 44 20867 : this->fp=fp; 45 20867 : cloned=true; 46 20867 : return *this; 47 : } 48 : 49 4719 : FileBase& FileBase::flush() { 50 4719 : if(fp) fflush(fp); 51 4719 : return *this; 52 : } 53 : 54 409217 : FileBase& FileBase::link(Communicator&comm) { 55 409217 : plumed_massert(!fp,"cannot link an already open file"); 56 409217 : this->comm=&comm; 57 409217 : return *this; 58 : } 59 : 60 4607 : FileBase& FileBase::link(PlumedMain&plumed) { 61 4607 : plumed_massert(!fp,"cannot link an already open file"); 62 4607 : this->plumed=&plumed; 63 4607 : link(plumed.comm); 64 4607 : return *this; 65 : } 66 : 67 3815 : FileBase& FileBase::link(Action&action) { 68 3815 : plumed_massert(!fp,"cannot link an already open file"); 69 3815 : this->action=&action; 70 3815 : link(action.plumed); 71 3815 : return *this; 72 : } 73 : 74 1793 : bool FileBase::FileExist(const std::string& path) { 75 : bool do_exist=false; 76 3586 : this->path=appendSuffix(path,getSuffix()); 77 1793 : mode="r"; 78 1793 : FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 79 1793 : if(!ff) { 80 : this->path=path; 81 565 : ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 82 : mode="r"; 83 : } 84 1793 : if(ff) {do_exist=true; fclose(ff);} 85 1793 : if(comm) comm->Barrier(); 86 1793 : return do_exist; 87 : } 88 : 89 411529 : bool FileBase::isOpen() { 90 : bool isopen=false; 91 411529 : if(fp) isopen=true; 92 411529 : return isopen; 93 : } 94 : 95 992 : void FileBase::close() { 96 992 : plumed_assert(!cloned); 97 992 : eof=false; 98 992 : err=false; 99 992 : if(fp) std::fclose(fp); 100 : #ifdef __PLUMED_HAS_ZLIB 101 992 : if(gzfp) gzclose(gzFile(gzfp)); 102 : #endif 103 992 : fp=NULL; 104 992 : gzfp=NULL; 105 992 : } 106 : 107 430294 : FileBase::FileBase(): 108 430294 : fp(NULL), 109 430294 : gzfp(NULL), 110 430294 : comm(NULL), 111 430294 : plumed(NULL), 112 430294 : action(NULL), 113 430294 : cloned(false), 114 430294 : eof(false), 115 430294 : err(false), 116 430294 : heavyFlush(false), 117 430294 : enforcedSuffix_(false) 118 : { 119 430294 : } 120 : 121 430294 : FileBase::~FileBase() 122 : { 123 430294 : if(plumed) plumed->eraseFile(*this); 124 430294 : if(!cloned && fp) fclose(fp); 125 : #ifdef __PLUMED_HAS_ZLIB 126 430294 : if(!cloned && gzfp) gzclose(gzFile(gzfp)); 127 : #endif 128 430294 : } 129 : 130 29221069 : FileBase::operator bool()const { 131 29221069 : return !eof; 132 : } 133 : 134 6506 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) { 135 6506 : if(path=="/dev/null") return path; // do not append a suffix to /dev/null 136 6331 : std::string ret=path; 137 6331 : 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 6331 : if(ext.length()>0) { 148 4578 : int l=path.length()-(ext.length()+1); 149 4578 : plumed_assert(l>=0); 150 9156 : ret=ret.substr(0,l); 151 : } 152 : ret+=suffix; 153 10909 : if(ext.length()>0)ret+="."+ext; 154 : return ret; 155 : } 156 : 157 258 : FileBase& FileBase::enforceSuffix(const std::string&suffix) { 158 258 : enforcedSuffix_=true; 159 258 : enforcedSuffix=suffix; 160 258 : return *this; 161 : } 162 : 163 5311 : std::string FileBase::getSuffix()const { 164 5311 : if(enforcedSuffix_) return enforcedSuffix; 165 5047 : if(plumed) return plumed->getSuffix(); 166 501 : return ""; 167 : } 168 : 169 : }