Skip to content
Snippets Groups Projects
IOobject.C 12.2 KiB
Newer Older
  • Learn to ignore specific revisions
  • /*---------------------------------------------------------------------------*\
      =========                 |
      \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
       \\    /   O peration     |
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        \\  /    A nd           | www.openfoam.com
    
         \\/     M anipulation  |
    -------------------------------------------------------------------------------
    
    OpenFOAM bot's avatar
    OpenFOAM bot committed
        Copyright (C) 2011-2017 OpenFOAM Foundation
    
        Copyright (C) 2016-2020 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 * * * * * * * * * * * * * //
    
    
    char Foam::IOobject::scopeSeparator
    (
        #ifdef _WIN32
    
        // Windows: using ':' causes scoping conflicts with d:/path etc
    
        Foam::debug::infoSwitch("scopeSeparator", '_')
        #else
        Foam::debug::infoSwitch("scopeSeparator", ':')
        #endif
    );
    
    
    
    const Foam::Enum
    <
        Foam::IOobject::fileCheckTypes
    >
    Foam::IOobject::fileCheckTypesNames
    
        { fileCheckTypes::timeStamp, "timeStamp" },
        { fileCheckTypes::timeStampMaster, "timeStampMaster" },
        { fileCheckTypes::inotify, "inotify" },
        { fileCheckTypes::inotifyMaster, "inotifyMaster" },
    
    Mark OLESEN's avatar
    Mark OLESEN committed
    });
    
    
    
    // Default fileCheck type
    Foam::IOobject::fileCheckTypes Foam::IOobject::fileModificationChecking
    (
    
    Mark OLESEN's avatar
    Mark OLESEN committed
        fileCheckTypesNames.get
    
            "fileModificationChecking",
            debug::optimisationSwitches()
    
    //! \cond file-scope
    
    namespace Foam
    {
        // Register re-reader
        class addfileModificationCheckingToOpt
        :
            public ::Foam::simpleRegIOobject
        {
        public:
    
    
            addfileModificationCheckingToOpt
                (const addfileModificationCheckingToOpt&) = delete;
    
            void operator=
                (const addfileModificationCheckingToOpt&) = delete;
    
            explicit addfileModificationCheckingToOpt(const char* name)
    
            :
                ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
            {}
    
    
            virtual ~addfileModificationCheckingToOpt() = default;
    
    
            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"
        );
    
    
    } // End namespace Foam
    //! \endcond
    
    // * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
    
    
    william's avatar
    william committed
    bool Foam::IOobject::fileNameComponents
    
        fileName& instance,
        fileName& local,
        word& name
    )
    {
    
        // Convert explicit relative file-system path to absolute file-system path.
    
        if (path.starts_with("./") || path.starts_with("../"))
    
        {
            fileName absPath = cwd()/path;
            absPath.clean();
    
            return fileNameComponents(absPath, instance, local, 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::validate(path);
    
        else if
        (
            first == 0
            #ifdef _WIN32
         || (first == 2 && path[1] == ':')  // Eg, d:/path
            #endif
        )
    
            // Absolute path (starts with '/' or 'd:/')
    
            instance = path.substr(0, last);
    
            const std::string ending = path.substr(last+1);
            nameLen = ending.size();  // The raw length of name
    
            name = word::validate(ending);
    
            // 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::validate(ending);
    
        // 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;
    
    
    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()
            );
    }
    
    
    
    Foam::word Foam::IOobject::group(const word& name)
    {
    
        const auto i = name.rfind('.');
    
        if (i == std::string::npos || i == 0)
    
    
        return name.substr(i+1);
    
    }
    
    
    Foam::word Foam::IOobject::member(const word& name)
    {
    
        const auto i = name.rfind('.');
    
        if (i == std::string::npos || i == 0)
    
    
        return name.substr(0, i);
    
    // * * * * * * * * * * * * * * * * 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),
    
        labelByteSize_(sizeof(label)),
        scalarByteSize_(sizeof(scalar))
    
    {
        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),
    
        labelByteSize_(sizeof(label)),
        scalarByteSize_(sizeof(scalar))
    
    {
        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),
    
        labelByteSize_(sizeof(label)),
        scalarByteSize_(sizeof(scalar))
    
        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_),
        labelByteSize_(io.labelByteSize_),
        scalarByteSize_(io.scalarByteSize_)
    
    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_),
    
        objState_(io.objState_),
        labelByteSize_(io.labelByteSize_),
        scalarByteSize_(io.scalarByteSize_)
    
    // * * * * * * * * * * * * * * * 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::fileName Foam::IOobject::path() const
    {
    
        // A file is 'outside' of the case if it has been specified using an
    
        const auto first = instance().find('/');
    
        if
        (
            first == 0
            #ifdef _WIN32
         || (first == 2 && instance()[1] == ':')  // Eg, d:/path
            #endif
        )
    
            // Absolute path (starts with '/' or 'd:/')
    
            return instance();
        }
    
    
        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 word& typeName,
        const bool search
    ) const
    
        // Do not check for undecomposed files
        return fileHandler().filePath(false, *this, typeName, search);
    
    Foam::fileName Foam::IOobject::globalFilePath
    (
        const word& typeName,
        const bool search
    ) const
    
        // Check for undecomposed files
        return fileHandler().filePath(true, *this, typeName, search);
    
    }
    
    
    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_;
    
        labelByteSize_ = io.labelByteSize_;
        scalarByteSize_ = io.scalarByteSize_;
    
    }
    
    
    // ************************************************************************* //