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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011-2018 OpenFOAM Foundation
9  Copyright (C) 2015-2022 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "regIOobject.H"
30 #include "IFstream.H"
31 #include "Time.H"
32 #include "Pstream.H"
33 #include "HashSet.H"
34 #include "fileOperation.H"
35 
36 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
37 
39 (
41  const word& typeName
42 )
43 {
44  // Everyone check or just master
45  const bool masterOnly
46  (
47  global()
48  && (
51  )
52  );
53 
54 
55  // Check if header is ok for READ_IF_PRESENT
56  bool isHeaderOk = false;
57  if (isReadOptional())
58  {
59  if (masterOnly)
60  {
61  if (UPstream::master())
62  {
63  const bool oldParRun = UPstream::parRun(false);
64  isHeaderOk = headerOk();
65  UPstream::parRun(oldParRun);
66  }
67  Pstream::broadcast(isHeaderOk);
68  }
69  else
70  {
71  isHeaderOk = headerOk();
72  }
73  }
74 
75  if (isReadRequired() || isHeaderOk)
76  {
77  return fileHandler().read(*this, masterOnly, fmt, typeName);
78  }
79 
80  return false;
81 }
82 
83 
84 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
85 
86 void Foam::regIOobject::readStream(const bool readOnProc)
87 {
88  if (readOpt() == IOobject::NO_READ)
89  {
91  << "NO_READ specified for read-constructor of object " << name()
92  << " of class " << headerClassName()
93  << abort(FatalError);
94  }
95 
96  // Construct object stream and read header if not already constructed
97  if (!isPtr_)
98  {
99  fileName objPath;
100  if (watchIndices_.size())
101  {
102  // File is being watched. Read exact file that is being watched.
103  objPath = fileHandler().getFile(watchIndices_.back());
104  }
105  else
106  {
107  // Search intelligently for file
108  objPath = filePath();
109 
110  if (IFstream::debug)
111  {
112  Pout<< "regIOobject::readStream() : "
113  << "found object " << name()
114  << " (global " << global() << ")"
115  << " in file " << objPath
116  << endl;
117  }
118  }
120  isPtr_ = fileHandler().readStream(*this, objPath, type(), readOnProc);
121  }
122 }
123 
124 
125 Foam::Istream& Foam::regIOobject::readStream
126 (
127  const word& expectName,
128  const bool readOnProc
129 )
130 {
131  if (IFstream::debug)
132  {
133  Pout<< "regIOobject::readStream(const word&) : "
134  << "reading object " << name()
135  << " of type " << type()
136  << " from file " << filePath()
137  << endl;
138  }
139 
140  // Construct IFstream if not already constructed
141  if (!isPtr_)
142  {
143  readStream(readOnProc);
144 
145  // Check the className of the regIOobject
146  // dictionary is an allowable name in case the actual class
147  // instantiated is a dictionary
148  if
149  (
150  readOnProc
151  && expectName.size()
152  && headerClassName() != expectName
153  && headerClassName() != "dictionary"
154  )
155  {
156  FatalIOErrorInFunction(isPtr_())
157  << "unexpected class name " << headerClassName()
158  << " expected " << expectName << endl
159  << " while reading object " << name()
160  << exit(FatalIOError);
161  }
162  }
163 
164  return *isPtr_;
165 }
166 
167 
169 {
170  if (IFstream::debug)
171  {
172  Pout<< "regIOobject::close() : "
173  << "finished reading "
174  << (isPtr_ ? isPtr_->name() : "dummy")
175  << endl;
176  }
177 
178  isPtr_.reset(nullptr);
179 }
180 
183 {
184  return false;
185 }
186 
187 
189 {
190  // Note: cannot do anything in readStream itself since this is used by
191  // e.g. GeometricField.
192 
193  // Everyone or just master
194  const bool masterOnly
195  (
196  global()
197  && (
200  )
201  );
202 
203  // Remove old watches (indices) and clear:
204  // so the list of included files can change
205 
206  const bool needWatch(!watchIndices_.empty());
207 
208  if (!watchIndices_.empty())
209  {
210  forAllReverse(watchIndices_, i)
211  {
212  fileHandler().removeWatch(watchIndices_[i]);
213  }
214  watchIndices_.clear();
215  }
216 
217  // Note: IOstream::binary flag is for all the processor comms. (Only for
218  // dictionaries should it be ascii)
219  bool ok =
220  fileHandler().read(*this, masterOnly, IOstreamOption::BINARY, type());
221 
222  if (needWatch)
223  {
224  // Re-watch master file
225  addWatch();
226  }
227 
228  return ok;
229 }
230 
231 
232 bool Foam::regIOobject::modified() const
233 {
234  forAllReverse(watchIndices_, i)
235  {
236  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
237  {
238  return true;
239  }
240  }
241 
242  return false;
243 }
244 
245 
247 {
248  // Get index of modified file so we can give nice message. Could instead
249  // just call above modified()
250  label modified = -1;
251  forAllReverse(watchIndices_, i)
252  {
253  if (fileHandler().getState(watchIndices_[i]) != fileMonitor::UNMODIFIED)
254  {
255  modified = watchIndices_[i];
256  break;
257  }
258  }
259 
260  if (modified != -1)
261  {
262  const fileName fName = fileHandler().getFile(watchIndices_.back());
263 
264  if (modified == watchIndices_.back())
265  {
267  << " Re-reading object " << name()
268  << " from file " << fName << endl;
269  }
270  else
271  {
273  << " Re-reading object " << name()
274  << " from file " << fName
275  << " because of modified file "
276  << fileHandler().getFile(modified)
277  << endl;
278  }
279 
280  return read();
281  }
282 
283  return false;
284 }
285 
286 
287 // ************************************************************************* //
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
virtual bool read()
Read object.
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
bool headerOk()
Read and check header info. Does not check the headerClassName.
Definition: regIOobject.C:505
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler()
bool isReadOptional() const noexcept
True if (LAZY_READ) bits are set [same as READ_IF_PRESENT].
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
bool read(const char *buf, int32_t &val)
Same as readInt32.
Definition: int32.H:127
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Definition: POSIX.C:799
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
void close()
Close Istream.
A class for handling words, derived from Foam::string.
Definition: word.H:63
virtual bool readIfModified()
Read object if modified (as set by call to modified)
errorManip< error > abort(error &err)
Definition: errorManip.H:139
int debug
Static debugging option.
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:343
bool isReadRequired() const noexcept
True if (MUST_READ | READ_MODIFIED) bits are set.
virtual bool global() const
Is object global.
Definition: regIOobject.H:493
virtual bool readData(Istream &)
Virtual readData function.
#define FatalIOErrorInFunction(ios)
Report an error message using Foam::FatalIOError.
Definition: error.H:627
virtual bool modified() const
Return true if the object&#39;s file (or files for objectRegistry) have been modified. (modified state is cached by Time)
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
Nothing to be read.
streamFormat
Data format (ascii | binary)
#define forAllReverse(list, i)
Reverse loop across all elements in list.
Definition: stdFoam.H:437
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
bool readHeaderOk(const IOstreamOption::streamFormat fmt, const word &typeName)
Helper: check readOpt flags and read if necessary.
IOerror FatalIOError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL IO ERROR&#39; header text and ...
#define InfoInFunction
Report an information message using Foam::Info.