openFOAM中文件流的获取——lookup函数

openFOAM中的几乎所有类都提供了文件流操作的重定义,即>> <<即可实现文件流操作。例如对于标量来说,读取标量时:

scalar readScalar(Istream& is)
{
    scalar rs;
    is >> rs;

    return rs;
}

我们只需要提供文件流is,就可以通过调用函数返回一个标量值。

那么这样的文件流如何获取呢?这里讨论这部分内容

这里介绍的是lookup函数,他位于路径src/OpenFOAM/db/dictionary/dictionary.H中,其内容为:

Foam::ITstream& Foam::dictionary::lookup
(
    const word& keyword,
    bool recursive,
    bool patternMatch
) const
{
    return lookupEntry(keyword, recursive, patternMatch).stream();
}

const Foam::entry& Foam::dictionary::lookupEntry
(
    const word& keyword,
    bool recursive,
    bool patternMatch
) const
{
    const entry* entryPtr = lookupEntryPtr(keyword, recursive, patternMatch);

    if (entryPtr == nullptr)
    {
        FatalIOErrorInFunction
        (
            *this
        )   << "keyword " << keyword << " is undefined in dictionary "
            << name()
            << exit(FatalIOError);
    }

    return *entryPtr;
}

Foam::entry* Foam::dictionary::lookupEntryPtr
(
    const word& keyword,
    bool recursive,
    bool patternMatch
)
{
    HashTable<entry*>::iterator iter = hashedEntries_.find(keyword);

    if (iter == hashedEntries_.end()) //相当于当前字典没找到,就到更大范围查找
    {
        if (patternMatch && patternEntries_.size())
        {
            DLList<entry*>::iterator wcLink =
                patternEntries_.begin();
            DLList<autoPtr<regExp>>::iterator reLink =
                patternRegexps_.begin();

            // Find in patterns using regular expressions only
            if (findInPatterns(patternMatch, keyword, wcLink, reLink))
            {
                return wcLink();
            }
        }

        if (recursive && &parent_ != &dictionary::null)
        {
            return const_cast<dictionary&>(parent_).lookupEntryPtr
            (
                keyword,
                recursive,
                patternMatch
            );
        }
        else
        {
            return nullptr;
        }
    }

    return iter();
}

最终调用的是函数lookupEntryPtr,他通过HashTable中的find,以keyword查找entry*,并最终返回。中间是如果当前字典没有检索到,就扩大检索范围。

而函数lookupEntry,通过调用lookupEntryPtr得到entry* entryPtr。检查一下是否检索成功,并最终返回指针指向的对象。

函数lookup就只有一行return lookupEntry(keyword, recursive, patternMatch).stream();,他通过.stream()调用entry类的函数。而entry类中的这个函数为纯虚函数,他的实现在primitiveEntry.C中,内容如下:

 Foam::ITstream& Foam::primitiveEntry::stream() const
 {
     ITstream& is = const_cast<primitiveEntry&>(*this);
     is.rewind();
     return is;
 }

即得到了一个文件流并返回。

其中ITstream的内容会在后续博客中解释,写完后在这里补充链接

总结一下:
1.dictionary一系的类,可以检索文件中的关键字,并返回一个文件流
2.几乎所有的基础类型都提供了文件流的导入和导出操作,所以只需要使用能够给定文件流的类,就可以读取相应的文件。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片