diff --git a/applications/test/OCountStream/Test-OCountStream.C b/applications/test/OCountStream/Test-OCountStream.C index 9e5a5e84781014635c8a137093126337d5aa32d5..02594c2be0bbd33229133a08087590c2e27e3336 100644 --- a/applications/test/OCountStream/Test-OCountStream.C +++ b/applications/test/OCountStream/Test-OCountStream.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2018 OpenCFD Ltd. + Copyright (C) 2017-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,44 +24,88 @@ License along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. Description + Test null and counting output streams \*---------------------------------------------------------------------------*/ #include "OCountStream.H" #include "StringStream.H" +#include "Fstream.H" #include "IOstreams.H" #include "argList.H" using namespace Foam; +template<class OS> +void generateOutput(OS& os) +{ + for (label i = 0; i < 50; ++i) + { + os << 1002 << " " << "abcd" << " " + << "def" << " " << 3.14159 << ";\n"; + } +} + + +void printInfo(OSstream& os) +{ + Info<< "name: " << os.name() << " : " << os.stdStream().tellp() << nl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: int main(int argc, char *argv[]) { + argList::addOption("write", "file", "test writing to file"); + + #include "setRootCase.H" + OCountStream cnt; OStringStream str; - ocountstream plain; - for (label i = 0; i < 50; ++i) + generateOutput(str); + generateOutput(cnt); + generateOutput(plain); + + cnt.print(Info); + + Info<< "counter state: " << (cnt.stdStream().rdstate()) << nl + << "via string-stream: " << str.str().size() << " chars" << nl + << "via ocountstream: " << plain.size() << " chars" << endl; + + fileName outputName; + args.readIfPresent("write", outputName); + + if (outputName.size()) { - str - << 1002 << " " << "abcd" << " " - << "def" << " " << 3.14159 << ";\n"; + IOstreamOption streamOpt; - cnt - << 1002 << " " << "abcd" << " " - << "def" << " " << 3.14159 << ";\n"; + if (outputName.hasExt("gz")) + { + outputName.removeExt(); + streamOpt.compression(IOstreamOption::COMPRESSED); + } - plain - << 1002 << " " << "abcd" << " " - << "def" << " " << 3.14159 << ";\n"; - } - cnt.print(Info); - Info<< "via string-stream: " << str.str().size() << " chars" << endl; - Info<< "via ocountstream: " << plain.size() << " chars" << endl; + OFstream os1(outputName, streamOpt); + OFstream os2(nullptr); // A /dev/null equivalent + OFstream os3("/dev/null"); + + // Doubled output + generateOutput(os1); generateOutput(os1); + generateOutput(os2); generateOutput(os2); + generateOutput(os3); generateOutput(os3); + + Info<< nl + << "doubled output" << nl; + + printInfo(os1); + printInfo(os2); + printInfo(os3); + } Info<< "\nEnd\n" << endl; diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C index dede1ed7a0b7b59142cf638345a7688ffa6fb11e..d218df92ed62d3ac58471b6dc5d16da9b354b741 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C @@ -39,6 +39,21 @@ namespace Foam // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::OFstream::OFstream +( + std::nullptr_t +) +: + Foam::ofstreamPointer(nullptr), + OSstream(*(ofstreamPointer::get()), "/dev/null") +{ + setState(ofstreamPointer::get()->rdstate()); + setOpened(); + + lineNumber_ = 1; +} + + Foam::OFstream::OFstream ( const fileName& pathname, diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H index b1a144b5c688f4a8b367b82343d8ee06926f34a9..a9a7629d1a891b16a55991a863e9b29e563f5141 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.H @@ -64,6 +64,10 @@ public: // Constructors + //- Construct a null output file stream. + // Behaves like \c /dev/null and is named accordingly + explicit OFstream(std::nullptr_t); + //- Construct from pathname explicit OFstream ( diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H index 8e5c2c3b2c021a13a2b5cba8ec86c7a10fca33d1..02cd3eb47c210665a80903e922a24c62e8ff6a94 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H @@ -82,7 +82,7 @@ protected: // Protected Member Functions //- Special 'rewind' method for compressed stream - void reopen_gz(const fileName& pathname_gz); + void reopen_gz(const std::string& pathname_gz); public: @@ -164,7 +164,7 @@ class ofstreamPointer { // Private Data - //- The stream pointer (ofstream or ogzstream) + //- The stream pointer (ofstream | ogzstream | ocountstream) std::unique_ptr<std::ostream> ptr_; public: @@ -192,6 +192,9 @@ public: // Constructors + //- Construct as null output stream using Foam::ocountstream + explicit ofstreamPointer(std::nullptr_t); + //- Construct from pathname, with specified append option ofstreamPointer(const fileName& pathname, const bool append) : diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C index be4316e01276d934d6a6cac50688f1a0949a3f3c..8fd7021828c3f6962eb8f26220f6810733996367 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C @@ -27,6 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "fstreamPointer.H" +#include "OCountStream.H" #include "OSspecific.H" // HAVE_LIBZ defined externally @@ -131,6 +132,12 @@ Foam::ifstreamPointer::ifstreamPointer } +Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t) +: + ptr_(new Foam::ocountstream) +{} + + Foam::ofstreamPointer::ofstreamPointer ( const fileName& pathname, @@ -184,7 +191,7 @@ Foam::ofstreamPointer::ofstreamPointer // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::ifstreamPointer::reopen_gz(const fileName& pathname_gz) +void Foam::ifstreamPointer::reopen_gz(const std::string& pathname_gz) { #ifdef HAVE_LIBZ igzstream* gz = dynamic_cast<igzstream*>(ptr_.get()); diff --git a/src/OpenFOAM/db/IOstreams/IOstreams.C b/src/OpenFOAM/db/IOstreams/IOstreams.C index ff0935c317e090a76d8d9cd6d39d6ee9f3961afa..f3e73e1d404dbc899df636596756a00cb5d9f5c4 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams.C +++ b/src/OpenFOAM/db/IOstreams/IOstreams.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018-2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,7 +49,7 @@ unsigned int Foam::IOstream::precision_ Foam::ISstream Foam::Sin(std::cin, "Sin"); Foam::OSstream Foam::Sout(std::cout, "Sout"); Foam::OSstream Foam::Serr(std::cerr, "Serr"); -Foam::OFstream Foam::Snull("/dev/null"); +Foam::OFstream Foam::Snull(nullptr); // A "/dev/null" equivalent Foam::prefixOSstream Foam::Pout(std::cout, "Pout"); Foam::prefixOSstream Foam::Perr(std::cerr, "Perr"); diff --git a/src/OpenFOAM/db/IOstreams/IOstreams.H b/src/OpenFOAM/db/IOstreams/IOstreams.H index 9174f8ec91a5e7fb3c5c368fd3ae1443e7758e79..dff627a53b94609988d2de9f5afba06c41247546 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams.H @@ -6,6 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2020 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -49,19 +50,19 @@ Description namespace Foam { - //- An Istream wrapper for std::cin + //- ISstream wrapped stdin (std::cin) extern ISstream Sin; - //- An Ostream wrapper for std::cout + //- OSstream wrapped stdout (std::cout) extern OSstream Sout; - //- An Ostream wrapper for std::cerr + //- OSstream wrapped stderr (std::cerr) extern OSstream Serr; - //- An Ostream wrapper for parallel output to std::cout + //- OSstream wrapped stdout (std::cout) with parallel prefix extern prefixOSstream Pout; - //- An Ostream wrapper for parallel output to std::cerr + //- OSstream wrapped stderr (std::cerr) with parallel prefix extern prefixOSstream Perr; } diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H index cc1d325695fb2525a29dc0f912ef8e9e88539ce3..162a9df9416b359f68a8117233f8eaaf73b47d8f 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H @@ -56,45 +56,83 @@ class countstreambuf protected: - //- Handle output counting via overflow - virtual int overflow(int c = EOF) + //- Set position pointer to relative position + virtual std::streampos seekoff + ( + std::streamoff off, + std::ios_base::seekdir way, + std::ios_base::openmode which = std::ios_base::in|std::ios_base::out + ) { - if (c != EOF) + if (which & std::ios_base::out) { - ++size_; + if (way == std::ios_base::beg) + { + size_ = off; + } + else if (way == std::ios_base::cur) + { + size_ += off; + } + else if (way == std::ios_base::end) + { + // not really possible + } + + return size_; // tellp() } - return c; + + return -1; } + //- Set position pointer to absolute position - // For the counter, any positioning is ignored and it always acts like - // seekpos(0), which resets the count. + // For the counter, adjust the count accordingly. virtual std::streampos seekpos ( - std::streampos, + std::streampos pos, std::ios_base::openmode which = std::ios_base::in|std::ios_base::out ) { - size_ = 0; - return 0; + return seekoff(pos, std::ios_base::beg, which); + } + + + //- Handle output counting via overflow + virtual int overflow(int c = EOF) + { + if (c != EOF) + { + ++size_; + } + return c; + } + + + //- Put sequence of characters + virtual std::streamsize xsputn(const char* s, std::streamsize n) + { + size_ += n; + return n; } + public: //- Default construct, or with precount size - countstreambuf(std::streamsize precount=0) + explicit countstreambuf(std::streamsize precount=0) : size_(precount) {} - //- \return The number of bytes counted - std::streamsize size() const + //- \return The buffer put position == number of bytes counted. + std::streamsize tellp() const { return size_; } //- Some information about the number of bytes counted - inline void printBufInfo(Ostream& os) const + void printBufInfo(Ostream& os) const { os << "count=" << size_; } @@ -124,8 +162,14 @@ public: {} + //- \return The buffer put position == number of bytes counted. + using countstreambuf::tellp; + //- \return The number of bytes counted - using countstreambuf::size; + std::streamsize size() const + { + return countstreambuf::tellp(); + } //- Rewind the stream, reset the count void rewind() @@ -183,7 +227,7 @@ public: //- The number of bytes counted std::streamsize size() const { - return buf_.size(); + return buf_.tellp(); } //- Rewind the stream, reset the count