token class in OpenFOAM

Part of token class in OpenFOAM

This study comes from the following codes:

1
2
3
Istream& iss = coalParcels.composition().coeffDict().lookup("phases");
// or ITstream iss = coalParcels.composition().coeffDict().lookup("phases");
token firstToken(iss);

These codes are what I add in to the createCloud.H in the coalChemistryFoam folder. the iss is actually a reference to a ITstream object returned by function lookup() defined in dictionary.C:

1
2
3
4
5
6
7
8
9
Foam::ITstream& Foam::dictionary::lookup
(
const word& keyword,
bool recursive,
bool patternMatch
) const
{
return lookupEntry(keyword, recursive, patternMatch).stream();
}

We would like to see how this firstToken is initialized in the token class. This firstToken object takes an Istream object as an input parameter. As mentioned before, this object is actually a ITstream object. The ITstream class as its name indicates is a class takes care of Input token stream. Let’s go into the code now.

1
token firstToken(iss);

This will call the constructor of the token class defined in tokenIO.C:

1
2
3
4
5
6
Foam::token::token(Istream& is)
:
type_(UNDEFINED)
{
is.read(*this);
}

Here the is is Istream reference object. In the Istream class, there is pure virtual function called read() :

1
2
//- Return next token from stream
virtual Istream& read(token&) = 0;

The *this object here is of course a token class object. As ITstream is a subclass of Istream, and the ITstream class redefine the function read to read a token object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Foam::Istream& Foam::ITstream::read(token& t)
{
// Return the put back token if it exists
if (Istream::getBack(t))
{
lineNumber_ = t.lineNumber();
return *this;
}

if (tokenIndex_ < size())
{
t = operator[](tokenIndex_++);
lineNumber_ = t.lineNumber();

if (tokenIndex_ == size())
{
setEof();
}
}
else
{
if (eof())
{
FatalIOErrorInFunction
(
*this
) << "attempt to read beyond EOF"
<< exit(FatalIOError);

setBad();
}
else
{
setEof();
}

t = token::undefinedToken;

if (size())
{
t.lineNumber() = tokenList::last().lineNumber();
}
else
{
t.lineNumber() = lineNumber();
}
}

return *this;
}

In the first if loop, the Istream::getBack(t) is called:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool Foam::Istream::getBack(token& t)
{
if (bad())
{
FatalIOErrorInFunction(*this)
<< "Attempt to get back from bad stream"
<< exit(FatalIOError);
}
else if (putBack_)
{
t = putBackToken_;
putBack_ = false;
return true;
}

return false;
}

As the putBack_ is defined as false in the Istream constructor and not changed:

1
2
3
4
5
6
7
8
9
10
Istream
(
streamFormat format=ASCII,
versionNumber version=currentVersion,
compressionType compression=UNCOMPRESSED
)
:
IOstream(format, version, compression),
putBack_(false)
{}

This if loop will not be conducted. In the next loop, the tokenIndex_ is originally defined as 0 and not changed in the ITstream constructor.