Skip to content
Snippets Groups Projects
IOobject.C 14.6 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    Henry Weller's avatar
    Henry Weller committed
        \\  /    A nd           | Copyright (C) 2011-2016 OpenFOAM Foundation
    
         \\/     M anipulation  | Copyright (C) 2016-2017 OpenCFD Ltd.
    
    -------------------------------------------------------------------------------
    License
        This file is part of OpenFOAM.
    
    
        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.
    
    
        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
    
        along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
    
    
    \*---------------------------------------------------------------------------*/
    
    #include "IOobject.H"
    #include "Time.H"
    #include "IFstream.H"
    
    // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
    
    
    const Foam::Enum
    <
        Foam::IOobject::fileCheckTypes
    >
    Foam::IOobject::fileCheckTypesNames
    {
        { fileCheckTypes::timeStamp, "timeStamp" },
        { fileCheckTypes::timeStampMaster, "timeStampMaster" },
        { fileCheckTypes::inotify, "inotify" },
        { fileCheckTypes::inotifyMaster, "inotifyMaster" },
    };
    
    
    
    // Default fileCheck type
    Foam::IOobject::fileCheckTypes Foam::IOobject::fileModificationChecking
    (
    
        fileCheckTypesNames.lookup
    
            "fileModificationChecking",
            debug::optimisationSwitches()
    
    namespace Foam
    {
        // Register re-reader
        class addfileModificationCheckingToOpt
        :
            public ::Foam::simpleRegIOobject
        {
        public:
    
            addfileModificationCheckingToOpt(const char* name)
            :
                ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
            {}
    
            virtual ~addfileModificationCheckingToOpt()
            {}
    
            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"
        );
    
    // file-scope
    //
    // A file is 'outside' of the case if it has been specified using an
    // absolute path (starts with '/')
    //
    static inline bool isOutsideOfCase(const std::string& file)
    {
        return !file.empty() && file[0] == '/';
    }
    
    
    
    // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
    
    
    // Return components following the IOobject requirements
    //
    // behaviour
    //    input               IOobject(instance, local, name)
    //    -----               ------
    //    "foo"               ("", "", "foo")
    //    "foo/bar"           ("foo", "", "bar")
    //    "foo/bar/"          ERROR - no name
    //    "foo/xxx/bar"       ("foo", "xxx", "bar")
    //    "foo/xxx/yyy/bar"   ("foo", "xxx/yyy", "bar")
    
    //    "/xxx/yyy/bar"      ("/xxx/yyy", "", "bar")
    
    william's avatar
    william committed
    bool Foam::IOobject::fileNameComponents
    
    (
        const fileName& path,
        fileName& instance,
        fileName& local,
        word& name
    )
    {
        instance.clear();
        local.clear();
        name.clear();
    
    
            WarningInFunction
                << " called with directory: " << path << endl;
    
        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
    
            name = word::validated(path, false);
        }
        else if (first == 0)
    
            // Absolute path (starts with '/')
            // => no local
    
    
            instance = path.substr(0, last);
    
    
            const std::string ending = path.substr(last+1);
            nameLen = ending.size();  // The raw length of name
            name = word::validated(ending, false);
    
            // Normal case.
            // First part is instance, remainder is local
            instance = path.substr(0, first);
    
                // With local
                local = path.substr(first+1, last-first-1);
    
            const std::string ending = path.substr(last+1);
            nameLen = ending.size();  // The raw length of name
            name = word::validated(ending, false);
    
        // Check for valid (and stripped) name, regardless of the debug level
    
        if (!nameLen || nameLen != name.size())
    
                << "has invalid word for name: \"" << name
    
                << "\"\nwhile processing path: " << path << endl;
    
    
    // * * * * * * * * * * * * * * * * 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),
    
        globalObject_(false),
    
        objState_(GOOD)
    {
        if (objectRegistry::debug)
        {
    
    Henry Weller's avatar
    Henry Weller committed
            InfoInFunction
                << "Constructing IOobject called " << name_
    
                << " of type " << headerClassName_
                << endl;
        }
    }
    
    
    Foam::IOobject::IOobject
    (
        const word& name,
        const fileName& instance,
        const fileName& local,
        const objectRegistry& registry,
        readOption ro,
        writeOption wo,
    
        bool registerObject,
        bool globalObject
    
    )
    :
        name_(name),
        headerClassName_(typeName),
        note_(),
        instance_(instance),
        local_(local),
        db_(registry),
        rOpt_(ro),
        wOpt_(wo),
        registerObject_(registerObject),
    
        globalObject_(globalObject),
    
        objState_(GOOD)
    {
        if (objectRegistry::debug)
        {
    
    Henry Weller's avatar
    Henry Weller committed
            InfoInFunction
                << "Constructing IOobject called " << name_
    
                << " of type " << headerClassName_
                << endl;
        }
    }
    
    
    
    Foam::IOobject::IOobject
    (
        const fileName& path,
        const objectRegistry& registry,
        readOption ro,
        writeOption wo,
    
        bool registerObject,
        bool globalObject
    
    )
    :
        name_(),
        headerClassName_(typeName),
        note_(),
        instance_(),
        local_(),
        db_(registry),
        rOpt_(ro),
        wOpt_(wo),
        registerObject_(registerObject),
    
        globalObject_(globalObject),
    
        if (!fileNameComponents(path, instance_, local_, name_))
        {
    
                << " invalid path specification"
    
    
        if (objectRegistry::debug)
        {
    
    Henry Weller's avatar
    Henry Weller committed
            InfoInFunction
                << "Constructing IOobject called " << name_
    
                << " of type " << headerClassName_
                << endl;
        }
    }
    
    
    
    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_),
        objState_(io.objState_)
    {}
    
    
    
    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_),
    
        globalObject_(io.globalObject_),
    
    // * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * * //
    
    Foam::IOobject::~IOobject()
    {}
    
    
    // * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
    
    const Foam::objectRegistry& Foam::IOobject::db() const
    {
        return db_;
    }
    
    
    const Foam::Time& Foam::IOobject::time() const
    {
        return db_.time();
    }
    
    
    
    const Foam::fileName& Foam::IOobject::rootPath() const
    {
        return time().rootPath();
    }
    
    
    
    const Foam::fileName& Foam::IOobject::caseName() const
    {
        return time().caseName();
    }
    
    
    
    Foam::word Foam::IOobject::group() const
    {
    
        {
            return word::null;
        }
        else
        {
    
    Foam::fileName Foam::IOobject::path() const
    {
    
        {
            return instance();
        }
        else
        {
            return rootPath()/caseName()/instance()/db_.dbDir()/local();
        }
    
    }
    
    
    Foam::fileName Foam::IOobject::path
    (
        const word& instance,
        const fileName& local
    ) const
    {
    
        // Note: can only be called with relative instance since is word type
    
        return rootPath()/caseName()/instance/db_.dbDir()/local;
    }
    
    
    
    Foam::fileName Foam::IOobject::localFilePath(const bool search) const
    
            const fileName objectPath = instance()/name();
    
            if (isFile(objectPath))
            {
                return objectPath;
            }
            else
            {
                return fileName::null;
            }
    
            const fileName path = this->path();
            const fileName objectPath = path/name();
    
            if (isFile(objectPath))
            {
                return objectPath;
    
                    const word newInstancePath = time().findInstancePath
    
                    (
                        instant(instance())
                    );
    
                    if (newInstancePath.size())
                    {
    
                        (
                            rootPath()/caseName()
                           /newInstancePath/db_.dbDir()/local()/name()
                        );
    
                        if (isFile(fName))
                        {
                            return fName;
                        }
                    }
                }
            }
    
            return fileName::null;
        }
    }
    
    
    
    Foam::fileName Foam::IOobject::globalFilePath(const bool search) const
    
            const fileName objectPath = instance()/name();
    
            if (isFile(objectPath))
            {
                if (objectRegistry::debug)
                {
                    Pout<< "globalFilePath : returning absolute:" << objectPath
                        << endl;
                }
                return objectPath;
            }
            else
            {
                if (objectRegistry::debug)
                {
                    Pout<< "globalFilePath : absolute not found:" << objectPath
                        << endl;
                }
                return fileName::null;
            }
        }
        else
        {
    
            const fileName path = this->path();
            const fileName objectPath = path/name();
    
    
            if (isFile(objectPath))
            {
                if (objectRegistry::debug)
                {
                    Pout<< "globalFilePath : returning time:" << objectPath << endl;
                }
                return objectPath;
            }
            else
    
                if
                (
                    time().processorCase()
                 && (
                        instance() == time().system()
                     || instance() == time().constant()
                    )
                )
                {
    
                    // Constant & system can come from global case
    
    
    mattijs's avatar
    mattijs committed
                        rootPath()/time().globalCaseName()
    
                       /instance()/db().dbDir()/local()/name();
    
    
                    if (isFile(parentObjectPath))
                    {
    
                        if (objectRegistry::debug)
                        {
                            Pout<< "globalFilePath : returning parent:"
                                << parentObjectPath << endl;
                        }
    
                        return parentObjectPath;
                    }
                }
    
                // Check for approximately same (local) time
                if (!isDir(path) && search)
    
                    const word newInstancePath = time().findInstancePath
    
                        instant(instance())
    
                    if (newInstancePath.size())
    
                        (
                            rootPath()/caseName()
    
                           /newInstancePath/db().dbDir()/local()/name()
    
                        );
    
                        if (isFile(fName))
                        {
    
                            if (objectRegistry::debug)
                            {
                                Pout<< "globalFilePath : returning similar time:"
                                    << fName << endl;
                            }
    
    
                            return fName;
                        }
    
            if (objectRegistry::debug)
            {
                Pout<< "globalFilePath : time not found:" << objectPath << endl;
            }
    
            return fileName::null;
        }
    
    Foam::Istream* Foam::IOobject::objectStream(const fileName& fName)
    {
    
    Mark Olesen's avatar
    Mark Olesen committed
        if (fName.size())
    
        {
            IFstream* isPtr = new IFstream(fName);
    
            if (isPtr->good())
            {
                return isPtr;
            }
            else
            {
                delete isPtr;
    
    }
    
    
    void Foam::IOobject::setBad(const string& s)
    {
        if (objState_ != GOOD)
        {
    
    Henry Weller's avatar
    Henry Weller committed
                << "Recurrent failure for object " << s
    
                << exit(FatalError);
        }
    
        if (error::level)
        {
    
    Henry Weller's avatar
    Henry Weller committed
            InfoInFunction
                << "Broken object " << s << info() << endl;
    
    // * * * * * * * * * * * * * * * Member Operators  * * * * * * * * * * * * * //
    
    
    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_;
    
        globalObject_ = io.globalObject_;
    
        objState_ = io.objState_;
    }
    
    
    // ************************************************************************* //