ENH: minor cleanup of memory streams and IOstreamOption

- make memory streams header-only (simpler)
- add sub-views and direct seek for span streams

New IOobject convenience methods

- IOobject::instanceValue() : return the IOobject instance as a scalar
  value (or 0). Effectively the same as instant(io.instance()).value()
  but with far less typing.

- IOobject::fileModificationChecking_masterOnly() : combines checks for
  time-stamp and inotify variants

STYLE: minor adjustments for Enum
This commit is contained in:
Mark Olesen
2025-09-24 10:36:22 +02:00
parent d39b8a5c94
commit 462d04dcd4
39 changed files with 535 additions and 442 deletions

View File

@ -1,3 +1,3 @@
Test-IStringStream.C
Test-IStringStream.cxx
EXE = $(FOAM_USER_APPBIN)/Test-IStringStream

View File

@ -1,3 +1,3 @@
Test-OStringStream.C
Test-OStringStream.cxx
EXE = $(FOAM_USER_APPBIN)/Test-OStringStream

View File

@ -1,3 +1,3 @@
Test-base64Encoding.C
Test-base64Encoding.cxx
EXE = $(FOAM_USER_APPBIN)/Test-base64Encoding

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,25 +35,31 @@ Description
\*---------------------------------------------------------------------------*/
#include "base64Layer.H"
#include "SpanStream.H"
#include "List.H"
#include "Pair.H"
#include <sstream>
using namespace Foam;
bool test(const Pair<string>& unit)
{
const string& input = unit.first();
const string& expected = unit.second();
const auto& input = unit.first();
const auto& expected = unit.second();
std::ostringstream os;
Foam::ocharstream os;
base64Layer b64(os);
b64.write(input.data(), input.size());
b64.close();
{
base64Layer b64(os);
b64.write(input.data(), input.size());
const string encoded = os.str();
if (b64.close())
{
// Extra information
// std::cerr<< "closed with pending data" << nl;
}
}
const auto encoded = os.view();
Info<< input << nl;
@ -78,7 +84,7 @@ bool test(std::initializer_list<Pair<string>> list)
{
bool good = true;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
good = test(t) && good;
}
@ -91,7 +97,7 @@ bool test(const UList<Pair<string>>& list)
{
bool good = true;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
good = test(t) && good;
}
@ -107,7 +113,7 @@ void testMixed(std::ostream& os, const UList<Pair<string>>& list)
os << "<test-mixed>" << nl;
int i=0;
for (const Pair<string>& t : list)
for (const auto& t : list)
{
const string& input = t.first();

View File

@ -1,3 +1,3 @@
Test-SHA1.C
Test-SHA1.cxx
EXE = $(FOAM_USER_APPBIN)/Test-SHA1

View File

@ -64,6 +64,10 @@ int main(int argc, char * argv[])
osha<< str;
Info<< osha.digest() << " : output << to empty" << nl;
osha.reset();
osha<< std::string_view(str);
Info<< osha.digest() << " : << string_view [ not quite right !]" << nl;
sha.clear();
sha.append(str);
shaDig = sha;

View File

@ -271,9 +271,6 @@ $(hashes)/base64Layer.C
gzstream = $(Streams)/gzstream
$(gzstream)/gzstream.C
memstream = $(Streams)/memory
$(memstream)/SpanStreams.C
Fstreams = $(Streams)/Fstreams
$(Fstreams)/IFstream.C
$(Fstreams)/OFstream.C
@ -284,9 +281,6 @@ Tstreams = $(Streams)/Tstreams
$(Tstreams)/ITstream.C
$(Tstreams)/OTstream.C
StringStreams = $(Streams)/StringStreams
$(StringStreams)/StringStream.C
Pstreams = $(Streams)/Pstreams
/* $(Pstreams)/UPstream.C in global.C */
$(Pstreams)/UPstreamCommsStruct.C

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -484,6 +484,19 @@ const Foam::fileName& Foam::IOobject::globalCaseName() const noexcept
}
Foam::scalar Foam::IOobject::instanceValue() const
{
scalar val(0);
// Only makes sense for a relative instance (word type)
if (Foam::readScalar(instance_, val))
{
return val;
}
return 0;
}
Foam::fileName Foam::IOobject::path() const
{
if (file_isOutsideCase(instance()))

View File

@ -89,9 +89,10 @@ See also
SourceFiles
IOobject.C
IOobjectIO.C
IOobjectMetaData.C
IOobjectReadHeader.C
IOobjectWriteHeader.C
IOobjectPrint.C
\*---------------------------------------------------------------------------*/
@ -99,6 +100,7 @@ SourceFiles
#define Foam_IOobject_H
#include "fileName.H"
#include "scalarFwd.H"
#include "typeInfo.H"
#include "refPtr.H" // For autoPtr, refPtr, tmp, stdFoam
#include "Enum.H"
@ -127,6 +129,10 @@ Ostream& operator<<(Ostream&, const InfoProxy<IOobject>&);
template<class T>
struct is_globalIOobject : std::false_type {};
//- Trait for specifying IOobject types that support the coherent format
template<class T>
struct is_coherentIOobject : std::false_type {};
/*---------------------------------------------------------------------------*\
Class IOobject Declaration
@ -148,12 +154,11 @@ public:
};
//- Enumeration defining the file checking options
//- (time-stamp | inotify) | (all | masterOnly)
enum fileCheckTypes : char
{
timeStamp,
timeStampMaster,
inotify,
inotifyMaster
timeStamp = 1, timeStampMaster = 3,
inotify = 4, inotifyMaster = 6
};
//- Names for the fileCheckTypes
@ -285,6 +290,9 @@ public:
return old;
}
//- Test fileModificationChecking for master-only
static inline bool fileModificationChecking_masterOnly() noexcept;
//- Split path into instance, local, name components
//
// The splitting behaviour is as follows:
@ -576,6 +584,10 @@ public:
//- Modifiable access to instance path component
inline fileName& instance() noexcept;
//- Return the scalar value of the instance component (or 0),
//- which often corresponds to a time index/value.
scalar instanceValue() const;
//- Read access to local path component
inline const fileName& local() const noexcept;

View File

@ -27,6 +27,16 @@ License
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
inline bool Foam::IOobject::fileModificationChecking_masterOnly() noexcept
{
return
(
IOobject::fileModificationChecking == fileCheckTypes::timeStampMaster
|| IOobject::fileModificationChecking == fileCheckTypes::inotifyMaster
);
}
template<class StringType>
inline Foam::word Foam::IOobject::groupName
(

View File

@ -191,10 +191,7 @@ bool Foam::IOobject::readAndCheckHeader
const bool masterOnly
(
isGlobal
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
const auto& handler = Foam::fileHandler();

View File

@ -136,13 +136,10 @@ void Foam::unwatchedIOdictionary::addWatch()
const bool masterOnly
(
global()
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
if (masterOnly && Pstream::parRun())
if (masterOnly && UPstream::parRun())
{
Pstream::broadcast(files_);
}

View File

@ -172,7 +172,7 @@ public:
//- Emit begin marker for low-level raw binary output.
// The count indicates the number of bytes for subsequent
// writeRaw calls.
// writeRaw calls [currently only used by Pstream].
virtual bool beginRawWrite(std::streamsize count) = 0;
//- Emit end marker for low-level raw binary output.

View File

@ -1,52 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "StringStream.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::IStringStream::print(Ostream& os) const
{
os << "IStringStream " << name() << " : "
<< "buffer =\n" << str() << Foam::endl;
ISstream::print(os);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::OStringStream::print(Ostream& os) const
{
os << "OStringStream " << name() << " : "
<< "buffer =\n" << str() << Foam::endl;
OSstream::print(os);
}
// ************************************************************************* //

View File

@ -166,9 +166,9 @@ public:
//- Add (unquoted) string contents.
// Ensures that SHA1 of C-string or C++-string content are identical.
virtual Ostream& write(const std::string& str) override
virtual Ostream& write(const std::string& s) override
{
return writeQuoted(str, false); // Unquoted!
return writeQuoted(s.data(), s.size(), false); // Unquoted!
}
@ -176,10 +176,7 @@ public:
//- Deprecated(2017-07) clear the SHA1 calculation
// \deprecated(2017-07) - use reset() method
void rewind()
{
stream_.sha1().clear();
}
void rewind() { stream_.reset(); }
// Additional constructors and methods (as per v2012 and earlier)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2017 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -45,14 +45,6 @@ static const unsigned char base64Chars[64] =
//! \endcond
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
std::size_t Foam::base64Layer::encodedLength(std::size_t n)
{
return 4 * ((n / 3) + (n % 3 ? 1 : 0));
}
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
inline unsigned char Foam::base64Layer::encode0() const noexcept
@ -80,9 +72,10 @@ inline unsigned char Foam::base64Layer::encode3() const noexcept
}
void Foam::base64Layer::add(char c)
inline void Foam::base64Layer::add_char(char c)
{
group_[groupLen_++] = static_cast<unsigned char>(c);
if (groupLen_ == 3)
{
unsigned char out[4];
@ -95,19 +88,23 @@ void Foam::base64Layer::add(char c)
groupLen_ = 0;
}
}
dirty_ = true;
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::base64Layer::add(char c)
{
add_char(c);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::base64Layer::base64Layer(std::ostream& os)
Foam::base64Layer::base64Layer(std::ostream& os) noexcept
:
os_(os),
group_(),
groupLen_(0),
dirty_(false)
groupLen_(0)
{}
@ -125,54 +122,53 @@ void Foam::base64Layer::write(const char* s, std::streamsize n)
{
for (std::streamsize i=0; i < n; ++i)
{
add(s[i]);
add_char(s[i]);
}
}
void Foam::base64Layer::reset()
void Foam::base64Layer::reset() noexcept
{
groupLen_ = 0;
dirty_ = false;
}
bool Foam::base64Layer::close()
{
if (!dirty_)
{
return false;
}
bool had_pending = false;
unsigned char out[4];
if (groupLen_ == 1)
{
had_pending = true;
group_[1] = 0;
out[0] = encode0();
out[1] = encode1();
out[2] = '=';
out[3] = '=';
os_.write(reinterpret_cast<char*>(out), 4);
}
else if (groupLen_ == 2)
{
had_pending = true;
group_[2] = 0;
out[0] = encode0();
out[1] = encode1();
out[2] = encode2();
out[3] = '=';
os_.write(reinterpret_cast<char*>(out), 4);
}
// group-length == 0 (no content)
// group-length == 3 is not possible, already reset in add()
groupLen_ = 0;
dirty_ = false;
return true;
if (had_pending)
{
os_.write(reinterpret_cast<char*>(out), 4);
}
return had_pending;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -66,9 +66,6 @@ class base64Layer
//- Current length of the encode buffer
unsigned char groupLen_;
//- Track if anything has been encoded.
bool dirty_;
// Private Member Functions
@ -77,6 +74,8 @@ class base64Layer
inline unsigned char encode2() const noexcept;
inline unsigned char encode3() const noexcept;
//- Add a character to the group, outputting when the group is full.
inline void add_char(char c);
protected:
@ -85,6 +84,13 @@ protected:
//- Add a character to the group, outputting when the group is full.
void add(char c);
public:
// Constructors
//- Attach to an output stream
explicit base64Layer(std::ostream& os) noexcept;
//- No copy construct
base64Layer(const base64Layer&) = delete;
@ -92,29 +98,29 @@ protected:
void operator=(const base64Layer&) = delete;
public:
// Constructors
//- Construct and attach to an output stream
explicit base64Layer(std::ostream& os);
//- Destructor. Performs close()
~base64Layer();
// Static Functions
//- The encoded length has 4 bytes out for every 3 bytes and
//- any trailing bytes are padded with '='.
//
// The output length is (4*ceil(len / 3.0))
static constexpr std::size_t encodedLength(std::size_t len) noexcept
{
return (4*((len+2)/3));
}
// Member Functions
//- The encoded length has 4 bytes out for every 3 bytes in.
static std::size_t encodedLength(std::size_t n);
//- Encode the character sequence, writing when possible.
void write(const char* s, std::streamsize n);
//- Restart a new encoding sequence.
void reset();
void reset() noexcept;
//- End the encoding sequence, padding the final characters with '='.
// \return false if no encoding was actually performed.

View File

@ -131,7 +131,16 @@ public:
return buffer_type::span_remaining();
}
//- Span of the input characters (is modifiable!)
//- A string_view of buffer contents
auto view() const { return buffer_type::view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return buffer_type::view(pos, len);
}
//- A list 'span' of buffer contents (caution: is modifiable!!)
UList<char> list() const
{
return UList<char>
@ -141,12 +150,6 @@ public:
);
}
//- A string_view of buffer contents
auto view() const
{
return buffer_type::view();
}
//- For istringstream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
std::string str() const
@ -165,6 +168,16 @@ public:
stream_type::clear(); // Clear old errors
}
//- Reposition the stream from the start
void seek(std::streampos pos)
{
if (buffer_type::in_range(pos))
{
buffer_type::pubseekpos(pos, std::ios_base::in);
stream_type::clear(); // Clear old errors
}
}
//- Reset stream content (copy), reset positions
void reset(const char* buffer, size_t nbytes)
{
@ -198,8 +211,11 @@ public:
//- Some information about the input buffer position/capacity
void debug_info(Ostream& os) const
{
os << "get=" << input_pos() << '/' << capacity();
os << "get=" << input_pos() << '/' << capacity();
}
//- Information about stream
void print(Ostream& os) const { debug_info(os); os << '\n'; }
};
@ -271,6 +287,8 @@ public:
// Member Functions
// Access/Query
//- Position of the get buffer
std::streampos tellg() const { return stream_.input_pos(); }
@ -287,21 +305,24 @@ public:
//- Same as (capacity() - input_pos())
std::streamsize remaining() const { return stream_.remaining(); }
//- Span of the input characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- A string_view of buffer contents
auto view() const
auto view() const { return stream_.view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return stream_.view();
return stream_.view(pos, len);
}
//- A list \em span of the input characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- For IStringStream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
auto str() const
{
return stream_.str();
}
auto str() const { return stream_.str(); }
// Edit
//- Reset content (copy)
void reset(const char* buffer, size_t nbytes)
@ -340,8 +361,23 @@ public:
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Reposition the stream from the start
void seek(std::streampos pos)
{
stream_.seek(pos);
syncState();
}
// Other
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "icharstream: ";
stream_.debug_info(os);
os << '\n';
}
// Member Operators

View File

@ -159,7 +159,7 @@ public:
return buffer_type::span_remaining();
}
//- Span of the input characters (is modifiable!)
//- A list \em span of the input characters (is modifiable!)
UList<char> list() const
{
return UList<char>
@ -170,9 +170,12 @@ public:
}
//- A string_view of buffer contents
auto view() const
auto view() const { return buffer_type::view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return buffer_type::view();
return buffer_type::view(pos, len);
}
//- For istringstream compatibility, return the buffer as string copy.
@ -193,6 +196,16 @@ public:
stream_type::clear(); // Clear old errors
}
//- Reposition the stream from the start
void seek(std::streampos pos)
{
if (buffer_type::in_range(pos))
{
buffer_type::pubseekpos(pos, std::ios_base::in);
stream_type::clear(); // Clear old errors
}
}
//- Reset the get buffer area
void reset(const char* buffer, size_t nbytes)
{
@ -223,8 +236,11 @@ public:
//- Some information about the input buffer position/capacity
void debug_info(Ostream& os) const
{
os << "get=" << input_pos() << '/' << capacity();
os << "get=" << input_pos() << '/' << capacity();
}
//- Information about stream
void print(Ostream& os) const { debug_info(os); os << '\n'; }
};
@ -348,21 +364,22 @@ public:
//- Same as (capacity() - input_pos())
std::streamsize remaining() const { return stream_.remaining(); }
//- Span of the current input characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- A string_view of buffer contents
auto view() const
auto view() const { return stream_.view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return stream_.view();
return stream_.view(pos, len);
}
//- A list \em span of the input characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- For IStringStream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
auto str() const
{
return stream_.str();
}
auto str() const { return stream_.str(); }
//- Reset input area, position to buffer start and clear errors
void reset(const char* buffer, size_t nbytes)
@ -406,8 +423,20 @@ public:
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Reposition the stream from the start
void seek(std::streampos pos)
{
stream_.seek(pos);
syncState();
}
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "ispanstream: ";
stream_.debug_info(os);
os << '\n';
}
// Member Operators

View File

@ -124,8 +124,9 @@ public:
return buffer_type::span_capacity();
}
//- Reserve output space for at least this amount
void reserve(const std::streamsize n)
//- Reserve output space for at least this amount.
//- Applies a min-size and capacity doubling.
void reserve(std::streamsize n)
{
buffer_type::reserve(n);
}
@ -137,7 +138,26 @@ public:
stream_type::clear(); // Clear old errors
}
//- Span of the current output characters (is modifiable!)
//- Reposition the stream from the start
void seek(std::streampos pos)
{
if (buffer_type::in_range(pos))
{
buffer_type::pubseekpos(pos, std::ios_base::out);
stream_type::clear(); // Clear old errors
}
}
//- A string_view of buffer contents
auto view() const { return buffer_type::view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return buffer_type::view(pos, len);
}
//- A list \em span of current output contents (is modifiable!!)
UList<char> list() const
{
return UList<char>
@ -147,12 +167,6 @@ public:
);
}
//- A string_view of buffer contents
auto view() const
{
return buffer_type::view();
}
//- For ostringstream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
std::string str() const
@ -190,8 +204,11 @@ public:
//- Some information about the output buffer position/capacity
void debug_info(Ostream& os) const
{
os << "put=" << output_pos() << '/' << capacity();
os << "put=" << output_pos() << '/' << capacity();
}
//- Information about stream
void print(Ostream& os) const { debug_info(os); os << '\n'; }
};
@ -268,23 +285,24 @@ public:
std::streamsize capacity() const { return stream_.capacity(); }
//- Reserve output space for at least this amount
void reserve(const std::streamsize n) { stream_.reserve(n); }
void reserve(std::streamsize n) { stream_.reserve(n); }
//- Span of the current output characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- A string_view of buffer contents
auto view() const
auto view() const { return stream_.view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return stream_.view();
return stream_.view(pos, len);
}
//- A list \em span of the current output characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- For OStringStream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
auto str() const
{
return stream_.str();
}
auto str() const { return stream_.str(); }
//- Exchange stream content and parameter contents, reset positions
void swap(List<char>& other)
@ -316,11 +334,23 @@ public:
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Reposition the stream from the start
void seek(std::streampos pos)
{
stream_.seek(pos);
syncState();
}
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "ocharstream: ";
stream_.debug_info(os);
os << '\n';
}
// Houskeeping
// Housekeeping
//- Block size was used in OpenFOAM-v2306 and earlier
void setBlockSize(int n) {}

View File

@ -169,6 +169,9 @@ public:
{
os << "count=" << buf_.count();
}
//- Information about stream
void print(Ostream& os) const { debug_info(os); }
};
@ -228,8 +231,13 @@ public:
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "ocountstream: ";
stream_.debug_info(os);
os << '\n';
}
};

View File

@ -27,7 +27,7 @@ Class
Foam::OSpanStream
Description
Similar to OStringStream but using an externally managed buffer for
Similar to OCharStream but using an externally managed buffer for
its output.
This allows the output buffer to be reused and can make it easier when
@ -152,6 +152,32 @@ public:
return buffer_type::span_capacity();
}
//- Rewind the stream, clearing any old errors
void rewind()
{
buffer_type::pubseekpos(0, std::ios_base::out);
stream_type::clear(); // Clear old errors
}
//- Reposition the stream from the start
void seek(std::streampos pos)
{
if (buffer_type::in_range(pos))
{
buffer_type::pubseekpos(pos, std::ios_base::out);
stream_type::clear(); // Clear old errors
}
}
//- A string_view of buffer contents
auto view() const { return buffer_type::view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return buffer_type::view(pos, len);
}
//- Span of the current output characters (is modifiable!)
UList<char> list() const
{
@ -162,12 +188,6 @@ public:
);
}
//- A string_view of buffer contents
auto view() const
{
return buffer_type::view();
}
//- For ostringstream compatibility, return the buffer as string copy.
// Use sparingly - it creates a full copy!!
std::string str() const
@ -179,18 +199,11 @@ public:
);
}
//- Rewind the stream, clearing any old errors
void rewind()
{
buffer_type::pubseekpos(0, std::ios_base::out);
stream_type::clear(); // Clear any old errors
}
//- Reset the put buffer area
void reset(char* buffer, size_t nbytes)
{
buffer_type::resetp(buffer, nbytes);
stream_type::clear(); // Clear any old errors
stream_type::clear(); // Clear old errors
}
//- Reset the put buffer area to use the data area from a string
@ -198,14 +211,30 @@ public:
{
s.resize(s.capacity());
buffer_type::resetp(s.data(), s.size());
stream_type::clear(); // Clear any old errors
stream_type::clear(); // Clear old errors
}
//- Some information about the output buffer position/capacity
void debug_info(Ostream& os) const
{
os << "put=" << output_pos() << '/' << capacity();
os << "put=" << output_pos() << '/' << capacity();
}
//- Information about stream
void print(Ostream& os) const { debug_info(os); os << '\n'; }
// Extra/Convenience Methods
//- The output data (start of output characters)
const char* cdata_bytes() const { return buffer_type::data_bytes(); }
//- The output data (start of output characters)
char* data_bytes() { return buffer_type::data_bytes(); }
//- The current number of output characters
std::streamsize size_bytes() const { return buffer_type::size_bytes(); }
};
@ -302,21 +331,21 @@ public:
//- The put buffer capacity
std::streamsize capacity() const { return stream_.capacity(); }
//- A string_view of buffer contents
auto view() const { return stream_.view(); }
//- A sub-slice string view of the buffer contents
auto view(size_t pos, size_t len = std::string::npos) const
{
return stream_.view(pos, len);
}
//- Span of the current output characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- A string_view of buffer contents
auto view() const
{
return stream_.view();
}
//- For OStringStream compatibility, return buffer as string copy.
// Use sparingly - it creates a full copy!!
auto str() const
{
return stream_.str();
}
auto str() const { return stream_.str(); }
//- Reset the put area
void reset(char* buffer, size_t nbytes)
@ -339,8 +368,20 @@ public:
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Reposition the stream from the start
void seek(std::streampos pos)
{
stream_.seek(pos);
syncState();
}
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "ospanstream: ";
stream_.debug_info(os);
os << '\n';
}
};

View File

@ -1,74 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "OCountStream.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ISpanStream::print(Ostream& os) const
{
os << "ISpanStream: ";
stream_.debug_info(os);
os << Foam::endl;
}
void Foam::OSpanStream::print(Ostream& os) const
{
os << "OSpanStream: ";
stream_.debug_info(os);
os << Foam::endl;
}
void Foam::ICharStream::print(Ostream& os) const
{
os << "ICharStream: ";
stream_.debug_info(os);
os << Foam::endl;
}
void Foam::OCharStream::print(Ostream& os) const
{
os << "OCharStream: ";
stream_.debug_info(os);
os << Foam::endl;
}
void Foam::OCountStream::print(Ostream& os) const
{
os << "OCountStream: ";
// os << "count=" << stream_.count();
stream_.debug_info(os);
os << Foam::endl;
}
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -29,9 +29,6 @@ InClass
Description
Input/output from string buffers.
SourceFiles
StringStream.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_StringStream_H
@ -127,8 +124,13 @@ public:
this->rewind();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "istringstream : buffer =\n" << this->str() << '\n';
IOstream::print(os);
IOstream::print(os, stream_.rdstate());
}
// Member Operators
@ -236,8 +238,13 @@ public:
stream_.rdbuf()->pubseekpos(0, std::ios_base::out);
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const override;
//- Print stream description
virtual void print(Ostream& os) const override
{
os << "ostringstream : buffer =\n" << this->str() << '\n';
IOstream::print(os);
IOstream::print(os, stream_.rdstate());
}
// Older style, without stream option (including 2012 release)

View File

@ -35,10 +35,10 @@ Description
#ifndef Foam_memoryStreamBuffer_H
#define Foam_memoryStreamBuffer_H
#include "stdFoam.H" // For span
#include "DynamicList.H"
#include <memory>
#include <string>
#include <type_traits>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -213,11 +213,44 @@ public:
//- The span size (number of input characters)
std::streamsize size_bytes() const { return (egptr() - eback()); }
std::string_view view() const
//- True if position is within the current input range
bool in_range(std::streampos pos) const
{
return (pos >= 0 && pos < span_capacity());
}
//- A string view of the current input region
auto view() const
{
return std::string_view(data_bytes(), size_bytes());
}
//- A sub-slice string view of the current input region
auto view(size_t pos, size_t len) const
{
// Restrict intersection count to the current content range
if (len && in_range(pos))
{
if ((len == std::string::npos) || (len > (size_bytes()-pos)))
{
len = (size_bytes()-pos);
}
}
else
{
len = 0; // Ignore out-of-range
}
if (len)
{
return std::string_view(data_bytes()+pos, len);
}
else
{
return std::string_view();
}
}
//- Some information about the input buffer position/capacity
void info(Ostream& os) const
{
@ -316,7 +349,8 @@ public:
sync_gbuffer();
}
//- Reset buffer and return contents
//- Reset buffer and return contents.
//- The list size and capacity are identical
DynamicList<char> release()
{
DynamicList<char> chars(std::move(storage_));
@ -396,11 +430,44 @@ public:
//- The span size (size of output buffer)
std::streamsize size_bytes() const { return (pptr() - pbase()); }
std::string_view view() const
//- True if position is within the current output range
bool in_range(std::streampos pos) const
{
return (pos >= 0 && pos < span_tellp());
}
//- A string view of the current output region
auto view() const
{
return std::string_view(data_bytes(), size_bytes());
}
//- A sub-slice string view of the current output region
auto view(size_t pos, size_t len) const
{
// Restrict intersection count to the current content range
if (len && in_range(pos))
{
if ((len == std::string::npos) || (len > (size_bytes()-pos)))
{
len = (size_bytes()-pos);
}
}
else
{
len = 0; // Ignore out-of-range
}
if (len)
{
return std::string_view(data_bytes()+pos, len);
}
else
{
return std::string_view();
}
}
//- Some information about the output buffer position/capacity
void info(Ostream& os) const
{
@ -537,7 +604,7 @@ public:
}
//- Shrink storage to addressed storage
void shrink()
void shrink_to_fit()
{
const auto cur = span_tellp(); // Addressed length
@ -549,7 +616,7 @@ public:
//- Exchange buffer content and parameter contents, reset positions
void swap(List<char>& other)
{
const auto cur = span_tellp(); // Output length
const auto cur = span_tellp(); // Addressed length
other.swap(storage_);
other.resize(cur); // Truncate to output length
sync_pbuffer();
@ -559,7 +626,7 @@ public:
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
const auto cur = span_tellp(); // Output length
const auto cur = span_tellp(); // Addressed length
other.resize(other.capacity()); // Use entire space
other.swap(storage_); // NB: not storage_.swap(other)
@ -571,7 +638,7 @@ public:
//- The list size corresponds to the region of output.
DynamicList<char> release()
{
const auto cur = span_tellp(); // Output length
const auto cur = span_tellp(); // Addressed length
DynamicList<char> chars(std::move(storage_));
chars.resize(cur); // Restrict to output length
@ -579,6 +646,12 @@ public:
sync_pbuffer();
return chars;
}
// Housekeeping
//- Same as shrink_to_fit()
void shrink() { shrink_to_fit(); }
};

View File

@ -473,11 +473,8 @@ void Foam::Time::readModifiedObjects()
// processors!
fileHandler().updateStates
(
(
IOobject::fileModificationChecking == IOobject::inotifyMaster
|| IOobject::fileModificationChecking == IOobject::timeStampMaster
),
Pstream::parRun()
IOobject::fileModificationChecking_masterOnly(),
UPstream::parRun()
);
// Time handling is special since controlDict_ is the one dictionary
// that is not registered to any database.

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -105,6 +105,14 @@ public:
LEGACY_REGISTER = 2
};
//- The layout of the case structure
enum class Layout : unsigned char
{
//! Regular case layout, eg processor-local locations
regular,
//! Global case layout (serial locations)
global
};
private:

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,6 +54,7 @@ Foam::IOstreamOption::formatNames
({
{ streamFormat::ASCII, "ascii" },
{ streamFormat::BINARY, "binary" },
// No selection by name: UNKNOWN_FORMAT
});
@ -66,24 +67,22 @@ Foam::IOstreamOption::floatFormatEnum
const floatFormat deflt
)
{
// Handle bad input graciously. A no-op for an empty string
if (!fmtName.empty())
if (fmtName.empty())
{
auto iter = floatFormatNames.cfind(fmtName);
if (iter.good())
{
return iter.val();
}
// Fall-through to warning
// Empty string (no-op)
}
else if (auto iter = floatFormatNames.cfind(fmtName); iter.good())
{
return iter.val();
}
else
{
// Emit warning for bad input
auto& err = WarningInFunction
<< "Unknown float format '" << fmtName << "' using ";
iter = floatFormatNames.cfind(deflt);
if (iter.good())
if (auto iter = floatFormatNames.cfind(deflt); iter.good())
{
err << '\'' << iter.key() << '\'';
}
@ -117,24 +116,22 @@ Foam::IOstreamOption::formatEnum
const streamFormat deflt
)
{
// Handle bad input graciously. A no-op for an empty string
if (!fmtName.empty())
if (fmtName.empty())
{
auto iter = formatNames.cfind(fmtName);
if (iter.good())
{
return iter.val();
}
// Fall-through to warning
// Empty string (no-op)
}
else if (auto iter = formatNames.cfind(fmtName); iter.good())
{
return iter.val();
}
else
{
// Emit warning for bad input
auto& err = WarningInFunction
<< "Unknown stream format '" << fmtName << "' using ";
iter = formatNames.cfind(deflt);
if (iter.good())
if (auto iter = formatNames.cfind(deflt); iter.good())
{
err << '\'' << iter.key() << '\'';
}
@ -168,23 +165,22 @@ Foam::IOstreamOption::compressionEnum
const compressionType deflt
)
{
// Handle bad input graciously. A no-op for an empty string
if (!compName.empty())
if (compName.empty())
{
const Switch sw = Switch::find(compName);
if (sw.good())
{
return
(
sw
? compressionType::COMPRESSED
: compressionType::UNCOMPRESSED
);
}
// Fall-through to warning
// Empty string (no-op)
}
else if (Switch sw = Switch::find(compName); sw.good())
{
return
(
sw
? compressionType::COMPRESSED
: compressionType::UNCOMPRESSED
);
}
else
{
// Emit warning
WarningInFunction
<< "Unknown compression specifier '" << compName
@ -268,6 +264,7 @@ Foam::Ostream& Foam::operator<<
const IOstreamOption::streamFormat& fmt
)
{
// Silently ignores unnamed formats
os << IOstreamOption::formatNames[fmt];
return os;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2015 OpenFOAM Foundation
Copyright (C) 2018-2024 OpenCFD Ltd.
Copyright (C) 2018-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -67,11 +67,13 @@ public:
// Public Data Types
//- Data format (ascii | binary)
//- Data format (ascii | binary | coherent)
enum streamFormat : char
{
ASCII = 0, //!< "ascii" (normal default)
BINARY //!< "binary"
BINARY, //!< "binary"
COHERENT, //!< "coherent"
UNKNOWN_FORMAT
};
//- Compression treatment (UNCOMPRESSED | COMPRESSED)

View File

@ -281,10 +281,7 @@ void Foam::regIOobject::addWatch()
const bool masterOnly
(
global()
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
// if (debug)

View File

@ -45,10 +45,7 @@ bool Foam::regIOobject::readHeaderOk
const bool masterOnly
(
global()
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
@ -194,10 +191,7 @@ bool Foam::regIOobject::read()
const bool masterOnly
(
global()
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
// Remove old watches (indices) and clear:

View File

@ -98,22 +98,20 @@ bool Foam::regIOobject::writeObject
const bool masterOnly
(
isGlobal
&& (
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
bool osGood = false;
bool osGood = true;
if (!masterOnly || UPstream::master())
{
osGood = fileHandler().writeObject(*this, streamOpt, writeOnProc);
}
else
{
// Or scatter the master osGood?
osGood = true;
}
// Or broadcast the master osGood?
// if (masterOnly)
// {
// Pstream::broadcast(osGood);
// }
if (OFstream::debug)
{

View File

@ -320,11 +320,7 @@ Foam::fileMonitor& Foam::fileOperation::monitor() const
{
monitorPtr_.reset
(
new fileMonitor
(
IOobject::fileModificationChecking == IOobject::inotify
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
new fileMonitor(IOobject::fileModificationChecking_masterOnly())
);
}
return *monitorPtr_;
@ -476,11 +472,7 @@ Foam::fileOperation::lookupAndCacheProcessorsPath
const bool readDirMasterOnly
(
UPstream::parRun() && !distributed()
&&
(
IOobject::fileModificationChecking == IOobject::timeStampMaster
|| IOobject::fileModificationChecking == IOobject::inotifyMaster
)
&& IOobject::fileModificationChecking_masterOnly()
);
// The above selection excludes masterUncollated, which uses inotify or

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -242,12 +242,12 @@ public:
//- Return the enumeration corresponding to the given name
// FatalError if the name is not found.
// Identical to get()
inline EnumType operator[](const word& enumName) const;
EnumType operator[](const word& k) const { return get(k); }
//- Return the first name corresponding to the given enumeration,
//- or an empty word on failure.
//- or an empty word if not found.
// Identical to get()
inline const word& operator[](const EnumType e) const;
const word& operator[](EnumType e) const { return get(e); }
// Iteration
@ -256,11 +256,8 @@ public:
// \note The iterator dereference returns the \b key
class const_iterator
{
//- The list being iterated
const Enum* ptr_;
//- Index in the list
label idx_;
const Enum* ptr_; //!< The list being iterated upon
label idx_; //!< Index in the list
public:
@ -280,6 +277,9 @@ public:
//- Enumeration value at the current index
inline EnumType val() const;
//- True if iterator points to an entry
explicit operator bool() const noexcept { return good(); }
//- De-referencing returns the name (key)
// This is similar to HashSet (not HashTable!) and allows
// convenient output and traversing of the names
@ -375,6 +375,8 @@ public:
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Ostream Operator
//- Write enumeration names, without line-breaks (ie, FlatOutput)

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2024 OpenCFD Ltd.
Copyright (C) 2017-2025 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -86,9 +86,9 @@ inline void Foam::Enum<EnumType>::clear()
template<class EnumType>
inline bool Foam::Enum<EnumType>::contains(const word& enumName) const
inline bool Foam::Enum<EnumType>::contains(const word& key) const
{
return keys_.contains(enumName);
return (!key.empty() && keys_.contains(key));
}
@ -242,7 +242,7 @@ template<class EnumType>
inline typename Foam::Enum<EnumType>::const_iterator
Foam::Enum<EnumType>::cfind(const word& key) const
{
const label idx = keys_.find(key);
const label idx = (key.empty() ? -1 : keys_.find(key));
return typename Enum<EnumType>::const_iterator
(
@ -266,28 +266,6 @@ Foam::Enum<EnumType>::cfind(const EnumType e) const
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
template<class EnumType>
inline EnumType Foam::Enum<EnumType>::operator[]
(
const word& enumName
) const
{
return get(enumName);
}
template<class EnumType>
inline const Foam::word& Foam::Enum<EnumType>::operator[]
(
const EnumType e
) const
{
return get(e);
}
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
template<class EnumType>

View File

@ -39,7 +39,8 @@ See Also
Foam::Enum
SourceFiles
NamedEnum.C
NamedEnum.txx
NamedEnumI.H
\*---------------------------------------------------------------------------*/
@ -199,10 +200,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "NamedEnumI.H"
#ifdef NoRepository
#include "NamedEnum.C"
#endif
#include "NamedEnum.txx"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //