IOobject.C 12 KB
Newer Older
1
2
3
4
/*---------------------------------------------------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     |
OpenFOAM bot's avatar
OpenFOAM bot committed
5
    \\  /    A nd           | www.openfoam.com
OpenFOAM bot's avatar
OpenFOAM bot committed
6
7
     \\/     M anipulation  |
-------------------------------------------------------------------------------
OpenFOAM bot's avatar
OpenFOAM bot committed
8
9
    Copyright (C) 2011-2017 OpenFOAM Foundation
    Copyright (C) 2016-2019 OpenCFD Ltd.
10
11
12
13
-------------------------------------------------------------------------------
License
    This file is part of OpenFOAM.

14
15
16
17
    OpenFOAM is free software: you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
18
19
20
21
22
23
24

    OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    for more details.

    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
30
31
32
33
34

\*---------------------------------------------------------------------------*/

#include "IOobject.H"
#include "Time.H"
#include "IFstream.H"

// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //

35
36
namespace Foam
{
37
    defineTypeNameAndDebug(IOobject, 0);
38
39
}

40
41
42
43
44
const Foam::Enum
<
    Foam::IOobject::fileCheckTypes
>
Foam::IOobject::fileCheckTypesNames
Mark Olesen's avatar
Mark Olesen committed
45
({
46
47
48
49
    { fileCheckTypes::timeStamp, "timeStamp" },
    { fileCheckTypes::timeStampMaster, "timeStampMaster" },
    { fileCheckTypes::inotify, "inotify" },
    { fileCheckTypes::inotifyMaster, "inotifyMaster" },
Mark Olesen's avatar
Mark Olesen committed
50
});
51
52
53
54
55


// Default fileCheck type
Foam::IOobject::fileCheckTypes Foam::IOobject::fileModificationChecking
(
Mark Olesen's avatar
Mark Olesen committed
56
    fileCheckTypesNames.get
57
    (
58
59
        "fileModificationChecking",
        debug::optimisationSwitches()
60
61
62
    )
);

63

64
//! \cond file-scope
65
66
67
68
69
70
71
72
73
namespace Foam
{
    // Register re-reader
    class addfileModificationCheckingToOpt
    :
        public ::Foam::simpleRegIOobject
    {
    public:

74
75
76
77
78
79
80
        addfileModificationCheckingToOpt
            (const addfileModificationCheckingToOpt&) = delete;

        void operator=
            (const addfileModificationCheckingToOpt&) = delete;

        explicit addfileModificationCheckingToOpt(const char* name)
81
82
83
84
        :
            ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
        {}

85
        virtual ~addfileModificationCheckingToOpt() = default;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103

        virtual void readData(Foam::Istream& is)
        {
            IOobject::fileModificationChecking =
                IOobject::fileCheckTypesNames.read(is);
        }

        virtual void writeData(Foam::Ostream& os) const
        {
            os <<  IOobject::fileCheckTypesNames
                [IOobject::fileModificationChecking];
        }
    };

    addfileModificationCheckingToOpt addfileModificationCheckingToOpt_
    (
        "fileModificationChecking"
    );
104
105
106

} // End namespace Foam
//! \endcond
107

108

109
110
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //

william's avatar
william committed
111
bool Foam::IOobject::fileNameComponents
112
(
113
    const fileName& path,
114
115
116
117
118
    fileName& instance,
    fileName& local,
    word& name
)
{
119
    // Convert explicit relative file-system path to absolute file-system path.
120
    if (path.starts_with("./") || path.starts_with("../"))
121
122
123
124
125
126
    {
        fileName absPath = cwd()/path;
        absPath.clean();

        return fileNameComponents(absPath, instance, local, name);
    }
127

128
129
130
131
    instance.clear();
    local.clear();
    name.clear();

132
    // Called with directory
133
    if (isDir(path))
134
    {
135
136
        WarningInFunction
            << " called with directory: " << path << endl;
137

138
139
140
        return false;
    }

141
142
143
144
145
146
147
148
149
150
151
    const auto first = path.find('/');
    const auto last  = path.rfind('/');

    // The raw length of name (without validating for word chars)
    auto nameLen = path.size();

    if (first == std::string::npos)
    {
        // No '/' found (or empty entirely)
        // => no instance or local

152
        name = word::validate(path);
153
    }
154
155
156
157
158
159
160
    else if
    (
        first == 0
        #ifdef _WIN32
     || (first == 2 && path[1] == ':')  // Eg, d:/path
        #endif
    )
161
    {
162
        // Absolute path (starts with '/' or 'd:/')
163
164
        // => no local

165
        instance = path.substr(0, last);
166

167
168
        const std::string ending = path.substr(last+1);
        nameLen = ending.size();  // The raw length of name
169
        name = word::validate(ending);
170
    }
171
172
    else
    {
173
174
175
        // Normal case.
        // First part is instance, remainder is local
        instance = path.substr(0, first);
176

177
        if (last > first)
178
        {
179
180
            // With local
            local = path.substr(first+1, last-first-1);
181
        }
182

183
184
        const std::string ending = path.substr(last+1);
        nameLen = ending.size();  // The raw length of name
185
        name = word::validate(ending);
186
187
    }

188
    // Check for valid (and stripped) name, regardless of the debug level
189
    if (!nameLen || nameLen != name.size())
190
    {
191
        WarningInFunction
192
            << "has invalid word for name: \"" << name
193
194
            << "\"\nwhile processing path: " << path << endl;

195
196
197
198
199
200
201
        return false;
    }

    return true;
}


