diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C b/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C index a627e382bf..eba797a2bc 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C +++ b/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.C @@ -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 diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.H b/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.H index b05e073cb3..270e373ed6 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams/IOstream.H @@ -157,6 +157,9 @@ protected: ioState_ = std::ios_base::goodbit; } + //- Adjustments when attaching a new stream + void attach(const std::ios& s); + public: diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C index 7aa75ebd92..9ade46c888 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C @@ -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(); } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H index f1d9a6d615..27859b0086 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H @@ -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 diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H index 84a83df8db..49a41910d9 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstreamI.H @@ -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::max(), delim); + is_->ignore(std::numeric_limits::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(); } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C index fd7baf3e9d..cac18ee0cc 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C @@ -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); } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H index 23318a7646..3a543ba9ac 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H @@ -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 diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstreamI.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstreamI.H index f559ee5001..35ea994848 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstreamI.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstreamI.H @@ -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; +} + + // ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/SstreamsPrint.C b/src/OpenFOAM/db/IOstreams/Sstreams/SstreamsPrint.C index b1cd14976b..7d9164d67e 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/SstreamsPrint.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/SstreamsPrint.C @@ -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; + } }