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 592 : FileBase& FileBase::link(FILE*fp) {
43 592 : plumed_massert(!this->fp,"cannot link an already open file");
44 592 : this->fp=fp;
45 592 : cloned=true;
46 592 : return *this;
47 : }
48 :
49 3542 : FileBase& FileBase::flush() {
50 3542 : if(fp) fflush(fp);
51 3542 : return *this;
52 : }
53 :
54 5978 : FileBase& FileBase::link(Communicator&comm) {
55 5978 : plumed_massert(!fp,"cannot link an already open file");
56 5978 : this->comm=&comm;
57 5978 : return *this;
58 : }
59 :
60 3553 : FileBase& FileBase::link(PlumedMain&plumed) {
61 3553 : plumed_massert(!fp,"cannot link an already open file");
62 3553 : this->plumed=&plumed;
63 3553 : link(plumed.comm);
64 3553 : return *this;
65 : }
66 :
67 2981 : FileBase& FileBase::link(Action&action) {
68 2981 : plumed_massert(!fp,"cannot link an already open file");
69 2981 : this->action=&action;
70 2981 : link(action.plumed);
71 2981 : return *this;
72 : }
73 :
74 1235 : bool FileBase::FileExist(const std::string& path) {
75 : bool do_exist=false;
76 3705 : this->path=appendSuffix(path,getSuffix());
77 1235 : mode="r";
78 1235 : FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
79 1235 : if(!ff) {
80 : this->path=path;
81 401 : ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
82 : mode="r";
83 : }
84 1235 : if(ff) {do_exist=true; fclose(ff);}
85 1235 : if(comm) comm->Barrier();
86 1235 : return do_exist;
87 : }
88 :
89 6950 : bool FileBase::isOpen() {
90 : bool isopen=false;
91 6950 : if(fp) isopen=true;
92 6950 : return isopen;
93 : }
94 :
95 2056 : void FileBase::close() {
96 2056 : plumed_assert(!cloned);
97 2056 : eof=false;
98 2056 : err=false;
99 2056 : if(fp) std::fclose(fp);
100 : #ifdef __PLUMED_HAS_ZLIB
101 2056 : if(gzfp) gzclose(gzFile(gzfp));
102 : #endif
103 2056 : fp=NULL;
104 2056 : gzfp=NULL;
105 2056 : }
106 :
107 6695 : 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 20085 : enforcedSuffix_(false)
118 : {
119 6695 : }
120 :
121 13390 : FileBase::~FileBase()
122 : {
123 6695 : if(plumed) plumed->eraseFile(*this);
124 6695 : if(!cloned && fp) fclose(fp);
125 : #ifdef __PLUMED_HAS_ZLIB
126 6695 : if(!cloned && gzfp) gzclose(gzFile(gzfp));
127 : #endif
128 6695 : }
129 :
130 2265785 : FileBase::operator bool()const {
131 2265785 : return !eof;
132 : }
133 :
134 5009 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
135 5009 : if(path=="/dev/null") return path; // do not append a suffix to /dev/null
136 : std::string ret=path;
137 4847 : 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 4847 : if(ext.length()>0) {
148 3554 : int l=path.length()-(ext.length()+1);
149 3554 : plumed_assert(l>=0);
150 7108 : ret=ret.substr(0,l);
151 : }
152 : ret+=suffix;
153 8401 : if(ext.length()>0)ret+="."+ext;
154 : return ret;
155 : }
156 :
157 204 : FileBase& FileBase::enforceSuffix(const std::string&suffix) {
158 204 : enforcedSuffix_=true;
159 204 : enforcedSuffix=suffix;
160 204 : return *this;
161 : }
162 :
163 3982 : std::string FileBase::getSuffix()const {
164 3982 : if(enforcedSuffix_) return enforcedSuffix;
165 3774 : if(plumed) return plumed->getSuffix();
166 320 : return "";
167 : }
168 :
169 4839 : }
|