202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
Foam::IOobject Foam::IOobject::selectIO
(
    const IOobject& io,
    const fileName& altFile,
    const word& ioName
)
{
    if (altFile.empty())
    {
        return io;
    }

    // Construct from file path instead

    fileName altPath = altFile;

    if (isDir(altPath))
    {
        // Resolve directories as well

        if (ioName.empty())
        {
            altPath /= io.name();
        }
        else
        {
            altPath /= ioName;
        }
    }
    altPath.expand();


    return
        IOobject
        (
            altPath,
            io.db(),
            io.readOpt(),
            io.writeOpt(),
            io.registerObject(),
            io.globalObject()
        );
}


247
248
Foam::word Foam::IOobject::group(const word& name)
{
249
    const auto i = name.rfind('.');
250

251
    if (i == std::string::npos || i == 0)
252
253
254
    {
        return word::null;
    }
255
256

    return name.substr(i+1);
257
258
259
260
261
}


Foam::word Foam::IOobject::member(const word& name)
{
262
    const auto i = name.rfind('.');
263

264
    if (i == std::string::npos || i == 0)
265
266
267
    {
        return name;
    }
268
269

    return name.substr(0, i);
270
271
272
}


273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
// * * * * * * * * * * * * * * * * Constructors  * * * * * * * * * * * * * * //

Foam::IOobject::IOobject
(
    const word& name,
    const fileName& instance,
    const objectRegistry& registry,
    readOption ro,
    writeOption wo,
    bool registerObject
)
:
    name_(name),
    headerClassName_(typeName),
    note_(),
    instance_(instance),
    local_(),
    db_(registry),
    rOpt_(ro),
    wOpt_(wo),
    registerObject_(registerObject),
294
    globalObject_(false),
295
    objState_(GOOD),
296
297
    labelByteSize_(sizeof(label)),
    scalarByteSize_(sizeof(scalar))
298
299
300
{
    if (objectRegistry::debug)
    {
Henry Weller's avatar
Henry Weller committed
301
302
        InfoInFunction
            << "Constructing IOobject called " << name_
303
304
305
306
307
308
309
310
311
312
313
314
315
316
            << " of type " << headerClassName_
            << endl;
    }
}


Foam::IOobject::IOobject
(
    const word& name,
    const fileName& instance,
    const fileName& local,
    const objectRegistry& registry,
    readOption ro,
    writeOption wo,
317
318
    bool registerObject,
    bool globalObject
319
320
321
322
323
324
325
326
327
328
329
)
:
    name_(name),
    headerClassName_(typeName),
    note_(),
    instance_(instance),
    local_(local),
    db_(registry),
    rOpt_(ro),
    wOpt_(wo),
    registerObject_(registerObject),
330
    globalObject_(globalObject),
331
    objState_(GOOD),
332
333
    labelByteSize_(sizeof(label)),
    scalarByteSize_(sizeof(scalar))
334
335
336
{
    if (objectRegistry::debug)
    {
Henry Weller's avatar
Henry Weller committed
337
338
        InfoInFunction
            << "Constructing IOobject called " << name_
339
340
341
342
343
344
            << " of type " << headerClassName_
            << endl;
    }
}


345
346
347
348
349
350
Foam::IOobject::IOobject
(
    const fileName& path,
    const objectRegistry& registry,
    readOption ro,
    writeOption wo,
351
352
    bool registerObject,
    bool globalObject
353
354
355
356
357
358
359
360
361
362
363
)
:
    name_(),
    headerClassName_(typeName),
    note_(),
    instance_(),
    local_(),
    db_(registry),
    rOpt_(ro),
    wOpt_(wo),
    registerObject_(registerObject),
364
    globalObject_(globalObject),
365
    objState_(GOOD),
366
367
    labelByteSize_(sizeof(label)),
    scalarByteSize_(sizeof(scalar))
