IOobject.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-2017 OpenFOAM Foundation
9  Copyright (C) 2016-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 "IOobject.H"
30 #include "Time.H"
31 #include "Istream.H"
32 #include "registerSwitch.H"
33 
34 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
35 
36 namespace Foam
37 {
38  defineTypeNameAndDebug(IOobject, 0);
39 }
40 
41 bool Foam::IOobject::bannerEnabled_(true);
42 
44 (
45  #ifdef _WIN32
46  // Windows: using ':' causes scoping conflicts with d:/path etc
47  Foam::debug::infoSwitch("scopeSeparator", '_')
48  #else
49  Foam::debug::infoSwitch("scopeSeparator", ':')
50  #endif
51 );
52 
53 const Foam::Enum
54 <
56 >
58 ({
59  { fileCheckTypes::timeStamp, "timeStamp" },
60  { fileCheckTypes::timeStampMaster, "timeStampMaster" },
61  { fileCheckTypes::inotify, "inotify" },
62  { fileCheckTypes::inotifyMaster, "inotifyMaster" },
63 });
64 
65 // Default fileCheck type
67 (
68  fileCheckTypesNames.get
69  (
70  "fileModificationChecking",
72  )
73 );
74 
75 
77 (
78  Foam::debug::floatOptimisationSwitch("fileModificationSkew", 30)
79 );
81 (
82  "fileModificationSkew",
83  float,
85 );
86 
88 (
89  Foam::debug::optimisationSwitch("maxFileModificationPolls", 1)
90 );
92 (
93  "maxFileModificationPolls",
94  int,
96 );
97 
98 
100 namespace Foam
101 {
102  // Register re-reader
103  class addfileModificationCheckingToOpt
104  :
106  {
107  public:
108 
109  addfileModificationCheckingToOpt
110  (const addfileModificationCheckingToOpt&) = delete;
111 
112  void operator=
113  (const addfileModificationCheckingToOpt&) = delete;
114 
115  explicit addfileModificationCheckingToOpt(const char* name)
116  :
117  ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
118  {}
119 
120  virtual ~addfileModificationCheckingToOpt() = default;
121 
122  virtual void readData(Foam::Istream& is)
123  {
126  }
127 
128  virtual void writeData(Foam::Ostream& os) const
129  {
132  }
133  };
134 
135  addfileModificationCheckingToOpt addfileModificationCheckingToOpt_
136  (
137  "fileModificationChecking"
138  );
139 
140 } // End namespace Foam
142 
143 
144 // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
145 
147 (
148  const fileName& path,
149  fileName& instance,
150  fileName& local,
151  word& name
152 )
153 {
154  // Convert explicit relative file-system path to absolute file-system path.
155  if (path.starts_with("./") || path.starts_with("../"))
156  {
157  fileName absPath(cwd()/path);
158  absPath.clean(); // Remove unneeded ".."
159 
160  return fileNameComponents(absPath, instance, local, name);
161  }
162 
163  instance.clear();
164  local.clear();
165  name.clear();
166 
167  // Called with directory
168  if (isDir(path))
169  {
171  << " called with directory: " << path << endl;
172 
173  return false;
174  }
175 
176  const auto first = path.find('/');
177  const auto last = path.rfind('/');
178 
179  // The raw length of name (without validating for word chars)
180  auto nameLen = path.size();
181 
182  if (first == std::string::npos)
183  {
184  // No '/' found (or empty entirely)
185  // => no instance or local
186 
188  }
189  else if
190  (
191  first == 0
192  #ifdef _WIN32
193  || (first == 2 && path[1] == ':') // Eg, d:/path
194  #endif
195  )
196  {
197  // Absolute path (starts with '/' or 'd:/')
198  // => no local
199 
200  instance = path.substr(0, last);
201 
202  const std::string ending = path.substr(last+1);
203  nameLen = ending.size(); // The raw length of name
204  name = word::validate(ending);
205  }
206  else
207  {
208  // Normal case.
209  // First part is instance, remainder is local
210  instance = path.substr(0, first);
211 
212  if (last > first)
213  {
214  // With local
215  local = path.substr(first+1, last-first-1);
216  }
217 
218  const std::string ending = path.substr(last+1);
219  nameLen = ending.size(); // The raw length of name
220  name = word::validate(ending);
221  }
222 
223  // Check for valid (and stripped) name, regardless of the debug level
224  if (!nameLen || nameLen != name.size())
225  {
227  << "has invalid word for name: \"" << name
228  << "\"\nwhile processing path: " << path << endl;
229 
230  return false;
231  }
232 
233  return true;
234 }
235 
236 
238 (
239  const IOobject& io,
240  const fileName& altFile,
241  const word& ioName
242 )
243 {
244  if (altFile.empty())
245  {
246  return io;
247  }
248 
249  // Construct from file path instead
250 
251  fileName altPath = altFile;
252 
253  if (isDir(altPath))
254  {
255  // Resolve directories as well
256 
257  if (ioName.empty())
258  {
259  altPath /= io.name();
260  }
261  else
262  {
263  altPath /= ioName;
264  }
265  }
266  altPath.expand();
267 
268 
269  return
270  IOobject
271  (
272  altPath,
273  io.db(),
274  io.readOpt(),
276  io.registerObject(),
277  io.globalObject()
278  );
279 }
280 
281 
283 {
284  const auto i = name.rfind('.');
285 
286  if (i == std::string::npos || i == 0)
287  {
288  return word::null;
289  }
290 
291  return name.substr(i+1);
292 }
293 
294 
296 {
297  const auto i = name.rfind('.');
298 
299  if (i == std::string::npos || i == 0)
300  {
301  return name;
302  }
303 
304  return name.substr(0, i);
305 }
306 
307 
308 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
309 
311 (
312  const word& name,
313  const fileName& instance,
314  const objectRegistry& registry,
315  IOobjectOption ioOpt
316 )
317 :
318  IOobjectOption(ioOpt),
319  objState_(objectState::GOOD),
320  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
321  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
322 
323  name_(name),
324  headerClassName_(),
325  note_(),
326  instance_(instance),
327  local_(),
328 
329  db_(registry)
330 {
332  {
334  << "Constructing IOobject: " << name_ << endl;
335  }
336 }
337 
338 
340 (
341  const word& name,
342  const fileName& instance,
343  const fileName& local,
344  const objectRegistry& registry,
345  IOobjectOption ioOpt
346 )
347 :
348  IOobjectOption(ioOpt),
349  objState_(objectState::GOOD),
350  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
351  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
352 
353  name_(name),
354  headerClassName_(),
355  note_(),
356  instance_(instance),
357  local_(local),
358 
359  db_(registry)
360 {
362  {
364  << "Constructing IOobject: " << name_ << endl;
365  }
366 }
367 
368 
370 (
371  const fileName& path,
372  const objectRegistry& registry,
373  IOobjectOption ioOpt
374 )
375 :
376  IOobjectOption(ioOpt),
377  objState_(objectState::GOOD),
378  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
379  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
380 
381  name_(),
382  headerClassName_(),
383  note_(),
384  instance_(),
385  local_(),
386 
387  db_(registry)
388 {
389  if (!fileNameComponents(path, instance_, local_, name_))
390  {
392  << " invalid path specification"
393  << exit(FatalError);
394  }
395 
397  {
399  << "Constructing IOobject: " << name_ << endl;
400  }
401 }
402 
403 
405 (
406  const IOobject& io,
407  const objectRegistry& registry
408 )
409 :
410  IOobjectOption(static_cast<IOobjectOption>(io)),
411  objState_(io.objState_),
412  sizeofLabel_(io.sizeofLabel_),
413  sizeofScalar_(io.sizeofScalar_),
414 
415  name_(io.name_),
416  headerClassName_(io.headerClassName_),
417  note_(io.note_),
418  instance_(io.instance_),
419  local_(io.local_),
420 
421  db_(registry)
422 {}
423 
424 
426 (
427  const IOobject& io,
428  const word& name
429 )
430 :
431  IOobjectOption(static_cast<IOobjectOption>(io)),
432  objState_(io.objState_),
433  sizeofLabel_(io.sizeofLabel_),
434  sizeofScalar_(io.sizeofScalar_),
435 
436  name_(name),
437  headerClassName_(io.headerClassName_),
438  note_(io.note_),
439  instance_(io.instance_),
440  local_(io.local_),
442  db_(io.db_)
443 {}
444 
445 
446 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
449 {
450  return db_;
451 }
452 
454 const Foam::Time& Foam::IOobject::time() const
455 {
456  return db_.time();
457 }
458 
461 {
462  return time().rootPath();
463 }
464 
467 {
468  return time().caseName();
469 }
470 
471 
473 {
474  // A file is 'outside' of the case if it has been specified using an
475  // absolute path
476 
477  const auto first = instance().find('/');
478 
479  if
480  (
481  first == 0
482  #ifdef _WIN32
483  || (first == 2 && instance()[1] == ':') // Eg, d:/path
484  #endif
485  )
486  {
487  // Absolute path (starts with '/' or 'd:/')
488  return instance();
489  }
490 
491  return rootPath()/caseName()/instance()/db_.dbDir()/local();
492 }
493 
494 
496 (
497  const word& instance,
498  const fileName& local
499 ) const
500 {
501  // Note: can only be called with relative instance since is word type
502  return rootPath()/caseName()/instance/db_.dbDir()/local;
503 }
504 
505 
507 {
508  // A file is 'outside' of the case if it has been specified using an
509  // absolute path
510 
511  const auto first = instance().find('/');
512 
513  if
514  (
515  first == 0
516  #ifdef _WIN32
517  || (first == 2 && instance()[1] == ':') // Eg, d:/path
518  #endif
519  )
520  {
521  // Absolute path (starts with '/' or 'd:/')
522  return instance()/name();
523  }
524 
525  return instance()/db_.dbDir()/local()/name();
526 }
527 
528 
530 (
531  const word& typeName,
532  const bool search
533 ) const
534 {
535  // Do not check for undecomposed files
536  return fileHandler().filePath(false, *this, typeName, search);
537 }
538 
539 
541 (
542  const word& typeName,
543  const bool search
544 ) const
545 {
546  // Check for undecomposed files
547  return fileHandler().filePath(true, *this, typeName, search);
548 }
549 
550 
551 void Foam::IOobject::setBad(const string& s)
552 {
553  if (objState_ != objectState::GOOD)
554  {
556  << "Recurrent failure for object " << s
557  << exit(FatalError);
558  }
559 
560  if (error::level)
561  {
563  << "Broken object " << s << info() << endl;
564  }
566  objState_ = objectState::BAD;
567 }
568 
569 
570 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
571 
573 {
574  readOpt(io.readOpt());
575  writeOpt(io.writeOpt());
576  // No change to registerObject
577  globalObject(io.globalObject());
578 
579  objState_ = io.objState_;
580  sizeofLabel_ = io.sizeofLabel_;
581  sizeofScalar_ = io.sizeofScalar_;
582 
583  name_ = io.name_;
584  headerClassName_ = io.headerClassName_;
585  note_ = io.note_;
586  instance_ = io.instance_;
587  local_ = io.local_;
588 }
589 
590 
591 // ************************************************************************* //
static word validate(const std::string &s, const bool prefix=false)
Construct validated word (no invalid characters).
Definition: word.C:38
Abstract base class for registered object with I/O. Used in debug symbol registration.
EnumType read(Istream &is) const
Read a word from Istream and return the corresponding enumeration.
Definition: Enum.C:102
static bool fileNameComponents(const fileName &path, fileName &instance, fileName &local, word &name)
Split path into instance, local, name components.
Definition: IOobject.C:140
A class for handling file names.
Definition: fileName.H:71
readOption readOpt() const noexcept
Get the read option.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
fileName globalFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching up if in parallel.
Definition: IOobject.C:534
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition: IOobject.H:318
static void writeData(Ostream &os, const Type &val)
void operator=(const IOobject &io)
Copy assignment, copies all values (except the registry)
Definition: IOobject.C:565
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:578
const word & name() const noexcept
Return the object name.
Definition: IOobjectI.H:150
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:487
word member() const
Return member (name without the extension)
Definition: IOobjectI.H:162
autoPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler.
void setBad(const string &s)
Set the object state to bad.
Definition: IOobject.C:544
word group() const
Return group (extension part of name)
Definition: IOobjectI.H:156
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:228
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:69
fileName path() const
The complete path.
Definition: IOobject.C:465
registerOptSwitch("fileModificationSkew", float, Foam::IOobject::fileModificationSkew)
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: POSIX.C:813
bool globalObject() const noexcept
True if object is treated the same for all processors.
writeOption writeOpt() const noexcept
Get the write option.
IOobject io("surfaceFilmProperties", mesh.time().constant(), mesh, IOobject::READ_IF_PRESENT, IOobject::NO_WRITE, false)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:52
A class for handling words, derived from Foam::string.
Definition: word.H:63
const Time & time() const noexcept
Return time registry.
fileCheckTypes
Enumeration defining the file checking options.
Definition: IOobject.H:186
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition: IOobject.H:323
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:441
static const word null
An empty word.
Definition: word.H:84
fileName localFilePath(const word &typeName, const bool search=true) const
Redirect to fileHandler filePath, searching locally.
Definition: IOobject.C:523
bool local
Definition: EEqn.H:20
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
const direction noexcept
Definition: Scalar.H:258
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:234
int debug
Static debugging option.
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition: IOobject.H:197
OBJstream os(runTime.globalPath()/outputName)
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
defineTypeNameAndDebug(combustionModel, 0)
static bool clean(std::string &str)
Cleanup filename string, possibly applies other transformations such as changing the path separator e...
Definition: fileName.C:192
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:313
const fileName & instance() const noexcept
Read access to instance path component.
Definition: IOobjectI.H:221
static char scopeSeparator
Character for scoping object names (&#39;:&#39; or &#39;_&#39;)
Definition: IOobject.H:308
const fileName & rootPath() const
Return the Time::rootPath()
Definition: IOobject.C:453
bool starts_with(char c) const
True if string starts with given character (cf. C++20)
Definition: string.H:414
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:240
#define WarningInFunction
Report a warning using Foam::Warning.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
Definition: string.C:166
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:447
IOobject(const IOobject &)=default
Copy construct.
A simple container of IOobject preferences. Can also be used for general handling of read/no-read/rea...
fileName cwd()
The physical or logical current working directory path name.
Definition: POSIX.C:543
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:499
bool registerObject() const noexcept
Should objects created with this IOobject be registered?
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:640
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict(s).
Definition: debug.C:216
Registry of regIOobjects.
void addOptimisationObject(const char *name, simpleRegIOobject *obj)
Register optimisation switch read/write object.
Definition: debug.C:259
const fileName & local() const noexcept
Read access to local path component.
Definition: IOobjectI.H:233
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Defines the attributes of an object for which implicit objectRegistry management is supported...
Definition: IOobject.H:166
const fileName & caseName() const
Return the Time::caseName()
Definition: IOobject.C:459
static int level
The output level (verbosity) of messages.
Namespace for OpenFOAM.
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
Definition: IOobject.C:231
#define InfoInFunction
Report an information message using Foam::Info.