openFOAM中的char和string並不是直接使用C++提供的string,而是進行了一系列的封裝,並添加了更多的功能。這裏進行一個總結。
char類型的更多功能
openFOAM中並沒有對char
進行封裝,而是直接在上面添加功能。主要依賴的是如下路徑的幾個文件:
src/OpenFOAM/primitives/chars/char
char.H charIO.C
src/OpenFOAM/primitives/chars/wchar
wchar.H wcharIO.C
添加了readChar
作爲文件流讀入的函數,以及判斷是否爲空格的isspace
函數,和運算符<< >>
的重定向。而char
和wchar
的區別在於,後者使用了一個佔用字節數更高的編碼方式,所以在文件操作時的實現還需要藉助一下位運算符。
string的重新封裝
在如下路徑中
src/OpenFOAM/primitives/strings/
fileName/ keyType/ lists/ string/
stringOps/ word/ wordRe/
其中基礎的是string
文件夾,他講std::string
繼承到自己的Foam::string
中。然後額外添加了靜態成員變量typeName debug null
,以及一個hash
類。另外定義了一系列的構造函數,用來進行初始化。代碼另外給string
添加了很多功能。
//- Count and return the number of a given character in the string
//返回string的字符數
size_type count(const char) const;
//- Is this string type valid?
//判斷是否合法,主要通過比較當前迭代器的首尾位置是否與內置迭代器重合判斷
template<class String>
static inline bool valid(const string&);
//- Does this string have particular meta-characters?
// The meta characters can be optionally quoted.
//判斷是否存在特定字符
template<class String>
static inline bool meta(const string&, const char quote='\\');
//- Strip invalid characters from the given string
//去掉其中不合法的字符,即去掉迭代器首尾之外的
template<class String>
static inline bool stripInvalid(string&);
//- Return a valid String from the given string
//返回迭代器之外的部分
template<class String>
static inline String validate(const string&);
//- Return a String with quoted meta-characters from the given string
template<class String>
static inline string quotemeta(const string&, const char quote='\\');
//- True when strings match literally
//字符匹配
inline bool match(const std::string&) const;
//- Avoid masking the normal std::string replace
//爲了避免下面的定義覆蓋原來的string
using std::string::replace;
//- Replace first occurrence of sub-string oldStr with newStr
// starting at start
string& replace
(
const string& oldStr,
const string& newStr,
size_type start = 0
);
//- Replace all occurrences of sub-string oldStr with newStr
// starting at start
string& replaceAll
(
const string& oldStr,
const string& newStr,
size_type start = 0
);
//- Expand initial tildes and all occurrences of environment variables
// Expansion includes:
// -# environment variables
// - "$VAR", "${VAR}"
// -# current directory
// - leading "./" : the current directory
// -# tilde expansion
// - leading "~/" : home directory
// - leading "~user" : home directory for specified user
// - leading "~OpenFOAM" : site/user OpenFOAM configuration directory
//
// Any unknown entries are removed silently if allowEmpty is true
// \sa
// Foam::findEtcFile
string& expand(const bool allowEmpty = false);
//- Remove repeated characters returning true if string changed
//去掉重複部分
bool removeRepeated(const char);
//- Return string with repeated characters removed
//同上,但是返回值變成了string
string removeRepeated(const char) const;
//- Remove trailing character returning true if string changed
//去掉尾部字符
bool removeTrailing(const char);
//- Return string with trailing character removed
//同上,但是返回值變成了string
string removeTrailing(const char) const;
另外,<< >>
被進行了重定向,方便文件流寫入string
。另外,這裏定義了兩個函數
void writeEntry(Ostream& os, const char* value);
void writeEntry(Ostream& os, const string& value);
是方便用戶在未創建類的情況下進行函數的調動,也是將文件流和string
進行交互。其中string\
和stringOps\
兩個文件夾都是對這一系列功能的支持文件。
通過string創建word類
word
是通過繼承當前Foam
這個名字空間下的string
類得到的。同樣給定了成員變量
static const char* const typeName;
static int debug;
//- An empty word
static const word null;
然後給定了一系列的構造函數,而成員函數只添加了一個
//- Is this character valid for a word
inline static bool valid(char);
其實現如下:
inline void Foam::word::stripInvalid()
{
// skip stripping unless debug is active to avoid
// costly operations
if (debug && string::stripInvalid<word>(*this))
{
std::cerr
<< "word::stripInvalid() called for word "
<< this->c_str() << std::endl;
if (debug > 1)
{
std::cerr
<< " For debug level (= " << debug
<< ") > 1 this is considered fatal" << std::endl;
std::abort();
}
}
}
我們可以看到他是通過父類string
中的stripInvalid
函數和自己的成員變量debug
進行判斷的。而debug
是通過一系列宏定義的,這裏先跳過,在後續的博客中會繼續補充。之後,當前類對運算符也進行了重定義,然後對函數writeEntry
進行了多態的補充。這一系列操作在文件夾word\
中
但是除此之外,word
相關還有一系列支持性的操作,在wordRe\
中,它以word
爲父類,創建了wordRe
類。除去構造函數之外,還定義了一系列功能性的成員函數,
從註釋上看,主要和與字符相關的正則表達式相關。這裏不展開,在後續使用過程中用到了繼續補充。
fileName和keyType的功能
他們兩個又是以word
爲父類的,然後添加了更多的功能,分別又fileName\
和keyType\
兩個文件夾支持。
首先來看fileName
,這裏的註釋給了比較好的說明:
Description
A class for handling file names.
A fileName is a string of characters without whitespace or quotes.
A fileName can be
- constructed from a char*, a string or a word
- concatenated by adding a '/' separator
- decomposed into the path, name or component list
- interrogated for type and access mode
The string::expand() method expands environment variables, etc,
就是用來存儲文件路徑的,這裏說明了構造函數的類型。另外還添加了一系列函數,總體實現的功能有:
//判斷路徑是否合法,就是a///b等這些是否會出現
inline static bool valid(char);
//清除文件路徑
fileName clean() const;
//判斷文件的類型,文件or文件夾orlinkor未知
fileType type
(
const bool checkVariants = true,
const bool followLink = true
)
//判斷文件是否爲絕對路徑,以及轉換爲絕對路徑
bool isAbsolute() const;
fileName& toAbsolute();
//分解出名字
word name() const;
string caseName() const;
word name(const bool noExt) const;
另外給定了一系列運算符的重定義,和之前類似,主要是爲了方便和文件流進行交互。
我們再來看keyType
,這裏的註釋也給出
Description
A class for handling keywords in dictionaries.
A keyType is the keyword of a dictionary.
It differs from word in that it accepts patterns (regular expressions).
就是說我們在使用openFOAM時,常常修改的配置文件,都是用字典的形式給出的,這些字典中的字符,將會使用這個類保存。除去基礎的成員變量和構造函數外,還定義瞭如下的成員函數:
//- Should be treated as a match rather than a literal string
inline bool isPattern() const;
//- Smart match as regular expression or as a string
// Optionally force a literal match only
bool match(const std::string&, bool literalMatch=false) const;
主要是服務於關鍵字的匹配,另外也同樣做了方便文件流使用的運算符重定義。
如上所有類的List類型
在文件夾lists\
中,其中包括了當前strings\
文件夾中所有類創建的List
的類型重定義,比如
#include "string.H"
#include "List.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
typedef UList<string> stringUList;
typedef List<string> stringList;
}
就是將用string
創建的List
和UList
重新定義爲類型stringUList
和stringList
,其他文件的內容也是一樣的。而List
的具體實現我們將在後續的博客中討論。