diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C index e59bad6f8f..345734aa10 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -45,7 +45,7 @@ Foam::IFstream::IFstream IOstreamOption streamOpt ) : - Foam::ifstreamPointer(pathname), + Foam::ifstreamPointer(pathname, streamOpt), ISstream(*(ifstreamPointer::get()), pathname, streamOpt) { IOstreamOption::compression(ifstreamPointer::whichCompression()); diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C index fc65cfd462..bc162c94f3 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/OFstream.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -65,7 +65,7 @@ Foam::OFstream::OFstream Foam::ofstreamPointer ( pathname, - streamOpt.compression(), + streamOpt, (IOstreamOption::appendType::APPEND == append), (IOstreamOption::atomicType::ATOMIC == atomic) ), diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H index 4fb72dbd3e..ce94bcd6ff 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointer.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2020-2022 OpenCFD Ltd. + Copyright (C) 2020-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -74,7 +74,7 @@ class ifstreamPointer { // Private Data - //- The stream pointer (ifstream or igzstream) + //- The stream pointer (ifstream | igzstream, ...) std::unique_ptr ptr_; @@ -114,8 +114,20 @@ public: //- Construct from pathname. // Attempts to read the specified file. // If that fails, try as a compressed file (.gz ending). + // \param pathname The file name to open for reading explicit ifstreamPointer(const fileName& pathname); + //- Construct from pathname, option. + // Attempts to read the specified file. + // If that fails, try as a compressed file (.gz ending). + // \param pathname The file name to open for reading + // \param streamOpt Currently unused + ifstreamPointer + ( + const fileName& pathname, + IOstreamOption streamOpt + ); + // Member Functions @@ -125,6 +137,9 @@ public: // Access + //- True if it holds a valid pointer + explicit operator bool() const noexcept { return bool(ptr_); } + //- The stream pointer (ifstream or igzstream) std::istream* get() noexcept { return ptr_.get(); } @@ -135,6 +150,19 @@ public: IOstreamOption::compressionType whichCompression() const; + // Wrapped Methods + + //- Attempts to open the specified file for reading. + // If that fails, try as a compressed file (.gz ending). + // \param pathname The file name to open for reading + // \param streamOpt Currently unused + void open + ( + const fileName& pathname, + IOstreamOption streamOpt = IOstreamOption() + ); + + // Edit //- Return managed pointer and release ownership @@ -168,7 +196,7 @@ class ofstreamPointer { // Private Data - //- The stream pointer (ofstream | ogzstream | ocountstream) + //- The stream pointer (ofstream | ogzstream | ocountstream, ...) std::unique_ptr ptr_; //- Atomic file creation @@ -211,9 +239,24 @@ public: //- Default construct (empty) ofstreamPointer() noexcept; - //- Construct as null output stream using Foam::ocountstream + //- Construct as null output stream (Foam::ocountstream) explicit ofstreamPointer(std::nullptr_t); + //- Construct from pathname, option, append, file handling atomic + // \param pathname The file name to open for writing + // \param streamOpt Respects (UNCOMPRESSED | COMPRESSED) + // \param append Open in append mode + // \param atomic Write into temporary file (not target file). + // This option should only be used with a stream wrapper + // (eg, OFstream) that handles the final renaming. + explicit ofstreamPointer + ( + const fileName& pathname, + IOstreamOption streamOpt = IOstreamOption(), + const bool append = false, + const bool atomic = false + ); + //- Construct from pathname, compression, append, file handling atomic // \param pathname The file name to open for writing // \param comp UNCOMPRESSED | COMPRESSED @@ -221,10 +264,10 @@ public: // \param atomic Write into temporary file (not target file). // This option should only be used with a stream wrapper // (eg, OFstream) that handles the final renaming. - explicit ofstreamPointer + ofstreamPointer ( const fileName& pathname, - IOstreamOption::compressionType comp = IOstreamOption::UNCOMPRESSED, + IOstreamOption::compressionType comp, const bool append = false, const bool atomic = false ); @@ -238,6 +281,9 @@ public: // Access + //- True if it holds a valid pointer + explicit operator bool() const noexcept { return bool(ptr_); } + //- The stream pointer (ofstream or ogzstream) std::ostream* get() noexcept { return ptr_.get(); } diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C index 16815f7a0a..2f69d064f3 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/fstreamPointers.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2018-2022 OpenCFD Ltd. + Copyright (C) 2018-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -60,8 +60,23 @@ bool Foam::ofstreamPointer::supports_gz() } +// Future: List slurpFile(....); + + // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // +Foam::ifstreamPointer::ifstreamPointer +( + const fileName& pathname, + IOstreamOption streamOpt // Currently unused +) +: + ptr_(nullptr) +{ + open(pathname, streamOpt); +} + + Foam::ifstreamPointer::ifstreamPointer ( const fileName& pathname @@ -69,6 +84,162 @@ Foam::ifstreamPointer::ifstreamPointer : ptr_(nullptr) { + open(pathname); +} + + +Foam::ofstreamPointer::ofstreamPointer() noexcept +: + ptr_(), + atomic_(false) +{} + + +Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t) +: + ptr_(new Foam::ocountstream), + atomic_(false) +{} + + +Foam::ofstreamPointer::ofstreamPointer +( + const fileName& pathname, + IOstreamOption streamOpt, + const bool append, + const bool atomic +) +: + ptr_(nullptr), + atomic_(atomic) +{ + std::ios_base::openmode mode + ( + std::ios_base::out | std::ios_base::binary + ); + + if (append) + { + mode |= std::ios_base::app; + + // Cannot append to gzstream + streamOpt.compression(IOstreamOption::UNCOMPRESSED); + + // Cannot use append + atomic operation, without lots of extra work + atomic_ = false; + } + + + // When opening new files, remove file variants out of the way. + // Eg, opening "file1" + // - remove old "file1.gz" (compressed) + // - also remove old "file1" if it is a symlink and we are not appending + // + // Not writing into symlinked files avoids problems with symlinked + // initial fields (eg, 0/U -> ../0.orig/U) + + const fileName pathname_gz(pathname + ".gz"); + const fileName pathname_tmp(pathname + "~tmp~"); + + fileName::Type fType = fileName::Type::UNDEFINED; + + if (IOstreamOption::COMPRESSED == streamOpt.compression()) + { + // Output compression requested. + + #ifdef HAVE_LIBZ + // TBD: + // atomic_ = true; // Always treat COMPRESSED like an atomic + + const fileName& target = (atomic_ ? pathname_tmp : pathname_gz); + + // Remove old uncompressed version (if any) + fType = Foam::type(pathname, false); + if (fType == fileName::SYMLINK || fType == fileName::FILE) + { + Foam::rm(pathname); + } + + // Avoid writing into symlinked files (non-append mode) + if (!append || atomic_) + { + fType = Foam::type(target, false); + if (fType == fileName::SYMLINK) + { + Foam::rm(target); + } + } + + ptr_.reset(new ogzstream(target, mode)); + + #else /* HAVE_LIBZ */ + + streamOpt.compression(IOstreamOption::UNCOMPRESSED); + + Warning + << nl + << "No write support for gz compressed files (libz)" + << " : downgraded to UNCOMPRESSED" << nl + << "file: " << pathname_gz << endl; + + #endif /* HAVE_LIBZ */ + } + + if (IOstreamOption::COMPRESSED != streamOpt.compression()) + { + const fileName& target = (atomic_ ? pathname_tmp : pathname); + + // Remove old compressed version (if any) + fType = Foam::type(pathname_gz, false); + if (fType == fileName::SYMLINK || fType == fileName::FILE) + { + Foam::rm(pathname_gz); + } + + // Avoid writing into symlinked files (non-append mode) + if (!append || atomic_) + { + fType = Foam::type(target, false); + if (fType == fileName::SYMLINK) + { + Foam::rm(target); + } + } + + ptr_.reset(new std::ofstream(target, mode)); + } +} + + +Foam::ofstreamPointer::ofstreamPointer +( + const fileName& pathname, + IOstreamOption::compressionType comp, + const bool append, + const bool atomic +) +: + ofstreamPointer + ( + pathname, + IOstreamOption(IOstreamOption::ASCII, comp), + append, + atomic + ) +{} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::ifstreamPointer::open +( + const fileName& pathname, + IOstreamOption streamOpt // Currently unused +) +{ + // Forcibly close old stream (if any) + ptr_.reset(nullptr); + const std::ios_base::openmode mode ( std::ios_base::in | std::ios_base::binary @@ -110,131 +281,6 @@ Foam::ifstreamPointer::ifstreamPointer } -Foam::ofstreamPointer::ofstreamPointer() noexcept -: - ptr_(), - atomic_(false) -{} - - -Foam::ofstreamPointer::ofstreamPointer(std::nullptr_t) -: - ptr_(new Foam::ocountstream), - atomic_(false) -{} - - -Foam::ofstreamPointer::ofstreamPointer -( - const fileName& pathname, - IOstreamOption::compressionType comp, - const bool append, - const bool atomic -) -: - ptr_(nullptr), - atomic_(atomic) -{ - std::ios_base::openmode mode - ( - std::ios_base::out | std::ios_base::binary - ); - - if (append) - { - mode |= std::ios_base::app; - - // Cannot append to gzstream - comp = IOstreamOption::UNCOMPRESSED; - - // Cannot use append + atomic operation, without lots of extra work - atomic_ = false; - } - - - // When opening new files, remove file variants out of the way. - // Eg, opening "file1" - // - remove old "file1.gz" (compressed) - // - also remove old "file1" if it is a symlink and we are not appending - // - // Not writing into symlinked files avoids problems with symlinked - // initial fields (eg, 0/U -> ../0.orig/U) - - const fileName pathname_gz(pathname + ".gz"); - const fileName pathname_tmp(pathname + "~tmp~"); - - fileName::Type fType = fileName::Type::UNDEFINED; - - if (IOstreamOption::COMPRESSED == comp) - { - // Output compression requested. - - #ifdef HAVE_LIBZ - // TBD: - // atomic_ = true; // Always treat COMPRESSED like an atomic - - const fileName& target = (atomic_ ? pathname_tmp : pathname_gz); - - // Remove old uncompressed version (if any) - fType = Foam::type(pathname, false); - if (fType == fileName::SYMLINK || fType == fileName::FILE) - { - Foam::rm(pathname); - } - - // Avoid writing into symlinked files (non-append mode) - if (!append || atomic_) - { - fType = Foam::type(target, false); - if (fType == fileName::SYMLINK) - { - Foam::rm(target); - } - } - - ptr_.reset(new ogzstream(target, mode)); - - #else /* HAVE_LIBZ */ - - comp = IOstreamOption::UNCOMPRESSED; - - Warning - << nl - << "No write support for gz compressed files (libz)" - << " : downgraded to UNCOMPRESSED" << nl - << "file: " << pathname_gz << endl; - - #endif /* HAVE_LIBZ */ - } - - if (IOstreamOption::COMPRESSED != comp) - { - const fileName& target = (atomic_ ? pathname_tmp : pathname); - - // Remove old compressed version (if any) - fType = Foam::type(pathname_gz, false); - if (fType == fileName::SYMLINK || fType == fileName::FILE) - { - Foam::rm(pathname_gz); - } - - // Avoid writing into symlinked files (non-append mode) - if (!append || atomic_) - { - fType = Foam::type(target, false); - if (fType == fileName::SYMLINK) - { - Foam::rm(target); - } - } - - ptr_.reset(new std::ofstream(target, mode)); - } -} - - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - void Foam::ifstreamPointer::reopen_gz(const std::string& pathname) { #ifdef HAVE_LIBZ