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