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-2018 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 valid)
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(), valid);
131  }
132 
133  return isPtr_();
134 }
135 
136 
137 Foam::Istream& Foam::regIOobject::readStream
138 (
139  const word& expectName,
140  const bool valid
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(valid);
154 
155  // Check the className of the regIOobject
156  // dictionary is an allowable name in case the actual class
157  // instantiated is a dictionary
158  if
159  (
160  valid
161  && expectName.size()
162  && headerClassName() != expectName
163  && headerClassName() != "dictionary"
164  )
165  {
166  FatalIOErrorInFunction(isPtr_())
167  << "unexpected class name " << headerClassName()
168  << " expected " << expectName << endl
169  << " while reading object " << name()
170  << exit(FatalIOError);
171  }
172  }
173 
174  return isPtr_();
175 }
176 
177 
179 {
180  if (IFstream::debug)
181  {
182  Pout<< "regIOobject::close() : "
183  << "finished reading "
184  << (isPtr_.valid() ? isPtr_().name() : "dummy")
185  << endl;
186  }
187 
188  isPtr_.clear();
189 }
190 
191 
193 {
194  return false;
195 }
196 
197 
199 {
200  // Note: cannot do anything in readStream itself since this is used by
201  // e.g. GeometricField.
202 
203 
204  // Save old watchIndices and clear (so the list of included files can
205  // change)
206  fileNameList oldWatchFiles;
207  if (watchIndices_.size())
208  {
209  oldWatchFiles.setSize(watchIndices_.size());
210  forAll(watchIndices_, i)
211  {
212  oldWatchFiles[i] = fileHandler().getFile(watchIndices_[i]);
213  }
214  forAllReverse(watchIndices_, i)
215  {
216  fileHandler().removeWatch(watchIndices_[i]);
217  }
218  watchIndices_.clear();
219  }
220 
221 
222  // Read
223  bool masterOnly =
224  global()
225  && (
228  );
229 
230  // Note: IOstream::binary flag is for all the processor comms. (Only for
231  // dictionaries should it be ascii)
232  bool ok = fileHandler().read(*this, masterOnly, IOstream::BINARY, type());
233 
234  if (oldWatchFiles.size())
235  {
236  // Re-watch master file
237  addWatch();
238  }
239 
240  return ok;
241 }
242 
243 
245 {
246  forAllReverse(watchIndices_, i)
247  {
248  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
249  {
250  return true;
251  }
252  }
253 
254  return false;
255 }
256 
257 
259 {
260  // Get index of modified file so we can give nice message. Could instead
261  // just call above modified()
262  label modified = -1;
263  forAllReverse(watchIndices_, i)
264  {
265  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
266  {
267  modified = watchIndices_[i];
268  break;
269  }
270  }
271 
272  if (modified != -1)
273  {
274  const fileName fName = fileHandler().getFile(watchIndices_.last());
275 
276  if (modified == watchIndices_.last())
277  {
278  Info<< "regIOobject::readIfModified() : " << nl
279  << " Re-reading object " << name()
280  << " from file " << fName << endl;
281  }
282  else
283  {
284  Info<< "regIOobject::readIfModified() : " << nl
285  << " Re-reading object " << name()
286  << " from file " << fName
287  << " because of modified file "
288  << fileHandler().getFile(modified)
289  << endl;
290  }
291 
292  return read();
293  }
294  else
295  {
296  return false;
297  }
298 }
299 
300 
301 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:428
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:297
A class for handling file names.
Definition: fileName.H:69
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:163
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:256
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: UList.H:440
virtual fileName filePath() const
Return complete path + object name if the file exists.
Definition: regIOobject.C:424
virtual autoPtr< ISstream > readStream(regIOobject &, const fileName &, const word &typeName, const bool valid=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:124
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:265
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:214
virtual void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:251
fileName::Type type(const fileName &, const bool followLink=true)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:481
virtual bool global() const
Is object global.
Definition: regIOobject.H:299
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)
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:359
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:303
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:418
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.