ENH: improved behaviour of input stream rewind (issue #534)

- clear error flags. Special handling for igzstream.
This commit is contained in:
Mark Olesen 2017-07-18 11:10:51 +02:00
parent b4b50a3aa8
commit db376a412d
4 changed files with 72 additions and 11 deletions

View File

@ -41,22 +41,28 @@ using namespace Foam;
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::validArgs.insert("string .. stringN");
argList::addOption("file", "name");
argList::addOption("repeat", "count");
argList::addBoolOption("verbose", "report for each repeat");
argList args(argc, argv, false, true);
const label repeat = args.optionLookupOrDefault<label>("repeat", 1);
const bool optVerbose = args.optionFound("verbose");
cpuTime timer;
for (label count = 0; count < repeat; ++count)
{
const bool verbose = (optVerbose || count == 0);
for (label argI=1; argI < args.size(); ++argI)
{
const string& rawArg = args[argI];
if (count == 0)
if (verbose)
{
Info<< "input string: " << rawArg << nl;
}
@ -71,14 +77,15 @@ int main(int argc, char *argv[])
// is.putback(ch);
int lookahead = is.peek();
if (count == 0)
if (verbose)
{
Info<< "token: " << tok.info();
Info<< " lookahead: '" << char(lookahead) << "'" << endl;
Info<< "token: " << tok.info()
<< " lookahead: '" << char(lookahead) << "'"
<< endl;
}
}
if (count == 0)
if (verbose)
{
Info<< nl;
IOobject::writeDivider(Info);
@ -89,31 +96,44 @@ int main(int argc, char *argv[])
Info<< "tokenized args " << repeat << " times in "
<< timer.cpuTimeIncrement() << " s\n\n";
if (args.optionFound("file"))
fileName inputFile;
if (args.optionReadIfPresent("file", inputFile))
{
IFstream is(inputFile);
for (label count = 0; count < repeat; ++count)
{
IFstream is(args["file"]);
const bool verbose = (optVerbose || count == 0);
label nTokens = 0;
if (count == 0)
if (count)
{
Info<< "tokenizing file: " << args["file"] << nl;
is.rewind();
}
Info<< nl
<< "tokenizing file (pass #" << (count+1) << ") "
<< inputFile << nl
<< "state: " << is.info() << endl;
while (is.good())
{
token tok(is);
if (count == 0)
if (verbose)
{
Info<< "token: " << tok.info() << endl;
}
++nTokens;
}
if (count == 0)
if (verbose)
{
Info<< nl;
IOobject::writeDivider(Info);
}
Info<<"pass #" << (count+1)
<< " extracted " << nTokens << " tokens" << endl;
}
Info<< "tokenized file " << repeat << " times in "

View File

@ -167,6 +167,39 @@ const std::istream& Foam::IFstream::stdStream() const
}
Foam::Istream& Foam::IFstream::rewind()
{
lineNumber_ = 1; // Reset line number
igzstream* gzPtr = nullptr;
try
{
gzPtr = dynamic_cast<igzstream*>(allocatedPtr_);
}
catch (std::bad_cast)
{
gzPtr = nullptr;
}
if (gzPtr)
{
// Need special treatment for gzstream.
gzPtr->close();
gzPtr->clear();
gzPtr->open((this->name() + ".gz").c_str());
setState(gzPtr->rdstate());
}
else
{
ISstream::rewind();
}
return *this;
}
void Foam::IFstream::print(Ostream& os) const
{
os << "IFstream: ";

View File

@ -129,6 +129,9 @@ public:
//- Const access to underlying std::istream
virtual const std::istream& stdStream() const;
//- Rewind the stream so that it may be read again
virtual Istream& rewind();
// Print

View File

@ -799,6 +799,11 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
Foam::Istream& Foam::ISstream::rewind()
{
lineNumber_ = 1; // Reset line number
stdStream().clear(); // Clear the iostate error state flags
setGood(); // Sync local copy of iostate
// pubseekpos() rather than seekg() so that it works with gzstream
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);