mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: add in-place modification for OCharStream
- enables partial overwriting of content - make default construct zero-sized, add reserve_exact() method STYLE: minor adjustments for Enum, IOstreamOption
This commit is contained in:
@ -1,3 +1,3 @@
|
||||
Test-IStringStream.C
|
||||
Test-IStringStream.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-IStringStream
|
||||
|
||||
@ -111,7 +111,10 @@ template<class BufType>
|
||||
void printInfo(const BufType& buf)
|
||||
{
|
||||
Info<< nl << "=========================" << endl;
|
||||
if constexpr (std::is_same_v<OCharStream, BufType>)
|
||||
{
|
||||
buf.print(Info);
|
||||
}
|
||||
Info<< "addr: " << Foam::name(buf.list().cdata()) << nl;
|
||||
toString(Info, buf.list());
|
||||
Info<< nl << "=========================" << endl;
|
||||
@ -183,12 +186,25 @@ int main(int argc, char *argv[])
|
||||
printInfo(obuf);
|
||||
|
||||
// Overwrite at some position
|
||||
obuf.stdStream().rdbuf()->pubseekpos(0.60 * obuf.size());
|
||||
obuf << "<" << nl << "OVERWRITE" << nl;
|
||||
if (auto i = obuf.view().find("item5"); i != std::string::npos)
|
||||
{
|
||||
// obuf.seek(0.60 * obuf.size());
|
||||
obuf.seek(i);
|
||||
obuf << "<OVERWRITE>" << nl;
|
||||
}
|
||||
|
||||
Info<<"after overwrite" << nl;
|
||||
printInfo(obuf);
|
||||
|
||||
// Truncate
|
||||
{
|
||||
constexpr float fraction = 0.90;
|
||||
Info<<"truncated at " << (100*fraction) << "% ["
|
||||
<< int(fraction*obuf.size()) << " chars]" << nl;
|
||||
obuf.seek(fraction*obuf.size());
|
||||
printInfo(obuf);
|
||||
}
|
||||
|
||||
Info<< "transfer contents to a List or ICharStream" << nl;
|
||||
|
||||
// Reclaim data storage from OCharStream -> ICharStream
|
||||
|
||||
3
applications/test/OCharStream2/Make/files
Normal file
3
applications/test/OCharStream2/Make/files
Normal file
@ -0,0 +1,3 @@
|
||||
Test-OCharStream2.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-OCharStream2
|
||||
2
applications/test/OCharStream2/Make/options
Normal file
2
applications/test/OCharStream2/Make/options
Normal file
@ -0,0 +1,2 @@
|
||||
/* EXE_INC = */
|
||||
/* EXE_LIBS = */
|
||||
404
applications/test/OCharStream2/Test-OCharStream2.cxx
Normal file
404
applications/test/OCharStream2/Test-OCharStream2.cxx
Normal file
@ -0,0 +1,404 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2025 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/>.
|
||||
|
||||
Description
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "SpanStream.H"
|
||||
#include "wordList.H"
|
||||
#include "IOstreams.H"
|
||||
#include "argList.H"
|
||||
|
||||
#include <cctype>
|
||||
#include <cstdio>
|
||||
#include <limits>
|
||||
#include <iomanip>
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
Ostream& printString(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
os << '"';
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
os << *first;
|
||||
}
|
||||
os << '"';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const char* first, const char* last)
|
||||
{
|
||||
char buf[4];
|
||||
os << label(last-first) << '(';
|
||||
|
||||
for (; first != last; (void)++first)
|
||||
{
|
||||
const char c = *first;
|
||||
|
||||
if (isprint(c))
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
os << "\\t";
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
os << "\\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
::snprintf(buf, 4, "%02X", c);
|
||||
os << "\\x" << buf;
|
||||
}
|
||||
}
|
||||
os << ')';
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, std::string_view s)
|
||||
{
|
||||
return printView(os, s.begin(), s.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& printView(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& writeList(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printView(os, list);
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, const UList<char>& list)
|
||||
{
|
||||
return printString(os, list.begin(), list.end());
|
||||
}
|
||||
|
||||
|
||||
Ostream& toString(Ostream& os, std::string_view s)
|
||||
{
|
||||
return printString(os, s.begin(), s.end());
|
||||
}
|
||||
|
||||
|
||||
template<class BufType>
|
||||
void printInfo(const BufType& buf)
|
||||
{
|
||||
Info<< nl << "=========================" << endl;
|
||||
if constexpr (std::is_same_v<OCharStream, BufType>)
|
||||
{
|
||||
buf.print(Info);
|
||||
}
|
||||
Info<< "addr: " << Foam::name(buf.view().data()) << nl;
|
||||
toString(Info, buf.view());
|
||||
Info<< nl << "=========================" << endl;
|
||||
}
|
||||
|
||||
|
||||
template<class IntType>
|
||||
void leftpad(std::ostream& os, IntType val, char fillch = ' ')
|
||||
{
|
||||
// set fill char and width
|
||||
os.setf(std::ios_base::left, std::ios_base::adjustfield);
|
||||
fillch = os.fill(fillch);
|
||||
os.width(std::numeric_limits<IntType>::digits10+1);
|
||||
os << val;
|
||||
// restore fill char
|
||||
os.fill(fillch);
|
||||
}
|
||||
|
||||
|
||||
template<class IntType>
|
||||
void rightpad(std::ostream& os, IntType val, char fillch = ' ')
|
||||
{
|
||||
// set fill char and width
|
||||
os.setf(std::ios_base::right, std::ios_base::adjustfield);
|
||||
fillch = os.fill(fillch);
|
||||
os.width(std::numeric_limits<IntType>::digits10+1);
|
||||
os << val;
|
||||
// restore fill char
|
||||
os.fill(fillch);
|
||||
}
|
||||
|
||||
|
||||
// Left-padded value with trailing comment slashes
|
||||
template<class IntType>
|
||||
void leftpad(ocharstream& os, IntType val)
|
||||
{
|
||||
const auto beg = os.tellp();
|
||||
os << val;
|
||||
int count = (std::numeric_limits<IntType>::digits10+1) - (os.tellp() - beg);
|
||||
|
||||
// With two spaces before comments
|
||||
if (count > 0) { os << ' '; --count; }
|
||||
if (count > 0) { os << ' '; --count; }
|
||||
for (const char c = (count >= 2 ? '/' : ' '); count > 0; --count)
|
||||
{
|
||||
os << c;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
argList::addBoolOption("fake-zerosize", "Fake overwriting with zero data");
|
||||
argList::addBoolOption("dict-format", "Format as dictionary entry");
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
const bool optFakeZerosize = args.found("fake-zerosize");
|
||||
const bool isDictFormat = args.found("dict-format");
|
||||
|
||||
// const constexpr int width = (std::numeric_limits<label>::digits10+1);
|
||||
|
||||
ocharstream labelbuf{charList(32)};
|
||||
|
||||
// Some value
|
||||
labelbuf.rewind();
|
||||
rightpad(labelbuf, label(10));
|
||||
|
||||
printInfo(labelbuf);
|
||||
|
||||
OCharStream obuf{charList(32)};
|
||||
|
||||
printInfo(obuf);
|
||||
|
||||
// Fill with some content
|
||||
for (int i = 0; i < 26; ++i)
|
||||
{
|
||||
obuf<< char('A' + i);
|
||||
}
|
||||
|
||||
// Change letter 'O' to '_'
|
||||
if (auto i = obuf.view().find('O'); i != std::string::npos)
|
||||
{
|
||||
obuf.overwrite(i, '_');
|
||||
}
|
||||
|
||||
printInfo(obuf);
|
||||
|
||||
obuf.overwrite(4, labelbuf.view());
|
||||
printInfo(obuf);
|
||||
|
||||
obuf.overwrite(20, "####");
|
||||
printInfo(obuf);
|
||||
|
||||
Info<< "operation Ignored..." << nl;
|
||||
obuf.overwrite(45, "????");
|
||||
printInfo(obuf);
|
||||
|
||||
// Update with new value
|
||||
{
|
||||
labelbuf.rewind();
|
||||
rightpad(labelbuf, label(200), '.');
|
||||
obuf.overwrite(4, labelbuf.view());
|
||||
|
||||
printInfo(obuf);
|
||||
}
|
||||
|
||||
// With yet another value (non-fixed width)
|
||||
{
|
||||
labelbuf.rewind();
|
||||
labelbuf << label(15);
|
||||
obuf.overwrite(4, labelbuf.view());
|
||||
|
||||
printInfo(obuf);
|
||||
}
|
||||
|
||||
// Slightly harder test
|
||||
{
|
||||
std::string chars(26, '?');
|
||||
|
||||
for (int i = 0; i < 26; ++i)
|
||||
{
|
||||
chars[i] = char('A' + i);
|
||||
}
|
||||
|
||||
auto& os = obuf;
|
||||
os.rewind();
|
||||
|
||||
const word procName("processor0");
|
||||
|
||||
// Write as primitiveEntry or commented content
|
||||
// // constexpr bool isDictFormat = true;
|
||||
|
||||
// if constexpr (isDictFormat)
|
||||
if (isDictFormat)
|
||||
{
|
||||
// Like writeKeyword() with compoundToken
|
||||
os << nl << procName << ' ' << word("List<char>") << nl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Human-readable comments
|
||||
os << nl << "// " << procName << nl;
|
||||
}
|
||||
|
||||
// This is the code we want to have, but assume we don't know
|
||||
// the size or data beforehand.
|
||||
//
|
||||
// if (str && len > 0)
|
||||
// {
|
||||
// // Special treatment for char data (binary I/O only)
|
||||
// const auto oldFmt = os.format(IOstreamOption::BINARY);
|
||||
//
|
||||
// os << label(len) << nl;
|
||||
// os.write(str, len);
|
||||
// os << nl;
|
||||
//
|
||||
// os.format(oldFmt);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// os << label(0) << nl;
|
||||
// }
|
||||
|
||||
// Position before writing the label
|
||||
const auto labelBegin = os.tellp();
|
||||
|
||||
// Replace: os << label(len) << nl;
|
||||
// with a fixed-length version
|
||||
{
|
||||
labelbuf.rewind();
|
||||
rightpad(labelbuf, 0);
|
||||
|
||||
os.append(labelbuf.view());
|
||||
os << nl;
|
||||
}
|
||||
|
||||
constexpr bool testUnknown = true;
|
||||
|
||||
label dataCount = 0;
|
||||
|
||||
if constexpr (testUnknown)
|
||||
{
|
||||
// Pretend we don't know the number of characters a priori
|
||||
|
||||
const auto oldFmt = os.format(IOstreamOption::BINARY);
|
||||
|
||||
const auto lineNumber = os.lineNumber();
|
||||
|
||||
// count is unknown but irrelevant for serial
|
||||
os.beginRawWrite(0);
|
||||
|
||||
// Position before raw binary data
|
||||
const auto dataBegin = os.tellp();
|
||||
|
||||
// Some type of output, streaming etc
|
||||
os.writeRaw(chars.data(), chars.size());
|
||||
|
||||
// How many chars of binary data written?
|
||||
dataCount = (os.tellp() - dataBegin);
|
||||
|
||||
os.endRawWrite();
|
||||
os.lineNumber() = lineNumber;
|
||||
os << nl;
|
||||
|
||||
os.format(oldFmt);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we had all data collected a priori
|
||||
|
||||
dataCount = chars.size();
|
||||
|
||||
const auto oldFmt = os.format(IOstreamOption::BINARY);
|
||||
|
||||
if (dataCount > 0)
|
||||
{
|
||||
os.write(chars.data(), chars.size());
|
||||
os << nl;
|
||||
}
|
||||
os.format(oldFmt);
|
||||
}
|
||||
|
||||
if (optFakeZerosize)
|
||||
{
|
||||
dataCount = 0; // fake zero-size
|
||||
}
|
||||
|
||||
printInfo(os);
|
||||
|
||||
// Update the data count with the correct value
|
||||
|
||||
if (dataCount > 0)
|
||||
{
|
||||
labelbuf.rewind();
|
||||
leftpad(labelbuf, label(dataCount));
|
||||
|
||||
os.overwrite(labelBegin, labelbuf.view());
|
||||
}
|
||||
else
|
||||
{
|
||||
os.seek(int64_t(labelBegin)-1);
|
||||
|
||||
// if constexpr (isDictFormat)
|
||||
if (isDictFormat)
|
||||
{
|
||||
os << ' ' << label(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
os << nl << label(0) << nl;
|
||||
}
|
||||
}
|
||||
|
||||
// if constexpr (isDictFormat)
|
||||
if (isDictFormat)
|
||||
{
|
||||
os.endEntry();
|
||||
}
|
||||
|
||||
printInfo(os);
|
||||
|
||||
Info<< "view: " << os.view(4, 8) << nl;
|
||||
Info<< "view: " << os.view(32) << nl;
|
||||
// Ignores out-of-range
|
||||
Info<< "view: " << os.view(1000) << nl;
|
||||
}
|
||||
|
||||
Info<< "\nEnd\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -1,3 +1,3 @@
|
||||
Test-OStringStream.C
|
||||
Test-OStringStream.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-OStringStream
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
Test-SHA1.C
|
||||
Test-SHA1.cxx
|
||||
|
||||
EXE = $(FOAM_USER_APPBIN)/Test-SHA1
|
||||
|
||||
@ -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;
|
||||
@ -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 Pstream].
|
||||
virtual bool beginRawWrite(std::streamsize count) = 0;
|
||||
|
||||
//- Emit end marker for low-level raw binary output.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -142,9 +142,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.
|
||||
@ -291,17 +294,17 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
//- 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 content (copy)
|
||||
void reset(const char* buffer, size_t nbytes)
|
||||
|
||||
@ -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.
|
||||
@ -352,17 +355,17 @@ public:
|
||||
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);
|
||||
}
|
||||
|
||||
//- 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)
|
||||
|
||||
@ -31,8 +31,7 @@ Description
|
||||
Similar to OStringStream but with a List for its storage instead of
|
||||
as string to allow reuse of List contents without copying.
|
||||
|
||||
The default initial size is 512-bytes and uses size doubling.
|
||||
After construction can use the reserve() method to adjust this.
|
||||
Internally imposes a 512 byte min-size and uses capacity doubling.
|
||||
|
||||
See Also
|
||||
Foam::ICharStream
|
||||
@ -124,12 +123,20 @@ 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);
|
||||
}
|
||||
|
||||
//- Reserve output space for at least this amount.
|
||||
//- Does not apply min-size or capacity doubling etc.
|
||||
void reserve_exact(std::streamsize n)
|
||||
{
|
||||
buffer_type::reserve_exact(n);
|
||||
}
|
||||
|
||||
//- Rewind the stream, clearing any old errors
|
||||
void rewind()
|
||||
{
|
||||
@ -137,6 +144,25 @@ 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::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
|
||||
{
|
||||
@ -147,12 +173,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
|
||||
@ -192,6 +212,34 @@ public:
|
||||
{
|
||||
os << "put=" << output_pos() << '/' << capacity();
|
||||
}
|
||||
|
||||
|
||||
// Extra/Convenience Methods
|
||||
|
||||
// No append functions - just use write(...)
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite
|
||||
(
|
||||
std::streampos pos,
|
||||
const char* data,
|
||||
std::streamsize count
|
||||
)
|
||||
{
|
||||
buffer_type::overwrite(pos, data, count);
|
||||
}
|
||||
|
||||
//- Overwrite a single character
|
||||
void overwrite(std::streampos pos, char c)
|
||||
{
|
||||
buffer_type::overwrite(pos, c);
|
||||
}
|
||||
|
||||
//- The output data (start of output characters)
|
||||
const char* cdata_bytes() const { return buffer_type::cdata_bytes(); }
|
||||
|
||||
//- The output data (start of output characters)
|
||||
char* data_bytes() { return buffer_type::data_bytes(); }
|
||||
};
|
||||
|
||||
|
||||
@ -268,23 +316,27 @@ 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); }
|
||||
|
||||
//- Reserve output space for at least this amount.
|
||||
//- Does not apply min-size or capacity doubling etc.
|
||||
void reserve_exact(std::streamsize n) { stream_.reserve_exact(n); }
|
||||
|
||||
//- 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 the buffer as string copy.
|
||||
//- 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(); }
|
||||
|
||||
//- Exchange stream content and parameter contents, reset positions
|
||||
void swap(List<char>& other)
|
||||
@ -320,7 +372,55 @@ public:
|
||||
virtual void print(Ostream& os) const override;
|
||||
|
||||
|
||||
// Houskeeping
|
||||
// Extra/Convenience Methods
|
||||
|
||||
//- Reposition the stream from the start
|
||||
void seek(std::streampos pos)
|
||||
{
|
||||
stream_.seek(pos);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Append character content - same as writeRaw()
|
||||
void append(const char* data, std::streamsize count)
|
||||
{
|
||||
if (data && count > 0)
|
||||
{
|
||||
writeRaw(data, count);
|
||||
}
|
||||
}
|
||||
|
||||
//- Append character content - same as writeRaw()
|
||||
void append(std::string_view sv)
|
||||
{
|
||||
append(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite
|
||||
(
|
||||
std::streampos pos,
|
||||
const char* data,
|
||||
std::streamsize count
|
||||
)
|
||||
{
|
||||
stream_.overwrite(pos, data, count);
|
||||
}
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite(std::streampos pos, std::string_view sv)
|
||||
{
|
||||
stream_.overwrite(pos, sv.data(), sv.size());
|
||||
}
|
||||
|
||||
//- Overwrite a single character
|
||||
void overwrite(std::streampos pos, char c)
|
||||
{
|
||||
stream_.overwrite(pos, c);
|
||||
}
|
||||
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Block size was used in OpenFOAM-v2306 and earlier
|
||||
void setBlockSize(int n) {}
|
||||
|
||||
@ -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,7 +211,7 @@ 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
|
||||
@ -206,6 +219,34 @@ public:
|
||||
{
|
||||
os << "put=" << output_pos() << '/' << capacity();
|
||||
}
|
||||
|
||||
|
||||
// Extra/Convenience Methods
|
||||
|
||||
// No append functions - just use write(...)
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite
|
||||
(
|
||||
std::streampos pos,
|
||||
const char* data,
|
||||
std::streamsize count
|
||||
)
|
||||
{
|
||||
buffer_type::overwrite(pos, data, count);
|
||||
}
|
||||
|
||||
//- Overwrite a single character
|
||||
void overwrite(std::streampos pos, char c)
|
||||
{
|
||||
buffer_type::overwrite(pos, c);
|
||||
}
|
||||
|
||||
//- The output data (start of output characters)
|
||||
const char* cdata_bytes() const { return buffer_type::cdata_bytes(); }
|
||||
|
||||
//- The output data (start of output characters)
|
||||
char* data_bytes() { return buffer_type::data_bytes(); }
|
||||
};
|
||||
|
||||
|
||||
@ -302,21 +343,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)
|
||||
@ -341,6 +382,54 @@ public:
|
||||
|
||||
//- Print stream description to Ostream
|
||||
virtual void print(Ostream& os) const override;
|
||||
|
||||
|
||||
// Extra/Convenience Methods
|
||||
|
||||
//- Reposition the stream from the start
|
||||
void seek(std::streampos pos)
|
||||
{
|
||||
stream_.seek(pos);
|
||||
syncState();
|
||||
}
|
||||
|
||||
//- Append character content - same as writeRaw()
|
||||
void append(const char* data, std::streamsize count)
|
||||
{
|
||||
if (data && count > 0)
|
||||
{
|
||||
writeRaw(data, count);
|
||||
}
|
||||
}
|
||||
|
||||
//- Append character content - same as writeRaw()
|
||||
void append(std::string_view sv)
|
||||
{
|
||||
append(sv.data(), sv.size());
|
||||
}
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite
|
||||
(
|
||||
std::streampos pos,
|
||||
const char* data,
|
||||
std::streamsize count
|
||||
)
|
||||
{
|
||||
stream_.overwrite(pos, data, count);
|
||||
}
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite(std::streampos pos, std::string_view sv)
|
||||
{
|
||||
stream_.overwrite(pos, sv.data(), sv.size());
|
||||
}
|
||||
|
||||
//- Overwrite a single character
|
||||
void overwrite(std::streampos pos, char c)
|
||||
{
|
||||
stream_.overwrite(pos, c);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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
|
||||
{
|
||||
@ -390,17 +423,81 @@ public:
|
||||
//- The put buffer capacity
|
||||
std::streamsize span_capacity() const { return (epptr() - pbase()); }
|
||||
|
||||
//- The span data (start of output characters)
|
||||
const char* cdata_bytes() const { return pbase(); }
|
||||
|
||||
//- The span data (start of output characters)
|
||||
char* data_bytes() const { return pbase(); }
|
||||
|
||||
//- 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();
|
||||
}
|
||||
}
|
||||
|
||||
//- Overwrite a sub-slice with character content
|
||||
void overwrite
|
||||
(
|
||||
std::streampos pos,
|
||||
const char* data,
|
||||
std::streamsize count
|
||||
)
|
||||
{
|
||||
if (data && (count > 0) && in_range(pos))
|
||||
{
|
||||
// Restrict to intersection with current content
|
||||
if (span_tellp() <= std::streampos(pos+count))
|
||||
{
|
||||
count = (span_tellp() - pos);
|
||||
}
|
||||
std::copy(data, (data+count), (data_bytes()+pos));
|
||||
}
|
||||
}
|
||||
|
||||
//- Overwrite a single character
|
||||
void overwrite(std::streampos pos, char c)
|
||||
{
|
||||
if (c && in_range(pos))
|
||||
{
|
||||
*(data_bytes()+pos) = c;
|
||||
}
|
||||
}
|
||||
|
||||
//- Some information about the output buffer position/capacity
|
||||
void info(Ostream& os) const
|
||||
{
|
||||
@ -433,8 +530,8 @@ protected:
|
||||
{
|
||||
if (c != traits_type::eof())
|
||||
{
|
||||
// Need more space?
|
||||
reserve(1 + span_tellp());
|
||||
// Needed more space?
|
||||
extend(1);
|
||||
|
||||
*(pptr()) = c;
|
||||
pbump(1);
|
||||
@ -446,7 +543,7 @@ protected:
|
||||
virtual std::streamsize xsputn(const char* s, std::streamsize n)
|
||||
{
|
||||
// Enough space so that appends work without problem
|
||||
reserve(n + span_tellp());
|
||||
extend(n);
|
||||
|
||||
std::streamsize count = 0;
|
||||
while (count < n && pptr() < epptr())
|
||||
@ -463,10 +560,14 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct - no initial reserved number of bytes.
|
||||
out_dynamic()
|
||||
{
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Default construct with initial reserved number of bytes.
|
||||
// The value of 512 is a bit arbitrary, but consistent with
|
||||
// std::stringstream
|
||||
out_dynamic(size_t nbytes = 512)
|
||||
out_dynamic(size_t nbytes)
|
||||
:
|
||||
storage_(label(nbytes))
|
||||
{
|
||||
@ -493,40 +594,88 @@ public:
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Increment capacity (if needed) and adjust buffer pointers
|
||||
//- Sync put buffer pointers to agree with list dimensions.
|
||||
// Sets put pointer to the begin (rewind).
|
||||
void sync_pbuffer()
|
||||
{
|
||||
resetp(storage_.data(), storage_.size());
|
||||
}
|
||||
|
||||
//- Increase capacity (if needed) and adjust buffer pointers.
|
||||
//- Applies a min-size and capacity doubling.
|
||||
void reserve(const std::streamsize len)
|
||||
{
|
||||
// The min-size : 512 bytes is a bit arbitrary
|
||||
// but consistent with std::stringstream
|
||||
|
||||
constexpr label minSize = 512;
|
||||
|
||||
if (storage_.size() < len)
|
||||
{
|
||||
const auto cur = span_tellp(); // Current location
|
||||
const auto cur = span_tellp(); // Output position
|
||||
|
||||
label newCapacity = 512;
|
||||
label size = minSize;
|
||||
|
||||
if (newCapacity < len)
|
||||
if (size < len)
|
||||
{
|
||||
// Increase capacity (doubling)
|
||||
newCapacity =
|
||||
Foam::max(label(len), label(2*storage_.size()));
|
||||
// ratio=2 :
|
||||
size = label(2*storage_.size());
|
||||
|
||||
// ratio=1.5 :
|
||||
// Foam::max(label(len), label((storage_.size()/2)*3));
|
||||
// size = label((storage_.size()/2)*3);
|
||||
|
||||
// max(size, len)
|
||||
if (size < len)
|
||||
{
|
||||
size = len;
|
||||
}
|
||||
}
|
||||
|
||||
// Info<<"request:" << len
|
||||
// << " cur cap:" << storage_.size()
|
||||
// << " new cap:" << newCapacity
|
||||
// << " new cap:" << size
|
||||
// << " pos:" << cur << endl;
|
||||
|
||||
storage_.resize(newCapacity);
|
||||
storage_.resize(size);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
}
|
||||
|
||||
//- Sync put buffer pointers to agree with list dimensions
|
||||
// Sets put pointer to the begin (rewind).
|
||||
void sync_pbuffer()
|
||||
//- Increase capacity for at least this size.
|
||||
//- Does not apply min-size or capacity doubling etc.
|
||||
void reserve_exact(const std::streamsize len)
|
||||
{
|
||||
resetp(storage_.data(), storage_.size());
|
||||
if (storage_.size() < len)
|
||||
{
|
||||
const auto cur = span_tellp(); // Output position
|
||||
|
||||
storage_.resize(len);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
}
|
||||
|
||||
//- Shrink storage to addressed storage
|
||||
void shrink_to_fit()
|
||||
{
|
||||
const auto cur = span_tellp(); // Addressed length
|
||||
|
||||
storage_.resize(cur);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
|
||||
//- Increase (reserve) space for another \c count entries
|
||||
void extend(const std::streamsize count)
|
||||
{
|
||||
reserve(span_tellp() + count);
|
||||
}
|
||||
|
||||
//- Increase (reserve) space for another \c count entries
|
||||
void extend_exact(const std::streamsize count)
|
||||
{
|
||||
reserve_exact(span_tellp() + count);
|
||||
}
|
||||
|
||||
//- Clear storage
|
||||
@ -536,20 +685,10 @@ public:
|
||||
sync_pbuffer();
|
||||
}
|
||||
|
||||
//- Shrink storage to addressed storage
|
||||
void shrink()
|
||||
{
|
||||
const auto cur = span_tellp(); // Addressed length
|
||||
|
||||
storage_.resize(cur);
|
||||
sync_pbuffer();
|
||||
pbump(cur);
|
||||
}
|
||||
|
||||
//- 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();
|
||||
@ -579,6 +718,12 @@ public:
|
||||
sync_pbuffer();
|
||||
return chars;
|
||||
}
|
||||
|
||||
|
||||
// Housekeeping
|
||||
|
||||
//- Same as shrink_to_fit()
|
||||
void shrink() { shrink_to_fit(); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -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())
|
||||
// Empty string (no-op)
|
||||
}
|
||||
else if (auto iter = floatFormatNames.cfind(fmtName); iter.good())
|
||||
{
|
||||
return iter.val();
|
||||
}
|
||||
|
||||
// Fall-through to warning
|
||||
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())
|
||||
// Empty string (no-op)
|
||||
}
|
||||
else if (auto iter = formatNames.cfind(fmtName); iter.good())
|
||||
{
|
||||
return iter.val();
|
||||
}
|
||||
|
||||
// Fall-through to warning
|
||||
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,13 +165,11 @@ 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())
|
||||
// Empty string (no-op)
|
||||
}
|
||||
else if (Switch sw = Switch::find(compName); sw.good())
|
||||
{
|
||||
return
|
||||
(
|
||||
@ -183,8 +178,9 @@ Foam::IOstreamOption::compressionEnum
|
||||
: compressionType::UNCOMPRESSED
|
||||
);
|
||||
}
|
||||
|
||||
// Fall-through to warning
|
||||
else
|
||||
{
|
||||
// Emit warning
|
||||
|
||||
WarningInFunction
|
||||
<< "Unknown compression specifier '" << compName
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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>
|
||||
|
||||
Reference in New Issue
Block a user