regIOobjectRead.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2019 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "regIOobject.H"
27 #include "IFstream.H"
28 #include "Time.H"
29 #include "Pstream.H"
30 #include "HashSet.H"
31 #include "fileOperation.H"
32 
33 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
34 
36 (
37  const IOstream::streamFormat format,
38  const word& typeName
39 )
40 {
41  // Everyone check or just master
42  bool masterOnly =
43  global()
44  && (
45  regIOobject::fileModificationChecking == timeStampMaster
46  || regIOobject::fileModificationChecking == inotifyMaster
47  );
48 
49 
50  // Check if header is ok for READ_IF_PRESENT
51  bool isHeaderOk = false;
52  if (readOpt() == IOobject::READ_IF_PRESENT)
53  {
54  if (masterOnly)
55  {
56  if (Pstream::master())
57  {
58  isHeaderOk = headerOk();
59  }
60  Pstream::scatter(isHeaderOk);
61  }
62  else
63  {
64  isHeaderOk = headerOk();
65  }
66  }
67 
68  if
69  (
70  (
71  readOpt() == IOobject::MUST_READ
72  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
73  )
74  || isHeaderOk
75  )
76  {
77  return fileHandler().read(*this, masterOnly, format, typeName);
78  }
79  else
80  {
81  return false;
82  }
83 }
84 
85 
86 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
87 
88 Foam::Istream& Foam::regIOobject::readStream(const bool read)
89 {
90  if (IFstream::debug)
91  {
93  << "Reading object " << name()
94  << " from file " << objectPath()
95  << endl;
96  }
97 
98  if (readOpt() == NO_READ)
99  {
101  << "NO_READ specified for read-constructor of object " << name()
102  << " of class " << headerClassName()
103  << abort(FatalError);
104  }
105 
106  // Construct object stream and read header if not already constructed
107  if (!isPtr_.valid())
108  {
109  fileName objPath;
110  if (watchIndices_.size())
111  {
112  // File is being watched. Read exact file that is being watched.
113  objPath = fileHandler().getFile(watchIndices_.last());
114  }
115  else
116  {
117  // Search intelligently for file
118  objPath = filePath();
119 
120  if (IFstream::debug)
121  {
122  Pout<< "regIOobject::readStream() : "
123  << "found object " << name()
124  << " (global " << global() << ")"
125  << " in file " << objPath
126  << endl;
127  }
128  }
129 
130  isPtr_ = fileHandler().readStream(*this, objPath, type(), read);
131  }
132 
133  return isPtr_();
134 }
135 
136 
137 Foam::Istream& Foam::regIOobject::readStream
138 (
139  const word& expectName,
140  const bool read
141 )
142 {
143  if (IFstream::debug)
144  {
145  Pout<< "regIOobject::readStream(const word&) : "
146  << "reading object " << name()
147  << endl;
148  }
149 
150  // Construct IFstream if not already constructed
151  if (!isPtr_.valid())
152  {
153  readStream(read);
154 
155  // Check the className of the regIOobject
156  // dictionary is an allowable name so that any file can be processed
157  // as raw dictionary and the original type preserved
158  if
159  (
160  read
161  && expectName.size()
162  && headerClassName() != expectName
163  && headerClassName() != dictionary::typeName
164  )
165  {
166  if (expectName == dictionary::typeName)
167  {
168  const_cast<word&>(type()) = headerClassName();
169  }
170  else
171  {
172  FatalIOErrorInFunction(isPtr_())
173  << "unexpected class name " << headerClassName()
174  << " expected " << expectName << endl
175  << " while reading object " << name()
176  << exit(FatalIOError);
177  }
178  }
179  }
180 
181  return isPtr_();
182 }
183 
184 
186 {
187  if (IFstream::debug)
188  {
189  Pout<< "regIOobject::close() : "
190  << "finished reading "
191  << (isPtr_.valid() ? isPtr_().name() : "dummy")
192  << endl;
193  }
194 
195  isPtr_.clear();
196 }
197 
198 
200 {
201  return false;
202 }
203 
204 
206 {
207  // Note: cannot do anything in readStream itself since this is used by
208  // e.g. GeometricField.
209 
210 
211  // Save old watchIndices and clear (so the list of included files can
212  // change)
213  fileNameList oldWatchFiles;
214  if (watchIndices_.size())
215  {
216  oldWatchFiles.setSize(watchIndices_.size());
217  forAll(watchIndices_, i)
218  {
219  oldWatchFiles[i] = fileHandler().getFile(watchIndices_[i]);
220  }
221  forAllReverse(watchIndices_, i)
222  {
223  fileHandler().removeWatch(watchIndices_[i]);
224  }
225  watchIndices_.clear();
226  }
227 
228 
229  // Read
230  bool masterOnly =
231  global()
232  && (
235  );
236 
237  // Note: IOstream::binary flag is for all the processor comms. (Only for
238  // dictionaries should it be ascii)
239  bool ok = fileHandler().read(*this, masterOnly, IOstream::BINARY, type());
240 
241  if (oldWatchFiles.size())
242  {
243  // Re-watch master file
244  addWatch();
245  }
246 
247  return ok;
248 }
249 
250 
252 {
253  forAllReverse(watchIndices_, i)
254  {
255  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
256  {
257  return true;
258  }
259  }
260 
261  return false;
262 }
263 
264 
266 {
267  // Get index of modified file so we can give nice message. Could instead
268  // just call above modified()
269  label modified = -1;
270  forAllReverse(watchIndices_, i)
271  {
272  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
273  {
274  modified = watchIndices_[i];
275  break;
276  }
277  }
278 
279  if (modified != -1)
280  {
281  const fileName fName = fileHandler().getFile(watchIndices_.last());
282 
283  if (modified == watchIndices_.last())
284  {
285  Info<< "regIOobject::readIfModified() : " << nl
286  << " Re-reading object " << name()
287  << " from file " << fName << endl;
288  }
289  else
290  {
291  Info<< "regIOobject::readIfModified() : " << nl
292  << " Re-reading object " << name()
293  << " from file " << fName
294  << " because of modified file "
295  << fileHandler().getFile(modified)
296  << endl;
297  }
298 
299  return read();
300  }
301  else
302  {
303  return false;
304  }
305 }
306 
307 
308 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
const word & name() const
Return name.
Definition: IOobject.H:303
A class for handling file names.
Definition: fileName.H:79
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
virtual bool read()
Read object.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:319
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
virtual fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:415
virtual autoPtr< ISstream > readStream(regIOobject &, const fileName &, const word &typeName, const bool read=true) const =0
Reads header for regIOobject and returns an ISstream.
void close()
Close Istream.
void clear()
Clear the list, i.e. set size to zero.
Definition: ListI.H:125
A class for handling words, derived from string.
Definition: word.H:59
virtual bool readIfModified()
Read object if modified (as set by call to modified)
virtual fileName getFile(const label) const
Get name of file being watched (using handle)
streamFormat
Enumeration for the format of data in the stream.
Definition: IOstream.H:86
const fileOperation & fileHandler()
Get current file handler.
errorManip< error > abort(error &err)
Definition: errorManip.H:131
static const char nl
Definition: Ostream.H:260
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:219
virtual void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:242
void setSize(const label)
Reset size of List.
Definition: List.C:281
virtual bool readData(Istream &)
Virtual readData function.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:331
prefixOSstream Pout(cout, "Pout")
Definition: IOstreams.H:53
virtual bool modified() const
Return true if the object&#39;s file (or files for objectRegistry)
fileType type(const fileName &, const bool checkVariants=true, const bool followLink=true)
Return the file type: directory or file.
Definition: POSIX.C:488
virtual bool global() const
Is object same for all processors.
Definition: regIOobject.C:442
messageStream Info
virtual bool read(regIOobject &, const bool masterOnly, const IOstream::streamFormat format, const word &typeName) const =0
Top-level read.
T & last()
Return the last element of the list.
Definition: UListI.H:128
readOption readOpt() const
Definition: IOobject.H:353
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:309
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:419
bool readHeaderOk(const IOstream::streamFormat PstreamFormat, const word &typeName)
Helper: check readOpt flags and read if necessary.
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
IOerror FatalIOError
#define InfoInFunction
Report an information message using Foam::Info.