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-2021 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(),
275  io.writeOpt(),
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  readOption ro,
316  writeOption wo,
317  bool registerObject,
318  bool globalObject
319 )
320 :
321  name_(name),
322  headerClassName_(typeName),
323  note_(),
324  instance_(instance),
325  local_(),
326  rOpt_(ro),
327  wOpt_(wo),
328  registerObject_(registerObject),
329  globalObject_(globalObject),
330  objState_(GOOD),
331  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
332  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
333 
334  db_(registry)
335 {
337  {
339  << "Constructing IOobject called " << name_
340  << " of type " << headerClassName_
341  << endl;
342  }
343 }
344 
345 
347 (
348  const word& name,
349  const fileName& instance,
350  const fileName& local,
351  const objectRegistry& registry,
352  readOption ro,
353  writeOption wo,
354  bool registerObject,
355  bool globalObject
356 )
357 :
358  name_(name),
359  headerClassName_(typeName),
360  note_(),
361  instance_(instance),
362  local_(local),
363  rOpt_(ro),
364  wOpt_(wo),
365  registerObject_(registerObject),
366  globalObject_(globalObject),
367  objState_(GOOD),
368  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
369  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
370 
371  db_(registry)
372 {
374  {
376  << "Constructing IOobject called " << name_
377  << " of type " << headerClassName_
378  << endl;
379  }
380 }
381 
382 
384 (
385  const fileName& path,
386  const objectRegistry& registry,
387  readOption ro,
388  writeOption wo,
389  bool registerObject,
390  bool globalObject
391 )
392 :
393  name_(),
394  headerClassName_(typeName),
395  note_(),
396  instance_(),
397  local_(),
398  rOpt_(ro),
399  wOpt_(wo),
400  registerObject_(registerObject),
401  globalObject_(globalObject),
402  objState_(GOOD),
403  sizeofLabel_(static_cast<unsigned char>(sizeof(label))),
404  sizeofScalar_(static_cast<unsigned char>(sizeof(scalar))),
405 
406  db_(registry)
407 {
408  if (!fileNameComponents(path, instance_, local_, name_))
409  {
411  << " invalid path specification"
412  << exit(FatalError);
413  }
414 
416  {
418  << "Constructing IOobject called " << name_
419  << " of type " << headerClassName_
420  << endl;
421  }
422 }
423 
424 
426 (
427  const IOobject& io,
428  const objectRegistry& registry
429 )
430 :
431  name_(io.name_),
432  headerClassName_(io.headerClassName_),
433  note_(io.note_),
434  instance_(io.instance_),
435  local_(io.local_),
436  rOpt_(io.rOpt_),
437  wOpt_(io.wOpt_),
438  registerObject_(io.registerObject_),
439  globalObject_(io.globalObject_),
440  objState_(io.objState_),
441  sizeofLabel_(io.sizeofLabel_),
442  sizeofScalar_(io.sizeofScalar_),
443 
444  db_(registry)
445 {}
446 
447 
449 (
450  const IOobject& io,
451  const word& name
452 )
453 :
454  name_(name),
455  headerClassName_(io.headerClassName_),
456  note_(io.note_),
457  instance_(io.instance_),
458  local_(io.local_),
459  rOpt_(io.rOpt_),
460  wOpt_(io.wOpt_),
461  registerObject_(io.registerObject_),
462  globalObject_(io.globalObject_),
463  objState_(io.objState_),
464  sizeofLabel_(io.sizeofLabel_),
465  sizeofScalar_(io.sizeofScalar_),
466 
467  db_(io.db_)
468 {}
469 
470 
472 (
473  const IOobject& io,
474  readOption ro,
475  writeOption wo
476 )
477 :
478  IOobject(io)
479 {
480  rOpt_ = ro;
481  wOpt_ = wo;
482 }
483 
484 
485 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
486 
488 {
489  return db_;
490 }
491 
492 
494 {
495  return db_.time();
496 }
497 
498 
500 {
501  return time().rootPath();
502 }
503 
504 
506 {
507  return time().caseName();
508 }
509 
510 
512 {
513  // A file is 'outside' of the case if it has been specified using an
514  // absolute path
515 
516  const auto first = instance().find('/');
517 
518  if
519  (
520  first == 0
521  #ifdef _WIN32
522  || (first == 2 && instance()[1] == ':') // Eg, d:/path
523  #endif
524  )
525  {
526  // Absolute path (starts with '/' or 'd:/')
527  return instance();
528  }
529 
530  return rootPath()/caseName()/instance()/db_.dbDir()/local();
531 }
532 
533 
535 (
536  const word& instance,
537  const fileName& local
538 ) const
539 {
540  // Note: can only be called with relative instance since is word type
541  return rootPath()/caseName()/instance/db_.dbDir()/local;
542 }
543 
544 
546 {
547  // A file is 'outside' of the case if it has been specified using an
548  // absolute path
549 
550  const auto first = instance().find('/');
551 
552  if
553  (
554  first == 0
555  #ifdef _WIN32
556  || (first == 2 && instance()[1] == ':') // Eg, d:/path
557  #endif
558  )
559  {
560  // Absolute path (starts with '/' or 'd:/')
561  return instance()/name();
562  }
563 
564  return instance()/db_.dbDir()/local()/name();
565 }
566 
567 
569 (
570  const word& typeName,
571  const bool search
572 ) const
573 {
574  // Do not check for undecomposed files
575  return fileHandler().filePath(false, *this, typeName, search);
576 }
577 
578 
580 (
581  const word& typeName,
582  const bool search
583 ) const
584 {
585  // Check for undecomposed files
586  return fileHandler().filePath(true, *this, typeName, search);
587 }
588 
589 
590 void Foam::IOobject::setBad(const string& s)
591 {
592  if (objState_ != GOOD)
593  {
595  << "Recurrent failure for object " << s
596  << exit(FatalError);
597  }
598 
599  if (error::level)
600  {
602  << "Broken object " << s << info() << endl;
603  }
604 
605  objState_ = BAD;
606 }
607 
608 
609 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
610 
612 {
613  name_ = io.name_;
614  headerClassName_ = io.headerClassName_;
615  note_ = io.note_;
616  instance_ = io.instance_;
617  local_ = io.local_;
618  rOpt_ = io.rOpt_;
619  wOpt_ = io.wOpt_;
620  globalObject_ = io.globalObject_;
621  objState_ = io.objState_;
622  sizeofLabel_ = io.sizeofLabel_;
623  sizeofScalar_ = io.sizeofScalar_;
624 }
625 
626 
627 // ************************************************************************* //
Foam::expressions::patchExpr::debug
int debug
Static debugging option.
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
InfoInFunction
#define InfoInFunction
Report an information message using Foam::Info.
Definition: messageStream.H:350
Foam::IOobject::fileCheckTypes
fileCheckTypes
Enumeration defining the file checking options.
Definition: IOobject.H:199
Foam::Enum
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: IOstreamOption.H:57
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::IOobject::localFilePath
fileName localFilePath(const word &typeName, const bool search=true) const
Helper for filePath that searches locally.
Definition: IOobject.C:569
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::IOobject::fileCheckTypesNames
static const Enum< fileCheckTypes > fileCheckTypesNames
Names for the fileCheckTypes.
Definition: IOobject.H:208
Foam::fileName
A class for handling file names.
Definition: fileName.H:73
Foam::IOobject::registerObject
bool registerObject() const noexcept
Should object created with this IOobject be registered?
Definition: IOobjectI.H:107
s
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))
Definition: gmvOutputSpray.H:25
registerOptSwitch
registerOptSwitch("fileModificationSkew", float, Foam::IOobject::fileModificationSkew)
Foam::IOobject::rootPath
const fileName & rootPath() const
Definition: IOobject.C:499
Foam::messageStream::level
static int level
The output level (verbosity) of messages.
Definition: messageStream.H:112
Foam::IOobject::fileModificationChecking
static fileCheckTypes fileModificationChecking
Type of file modification checking.
Definition: IOobject.H:303
Foam::fileOperation::filePath
virtual fileName filePath(const bool checkGlobal, const IOobject &, const word &typeName, const bool search=true) const =0
Search for an object. checkGlobal : also check undecomposed case.
Foam::IOobject::scopeSeparator
static char scopeSeparator
Character for scoping object names (':' or '_')
Definition: IOobject.H:300
Foam::fileHandler
const fileOperation & fileHandler()
Get current file handler.
Definition: fileOperation.C:1485
Foam::IOobject::IOobject
IOobject(const IOobject &)=default
Copy construct.
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
Foam::IOobject::objectRelPath
fileName objectRelPath() const
The object path relative to the root.
Definition: IOobject.C:545
Foam::IOobject::writeOpt
writeOption writeOpt() const noexcept
The write option.
Definition: IOobjectI.H:179
Foam::IOobject::time
const Time & time() const
Return Time associated with the objectRegistry.
Definition: IOobject.C:493
Foam::objectRegistry
Registry of regIOobjects.
Definition: objectRegistry.H:60
Foam::debug::infoSwitch
int infoSwitch(const char *name, const int deflt=0)
Lookup info switch or add default value.
Definition: debug.C:231
Foam::IOobject::writeOption
writeOption
Enumeration defining the write options.
Definition: IOobject.H:192
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:61
Foam::IOobject::caseName
const fileName & caseName() const
Definition: IOobject.C:505
Foam::IOobject::globalObject
bool globalObject() const noexcept
Is object same for all processors?
Definition: IOobjectI.H:121
Foam::IOobject::selectIO
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:238
Istream.H
Foam::IOobject::fileNameComponents
static bool fileNameComponents(const fileName &path, fileName &instance, fileName &local, word &name)
Split path into instance, local, name components.
Definition: IOobject.C:147
Foam::IOobject::fileModificationSkew
static float fileModificationSkew
Time skew (seconds) for file modification checks.
Definition: IOobject.H:306
Foam::debug::optimisationSwitch
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:237
Foam::writeData
static void writeData(Ostream &os, const Type &val)
Definition: rawSurfaceWriterImpl.C:45
IOobject.H
Foam::IOobject::globalFilePath
fileName globalFilePath(const word &typeName, const bool search=true) const
Helper for filePath that searches up if in parallel.
Definition: IOobject.C:580
Foam::FatalError
error FatalError
os
OBJstream os(runTime.globalPath()/outputName)
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::IOobject::readOpt
readOption readOpt() const noexcept
The read option.
Definition: IOobjectI.H:164
Foam::IOobject::operator=
void operator=(const IOobject &io)
Definition: IOobject.C:611
Foam::IOobject::name
const word & name() const noexcept
Return name.
Definition: IOobjectI.H:65
Time.H
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::debug::floatOptimisationSwitch
float floatOptimisationSwitch(const char *name, const float deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:243
Foam::IOobject::member
word member() const
Return member (name without the extension)
Definition: IOobjectI.H:77
Foam::string::expand
string & expand(const bool allowEmpty=false)
Definition: string.C:173
path
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
Foam::search
fileName search(const word &file, const fileName &directory)
Recursively search the given directory for the file.
Definition: fileName.C:571
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
Foam::IOobject::group
word group() const
Return group (extension part of name)
Definition: IOobjectI.H:71
Foam::IOobject::setBad
void setBad(const string &s)
Set the object state to bad.
Definition: IOobject.C:590
Foam::name
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
Definition: exprTraits.C:59
Foam::fileName::clean
static bool clean(std::string &str)
Definition: fileName.C:199
Foam::cwd
fileName cwd()
The physical or logical current working directory path name.
Definition: MSwindows.C:468
registerSwitch.H
Foam::IOobject::readOption
readOption
Enumeration defining the read options.
Definition: IOobject.H:183
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::stringOps::validate
StringType validate(const std::string &str, const UnaryPredicate &accept, const bool invert=false)
Return a copy of the input string with validated characters.
Definition: stringOpsTemplates.C:71
Foam::IOobject::path
fileName path() const
The complete path.
Definition: IOobject.C:511
Foam::debug::optimisationSwitches
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict(s).
Definition: debug.C:219
Foam::Enum::read
EnumType read(Istream &is) const
Read a word from Istream and return the corresponding enumeration.
Definition: Enum.C:109
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
Foam::debug::addOptimisationObject
void addOptimisationObject(const char *name, simpleRegIOobject *obj)
Register optimisation switch read/write object.
Definition: debug.C:262
Foam::objectRegistry::time
const Time & time() const noexcept
Return time registry.
Definition: objectRegistry.H:178
Foam::simpleRegIOobject
Abstract base class for registered object with I/O. Used in debug symbol registration.
Definition: simpleRegIOobject.H:52
Foam::isDir
bool isDir(const fileName &name, const bool followLink=true)
Does the name exist as a DIRECTORY in the file system?
Definition: MSwindows.C:643
Foam::IOobject::db
const objectRegistry & db() const noexcept
Return the local objectRegistry.
Definition: IOobject.C:487
Foam::IOobject::maxFileModificationPolls
static int maxFileModificationPolls
Max number of times to poll for file modification changes.
Definition: IOobject.H:309