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

View File

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

View File

@ -799,6 +799,11 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count)
Foam::Istream& Foam::ISstream::rewind() 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 // pubseekpos() rather than seekg() so that it works with gzstream
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in); stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);