ENH: support change of stream for ISstream, OSstream (#1880)
- allows, for example, rebinding of the output stream to a file
This commit is contained in:
parent
9d291ab4cc
commit
fe1e056196
@ -35,6 +35,27 @@ License
|
||||
Foam::fileName Foam::IOstream::staticName_("stream");
|
||||
|
||||
|
||||
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||
|
||||
void Foam::IOstream::attach(const std::ios& s)
|
||||
{
|
||||
labelByteSize_ = sizeof(label);
|
||||
scalarByteSize_ = sizeof(scalar);
|
||||
lineNumber_ = 0;
|
||||
|
||||
if (s.good())
|
||||
{
|
||||
setOpened();
|
||||
setGood();
|
||||
}
|
||||
else
|
||||
{
|
||||
setClosed();
|
||||
setState(s.rdstate());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::fileName& Foam::IOstream::name() const
|
||||
|
@ -157,6 +157,9 @@ protected:
|
||||
ioState_ = std::ios_base::goodbit;
|
||||
}
|
||||
|
||||
//- Adjustments when attaching a new stream
|
||||
void attach(const std::ios& s);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
|
@ -723,7 +723,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
// readScalar determine the validity
|
||||
while
|
||||
(
|
||||
is_.get(c)
|
||||
is_->get(c)
|
||||
&& (
|
||||
isdigit(c)
|
||||
|| c == '+'
|
||||
@ -758,13 +758,13 @@ Foam::Istream& Foam::ISstream::read(token& t)
|
||||
|
||||
syncState();
|
||||
|
||||
if (is_.bad())
|
||||
if (is_->bad())
|
||||
{
|
||||
t.setBad();
|
||||
}
|
||||
else
|
||||
{
|
||||
is_.putback(c);
|
||||
is_->putback(c);
|
||||
|
||||
if (nChar == 1 && buf[0] == '-')
|
||||
{
|
||||
@ -1009,7 +1009,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(label& val)
|
||||
{
|
||||
is_ >> val;
|
||||
(*is_) >> val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -1017,7 +1017,7 @@ Foam::Istream& Foam::ISstream::read(label& val)
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(float& val)
|
||||
{
|
||||
is_ >> val;
|
||||
(*is_) >> val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -1025,7 +1025,7 @@ Foam::Istream& Foam::ISstream::read(float& val)
|
||||
|
||||
Foam::Istream& Foam::ISstream::read(double& val)
|
||||
{
|
||||
is_ >> val;
|
||||
(*is_) >> val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -1047,24 +1047,11 @@ Foam::Istream& Foam::ISstream::readRaw(char* data, std::streamsize count)
|
||||
{
|
||||
if (data)
|
||||
{
|
||||
is_.read(data, count);
|
||||
is_->read(data, count);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Forward seek
|
||||
// - use absolute positioning (see C++ notes about std::ifstream)
|
||||
is_.seekg(is_.tellg() + std::istream::pos_type(count));
|
||||
|
||||
// Not sure if this is needed (as per rewind)
|
||||
// some documentation indicates that ifstream needs
|
||||
// seekg with values from a tellg
|
||||
//
|
||||
// stdStream().rdbuf()->pubseekpos
|
||||
// (
|
||||
// count,
|
||||
// std::ios_base::seekdir::cur,
|
||||
// std::ios_base::in
|
||||
// );
|
||||
is_->ignore(count);
|
||||
}
|
||||
}
|
||||
syncState();
|
||||
@ -1083,7 +1070,7 @@ bool Foam::ISstream::beginRawRead()
|
||||
|
||||
readBegin("binaryBlock");
|
||||
syncState();
|
||||
return is_.good();
|
||||
return is_->good();
|
||||
}
|
||||
|
||||
|
||||
@ -1091,7 +1078,7 @@ bool Foam::ISstream::endRawRead()
|
||||
{
|
||||
readEnd("binaryBlock");
|
||||
syncState();
|
||||
return is_.good();
|
||||
return is_->good();
|
||||
}
|
||||
|
||||
|
||||
|
@ -61,7 +61,7 @@ class ISstream
|
||||
|
||||
fileName name_;
|
||||
|
||||
std::istream& is_;
|
||||
std::istream* is_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
@ -135,10 +135,10 @@ public:
|
||||
// STL stream
|
||||
|
||||
//- Const access to underlying std::istream
|
||||
virtual const std::istream& stdStream() const { return is_; }
|
||||
virtual const std::istream& stdStream() const { return *is_; }
|
||||
|
||||
//- Access to underlying std::istream
|
||||
virtual std::istream& stdStream() { return is_; }
|
||||
virtual std::istream& stdStream() { return *is_; }
|
||||
|
||||
|
||||
// Stream State
|
||||
@ -146,19 +146,19 @@ public:
|
||||
//- Return flags of output stream
|
||||
virtual ios_base::fmtflags flags() const
|
||||
{
|
||||
return is_.flags();
|
||||
return is_->flags();
|
||||
}
|
||||
|
||||
//- Set stream flags
|
||||
virtual ios_base::fmtflags flags(const ios_base::fmtflags f)
|
||||
{
|
||||
return is_.flags(f);
|
||||
return is_->flags(f);
|
||||
}
|
||||
|
||||
//- Set stream state to match that of the std::istream
|
||||
void syncState()
|
||||
{
|
||||
setState(is_.rdstate());
|
||||
setState(is_->rdstate());
|
||||
}
|
||||
|
||||
|
||||
@ -180,6 +180,10 @@ public:
|
||||
const bool stripComments = true
|
||||
);
|
||||
|
||||
//- Associate a different std::istream with the ISstream
|
||||
// \return the previously attached stream
|
||||
inline std::istream& attach(std::istream& is);
|
||||
|
||||
|
||||
// Read Functions
|
||||
|
||||
|
@ -37,9 +37,9 @@ inline Foam::ISstream::ISstream
|
||||
:
|
||||
Istream(streamOpt),
|
||||
name_(streamName),
|
||||
is_(is)
|
||||
is_(&is)
|
||||
{
|
||||
if (is_.good())
|
||||
if (is_->good())
|
||||
{
|
||||
setOpened();
|
||||
setGood();
|
||||
@ -53,9 +53,20 @@ inline Foam::ISstream::ISstream
|
||||
|
||||
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
|
||||
|
||||
inline std::istream& Foam::ISstream::attach(std::istream& is)
|
||||
{
|
||||
std::istream* old = is_;
|
||||
|
||||
is_ = &is;
|
||||
IOstream::attach(*is_);
|
||||
|
||||
return *old;
|
||||
}
|
||||
|
||||
|
||||
inline Foam::ISstream& Foam::ISstream::get(char& c)
|
||||
{
|
||||
is_.get(c);
|
||||
is_->get(c);
|
||||
syncState();
|
||||
|
||||
if (c == '\n' && good())
|
||||
@ -69,13 +80,13 @@ inline Foam::ISstream& Foam::ISstream::get(char& c)
|
||||
|
||||
inline int Foam::ISstream::peek()
|
||||
{
|
||||
return is_.peek();
|
||||
return is_->peek();
|
||||
}
|
||||
|
||||
|
||||
inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
||||
{
|
||||
std::getline(is_, str, delim);
|
||||
std::getline(*is_, str, delim);
|
||||
syncState();
|
||||
|
||||
if (delim == '\n')
|
||||
@ -89,10 +100,10 @@ inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
|
||||
|
||||
inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim)
|
||||
{
|
||||
is_.ignore(std::numeric_limits<std::streamsize>::max(), delim);
|
||||
is_->ignore(std::numeric_limits<std::streamsize>::max(), delim);
|
||||
syncState();
|
||||
|
||||
std::streamsize count = is_.gcount();
|
||||
std::streamsize count = is_->gcount();
|
||||
|
||||
if (delim == '\n' && count)
|
||||
{
|
||||
@ -110,7 +121,7 @@ inline Foam::ISstream& Foam::ISstream::putback(const char c)
|
||||
--lineNumber_;
|
||||
}
|
||||
|
||||
if (!is_.putback(c))
|
||||
if (!is_->putback(c))
|
||||
{
|
||||
setBad();
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ bool Foam::OSstream::write(const token& tok)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const char c)
|
||||
{
|
||||
os_ << c;
|
||||
(*os_) << c;
|
||||
if (c == token::NL)
|
||||
{
|
||||
++lineNumber_;
|
||||
@ -101,7 +101,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
|
||||
Foam::Ostream& Foam::OSstream::write(const char* str)
|
||||
{
|
||||
lineNumber_ += stringOps::count(str, token::NL);
|
||||
os_ << str;
|
||||
(*os_) << str;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -109,7 +109,7 @@ Foam::Ostream& Foam::OSstream::write(const char* str)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const word& str)
|
||||
{
|
||||
os_ << str;
|
||||
(*os_) << str;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -125,7 +125,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
{
|
||||
// Output unquoted, only advance line number on newline
|
||||
lineNumber_ += stringOps::count(str, token::NL);
|
||||
os_ << str;
|
||||
(*os_) << str;
|
||||
|
||||
syncState();
|
||||
return *this;
|
||||
@ -133,7 +133,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
|
||||
|
||||
// Output with surrounding quotes and backslash escaping
|
||||
os_ << token::DQUOTE;
|
||||
(*os_) << token::DQUOTE;
|
||||
|
||||
unsigned backslash = 0;
|
||||
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
|
||||
@ -158,16 +158,16 @@ Foam::Ostream& Foam::OSstream::writeQuoted
|
||||
// output all pending backslashes
|
||||
while (backslash)
|
||||
{
|
||||
os_ << '\\';
|
||||
(*os_) << '\\';
|
||||
--backslash;
|
||||
}
|
||||
|
||||
os_ << c;
|
||||
(*os_) << c;
|
||||
}
|
||||
|
||||
// silently drop any trailing backslashes
|
||||
// they would otherwise appear like an escaped end-quote
|
||||
os_ << token::DQUOTE;
|
||||
(*os_) << token::DQUOTE;
|
||||
|
||||
syncState();
|
||||
return *this;
|
||||
@ -182,7 +182,7 @@ Foam::Ostream& Foam::OSstream::write(const string& str)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const int32_t val)
|
||||
{
|
||||
os_ << val;
|
||||
(*os_) << val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -190,7 +190,7 @@ Foam::Ostream& Foam::OSstream::write(const int32_t val)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const int64_t val)
|
||||
{
|
||||
os_ << val;
|
||||
(*os_) << val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -198,7 +198,7 @@ Foam::Ostream& Foam::OSstream::write(const int64_t val)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const float val)
|
||||
{
|
||||
os_ << val;
|
||||
(*os_) << val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -206,7 +206,7 @@ Foam::Ostream& Foam::OSstream::write(const float val)
|
||||
|
||||
Foam::Ostream& Foam::OSstream::write(const double val)
|
||||
{
|
||||
os_ << val;
|
||||
(*os_) << val;
|
||||
syncState();
|
||||
return *this;
|
||||
}
|
||||
@ -231,17 +231,18 @@ bool Foam::OSstream::beginRawWrite(std::streamsize count)
|
||||
<< abort(FatalIOError);
|
||||
}
|
||||
|
||||
os_ << token::BEGIN_LIST;
|
||||
(*os_) << token::BEGIN_LIST;
|
||||
syncState();
|
||||
return os_.good();
|
||||
|
||||
return os_->good();
|
||||
}
|
||||
|
||||
|
||||
bool Foam::OSstream::endRawWrite()
|
||||
{
|
||||
os_ << token::END_LIST;
|
||||
(*os_) << token::END_LIST;
|
||||
syncState();
|
||||
return os_.good();
|
||||
return os_->good();
|
||||
}
|
||||
|
||||
|
||||
@ -254,8 +255,9 @@ Foam::Ostream& Foam::OSstream::writeRaw
|
||||
// No check for IOstreamOption::BINARY since this is either done in the
|
||||
// beginRawWrite() method, or the caller knows what they are doing.
|
||||
|
||||
os_.write(data, count);
|
||||
os_->write(data, count);
|
||||
syncState();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -264,7 +266,7 @@ void Foam::OSstream::indent()
|
||||
{
|
||||
for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
|
||||
{
|
||||
os_ << ' ';
|
||||
(*os_) << ' ';
|
||||
}
|
||||
syncState();
|
||||
}
|
||||
@ -272,14 +274,14 @@ void Foam::OSstream::indent()
|
||||
|
||||
void Foam::OSstream::flush()
|
||||
{
|
||||
os_.flush();
|
||||
os_->flush();
|
||||
}
|
||||
|
||||
|
||||
void Foam::OSstream::endl()
|
||||
{
|
||||
write('\n');
|
||||
os_.flush();
|
||||
os_->flush();
|
||||
}
|
||||
|
||||
|
||||
@ -287,37 +289,37 @@ void Foam::OSstream::endl()
|
||||
|
||||
char Foam::OSstream::fill() const
|
||||
{
|
||||
return os_.fill();
|
||||
return os_->fill();
|
||||
}
|
||||
|
||||
|
||||
char Foam::OSstream::fill(const char fillch)
|
||||
{
|
||||
return os_.fill(fillch);
|
||||
return os_->fill(fillch);
|
||||
}
|
||||
|
||||
|
||||
int Foam::OSstream::width() const
|
||||
{
|
||||
return os_.width();
|
||||
return os_->width();
|
||||
}
|
||||
|
||||
|
||||
int Foam::OSstream::width(const int w)
|
||||
{
|
||||
return os_.width(w);
|
||||
return os_->width(w);
|
||||
}
|
||||
|
||||
|
||||
int Foam::OSstream::precision() const
|
||||
{
|
||||
return os_.precision();
|
||||
return os_->precision();
|
||||
}
|
||||
|
||||
|
||||
int Foam::OSstream::precision(const int p)
|
||||
{
|
||||
return os_.precision(p);
|
||||
return os_->precision(p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -60,7 +60,7 @@ class OSstream
|
||||
|
||||
fileName name_;
|
||||
|
||||
std::ostream& os_;
|
||||
std::ostream* os_;
|
||||
|
||||
|
||||
public:
|
||||
@ -123,10 +123,10 @@ public:
|
||||
// STL stream
|
||||
|
||||
//- Const access to underlying std::ostream
|
||||
virtual const std::ostream& stdStream() const { return os_; }
|
||||
virtual const std::ostream& stdStream() const { return *os_; }
|
||||
|
||||
//- Access to underlying std::ostream
|
||||
virtual std::ostream& stdStream() { return os_; }
|
||||
virtual std::ostream& stdStream() { return *os_; }
|
||||
|
||||
|
||||
// Stream State
|
||||
@ -134,21 +134,25 @@ public:
|
||||
//- Get stream flags
|
||||
virtual ios_base::fmtflags flags() const
|
||||
{
|
||||
return os_.flags();
|
||||
return os_->flags();
|
||||
}
|
||||
|
||||
//- Set stream flags
|
||||
virtual ios_base::fmtflags flags(const ios_base::fmtflags f)
|
||||
{
|
||||
return os_.flags(f);
|
||||
return os_->flags(f);
|
||||
}
|
||||
|
||||
//- Set stream state to match that of the std::ostream
|
||||
void syncState()
|
||||
{
|
||||
setState(os_.rdstate());
|
||||
setState(os_->rdstate());
|
||||
}
|
||||
|
||||
//- Associate a different std::ostream with the OSstream
|
||||
// \return the previously attached stream
|
||||
inline std::ostream& attach(std::ostream& os);
|
||||
|
||||
|
||||
// Write Functions
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2022 OpenCFD Ltd.
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -39,13 +39,13 @@ inline Foam::OSstream::OSstream
|
||||
:
|
||||
Ostream(streamOpt),
|
||||
name_(streamName),
|
||||
os_(os)
|
||||
os_(&os)
|
||||
{
|
||||
if (os_.good())
|
||||
if (os_->good())
|
||||
{
|
||||
setOpened();
|
||||
setGood();
|
||||
os_.precision(precision_);
|
||||
os_->precision(precision_);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -54,4 +54,18 @@ inline Foam::OSstream::OSstream
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
inline std::ostream& Foam::OSstream::attach(std::ostream& os)
|
||||
{
|
||||
std::ostream* old = os_;
|
||||
|
||||
os_ = &os;
|
||||
IOstream::attach(*os_);
|
||||
// Leave precision untouched
|
||||
|
||||
return *old;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
@ -6,6 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011 OpenFOAM Foundation
|
||||
Copyright (C) 2020-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -38,7 +39,14 @@ void Foam::ISstream::print(Ostream& os) const
|
||||
os << "ISstream: " << name().c_str() << ' ';
|
||||
|
||||
IOstream::print(os);
|
||||
IOstream::print(os, is_.rdstate());
|
||||
if (is_)
|
||||
{
|
||||
IOstream::print(os, is_->rdstate());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "std::stream not attached" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -47,7 +55,14 @@ void Foam::OSstream::print(Ostream& os) const
|
||||
os << "OSstream: " << name().c_str() << ' ';
|
||||
|
||||
IOstream::print(os);
|
||||
IOstream::print(os, os_.rdstate());
|
||||
if (os_)
|
||||
{
|
||||
IOstream::print(os, os_->rdstate());
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "std::stream not attached" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user