Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2012-2020 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 691 : FileBase& FileBase::link(FILE*fp) { 43 691 : plumed_massert(!this->fp,"cannot link an already open file"); 44 691 : this->fp=fp; 45 691 : cloned=true; 46 691 : return *this; 47 : } 48 : 49 4110 : FileBase& FileBase::flush() { 50 4110 : if(fp) fflush(fp); 51 4110 : return *this; 52 : } 53 : 54 6670 : FileBase& FileBase::link(Communicator&comm) { 55 6670 : plumed_massert(!fp,"cannot link an already open file"); 56 6670 : this->comm=&comm; 57 6670 : return *this; 58 : } 59 : 60 3899 : FileBase& FileBase::link(PlumedMain&plumed) { 61 3899 : plumed_massert(!fp,"cannot link an already open file"); 62 3899 : this->plumed=&plumed; 63 3899 : link(plumed.comm); 64 3899 : return *this; 65 : } 66 : 67 3249 : FileBase& FileBase::link(Action&action) { 68 3249 : plumed_massert(!fp,"cannot link an already open file"); 69 3249 : this->action=&action; 70 3249 : link(action.plumed); 71 3249 : return *this; 72 : } 73 : 74 1452 : bool FileBase::FileExist(const std::string& path) { 75 : bool do_exist=false; 76 4356 : this->path=appendSuffix(path,getSuffix()); 77 1452 : mode="r"; 78 1452 : FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 79 1452 : if(!ff) { 80 : this->path=path; 81 512 : ff=std::fopen(const_cast<char*>(this->path.c_str()),"r"); 82 : mode="r"; 83 : } 84 1452 : if(ff) {do_exist=true; fclose(ff);} 85 1452 : if(comm) comm->Barrier(); 86 1452 : return do_exist; 87 : } 88 : 89 9523 : bool FileBase::isOpen() { 90 : bool isopen=false; 91 9523 : if(fp) isopen=true; 92 9523 : return isopen; 93 : } 94 : 95 1661 : void FileBase::close() { 96 1661 : plumed_assert(!cloned); 97 1661 : eof=false; 98 1661 : err=false; 99 1661 : if(fp) std::fclose(fp); 100 : #ifdef __PLUMED_HAS_ZLIB 101 1661 : if(gzfp) gzclose(gzFile(gzfp)); 102 : #endif 103 1661 : fp=NULL; 104 1661 : gzfp=NULL; 105 1661 : } 106 : 107 7495 : 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 22485 : enforcedSuffix_(false) 118 : { 119 7495 : } 120 : 121 14990 : FileBase::~FileBase() 122 : { 123 7495 : if(plumed) plumed->eraseFile(*this); 124 7495 : if(!cloned && fp) fclose(fp); 125 : #ifdef __PLUMED_HAS_ZLIB 126 7495 : if(!cloned && gzfp) gzclose(gzFile(gzfp)); 127 : #endif 128 7495 : } 129 : 130 2458608 : FileBase::operator bool()const { 131 2458608 : return !eof; 132 : } 133 : 134 5498 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) { 135 5498 : if(path=="/dev/null") return path; // do not append a suffix to /dev/null 136 : std::string ret=path; 137 5324 : 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 5324 : if(ext.length()>0) { 148 3837 : int l=path.length()-(ext.length()+1); 149 3837 : plumed_assert(l>=0); 150 7674 : ret=ret.substr(0,l); 151 : } 152 : ret+=suffix; 153 9161 : if(ext.length()>0)ret+="."+ext; 154 : return ret; 155 : } 156 : 157 226 : FileBase& FileBase::enforceSuffix(const std::string&suffix) { 158 226 : enforcedSuffix_=true; 159 226 : enforcedSuffix=suffix; 160 226 : return *this; 161 : } 162 : 163 4443 : std::string FileBase::getSuffix()const { 164 4443 : if(enforcedSuffix_) return enforcedSuffix; 165 4213 : if(plumed) return plumed->getSuffix(); 166 374 : return ""; 167 : } 168 : 169 5517 : }