368
{
369
370
    if (!fileNameComponents(path, instance_, local_, name_))
    {
371
        FatalErrorInFunction
372
            << " invalid path specification"
373
374
            << exit(FatalError);
    }
375
376
377

    if (objectRegistry::debug)
    {
Henry Weller's avatar
Henry Weller committed
378
379
        InfoInFunction
            << "Constructing IOobject called " << name_
380
381
382
383
384
385
            << " of type " << headerClassName_
            << endl;
    }
}


386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
Foam::IOobject::IOobject
(
    const IOobject& io,
    const objectRegistry& registry
)
:
    name_(io.name_),
    headerClassName_(io.headerClassName_),
    note_(io.note_),
    instance_(io.instance_),
    local_(io.local_),
    db_(registry),
    rOpt_(io.rOpt_),
    wOpt_(io.wOpt_),
    registerObject_(io.registerObject_),
    globalObject_(io.globalObject_),
402
403
404
    objState_(io.objState_),
    labelByteSize_(io.labelByteSize_),
    scalarByteSize_(io.scalarByteSize_)
405
406
407
{}


408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
Foam::IOobject::IOobject
(
    const IOobject& io,
    const word& name
)
:
    name_(name),
    headerClassName_(io.headerClassName_),
    note_(io.note_),
    instance_(io.instance_),
    local_(io.local_),
    db_(io.db_),
    rOpt_(io.rOpt_),
    wOpt_(io.wOpt_),
    registerObject_(io.registerObject_),
423
    globalObject_(io.globalObject_),
424
425
426
    objState_(io.objState_),
    labelByteSize_(io.labelByteSize_),
    scalarByteSize_(io.scalarByteSize_)
427
428
429
{}


430
431
432
433
434
435
436
437
438
439
440
441
442
443
// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //

const Foam::objectRegistry& Foam::IOobject::db() const
{
    return db_;
}


const Foam::Time& Foam::IOobject::time() const
{
    return db_.time();
}


444
445
446
447
448
449
const Foam::fileName& Foam::IOobject::rootPath() const
{
    return time().rootPath();
}


450
451
452
453
454
455
456
457
const Foam::fileName& Foam::IOobject::caseName() const
{
    return time().caseName();
}


Foam::fileName Foam::IOobject::path() const
{
458
    // A file is 'outside' of the case if it has been specified using an
459
    // absolute path
460

461
462
463
464
465
466
467
468
469
    const auto first = instance().find('/');

    if
    (
        first == 0
        #ifdef _WIN32
     || (first == 2 && instance()[1] == ':')  // Eg, d:/path
        #endif
    )
470
    {
471
        // Absolute path (starts with '/' or 'd:/')
472
473
        return instance();
    }
474
475

    return rootPath()/caseName()/instance()/db_.dbDir()/local();
476
477
478
479
480
481
482
483
484
}


Foam::fileName Foam::IOobject::path
(
    const word& instance,
    const fileName& local
) const
{
485
    // Note: can only be called with relative instance since is word type
486
487
488
489
    return rootPath()/caseName()/instance/db_.dbDir()/local;
}


490
491
492
493
494
Foam::fileName Foam::IOobject::localFilePath
(
    const word& typeName,
    const bool search
) const
495
{
496
497
    // Do not check for undecomposed files
    return fileHandler().filePath(false, *this, typeName, search);
498
499
500
}


501
502
503
504
505
Foam::fileName Foam::IOobject::globalFilePath
(
    const word& typeName,
    const bool search
) const
506
{
507
508
    // Check for undecomposed files
    return fileHandler().filePath(true, *this, typeName, search);
509
510
511
512
513
514
515
}


void Foam::IOobject::setBad(const string& s)
{
    if (objState_ != GOOD)
    {
516
        FatalErrorInFunction
Henry Weller's avatar
Henry Weller committed
517
            << "Recurrent failure for object " << s
518
519
520
521
522
            << exit(FatalError);
    }

    if (error::level)
    {
Henry Weller's avatar
Henry Weller committed
523
524
        InfoInFunction
            << "Broken object " << s << info() << endl;
525
526
527
528
529
530
    }

    objState_ = BAD;
}


531
532
// * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //

533
534
535
536
537
538
539
540
541
void Foam::IOobject::operator=(const IOobject& io)
{
    name_ = io.name_;
    headerClassName_ = io.headerClassName_;
    note_ = io.note_;
    instance_ = io.instance_;
    local_ = io.local_;
    rOpt_ = io.rOpt_;
    wOpt_ = io.wOpt_;
542
    globalObject_ = io.globalObject_;
543
    objState_ = io.objState_;
544
545
    labelByteSize_ = io.labelByteSize_;
    scalarByteSize_ = io.scalarByteSize_;
546
547
548
549
}


// ************************************************************************* //