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-2020 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 "dictionary.H"
29 
30 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
31 
33 (
34  const IOstream::streamFormat defaultFormat,
35  const word& typeName
36 )
37 {
38  // Everyone check or just master
39  bool masterOnly =
40  global()
41  && (
42  regIOobject::fileModificationChecking == timeStampMaster
43  || regIOobject::fileModificationChecking == inotifyMaster
44  );
45 
46 
47  // Check if header is ok for READ_IF_PRESENT
48  bool isHeaderOk = false;
49  if (readOpt() == IOobject::READ_IF_PRESENT)
50  {
51  if (masterOnly)
52  {
53  if (Pstream::master())
54  {
55  isHeaderOk = headerOk();
56  }
57  Pstream::scatter(isHeaderOk);
58  }
59  else
60  {
61  isHeaderOk = headerOk();
62  }
63  }
64 
65  if
66  (
67  (
68  readOpt() == IOobject::MUST_READ
69  || readOpt() == IOobject::MUST_READ_IF_MODIFIED
70  )
71  || isHeaderOk
72  )
73  {
74  return fileHandler().read(*this, masterOnly, defaultFormat, typeName);
75  }
76  else
77  {
78  return false;
79  }
80 }
81 
82 
83 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
84 
85 Foam::Istream& Foam::regIOobject::readStream(const bool read)
86 {
87  if (IFstream::debug)
88  {
90  << "Reading object " << name()
91  << " from file " << objectPath()
92  << endl;
93  }
94 
95  if (readOpt() == NO_READ)
96  {
98  << "NO_READ specified for read-constructor of object " << name()
99  << " of class " << headerClassName()
100  << abort(FatalError);
101  }
102 
103  // Construct object stream and read header if not already constructed
104  if (!isPtr_.valid())
105  {
106  fileName objPath;
107  if (watchIndices_.size())
108  {
109  // File is being watched. Read exact file that is being watched.
110  objPath = fileHandler().getFile(watchIndices_.last());
111  }
112  else
113  {
114  // Search intelligently for file
115  objPath = filePath();
116 
117  if (IFstream::debug)
118  {
119  Pout<< "regIOobject::readStream() : "
120  << "found object " << name()
121  << " (global " << global() << ")"
122  << " in file " << objPath
123  << endl;
124  }
125  }
126 
127  isPtr_ = fileHandler().readStream(*this, objPath, type(), read);
128  }
129 
130  return isPtr_();
131 }
132 
133 
134 Foam::Istream& Foam::regIOobject::readStream
135 (
136  const word& expectName,
137  const bool read
138 )
139 {
140  if (IFstream::debug)
141  {
142  Pout<< "regIOobject::readStream(const word&) : "
143  << "reading object " << name()
144  << endl;
145  }
146 
147  // Construct IFstream if not already constructed
148  if (!isPtr_.valid())
149  {
150  readStream(read);
151 
152  // Check the className of the regIOobject
153  // dictionary is an allowable name so that any file can be processed
154  // as raw dictionary and the original type preserved
155  if
156  (
157  read
158  && expectName.size()
159  && headerClassName() != expectName
160  && headerClassName() != dictionary::typeName
161  )
162  {
163  if (expectName == dictionary::typeName)
164  {
165  const_cast<word&>(type()) = headerClassName();
166  }
167  else
168  {
169  FatalIOErrorInFunction(isPtr_())
170  << "unexpected class name " << headerClassName()
171  << " expected " << expectName << endl
172  << " while reading object " << name()
173  << exit(FatalIOError);
174  }
175  }
176  }
177 
178  return isPtr_();
179 }
180 
181 
183 {
184  if (IFstream::debug)
185  {
186  Pout<< "regIOobject::close() : "
187  << "finished reading "
188  << (isPtr_.valid() ? isPtr_().name() : "dummy")
189  << endl;
190  }
191 
192  isPtr_.clear();
193 }
194 
195 
197 {
198  return false;
199 }
200 
201 
203 {
204  // Note: cannot do anything in readStream itself since this is used by
205  // e.g. GeometricField.
206 
207 
208  // Save old watchIndices and clear (so the list of included files can
209  // change)
210  fileNameList oldWatchFiles;
211  if (watchIndices_.size())
212  {
213  oldWatchFiles.setSize(watchIndices_.size());
214  forAll(watchIndices_, i)
215  {
216  oldWatchFiles[i] = fileHandler().getFile(watchIndices_[i]);
217  }
218  forAllReverse(watchIndices_, i)
219  {
220  fileHandler().removeWatch(watchIndices_[i]);
221  }
222  watchIndices_.clear();
223  }
224 
225 
226  // Read
227  bool masterOnly =
228  global()
229  && (
232  );
233 
234  // Note: IOstream::binary flag is for all the processor comms. (Only for
235  // dictionaries should it be ascii)
236  bool ok = fileHandler().read(*this, masterOnly, IOstream::BINARY, type());
237 
238  if (oldWatchFiles.size())
239  {
240  // Re-watch master file
241  addWatch();
242  }
243 
244  return ok;
245 }
246 
247 
249 {
250  forAllReverse(watchIndices_, i)
251  {
252  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
253  {
254  return true;
255  }
256  }
257 
258  return false;
259 }
260 
261 
263 {
264  // Get index of modified file so we can give nice message. Could instead
265  // just call above modified()
266  label modified = -1;
267  forAllReverse(watchIndices_, i)
268  {
269  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
270  {
271  modified = watchIndices_[i];
272  break;
273  }
274  }
275 
276  if (modified != -1)
277  {
278  const fileName fName = fileHandler().getFile(watchIndices_.last());
279 
280  if (modified == watchIndices_.last())
281  {
282  Info<< "regIOobject::readIfModified() : " << nl
283  << " Re-reading object " << name()
284  << " from file " << fName << endl;
285  }
286  else
287  {
288  Info<< "regIOobject::readIfModified() : " << nl
289  << " Re-reading object " << name()
290  << " from file " << fName
291  << " because of modified file "
292  << fileHandler().getFile(modified)
293  << endl;
294  }
295 
296  return read();
297  }
298  else
299  {
300  return false;
301  }
302 }
303 
304 
305 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
bool readHeaderOk(const IOstream::streamFormat defaultFormat, const word &typeName)
Read header, check readOpt flags and read data if necessary.
const word & name() const
Return name.
Definition: IOobject.H:315
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(regIOobject &, const bool masterOnly, const IOstream::streamFormat defaultFormat, const word &typeName) const =0
Top-level read.
virtual bool read()
Read object.
error FatalError
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:306
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
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
fileName objectPath() const
Return complete path + object name.
Definition: regIOobject.H:159
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:446
fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:437
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:231
void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:259
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:318
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
Return true if object is global, i.e. same for all processors.
Definition: regIOobject.C:181
messageStream Info
T & last()
Return the last element of the list.
Definition: UListI.H:128
readOption readOpt() const
Definition: IOobject.H:365
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:321
virtual bool removeWatch(const label) const
Remove watch on a file (using handle)
IOerror FatalIOError
#define InfoInFunction
Report an information message using Foam::Info.