Commit 9fd514bb authored by Mark Olesen's avatar Mark Olesen
Browse files

ENH: support OFstream "/dev/null" equivalent directly

- uses ocountstream for the output, which swallows all output.
  Improves portability

ENH: improved efficiency in countstreambuf

- xsputn() instead of overflow
- more consistent seek* methods
parent 345a42f2
......@@ -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;
......
......@@ -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,
......
......@@ -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
(
......
......@@ -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)
:
......
......@@ -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());
......
......@@ -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");
......
......@@ -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;
}
......
......@@ -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
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment