regIOobjectRead.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2017 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 " << isPtr_().name()
184  << endl;
185  }
186 
187  isPtr_.clear();
188 }
189 
190 
192 {
193  return false;
194 }
195 
196 
198 {
199  // Note: cannot do anything in readStream itself since this is used by
200  // e.g. GeometricField.
201 
202 
203  // Save old watchIndices and clear (so the list of included files can
204  // change)
205  fileNameList oldWatchFiles;
206  if (watchIndices_.size())
207  {
208  oldWatchFiles.setSize(watchIndices_.size());
209  forAll(watchIndices_, i)
210  {
211  oldWatchFiles[i] = fileHandler().getFile(watchIndices_[i]);
212  }
213  forAllReverse(watchIndices_, i)
214  {
215  fileHandler().removeWatch(watchIndices_[i]);
216  }
217  watchIndices_.clear();
218  }
219 
220 
221  // Read
222  bool masterOnly =
223  global()
224  && (
227  );
228 
229  // Note: IOstream::binary flag is for all the processor comms. (Only for
230  // dictionaries should it be ascii)
231  bool ok = fileHandler().read(*this, masterOnly, IOstream::BINARY, type());
232 
233  if (oldWatchFiles.size())
234  {
235  // Re-watch master file
236  addWatch();
237  }
238 
239  return ok;
240 }
241 
242 
244 {
245  forAllReverse(watchIndices_, i)
246  {
247  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
248  {
249  return true;
250  }
251  }
252 
253  return false;
254 }
255 
256 
258 {
259  // Get index of modified file so we can give nice message. Could instead
260  // just call above modified()
261  label modified = -1;
262  forAllReverse(watchIndices_, i)
263  {
264  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
265  {
266  modified = watchIndices_[i];
267  break;
268  }
269  }
270 
271  if (modified != -1)
272  {
273  const fileName fName = fileHandler().getFile(watchIndices_.last());
274 
275  if (modified == watchIndices_.last())
276  {
277  Info<< "regIOobject::readIfModified() : " << nl
278  << " Re-reading object " << name()
279  << " from file " << fName << endl;
280  }
281  else
282  {
283  Info<< "regIOobject::readIfModified() : " << nl
284  << " Re-reading object " << name()
285  << " from file " << fName
286  << " because of modified file "
287  << fileHandler().getFile(modified)
288  << endl;
289  }
290 
291  return read();
292  }
293  else
294  {
295  return false;
296  }
297 }
298 
299 
300 // ************************************************************************* //
#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:291
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:253
#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:417
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:262
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:208
virtual void addWatch()
Add file watch on object (if registered and READ_IF_MODIFIED)
Definition: regIOobject.C:244
fileName::Type type(const fileName &, const bool followLink=true)
Return the file type: DIRECTORY or FILE.
Definition: POSIX.C:485
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:353
const word & headerClassName() const
Return name of the class name read from header.
Definition: IOobject.H:297
fileName objectPath() const
Return complete path + object name.
Definition: IOobject.H:412
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.