Compare commits

..

2 Commits

Author SHA1 Message Date
798a9dd9b1 WIP: support command-line redirection of stdout/stderr 2023-08-29 13:06:46 +02:00
fe1e056196 ENH: support change of stream for ISstream, OSstream (#1880)
- allows, for example, rebinding of the output stream to a file
2023-08-29 13:06:43 +02:00
115 changed files with 4025 additions and 6322 deletions

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020-2023 OpenCFD Ltd.
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,7 +33,6 @@ Description
#include "argList.H"
#include "Fstream.H"
#include "OSspecific.H"
#include "etcFiles.H"
using namespace Foam;
@ -45,14 +44,11 @@ int main(int argc, char *argv[])
{
argList::noBanner();
argList::noParallel();
argList::noParallel();
argList::addOption("ignore", "file", "Test readRaw with ignore");
#include "setRootCase.H"
// Test with etc/controlDict (mandatory, from distribution)
if (!args.found("ignore"))
{
const fileName inputFile
(
@ -101,43 +97,6 @@ int main(int argc, char *argv[])
}
}
fileName testFile;
if (args.readIfPresent("ignore", testFile))
{
if (testFile.has_ext("gz"))
{
testFile.remove_ext();
Info<< "stripping extraneous .gz ending" << endl;
}
IFstream is(testFile);
auto& stdStream = is.stdStream();
List<char> buffer(1000);
Info<< "Test readRaw with: " << is.name()
<< " compressed:" << int(is.compression())
<< " file-size:" << is.fileSize() << nl;
for (int iter = 0; is.good() && iter < 1000; ++iter)
{
Info<< "iter:" << iter;
if (iter % 2)
{
Info<< " [read] ";
is.readRaw(buffer.data(), buffer.size());
}
else
{
Info<< " [ignore]";
is.readRaw(nullptr, buffer.size() / 2);
}
Info<< " : " << stdStream.gcount() << endl;
}
}
Info<< "\nEnd\n" << endl;
return 0;
}

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,46 +27,14 @@ Description
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "ListStream.H"
#include "UListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
#include <cctype>
#include <cstdio>
using namespace Foam;
Ostream& writeList(Ostream& os, const UList<char>& list)
{
char buf[4];
os << list.size() << '(';
for (const char c : list)
{
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& toString(Ostream& os, const UList<char>& list)
{
os << '"';
@ -125,7 +93,7 @@ int main(int argc, char *argv[])
// Buffer storage
DynamicList<char> storage(16);
OCharStream obuf(std::move(storage));
OListStream obuf(std::move(storage));
obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
// Move contents to output buffer
@ -136,9 +104,9 @@ int main(int argc, char *argv[])
Info<< "transfer contents to a List" << endl;
ICharStream ibuf;
IListStream ibuf;
// Reclaim data storage from OCharStream -> ICharStream
// Reclaim data storage from OListStream -> IListStream
{
List<char> data;
obuf.swap(data);
@ -193,43 +161,6 @@ int main(int argc, char *argv[])
Info<<nl << "swapped out:";
printInfo(newvalues);
{
iliststream is(std::move(newvalues));
char c = 0;
Info<< nl
<< "getting values from iliststream of "
<< is.list() << endl;
// Info<< " (" << is.tellg() << " " << is.remaining() << ")";
// Info<< "get:";
while (is.get(c))
{
Info<< ' ' << c;
// Info<< " (" << is.tellg() << " " << is.remaining() << ")";
}
Info<< " - end" << nl;
// Info<< "remaining: " << is.list() << endl;
// Info<< "remaining: " << is.remaining() << endl;
// Manipulate the list view
{
UList<char> chars(is.list());
Foam::reverse(chars);
}
is.rewind();
Info<< "get:";
while (is.get(c))
{
Info<< ' ' << c;
}
Info<< " - end" << nl;
}
Info<< "\nEnd\n" << endl;
return 0;

View File

@ -28,6 +28,8 @@ Description
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "ListStream.H"
#include "UListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"

View File

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

View File

@ -74,7 +74,7 @@ int main(int argc, char *argv[])
Info<< "counter state: " << (cnt.stdStream().rdstate()) << nl
<< "via string-stream: " << str.str().size() << " chars" << nl
<< "via ocountstream: " << plain.count() << " chars" << endl;
<< "via ocountstream: " << plain.size() << " chars" << endl;
fileName outputName;
args.readIfPresent("write", outputName);

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,46 +27,13 @@ Description
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "ListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
#include <cctype>
#include <cstdio>
using namespace Foam;
Ostream& writeList(Ostream& os, const UList<char>& list)
{
char buf[4];
os << list.size() << '(';
for (const char c : list)
{
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& toString(Ostream& os, const UList<char>& list)
{
os << '"';
@ -124,12 +91,12 @@ void outputDict(OS& os)
int main(int argc, char *argv[])
{
#include "setRootCase.H"
// Buffer storage
DynamicList<char> storage(16);
OCharStream obuf(std::move(storage));
OListStream obuf(std::move(storage));
obuf.setBlockSize(100);
printInfo(obuf);
@ -173,10 +140,10 @@ int main(int argc, char *argv[])
Info<<"after overwrite" << nl;
printInfo(obuf);
Info<< "transfer contents to a List or ICharStream" << nl;
Info<< "transfer contents to a List or IListStream" << nl;
ICharStream ibuf;
// Reclaim data storage from OCharStream -> ICharStream
IListStream ibuf;
// Reclaim data storage from OListStream -> IListStream
{
List<char> data;
obuf.swap(data);
@ -202,7 +169,7 @@ int main(int argc, char *argv[])
Info<<"input:";
toString(Info, list) << endl;
OCharStream buf1(std::move(list));
OListStream buf1(std::move(list));
Info<<"orig:";
toString(Info, list) << endl;
@ -237,7 +204,7 @@ int main(int argc, char *argv[])
Info<< nl << "Test dictionary" << nl;
{
OCharStream os1;
OListStream os1;
outputDict(os1);
@ -246,7 +213,7 @@ int main(int argc, char *argv[])
}
{
OCharStream os2;
OListStream os2;
os2.indentSize(0);
outputDict(os2);

View File

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

View File

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

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -27,48 +27,16 @@ Description
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "UListStream.H"
#include "wordList.H"
#include "IOstreams.H"
#include "argList.H"
#include <cctype>
#include <cstdio>
#include <sstream>
#include <vector>
using namespace Foam;
Ostream& writeList(Ostream& os, const UList<char>& list)
{
char buf[4];
os << list.size() << '(';
for (const char c : list)
{
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& toString(Ostream& os, const UList<char>& list)
{
os << '"';
@ -140,7 +108,7 @@ int main(int argc, char *argv[])
// Buffer storage
DynamicList<char> storage(1000);
OSpanStream obuf(storage);
UOListStream obuf(storage);
obuf << 1002 << "\n" << "abcd" << "\n" << "def" << "\n" << 3.14159 << ";\n";
obuf.print(Info);
@ -152,7 +120,7 @@ int main(int argc, char *argv[])
// Attach input buffer - could also do without previous resize
{
ISpanStream ibuf(storage);
UIListStream ibuf(storage);
printTokens(ibuf);
@ -167,21 +135,13 @@ int main(int argc, char *argv[])
{
Info<< "parse as std::istream\n";
ispanstream is(storage.cdata(), storage.size());
Info<< "input: ";
writeList(Info, is.list()) << endl;
Info<< "where: " << is.tellg() << endl;
Info<< "capacity: " << is.capacity() << endl;
Info<< "total: " << is.capacity() << endl;
uiliststream is(storage.cdata(), storage.size());
string tok;
while (std::getline(is, tok))
{
std::cerr << "tok: " << tok << nl;
Info<< "where: " << is.tellg() << endl;
}
Info<< nl << "Repeat..." << endl;
@ -210,7 +170,7 @@ int main(int argc, char *argv[])
toString(Info, chars);
Info<< "----" << nl;
ispanstream is(chars.data(), chars.size());
uiliststream is(chars.data(), chars.size());
string tok;
std::cerr<< nl << "Parsed..." << nl;
while (std::getline(is, tok))

View File

@ -68,51 +68,25 @@ int main(int argc, char *argv[])
labelRange::debug = 1;
}
Info<< nl;
{
labelRange range(5, 10);
Info<< "identity: " << identity(range) << nl;
}
{
Info<< "test sorting" << endl;
labelRanges list1(10);
Info<<"test sorting" << endl;
DynamicList<labelRange> list1(10);
list1.emplace_back(25, 8);
list1.emplace_back(8);
list1.emplace_back(15, 5);
list1.emplace_back(50, -10, true);
// Move construct
labelRanges ranges(std::move(list1));
if (!list1.empty())
{
Info<< "Move construct failed? "
<< flatOutput(list1.ranges()) << nl;
}
Info<< "unsorted: ";
ranges.writeList(Info) << nl;
ranges.sort();
Info<< "sorted: ";
ranges.writeList(Info) << nl;
Info<< nl
<< "list linear length = " << ranges.totalSize() << nl;
Info<< "list labels = ";
ranges.labels().writeList(Info) << nl;
Info<< nl;
for (int i : { -1, 0, 5, 8, 10, 20, 26 })
{
Info<< "value at [" << i << "] = " << ranges[i] << nl;
}
sort(list1);
Info<<"sorted" << list1 << endl;
}
{
Info<< "test intersections" << endl;
Info<<"test intersections" << endl;
labelRange range1(-15, 25);
labelRange range2(7, 8);
labelRange range3(-20, 8);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,7 +33,7 @@ Description
#include "scalar.H"
#include "FlatOutput.H"
#include "SpanStream.H"
#include "ListStream.H"
#include "StringStream.H"
#include "NASCore.H"
#include "parsing.H"
@ -443,22 +443,22 @@ int main(int argc, char *argv[])
<< " read " << sizeof(scalar) << nl;
List<otherType> srcList(15);
forAll(srcList, i)
{
srcList[i] = 1 + 10*i;
}
OCharStream os(IOstreamOption::BINARY);
DynamicList<char> buf;
OListStream os(std::move(buf), IOstreamOption::BINARY);
os << srcList;
DynamicList<char> buf;
os.swap(buf); // Recover written contents
os.swap(buf); // Recover buffer
// Read back
List<scalar> dstList;
ISpanStream is(buf, IOstreamOption::BINARY);
UIListStream is(buf, IOstreamOption::BINARY);
is.setScalarByteSize(sizeof(otherType));
Info<< "Stream scalar-size ("

View File

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

View File

@ -1,2 +0,0 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -1,297 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 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/>.
Description
Test file reading with broadcast
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "OSspecific.H" // For fileSize()
#include "Fstream.H"
#include "Pstream.H"
#include "SpanStream.H"
#include <limits>
using namespace Foam;
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
bool optUseSeek = false;
bool optVerbose = false;
// Get file contents. Usually master-only and broadcast
static List<char> slurpFile
(
const fileName& pathname,
const bool parallel = UPstream::parRun(),
const bool masterOnly = true
)
{
Info<< "slurp master-only:" << masterOnly
<< " broadcast:" << (masterOnly && parallel)
<< " seek:" << optUseSeek
<< " file: " << pathname << nl;
if (optUseSeek)
{
Info<< "Rewinding gzstream does not work..." << nl;
}
// -------------------------
List<char> buffer;
ifstreamPointer ifp;
if (UPstream::master() || !masterOnly)
{
ifp.open(pathname);
}
if (ifp && ifp->good())
{
Info<< "compressed:"
<< (IOstreamOption::COMPRESSED == ifp.whichCompression()) << nl;
#if 0
uint64_t inputSize = Foam::fileSize(pathname);
if (IOstreamOption::COMPRESSED == ifp.whichCompression())
{
ifp->ignore(std::numeric_limits<std::streamsize>::max());
const std::streamsize nread = ifp->gcount();
if (nread == std::numeric_limits<std::streamsize>::max())
{
FatalErrorInFunction
<< "Failed call to ignore()" << nl
<< exit(FatalError);
}
inputSize = ifp->gcount();
if (optUseSeek)
{
// Rewinding gzstream does not really work...
ifp->rdbuf()->pubseekpos(0, std::ios_base::in);
}
else
{
// Open it again - gzstream rewinding is unreliable...
ifp.open(pathname);
}
}
buffer.resize(label(inputSize));
ifp->read(buffer.data(), buffer.size_bytes());
const std::streamsize nread = ifp->gcount();
if (nread == std::numeric_limits<std::streamsize>::max())
{
FatalErrorInFunction
<< "Failed call to read()" << nl
<< exit(FatalError);
}
buffer.resize(label(nread)); // Extra safety (paranoid)
#else
if (IOstreamOption::COMPRESSED == ifp.whichCompression())
{
// For compressed files we do not have any idea how large
// the result will be. So read chunk-wise.
// Using the compressed size for the chunk size:
// 50% compression = 2 iterations
// 66% compression = 3 iterations
// ...
const auto inputSize = Foam::fileSize(pathname + ".gz");
const uint64_t chunkSize =
(
(inputSize <= 1024)
? uint64_t(4096)
: uint64_t(2*inputSize)
);
uint64_t beg = 0;
bool normalExit = false;
for (int iter = 1; iter < 100000; ++iter)
{
if (optVerbose)
{
Info<< "iter " << iter << nl;
Info<< "chunk " << label(chunkSize) << nl;
Info<< "size " << label(iter * chunkSize) << nl;
}
buffer.resize(label(iter * chunkSize));
ifp->read(buffer.data() + beg, chunkSize);
const std::streamsize nread = ifp->gcount();
if (optVerbose)
{
Info<< "nread: " << nread << nl;
}
if
(
nread < 0
|| nread == std::numeric_limits<std::streamsize>::max()
)
{
if (iter == 0)
{
FatalErrorInFunction
<< "Failed call to read()" << nl
<< exit(FatalError);
}
break;
}
else
{
beg += uint64_t(nread);
if (nread >= 0 && uint64_t(nread) < chunkSize)
{
normalExit = true;
if (optVerbose)
{
Info<< "stopped after "
<< iter << " iterations" << nl;
}
buffer.resize(label(beg));
break;
}
}
}
if (!normalExit)
{
FatalErrorInFunction
<< "Abnormal exit" << nl
<< exit(FatalError);
}
}
else
{
const auto inputSize = Foam::fileSize(pathname);
if (inputSize >= 0)
{
buffer.resize(label(inputSize));
ifp->read(buffer.data(), buffer.size_bytes());
const std::streamsize nread = ifp->gcount();
if
(
nread < 0
|| nread == std::numeric_limits<std::streamsize>::max()
)
{
FatalErrorInFunction
<< "Failed call to read()" << nl
<< exit(FatalError);
}
buffer.resize(label(nread)); // Extra safety (paranoid)
}
}
#endif
}
// Done with input file
ifp.reset(nullptr);
if (parallel && masterOnly)
{
// On the assumption of larger files,
// prefer two broadcasts instead of serialization
Pstream::broadcastList(buffer);
}
return buffer;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Main program:
int main(int argc, char *argv[])
{
argList::noBanner();
argList::noFunctionObjects();
argList::noCheckProcessorDirectories();
argList::addBoolOption("seek", "seek with gzstream (fails!)");
argList::addVerboseOption("addition information");
argList::addBoolOption("seek", "seek with gzstream");
argList::addBoolOption("no-broadcast", "suppress broadcast contents");
argList::addNote("Test master-only reading (with broadcast)");
argList::addArgument("srcFile");
#include "setRootCase.H"
const bool syncPar = (UPstream::parRun() && !args.found("no-broadcast"));
optUseSeek = args.found("seek");
optVerbose = args.verbose();
auto srcName = args.get<fileName>(1);
if (srcName.has_ext("gz"))
{
srcName.remove_ext();
Info<< "stripping extraneous .gz ending" << endl;
}
ICharStream is;
{
List<char> buffer(slurpFile(srcName, syncPar));
is.swap(buffer);
}
Pout<< "input:" << is.capacity() << endl;
for (string line; is.getLine(line); /*nil*/)
{
Pout<< "L:" << is.lineNumber() << ": " << line.c_str() << nl;
}
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -5,6 +5,7 @@ global/globals.C
/* global/JobInfo/JobInfo.C in globals.C */
global/argList/argList.C
global/argList/argListHelp.C
global/argList/argListRedirect.C
global/clock/clock.C
global/clockValue/clockValue.C
global/cpuTime/cpuTimeCxx.C
@ -271,7 +272,7 @@ gzstream = $(Streams)/gzstream
$(gzstream)/gzstream.C
memstream = $(Streams)/memory
$(memstream)/SpanStreams.C
$(memstream)/ListStream.C
Fstreams = $(Streams)/Fstreams
$(Fstreams)/IFstream.C

View File

@ -46,31 +46,24 @@ std::streamsize Foam::FixedList<T, N>::byteSize()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class T, unsigned N>
Foam::label Foam::FixedList<T, N>::find
(
const T& val,
label pos,
label len
) const
Foam::label Foam::FixedList<T, N>::find(const T& val, label pos) const
{
if (pos >= 0 && pos < label(N))
if (pos >= 0)
{
// Change length to end iterator position
// len == -1 has same meaning as std::string::npos - search until end
// auto iter = std::find(this->begin(pos), this->end(), val);
// if (iter != this->end())
// {
// return label(iter - this->begin());
// }
if (len > 0) len += pos;
if (len < 0 || len > label(N))
while (pos < label(N))
{
len = label(N);
}
if (this->v_[pos] == val)
{
return pos;
}
auto iter = (this->cbegin() + pos);
const auto lastIter = (this->cbegin() + len);
iter = std::find(iter, lastIter, val);
if (iter != lastIter)
{
return label(iter - this->begin());
++pos;
}
}

View File

@ -276,11 +276,10 @@ public:
// Search
//- Find index of the first occurrence of the value.
// \param val The value to search for
// \param pos The first position to examine (default: 0, -ve no-op)
// \param len The length of the search region (-ve until the end)
// \return position in list or -1 if not found.
label find(const T& val, label pos = 0, label len = -1) const;
// Any occurrences before the start pos are ignored.
// Linear search.
// \return -1 if not found.
label find(const T& val, label pos = 0) const;
//- Find index of the last occurrence of the value.
// Any occurrences after the end pos are ignored.
@ -289,11 +288,10 @@ public:
label rfind(const T& val, label pos = -1) const;
//- Is the value contained in the list?
// \param val The value to search for
// \param pos The first position to examine (default: 0, -ve no-op)
// \param len The length of the search region (-ve until the end)
// Linear search from start pos until the end of the list.
// Any occurrences before the start pos are ignored.
// \return true if found.
inline bool contains(const T& val, label pos = 0, label len = -1) const;
inline bool contains(const T& val, label pos = 0) const;
// Edit

View File

@ -307,14 +307,9 @@ inline bool Foam::FixedList<T, N>::uniform() const
template<class T, unsigned N>
inline bool Foam::FixedList<T, N>::contains
(
const T& val,
label pos,
label len
) const
inline bool Foam::FixedList<T, N>::contains(const T& val, label pos) const
{
return (this->find(val, pos, len) >= 0);
return (this->find(val, pos) >= 0);
}

View File

@ -177,26 +177,26 @@ std::streamsize Foam::UList<T>::byteSize() const
template<class T>
Foam::label Foam::UList<T>::find(const T& val, label pos, label len) const
Foam::label Foam::UList<T>::find(const T& val, label pos) const
{
if (pos >= 0 && pos < this->size())
const label len = this->size();
if (pos >= 0)
{
// Change length to end iterator position
// len == -1 has same meaning as std::string::npos - search until end
// auto iter = std::find(this->begin(pos), this->end(), val);
// if (iter != this->end())
// {
// return label(iter - this->begin());
// }
if (len > 0) len += pos;
if (len < 0 || len > this->size())
while (pos < len)
{
len = this->size();
}
if (this->v_[pos] == val)
{
return pos;
}
auto iter = (this->cbegin() + pos);
const auto lastIter = (this->cbegin() + len);
iter = std::find(iter, lastIter, val);
if (iter != lastIter)
{
return label(iter - this->begin());
++pos;
}
}

View File

@ -319,11 +319,10 @@ public:
// Search
//- Find index of the first occurrence of the value.
// \param val The value to search for
// \param pos Initial position to examine (default: 0, -ve no-op)
// \param len The length of the search region (-ve until the end)
// Any occurrences before the start pos are ignored.
// Linear search.
// \return position in list or -1 if not found.
label find(const T& val, label pos = 0, label len = -1) const;
label find(const T& val, label pos = 0) const;
//- Find index of the last occurrence of the value.
// Any occurrences after the end pos are ignored.
@ -332,11 +331,10 @@ public:
label rfind(const T& val, label pos = -1) const;
//- Is the value contained in the list?
// \param val The value to search for
// \param pos The first position to examine (default: 0, -ve no-op)
// \param len The length of the search region (-ve until the end)
// Linear search from start pos until the end of the list.
// Any occurrences before the start pos are ignored.
// \return true if found.
inline bool contains(const T& val, label pos = 0, label len = -1) const;
inline bool contains(const T& val, label pos = 0) const;
// Edit

View File

@ -304,9 +304,9 @@ inline std::streamsize Foam::UList<T>::size_bytes() const noexcept
template<class T>
inline bool Foam::UList<T>::contains(const T& val, label pos, label len) const
inline bool Foam::UList<T>::contains(const T& val, label pos) const
{
return (this->find(val, pos, len) >= 0);
return (this->find(val, pos) >= 0);
}

View File

@ -37,7 +37,7 @@ License
#include "charList.H"
#include "labelPair.H"
#include "masterUncollatedFileOperation.H"
#include "SpanStream.H"
#include "ListStream.H"
#include "StringStream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -403,7 +403,7 @@ Foam::decomposedBlockData::readBlock
if (blocki == 0)
{
realIsPtr.reset(new ICharStream(std::move(data)));
realIsPtr.reset(new IListStream(std::move(data)));
realIsPtr->name() = is.name();
{
@ -422,7 +422,7 @@ Foam::decomposedBlockData::readBlock
{
{
// Read header from first block
ISpanStream headerStream(data);
UIListStream headerStream(data);
if (!headerIO.readHeader(headerStream))
{
FatalIOErrorInFunction(headerStream)
@ -440,7 +440,7 @@ Foam::decomposedBlockData::readBlock
// Read and discard data, only retain the last one
decomposedBlockData::readBlockEntry(is, data);
}
realIsPtr.reset(new ICharStream(std::move(data)));
realIsPtr.reset(new IListStream(std::move(data)));
realIsPtr->name() = is.name();
// Apply stream settings
@ -585,7 +585,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
// Read master data
decomposedBlockData::readBlockEntry(is, data);
realIsPtr.reset(new ICharStream(std::move(data)));
realIsPtr.reset(new IListStream(std::move(data)));
realIsPtr->name() = fName;
{
@ -639,7 +639,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
);
is >> data;
realIsPtr.reset(new ICharStream(std::move(data)));
realIsPtr.reset(new IListStream(std::move(data)));
realIsPtr->name() = fName;
}
}
@ -673,7 +673,7 @@ Foam::autoPtr<Foam::ISstream> Foam::decomposedBlockData::readBlocks
UIPstream is(UPstream::masterNo(), pBufs);
is >> data;
realIsPtr.reset(new ICharStream(std::move(data)));
realIsPtr.reset(new IListStream(std::move(data)));
realIsPtr->name() = fName;
}
}
@ -1090,7 +1090,7 @@ bool Foam::decomposedBlockData::writeData(Ostream& os) const
// Re-read my own data to find out the header information
if (Pstream::master(comm_))
{
ISpanStream headerStream(contentData_);
UIListStream headerStream(contentData_);
io.readHeader(headerStream);
verValue = headerStream.version().canonical();

View File

@ -29,7 +29,7 @@ License
#include "dictionary.H"
#include "foamVersion.H"
#include "objectRegistry.H"
#include "SpanStream.H"
#include "ListStream.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -125,7 +125,7 @@ bool Foam::decomposedBlockData::readHeader(IOobject& io, Istream& is)
List<char> charData;
decomposedBlockData::readBlockEntry(is, charData);
ISpanStream headerStream(charData);
UIListStream headerStream(charData);
headerStream.name() = is.name();
ok = io.readHeader(headerStream);

View File

@ -27,7 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "IFstream.H"
#include "OSspecific.H" // For isFile(), fileSize()
#include "OSspecific.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -91,45 +91,6 @@ Foam::IFstream::IFstream
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
std::streamsize Foam::IFstream::fileSize() const
{
const std::istream* ptr = ifstreamPointer::get();
if (!ptr || this->name().empty())
{
return std::streamsize(-1);
}
off_t fileLen = -1;
if (IOstreamOption::COMPRESSED == ifstreamPointer::whichCompression())
{
fileLen = Foam::fileSize(this->name() + ".gz");
}
else
{
// TBD: special handing for wrapped icharstream
// if
// (
// const Foam::icharstream* charstr
// = dynamic_cast<const Foam::icharstream*>(ptr)>(ptr)
// )
// {
// return charstr->capacity();
// }
fileLen = Foam::fileSize(this->name());
}
if (fileLen >= 0)
{
return std::streamsize(fileLen);
}
return std::streamsize(-1);
}
std::istream& Foam::IFstream::stdStream()
{
std::istream* ptr = ifstreamPointer::get();

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -94,13 +94,6 @@ public:
//- Read/write access to the name of the stream
using ISstream::name;
//- Return the size of the underlying file (-1 on error).
//- This corresponds to Foam::fileSize() but with extra handling of
//- compressed files.
// The return type is \c std::streamsize instead of \c off_t.
// \note Use sparingly since it involves a file stat()!
std::streamsize fileSize() const;
// STL stream

View File

@ -35,6 +35,27 @@ License
Foam::fileName Foam::IOstream::staticName_("stream");
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
void Foam::IOstream::attach(const std::ios& s)
{
labelByteSize_ = sizeof(label);
scalarByteSize_ = sizeof(scalar);
lineNumber_ = 0;
if (s.good())
{
setOpened();
setGood();
}
else
{
setClosed();
setState(s.rdstate());
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
const Foam::fileName& Foam::IOstream::name() const

View File

@ -157,6 +157,9 @@ protected:
ioState_ = std::ios_base::goodbit;
}
//- Adjustments when attaching a new stream
void attach(const std::ios& s);
public:

View File

@ -723,7 +723,7 @@ Foam::Istream& Foam::ISstream::read(token& t)
// readScalar determine the validity
while
(
is_.get(c)
is_->get(c)
&& (
isdigit(c)
|| c == '+'
@ -758,13 +758,13 @@ Foam::Istream& Foam::ISstream::read(token& t)
syncState();
if (is_.bad())
if (is_->bad())
{
t.setBad();
}
else
{
is_.putback(c);
is_->putback(c);
if (nChar == 1 && buf[0] == '-')
{
@ -1009,7 +1009,7 @@ Foam::Istream& Foam::ISstream::read(string& str)
Foam::Istream& Foam::ISstream::read(label& val)
{
is_ >> val;
(*is_) >> val;
syncState();
return *this;
}
@ -1017,7 +1017,7 @@ Foam::Istream& Foam::ISstream::read(label& val)
Foam::Istream& Foam::ISstream::read(float& val)
{
is_ >> val;
(*is_) >> val;
syncState();
return *this;
}
@ -1025,7 +1025,7 @@ Foam::Istream& Foam::ISstream::read(float& val)
Foam::Istream& Foam::ISstream::read(double& val)
{
is_ >> val;
(*is_) >> val;
syncState();
return *this;
}
@ -1047,11 +1047,11 @@ Foam::Istream& Foam::ISstream::readRaw(char* data, std::streamsize count)
{
if (data)
{
is_.read(data, count);
is_->read(data, count);
}
else
{
is_.ignore(count);
is_->ignore(count);
}
}
syncState();
@ -1070,7 +1070,7 @@ bool Foam::ISstream::beginRawRead()
readBegin("binaryBlock");
syncState();
return is_.good();
return is_->good();
}
@ -1078,7 +1078,7 @@ bool Foam::ISstream::endRawRead()
{
readEnd("binaryBlock");
syncState();
return is_.good();
return is_->good();
}
@ -1089,11 +1089,8 @@ void Foam::ISstream::rewind()
stdStream().clear(); // Clear the iostate error state flags
setGood(); // Sync local copy of iostate
// pubseekpos() rather than seekg() so that it works with gzstream
stdStream().rdbuf()->pubseekpos(0, std::ios_base::in);
// NOTE: this form of rewind does not work with igzstream.
// However, igzstream is usually wrapped as IFstream which has its
// own dedicated rewind treatment for igzstream.
}

View File

@ -61,7 +61,7 @@ class ISstream
fileName name_;
std::istream& is_;
std::istream* is_;
// Private Member Functions
@ -135,10 +135,10 @@ public:
// STL stream
//- Const access to underlying std::istream
virtual const std::istream& stdStream() const { return is_; }
virtual const std::istream& stdStream() const { return *is_; }
//- Access to underlying std::istream
virtual std::istream& stdStream() { return is_; }
virtual std::istream& stdStream() { return *is_; }
// Stream State
@ -146,19 +146,19 @@ public:
//- Return flags of output stream
virtual ios_base::fmtflags flags() const
{
return is_.flags();
return is_->flags();
}
//- Set stream flags
virtual ios_base::fmtflags flags(const ios_base::fmtflags f)
{
return is_.flags(f);
return is_->flags(f);
}
//- Set stream state to match that of the std::istream
void syncState()
{
setState(is_.rdstate());
setState(is_->rdstate());
}
@ -180,6 +180,10 @@ public:
const bool stripComments = true
);
//- Associate a different std::istream with the ISstream
// \return the previously attached stream
inline std::istream& attach(std::istream& is);
// Read Functions

View File

@ -37,9 +37,9 @@ inline Foam::ISstream::ISstream
:
Istream(streamOpt),
name_(streamName),
is_(is)
is_(&is)
{
if (is_.good())
if (is_->good())
{
setOpened();
setGood();
@ -53,9 +53,20 @@ inline Foam::ISstream::ISstream
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
inline std::istream& Foam::ISstream::attach(std::istream& is)
{
std::istream* old = is_;
is_ = &is;
IOstream::attach(*is_);
return *old;
}
inline Foam::ISstream& Foam::ISstream::get(char& c)
{
is_.get(c);
is_->get(c);
syncState();
if (c == '\n' && good())
@ -69,17 +80,16 @@ inline Foam::ISstream& Foam::ISstream::get(char& c)
inline int Foam::ISstream::peek()
{
return is_.peek();
return is_->peek();
}
inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
{
std::getline(is_, str, delim);
std::streamsize count = is_.gcount();
std::getline(*is_, str, delim);
syncState();
if (delim == '\n' && count > 0)
if (delim == '\n')
{
++lineNumber_;
}
@ -90,11 +100,12 @@ inline Foam::ISstream& Foam::ISstream::getLine(std::string& str, char delim)
inline std::streamsize Foam::ISstream::getLine(std::nullptr_t, char delim)
{
is_.ignore(std::numeric_limits<std::streamsize>::max(), delim);
std::streamsize count = is_.gcount();
is_->ignore(std::numeric_limits<std::streamsize>::max(), delim);
syncState();
if (delim == '\n' && count > 0)
std::streamsize count = is_->gcount();
if (delim == '\n' && count)
{
++lineNumber_;
}
@ -110,7 +121,7 @@ inline Foam::ISstream& Foam::ISstream::putback(const char c)
--lineNumber_;
}
if (!is_.putback(c))
if (!is_->putback(c))
{
setBad();
}

View File

@ -88,7 +88,7 @@ bool Foam::OSstream::write(const token& tok)
Foam::Ostream& Foam::OSstream::write(const char c)
{
os_ << c;
(*os_) << c;
if (c == token::NL)
{
++lineNumber_;
@ -101,7 +101,7 @@ Foam::Ostream& Foam::OSstream::write(const char c)
Foam::Ostream& Foam::OSstream::write(const char* str)
{
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
(*os_) << str;
syncState();
return *this;
}
@ -109,7 +109,7 @@ Foam::Ostream& Foam::OSstream::write(const char* str)
Foam::Ostream& Foam::OSstream::write(const word& str)
{
os_ << str;
(*os_) << str;
syncState();
return *this;
}
@ -125,7 +125,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
{
// Output unquoted, only advance line number on newline
lineNumber_ += stringOps::count(str, token::NL);
os_ << str;
(*os_) << str;
syncState();
return *this;
@ -133,7 +133,7 @@ Foam::Ostream& Foam::OSstream::writeQuoted
// Output with surrounding quotes and backslash escaping
os_ << token::DQUOTE;
(*os_) << token::DQUOTE;
unsigned backslash = 0;
for (auto iter = str.cbegin(); iter != str.cend(); ++iter)
@ -158,16 +158,16 @@ Foam::Ostream& Foam::OSstream::writeQuoted
// output all pending backslashes
while (backslash)
{
os_ << '\\';
(*os_) << '\\';
--backslash;
}
os_ << c;
(*os_) << c;
}
// silently drop any trailing backslashes
// they would otherwise appear like an escaped end-quote
os_ << token::DQUOTE;
(*os_) << token::DQUOTE;
syncState();
return *this;
@ -182,7 +182,7 @@ Foam::Ostream& Foam::OSstream::write(const string& str)
Foam::Ostream& Foam::OSstream::write(const int32_t val)
{
os_ << val;
(*os_) << val;
syncState();
return *this;
}
@ -190,7 +190,7 @@ Foam::Ostream& Foam::OSstream::write(const int32_t val)
Foam::Ostream& Foam::OSstream::write(const int64_t val)
{
os_ << val;
(*os_) << val;
syncState();
return *this;
}
@ -198,7 +198,7 @@ Foam::Ostream& Foam::OSstream::write(const int64_t val)
Foam::Ostream& Foam::OSstream::write(const float val)
{
os_ << val;
(*os_) << val;
syncState();
return *this;
}
@ -206,7 +206,7 @@ Foam::Ostream& Foam::OSstream::write(const float val)
Foam::Ostream& Foam::OSstream::write(const double val)
{
os_ << val;
(*os_) << val;
syncState();
return *this;
}
@ -231,17 +231,18 @@ bool Foam::OSstream::beginRawWrite(std::streamsize count)
<< abort(FatalIOError);
}
os_ << token::BEGIN_LIST;
(*os_) << token::BEGIN_LIST;
syncState();
return os_.good();
return os_->good();
}
bool Foam::OSstream::endRawWrite()
{
os_ << token::END_LIST;
(*os_) << token::END_LIST;
syncState();
return os_.good();
return os_->good();
}
@ -254,8 +255,9 @@ Foam::Ostream& Foam::OSstream::writeRaw
// No check for IOstreamOption::BINARY since this is either done in the
// beginRawWrite() method, or the caller knows what they are doing.
os_.write(data, count);
os_->write(data, count);
syncState();
return *this;
}
@ -264,7 +266,7 @@ void Foam::OSstream::indent()
{
for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i)
{
os_ << ' ';
(*os_) << ' ';
}
syncState();
}
@ -272,14 +274,14 @@ void Foam::OSstream::indent()
void Foam::OSstream::flush()
{
os_.flush();
os_->flush();
}
void Foam::OSstream::endl()
{
write('\n');
os_.flush();
os_->flush();
}
@ -287,37 +289,37 @@ void Foam::OSstream::endl()
char Foam::OSstream::fill() const
{
return os_.fill();
return os_->fill();
}
char Foam::OSstream::fill(const char fillch)
{
return os_.fill(fillch);
return os_->fill(fillch);
}
int Foam::OSstream::width() const
{
return os_.width();
return os_->width();
}
int Foam::OSstream::width(const int w)
{
return os_.width(w);
return os_->width(w);
}
int Foam::OSstream::precision() const
{
return os_.precision();
return os_->precision();
}
int Foam::OSstream::precision(const int p)
{
return os_.precision(p);
return os_->precision(p);
}

View File

@ -60,7 +60,7 @@ class OSstream
fileName name_;
std::ostream& os_;
std::ostream* os_;
public:
@ -123,10 +123,10 @@ public:
// STL stream
//- Const access to underlying std::ostream
virtual const std::ostream& stdStream() const { return os_; }
virtual const std::ostream& stdStream() const { return *os_; }
//- Access to underlying std::ostream
virtual std::ostream& stdStream() { return os_; }
virtual std::ostream& stdStream() { return *os_; }
// Stream State
@ -134,21 +134,25 @@ public:
//- Get stream flags
virtual ios_base::fmtflags flags() const
{
return os_.flags();
return os_->flags();
}
//- Set stream flags
virtual ios_base::fmtflags flags(const ios_base::fmtflags f)
{
return os_.flags(f);
return os_->flags(f);
}
//- Set stream state to match that of the std::ostream
void syncState()
{
setState(os_.rdstate());
setState(os_->rdstate());
}
//- Associate a different std::ostream with the OSstream
// \return the previously attached stream
inline std::ostream& attach(std::ostream& os);
// Write Functions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2020-2022 OpenCFD Ltd.
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -39,13 +39,13 @@ inline Foam::OSstream::OSstream
:
Ostream(streamOpt),
name_(streamName),
os_(os)
os_(&os)
{
if (os_.good())
if (os_->good())
{
setOpened();
setGood();
os_.precision(precision_);
os_->precision(precision_);
}
else
{
@ -54,4 +54,18 @@ inline Foam::OSstream::OSstream
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline std::ostream& Foam::OSstream::attach(std::ostream& os)
{
std::ostream* old = os_;
os_ = &os;
IOstream::attach(*os_);
// Leave precision untouched
return *old;
}
// ************************************************************************* //

View File

@ -6,6 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2020-2023 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -38,7 +39,14 @@ void Foam::ISstream::print(Ostream& os) const
os << "ISstream: " << name().c_str() << ' ';
IOstream::print(os);
IOstream::print(os, is_.rdstate());
if (is_)
{
IOstream::print(os, is_->rdstate());
}
else
{
os << "std::stream not attached" << endl;
}
}
@ -47,7 +55,14 @@ void Foam::OSstream::print(Ostream& os) const
os << "OSstream: " << name().c_str() << ' ';
IOstream::print(os);
IOstream::print(os, os_.rdstate());
if (os_)
{
IOstream::print(os, os_->rdstate());
}
else
{
os << "std::stream not attached" << endl;
}
}

View File

@ -4,8 +4,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef FoamCompat_IStringStream_H
#define FoamCompat_IStringStream_H
#ifndef IStringStream_H
#define IStringStream_H
#include "StringStream.H"

View File

@ -4,8 +4,8 @@ Description
\*---------------------------------------------------------------------------*/
#ifndef FoamCompat_OStringStream_H
#define FoamCompat_OStringStream_H
#ifndef OStringStream_H
#define OStringStream_H
#include "StringStream.H"

View File

@ -259,6 +259,7 @@ public:
//- Rewind the output stream
virtual void rewind()
{
// pubseekpos() instead of seekp() for symmetry with other classes
stream_.rdbuf()->pubseekpos(0, std::ios_base::out);
}

View File

@ -28,8 +28,8 @@ License
#include "error.H"
#include "ITstream.H"
#include "SpanStream.H"
#include "StringStream.H"
#include "UIListStream.H"
#include <memory>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -94,7 +94,7 @@ Foam::tokenList Foam::ITstream::parse
IOstreamOption streamOpt
)
{
ISpanStream is(input, streamOpt);
UIListStream is(input, streamOpt);
tokenList tokens;
parseStream(is, tokens);
@ -108,7 +108,7 @@ Foam::tokenList Foam::ITstream::parse
IOstreamOption streamOpt
)
{
ISpanStream is(input, streamOpt);
UIListStream is(input.data(), input.length(), streamOpt);
tokenList tokens;
parseStream(is, tokens);
@ -122,7 +122,7 @@ Foam::tokenList Foam::ITstream::parse
IOstreamOption streamOpt
)
{
ISpanStream is(input, strlen(input), streamOpt);
UIListStream is(input, strlen(input), streamOpt);
tokenList tokens;
parseStream(is, tokens);
@ -261,7 +261,7 @@ Foam::ITstream::ITstream
:
ITstream(streamOpt, name)
{
ISpanStream is(input, streamOpt);
UIListStream is(input, streamOpt);
parseStream(is, static_cast<tokenList&>(*this));
ITstream::seek(0); // rewind(), but bypasss virtual
@ -277,7 +277,7 @@ Foam::ITstream::ITstream
:
ITstream(streamOpt, name)
{
ISpanStream is(input.data(), input.length(), streamOpt);
UIListStream is(input.data(), input.length(), streamOpt);
parseStream(is, static_cast<tokenList&>(*this));
ITstream::seek(0); // rewind(), but bypasss virtual
@ -293,7 +293,7 @@ Foam::ITstream::ITstream
:
ITstream(streamOpt, name)
{
ISpanStream is(input, strlen(input), streamOpt);
UIListStream is(input, strlen(input), streamOpt);
parseStream(is, static_cast<tokenList&>(*this));
ITstream::seek(0); // rewind(), but bypasss virtual

View File

@ -1,10 +0,0 @@
// Compatibility include.
#ifndef FoamCompat_ListStream_H
#define FoamCompat_ListStream_H
#include "SpanStream.H"
#endif
// ************************************************************************* //

View File

@ -1,10 +0,0 @@
// Compatibility include.
#ifndef FoamCompat_OListStream_H
#define FoamCompat_UListStream_H
#include "SpanStream.H"
#endif
// ************************************************************************* //

View File

@ -1,10 +0,0 @@
// Compatibility include.
#ifndef FoamCompat_UIListStream_H
#define FoamCompat_UIListStream_H
#include "SpanStream.H"
#endif
// ************************************************************************* //

View File

@ -1,10 +0,0 @@
// Compatibility include.
#ifndef FoamCompat_UListStream_H
#define FoamCompat_UListStream_H
#include "SpanStream.H"
#endif
// ************************************************************************* //

View File

@ -1,10 +0,0 @@
// Compatibility include.
#ifndef FoamCompat_UOListStream_H
#define FoamCompat_UOListStream_H
#include "SpanStream.H"
#endif
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -54,21 +54,23 @@ class osha1stream
public std::ostream
{
//- A streambuf class for calculating SHA1 digests
class sha1buf : public std::streambuf
class sha1buf
:
public std::streambuf
{
//- This does all the work and has its own buffering
SHA1 sha1_;
protected:
//- Output overflow handling - append to SHA1
virtual int overflow(int_type c = traits_type::eof())
//- Handle overflow
virtual int overflow(int c = EOF)
{
if (c != traits_type::eof()) sha1_.append(c);
if (c != EOF) sha1_.append(c);
return c;
}
//- Put sequence of characters - append to SHA1
//- Put sequence of characters
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
if (n) sha1_.append(s, n);
@ -81,7 +83,10 @@ class osha1stream
sha1buf() = default;
//- Full access to the sha1
SHA1& sha1() noexcept { return sha1_; }
SHA1& sha1() noexcept
{
return sha1_;
}
};
@ -95,22 +100,25 @@ public:
// Constructors
//- Default construct
osha1stream() : std::ostream(&buf_) {}
osha1stream()
:
std::ostream(&buf_)
{}
// Member Functions
//- This hides both signatures of std::basic_ios::rdbuf()
sha1buf* rdbuf() { return &buf_; }
sha1buf* rdbuf()
{
return &buf_;
}
//- Full access to the sha1
SHA1& sha1() noexcept { return buf_.sha1(); }
//- Return SHA1::Digest for the data processed until now
SHA1Digest digest() { return buf_.sha1().digest(); }
//- Clear the SHA1 calculation
void reset() { buf_.sha1().clear(); }
SHA1& sha1() noexcept
{
return buf_.sha1();
}
};
@ -121,21 +129,48 @@ namespace Detail
Class Detail::OSHA1streamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::osha1stream
//- Allocator for an osha1stream
class OSHA1streamAllocator
{
protected:
// Protected Data
typedef osha1stream stream_type;
//- The output stream
Foam::osha1stream stream_;
stream_type stream_;
// Constructors
//- Default construct
OSHA1streamAllocator() = default;
public:
// Member Functions
//- Full access to the sha1
SHA1& sha1() noexcept
{
return stream_.sha1();
}
//- Return SHA1::Digest for the data processed until now
SHA1Digest digest()
{
return stream_.sha1().digest();
}
//- Clear the SHA1 calculation
void reset()
{
return stream_.sha1().clear();
}
};
} // End namespace Detail
@ -153,15 +188,16 @@ class OSHA1stream
{
typedef Detail::OSHA1streamAllocator allocator_type;
// Private Member Functions
//- No copy construct
OSHA1stream(const OSHA1stream&) = delete;
//- No copy assignment
void operator=(const OSHA1stream&) = delete;
public:
//- No copy construct
OSHA1stream(const OSHA1stream&) = delete;
//- No copy assignment
void operator=(const OSHA1stream&) = delete;
// Constructors
//- Construct with an empty digest
@ -175,18 +211,6 @@ public:
{}
// Member Functions
//- Full access to the sha1
SHA1& sha1() noexcept { return stream_.sha1(); }
//- Return SHA1::Digest for the data processed until now
SHA1Digest digest() { return stream_.digest(); }
//- Clear the SHA1 calculation
void reset() { stream_.reset(); }
// Write Functions
//- Add (unquoted) string contents.
@ -203,7 +227,7 @@ public:
// \deprecated(2017-07) - use reset() method
void rewind()
{
stream_.sha1().clear();
sha1().clear();
}

View File

@ -1,352 +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/>.
Class
Foam::ICharStream
Description
An input stream that reads from a List and manages the List storage.
Similar to IStringStream but with a List for its storage instead of
as string to allow reuse of List contents without copying.
See Also
Foam::OCharStream
Foam::ISpanStream
Foam::OSpanStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_ICharStream_H
#define Foam_ICharStream_H
#include "ISpanStream.H"
#include "List.H"
#include "DynamicList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class icharstream;
class ICharStream;
// Older names (prior to 2023-08)
typedef ICharStream IListStream;
/*---------------------------------------------------------------------------*\
Class icharstream Declaration
\*---------------------------------------------------------------------------*/
//- Similar to std::istringstream, but with the ability to swap
//- character content.
//- Has some similarity to std::ispanstream (C++23)
class icharstream
:
virtual public std::ios,
protected Foam::memorybuf::in_dynamic,
public std::istream
{
typedef Foam::memorybuf::in_dynamic buffer_type;
typedef std::istream stream_type;
public:
// Constructors
//- Default construct - empty
icharstream()
:
buffer_type(),
stream_type(static_cast<buffer_type*>(this))
{}
//- Copy construct from content
icharstream(const char* buffer, size_t nbytes)
:
icharstream()
{
reset(buffer, nbytes);
}
// //- Construct (deep copy) from span character content
// explicit icharstream(stdFoam::span<char> s)
// :
// icharstream()
// {
// reset(buffer, nbytes);
// }
//- Move construct from List
icharstream(List<char>&& buffer)
:
icharstream()
{
swap(buffer);
}
//- Move construct from DynamicList
template<int SizeMin>
icharstream(DynamicList<char,SizeMin>&& buffer)
:
icharstream()
{
swap(buffer);
}
// Member Functions
//- The current get position within the buffer (tellg)
std::streampos input_pos() const
{
return buffer_type::span_tellg();
}
//- The get buffer capacity
std::streamsize capacity() const
{
return buffer_type::span_capacity();
}
//- The number of characters remaining in the get area.
//- Same as (capacity() - input_pos())
std::streamsize remaining() const
{
return buffer_type::span_remaining();
}
//- Span of the input characters (is modifiable!)
UList<char> list() const
{
return buffer_type::span_list();
}
//- Rewind the stream, clearing any old errors
void rewind()
{
buffer_type::pubseekpos(0, std::ios_base::in);
stream_type::clear(); // Clear old errors
}
//- Reset content (copy)
void reset(const char* buffer, size_t nbytes)
{
buffer_type::reset(buffer, nbytes);
stream_type::clear(); // Clear old errors
}
//- Transfer list contents to List buffer
void swap(List<char>& other)
{
buffer_type::swap(other);
stream_type::clear(); // Clear old errors
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
buffer_type::swap(other);
stream_type::clear(); // Clear old errors
}
//- Some information about the input buffer position/capacity
void debug_info(Ostream& os) const
{
os << "get="
<< input_pos() << '/' << capacity();
}
};
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::ICharStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::icharstream
class ICharStreamAllocator
{
protected:
// Protected Data
//- The stream
Foam::icharstream stream_;
// Constructors
//- Default construct
ICharStreamAllocator() = default;
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class ICharStream Declaration
\*---------------------------------------------------------------------------*/
//- An ISstream with internal List storage. Always UNCOMPRESSED.
class ICharStream
:
public Detail::ICharStreamAllocator,
public Foam::ISstream
{
typedef Detail::ICharStreamAllocator allocator_type;
public:
// Constructors
//- Default construct (empty), optionally with specified stream option
explicit ICharStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
//- Copy construct from string content
explicit ICharStream
(
const std::string& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
ICharStream(streamOpt)
{
stream_.reset(buffer.data(), buffer.size());
}
//- Move construct from List
explicit ICharStream
(
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
IOstreamOption streamOpt = IOstreamOption()
)
:
ICharStream(streamOpt)
{
stream_.swap(buffer);
}
//- Move construct from DynamicList (uses current size)
template<int SizeMin>
explicit ICharStream
(
DynamicList<char,SizeMin>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
ICharStream(streamOpt)
{
stream_.swap(buffer);
}
// Member Functions
//- Position of the get buffer
std::streampos tellg() const { return stream_.input_pos(); }
//- The current get position within the buffer (tellg)
std::streampos input_pos() const { return stream_.input_pos(); }
//- The input list size. Same as capacity()
label size() const { return label(stream_.capacity()); }
//- The get buffer capacity
std::streamsize capacity() const { return stream_.capacity(); }
//- The number of characters remaining in the get area.
//- 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(); }
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
stream_.rewind();
syncState();
}
//- Reset content (copy)
void reset(const char* buffer, size_t nbytes)
{
stream_.reset(buffer, nbytes);
syncState();
}
//- Transfer list contents to List buffer
void swap(List<char>& other)
{
stream_.swap(other);
syncState();
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
stream_.swap(other);
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Member Operators
//- A non-const reference to const Istream
// Needed for read-constructors where the stream argument is temporary
Istream& operator()() const
{
// Could also rewind
return const_cast<ICharStream&>(*this);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,261 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2022 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/>.
Class
Foam::IListStream
Description
An input stream that reads from a List and manages the List storage.
Similar to IStringStream but with a List for its storage instead of
as string to allow reuse of List contents without copying.
See Also
Foam::OListStream
Foam::UIListStream
Foam::UOListStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_IListStream_H
#define Foam_IListStream_H
#include "List.H"
#include "UIListStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::IListStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An stream/stream-buffer input allocator with List storage
class IListStreamAllocator
:
private List<char>,
public UIListStreamAllocator
{
protected:
// Constructors
//- Default construct
IListStreamAllocator()
:
List<char>(),
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
//- Move construct from List
IListStreamAllocator(List<char>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
//- Move construct from DynamicList
template<int SizeMin>
IListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
// Protected Member Functions
//- Convenience method to address the underlying List storage
inline void reset_gbuffer()
{
UIListStreamAllocator::reset
(
List<char>::data(),
List<char>::size()
);
}
public:
// Member Functions
//- The current get position in the buffer
using UIListStreamAllocator::size;
//- Clear storage
inline void clearStorage()
{
List<char>::clear();
reset_gbuffer();
}
//- Transfer contents to other List
inline void swap(List<char>& list)
{
List<char>::swap(list);
reset_gbuffer();
}
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class IListStream Declaration
\*---------------------------------------------------------------------------*/
//- An ISstream with internal List storage. Always UNCOMPRESSED.
class IListStream
:
public Detail::IListStreamAllocator,
public ISstream
{
typedef Detail::IListStreamAllocator allocator_type;
public:
// Constructors
//- Default construct with an empty list
explicit IListStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
//- Move construct from List
explicit IListStream
(
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(std::move(buffer)),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
//- Move construct from DynamicList
template<int SizeMin>
explicit IListStream
(
DynamicList<char,SizeMin>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(std::move(buffer)),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
// Member Functions
//- The current get position in the buffer
using allocator_type::size;
//- Return the current get position in the buffer
std::streampos pos() const
{
return allocator_type::tellg();
}
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
allocator_type::rewind();
setGood(); // resynchronize with internal state
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Member Operators
//- A non-const reference to const Istream
// Needed for read-constructors where the stream argument is temporary
Istream& operator()() const
{
// Could also rewind
return const_cast<IListStream&>(*this);
}
// Additional constructors and methods (as per v2012 and earlier)
#ifdef Foam_IOstream_extras
//- Construct with an empty list
explicit IListStream
(
IOstreamOption::streamFormat fmt
)
:
IListStream(IOstreamOption(fmt))
{}
//- Move construct from List
IListStream
(
::Foam::List<char>&& buffer, // Fully qualify (issue #1521)
IOstreamOption::streamFormat fmt
)
:
IListStream(std::move(buffer), IOstreamOption(fmt))
{}
//- Move construct from DynamicList
template<int SizeMin>
explicit IListStream
(
DynamicList<char,SizeMin>&& buffer,
IOstreamOption::streamFormat fmt
)
:
IListStream(std::move(buffer), IOstreamOption(fmt))
{}
#endif /* Foam_IOstream_extras */
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,352 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-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/>.
Class
Foam::ISpanStream
Description
Similar to IStringStream but using an externally managed buffer for its
input. This allows the input buffer to be filled (and refilled) from
various sources.
Note that this stream will normally be used as a "one-shot" reader.
Caution must be exercised that the referenced buffer remains valid and
without any intermediate resizing for the duration of the stream's use.
An example of possible use:
\code
DynamicList<char> buffer(4096); // allocate some large buffer
nread = something.read(buffer.data(),1024); // fill with content
buffer.resize(nread); // content size
// Construct dictionary, or something else
ISpanStream is(buffer)
dictionary dict1(is);
// Sometime later
nread = something.read(buffer.data(),2048); // fill with content
buffer.resize(nread); // content size
// Without intermediate variable
dictionary dict2(ISpanStream(buffer)());
\endcode
See Also
Foam::ICharStream
Foam::OCharStream
Foam::OSpanStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_ISpanStream_H
#define Foam_ISpanStream_H
#include "UList.H"
#include "ISstream.H"
#include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class ispanstream;
class ISpanStream;
// Older names (prior to 2023-08)
typedef ispanstream uiliststream;
typedef ISpanStream UIListStream;
/*---------------------------------------------------------------------------*\
Class ispanstream Declaration
\*---------------------------------------------------------------------------*/
//- Similar to std::istringstream, but with an externally managed input buffer
//- which makes it most similar to std::ispanstream (C++23)
// This allows the input buffer to be filled or refilled from various sources
// without copying.
class ispanstream
:
virtual public std::ios,
protected Foam::memorybuf::in_base,
public std::istream
{
typedef Foam::memorybuf::in_base buffer_type;
typedef std::istream stream_type;
public:
// Constructors
//- Default construct - empty
ispanstream()
:
buffer_type(),
stream_type(static_cast<buffer_type*>(this))
{}
//- Construct (shallow copy) for character array and number of bytes
ispanstream(const char* buffer, size_t nbytes)
:
buffer_type(const_cast<char*>(buffer), nbytes),
stream_type(static_cast<buffer_type*>(this))
{}
// //- Construct (shallow copy) from span character content
// ispanstream(stdFoam::span<char> s)
// :
// buffer_type(const_cast<char*>(s.data()), s.size()),
// stream_type(static_cast<buffer_type*>(this))
// {}
// Member Functions
//- The current get position within the buffer (tellg)
std::streampos input_pos() const
{
return buffer_type::span_tellg();
}
//- The get buffer capacity
std::streamsize capacity() const
{
return buffer_type::span_capacity();
}
//- The number of characters remaining in the get area.
//- Same as (capacity() - input_pos())
std::streamsize remaining() const
{
return buffer_type::span_remaining();
}
//- Span of the input characters (is modifiable!)
UList<char> list() const
{
return buffer_type::span_list();
}
//- Rewind the stream, clearing any old errors
void rewind()
{
buffer_type::pubseekpos(0, std::ios_base::in);
stream_type::clear(); // Clear old errors
}
//- Reset the get buffer area
void reset(const char* buffer, size_t nbytes)
{
buffer_type::resetg(const_cast<char*>(buffer), nbytes);
stream_type::clear(); // Clear old errors
}
//- Reset the get buffer area to use the data from a string
void reset(const std::string& s)
{
buffer_type::resetg(const_cast<char*>(&s[0]), s.size());
stream_type::clear(); // Clear old errors
}
//- Some information about the input buffer position/capacity
void debug_info(Ostream& os) const
{
os << "get="
<< input_pos() << '/' << capacity();
}
};
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::ISpanStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::ispanstream
class ISpanStreamAllocator
{
protected:
// Protected Data
//- The stream
Foam::ispanstream stream_;
// Constructors
//- Default construct (empty)
ISpanStreamAllocator() = default;
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class ISpanStream Declaration
\*---------------------------------------------------------------------------*/
class ISpanStream
:
public Detail::ISpanStreamAllocator,
public Foam::ISstream
{
typedef Detail::ISpanStreamAllocator allocator_type;
public:
// Constructors
//- Default construct (empty), optionally with specified stream option
explicit ISpanStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
//- Construct using specified buffer and number of bytes
ISpanStream
(
const char* buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(streamOpt)
{
reset(buffer, nbytes);
}
//- Use data area from string content
explicit ISpanStream
(
const std::string& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(streamOpt)
{
reset(buffer);
}
//- Construct using data area from a List and number of bytes
ISpanStream
(
const ::Foam::UList<char>& buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(buffer.cdata(), nbytes, streamOpt)
{}
//- Construct using data area from a List and its inherent storage size
// Uses addressed size, thus no special treatment for a DynamicList
explicit ISpanStream
(
const ::Foam::UList<char>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
ISpanStream(buffer.cdata(), buffer.size(), streamOpt)
{}
// Member Functions
//- Position of the get buffer
std::streampos tellg() const { return stream_.input_pos(); }
//- The current get position within the buffer (tellg)
std::streampos input_pos() const { return stream_.input_pos(); }
//- The input list size. Same as capacity()
label size() const { return label(stream_.capacity()); }
//- The get buffer capacity
std::streamsize capacity() const { return stream_.capacity(); }
//- The number of characters remaining in the get area.
//- 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(); }
//- Reset input area, position to buffer start and clear errors
void reset(const char* buffer, size_t nbytes)
{
stream_.reset(buffer, nbytes);
syncState();
}
//- Reset input area to use data from a string
void reset(const std::string& s)
{
stream_.reset(s);
syncState();
}
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
stream_.rewind();
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Member Operators
//- A non-const reference to const Istream
// Needed for read-constructors where the stream argument is temporary
Istream& operator()() const
{
// Could also rewind
return const_cast<ISpanStream&>(*this);
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -25,39 +25,40 @@ License
\*---------------------------------------------------------------------------*/
#include "SpanStream.H"
#include "UListStream.H"
#include "ListStream.H"
#include "OCountStream.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::ISpanStream::print(Ostream& os) const
void Foam::IListStream::print(Ostream& os) const
{
os << "ISpanStream: ";
stream_.debug_info(os);
os << "IListStream: ";
printBufInfo(os);
os << Foam::endl;
}
void Foam::OSpanStream::print(Ostream& os) const
void Foam::UIListStream::print(Ostream& os) const
{
os << "OSpanStream: ";
stream_.debug_info(os);
os << "UIListStream: ";
printBufInfo(os);
os << Foam::endl;
}
void Foam::ICharStream::print(Ostream& os) const
void Foam::OListStream::print(Ostream& os) const
{
os << "ICharStream: ";
stream_.debug_info(os);
os << "OListStream: ";
printBufInfo(os);
os << Foam::endl;
}
void Foam::OCharStream::print(Ostream& os) const
void Foam::UOListStream::print(Ostream& os) const
{
os << "OCharStream: ";
stream_.debug_info(os);
os << "UOListStream: ";
printBufInfo(os);
os << Foam::endl;
}
@ -65,8 +66,7 @@ void Foam::OCharStream::print(Ostream& os) const
void Foam::OCountStream::print(Ostream& os) const
{
os << "OCountStream: ";
// os << "count=" << stream_.count();
stream_.debug_info(os);
printBufInfo(os);
os << Foam::endl;
}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -24,17 +24,15 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Input/output streams with (internal or external) character storage.
Input/output streams with managed List storage.
\*---------------------------------------------------------------------------*/
#ifndef Foam_SpanStream_H
#define Foam_SpanStream_H
#ifndef ListStream_H
#define ListStream_H
#include "ISpanStream.H"
#include "ICharStream.H"
#include "OSpanStream.H"
#include "OCharStream.H"
#include "IListStream.H"
#include "OListStream.H"
#endif

View File

@ -1,316 +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/>.
Class
Foam::OCharStream
Description
An output stream that writes to a List and manages the List storage.
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.
See Also
Foam::ICharStream
Foam::OSpanStream
Foam::ISpanStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_OCharStream_H
#define Foam_OCharStream_H
#include "OSpanStream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class ocharstream;
class OCharStream;
// Older names (prior to 2023-08)
typedef OCharStream OListStream;
/*---------------------------------------------------------------------------*\
Class ocharstream Declaration
\*---------------------------------------------------------------------------*/
//- Similar to std::ostringstream, but with the ability to swap
//- character content.
//- Has some similarity to std::ospanstream (C++23)
class ocharstream
:
virtual public std::ios,
protected Foam::memorybuf::out_dynamic,
public std::ostream
{
typedef Foam::memorybuf::out_dynamic buffer_type;
typedef std::ostream stream_type;
public:
// Constructors
//- Default construct - empty
ocharstream()
:
buffer_type(),
stream_type(static_cast<buffer_type*>(this))
{}
//- Move construct from List
ocharstream(List<char>&& buffer)
:
ocharstream()
{
swap(buffer);
}
//- Move construct from DynamicList
template<int SizeMin>
ocharstream(DynamicList<char,SizeMin>&& buffer)
:
ocharstream()
{
swap(buffer);
}
// Member Functions
//- The current output position within the buffer (tellp)
std::streampos output_pos() const
{
return (buffer_type::span_tellp());
}
//- The put buffer capacity
std::streamsize capacity() const
{
return buffer_type::span_capacity();
}
//- Reserve output space for at least this amount
void reserve(const std::streamsize n)
{
buffer_type::reserve(n);
}
//- Span of the current output characters (is modifiable!)
UList<char> list() const
{
return buffer_type::span_list();
}
//- Rewind the stream, clearing any old errors
void rewind()
{
buffer_type::pubseekpos(0, std::ios_base::out);
stream_type::clear(); // Clear old errors
}
//- Transfer list contents to List buffer
void swap(List<char>& other)
{
buffer_type::swap(other);
stream_type::clear(); // Clear old errors
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
buffer_type::swap(other);
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();
}
};
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::OCharStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::ocharstream
class OCharStreamAllocator
{
protected:
// Protected Data
//- The stream
Foam::ocharstream stream_;
// Constructors
//- Default construct - empty
OCharStreamAllocator() = default;
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class OCharStream Declaration
\*---------------------------------------------------------------------------*/
//- An OSstream with internal List storage
class OCharStream
:
public Detail::OCharStreamAllocator,
public Foam::OSstream
{
typedef Detail::OCharStreamAllocator allocator_type;
public:
// Constructors
//- Default construct (empty output)
explicit OCharStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Construct with initial reserved number of bytes
explicit OCharStream
(
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
OCharStream(streamOpt)
{
stream_.reserve(nbytes);
}
//- Move construct from a List
explicit OCharStream
(
::Foam::List<char>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
OCharStream(streamOpt)
{
stream_.swap(buffer);
}
//- Move construct from a DynamicList (uses entire capacity)
template<int SizeMin>
explicit OCharStream
(
::Foam::DynamicList<char,SizeMin>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
OCharStream(streamOpt)
{
stream_.swap(buffer);
}
// Member Functions
//- Position of the put buffer
std::streampos tellp() const { return stream_.output_pos(); }
//- The current output position within the buffer (tellp)
std::streampos output_pos() const { return stream_.output_pos(); }
//- The current output size. Same as tellp(), output_pos()
label size() const { return label(stream_.output_pos()); }
//- The put buffer capacity
std::streamsize capacity() const { return stream_.capacity(); }
//- Reserve output space for at least this amount
void reserve(const std::streamsize n) { stream_.reserve(n); }
//- Span of the current output characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
stream_.rewind();
syncState();
}
//- Transfer list contents to List buffer
void swap(List<char>& other)
{
stream_.swap(other);
syncState();
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
stream_.swap(other);
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Houskeeping
//- Block size was used in OpenFOAM-v2306 and earlier
void setBlockSize(int n) {}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -42,6 +42,103 @@ Description
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class countstreambuf Declaration
\*---------------------------------------------------------------------------*/
//- A streambuf class for determining byte counts
class countstreambuf
:
public std::streambuf
{
//- The number of bytes counted
std::streamsize size_;
protected:
//- Set position pointer to relative position
virtual std::streampos seekoff
(
std::streamoff off,
std::ios_base::seekdir way,
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
)
{
if (which & std::ios_base::out)
{
if (way == std::ios_base::beg)
{
size_ = off;
}
else if (way == std::ios_base::cur)
{
size_ += off;
}
else if (way == std::ios_base::end)
{
// not really possible
}
return size_; // tellp()
}
return -1;
}
//- Set position pointer to absolute position
// For the counter, adjust the count accordingly.
virtual std::streampos seekpos
(
std::streampos pos,
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
)
{
return seekoff(pos, std::ios_base::beg, which);
}
//- Handle output counting via overflow
virtual int overflow(int c = EOF)
{
if (c != EOF)
{
++size_;
}
return c;
}
//- Put sequence of characters
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
size_ += n;
return n;
}
public:
//- Default construct, or with precount size
explicit countstreambuf(std::streamsize precount=0)
:
size_(precount)
{}
//- \return The buffer put position == number of bytes counted.
std::streamsize tellp() const
{
return size_;
}
//- Some information about the number of bytes counted
void printBufInfo(Ostream& os) const
{
os << "count=" << size_;
}
};
/*---------------------------------------------------------------------------*\
Class ocountstream Declaration
\*---------------------------------------------------------------------------*/
@ -52,124 +149,34 @@ namespace Foam
class ocountstream
:
virtual public std::ios,
protected countstreambuf,
public std::ostream
{
//- A streambuf class for determining byte counts
class countbuf : public std::streambuf
{
//- The number of bytes counted
std::streamsize size_;
protected:
//- Set position pointer to relative position
virtual std::streampos seekoff
(
std::streamoff off,
std::ios_base::seekdir way,
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
)
{
if (which & std::ios_base::out)
{
if (way == std::ios_base::beg)
{
size_ = off;
}
else if (way == std::ios_base::cur)
{
size_ += off;
}
else if (way == std::ios_base::end)
{
// not really possible
}
return size_; // Like span_tellp()
}
return -1;
}
//- Set position pointer to absolute position
// For the counter, adjust the count accordingly.
virtual std::streampos seekpos
(
std::streampos pos,
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
)
{
return seekoff(pos, std::ios_base::beg, which);
}
//- Output overflow handling - increment counter
virtual int overflow(int_type c = traits_type::eof())
{
if (c != traits_type::eof()) ++size_;
return c;
}
//- Put sequence of characters - increment counter
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
size_ += n;
return n;
}
public:
// Constructors
//- Default construct, count = 0
countbuf() : size_(0) {}
// Member Functions
//- The number of bytes counted.
std::streamsize count() const noexcept { return size_; }
//- Reset the count
void reset(std::streamsize n = 0) noexcept { size_ = n; }
};
// Private Data
typedef countbuf buffer_type;
typedef std::ostream stream_type;
//- Reference to the underlying buffer
buffer_type buf_;
public:
// Constructors
//- Default construct
ocountstream() : stream_type(&buf_) {}
//- Default construct
ocountstream()
:
countstreambuf(),
std::ostream(static_cast<countstreambuf*>(this))
{}
// Member Functions
//- \return The buffer put position == number of bytes counted.
using countstreambuf::tellp;
//- This hides both signatures of std::basic_ios::rdbuf()
countbuf* rdbuf() { return &buf_; }
//- \return The number of bytes counted
std::streamsize size() const
{
return countstreambuf::tellp();
}
//- \return The number of bytes counted
std::streamsize count() const noexcept { return buf_.count(); }
//- Reset the count
void reset(std::streamsize n = 0) noexcept
{
buf_.reset(n);
stream_type::clear(); // Clear old errors
}
//- Some information about the output buffer position/capacity
void debug_info(Ostream& os) const
{
os << "count=" << buf_.count();
}
//- Rewind the stream, reset the count
void rewind()
{
this->pubseekpos(0, std::ios_base::out);
clear(); // for safety, clear any old errors
}
};
@ -180,21 +187,55 @@ namespace Detail
Class Detail::OCountStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::ocountstream
//- An stream/stream-buffer allocator for counting
class OCountStreamAllocator
{
protected:
// Protected Data
typedef std::ostream stream_type;
//- The stream buffer
countstreambuf buf_;
//- The output stream
Foam::ocountstream stream_;
stream_type stream_;
// Constructors
//- Default construct
OCountStreamAllocator() = default;
//- Default construct, or with precount size
OCountStreamAllocator(std::streamsize precount=0)
:
buf_(precount),
stream_(&buf_)
{}
// Protected Member Functions
void printBufInfo(Ostream& os) const
{
buf_.printBufInfo(os);
}
public:
// Member Functions
//- The number of bytes counted
std::streamsize size() const
{
return buf_.tellp();
}
//- Rewind the stream, reset the count
void rewind()
{
buf_.pubseekpos(0);
stream_.clear(); // for safety, clear any old errors
}
};
} // End namespace Detail
@ -229,33 +270,35 @@ public:
//- Copy construct
OCountStream(const OCountStream& str)
:
allocator_type(),
allocator_type(str.size()),
OSstream(stream_, str.name(), static_cast<IOstreamOption>(str))
{
stream_.reset(str.count());
}
{}
// Member Functions
//- \return The number of bytes counted
std::streamsize count() const noexcept { return stream_.count(); }
//- \return The number of bytes counted
std::streamsize size() const noexcept { return stream_.count(); }
//- Reset the count
void reset(std::streamsize n = 0) noexcept { stream_.reset(n); }
//- Rewind the stream, reset the count, clearing any old errors
virtual void rewind()
{
stream_.reset();
syncState();
allocator_type::rewind();
setGood(); // resynchronize with internal state
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Additional constructors and methods (as per v2012 and earlier)
#ifdef Foam_IOstream_extras
//- Construct empty with format
explicit OCountStream(IOstreamOption::streamFormat fmt)
:
OCountStream(IOstreamOption(fmt))
{}
#endif /* Foam_IOstream_extras */
};

View File

@ -0,0 +1,522 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017-2022 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/>.
Class
Foam::OListStream
Description
An output stream that writes to a List and manages the List storage.
Similar to OStringStream but with a List for its storage instead of
as string to allow reuse of List contents without copying.
The default list size is 512-bytes with a 256-byte block increment.
These values can be changed after construction using the reserve() and
the setBlockSize() methods.
See Also
Foam::IListStream
Foam::UOListStream
Foam::UIListStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_OListStream_H
#define Foam_OListStream_H
#include "DynamicList.H"
#include "OSstream.H"
#include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::OListStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An stream/stream-buffer output allocator with DynamicList-like storage
class OListStreamAllocator
{
//- A streambuf adapter with resizing similar to DynamicList
class dynbuf
:
public memorybuf::out
{
friend class OListStreamAllocator;
//- Helper for block size - small list minimum of 64 bytes.
constexpr static int min_size(int n)
{
return stdFoam::max(64, n);
}
//- Block size when resizing the list
int block_ = 256;
//- Underlying list storage.
// Internally manage like a DynamicList, with its capacity known
// from the list size and the addressable size known through the
// stream pointers.
List<char> storage_;
protected:
//- Increment capacity directly and adjust buffer pointers to
//- correspond with the storage size.
inline void minCapacity
(
const std::streamsize n,
const std::streamsize cur = 0
)
{
const auto newEnd = n + cur;
if (newEnd > storage_.size())
{
auto newCapacity =
(
(storage_.size() + block_)
- (storage_.size() % block_)
);
while (newCapacity < newEnd)
{
newCapacity += block_;
}
// Info<<"request:" << newEnd
// << " cur cap:" << storage_.size()
// << " new cap:" << newCapacity
// << " pos:" << cur
// << " incr:" << incr << endl;
storage_.resize(newCapacity);
sync_pbuffer();
pbump(cur);
}
}
//- Define new increment
inline void setBlockSize(const int i)
{
const auto prev = block_;
block_ = min_size(i);
if (block_ > prev)
{
minCapacity(0, tellp());
}
}
//- Handle overflow
virtual int overflow(int c = EOF)
{
if (c != EOF)
{
// Need another output block
minCapacity(block_, tellp());
*(pptr()) = c;
pbump(1);
}
return c;
}
//- Put sequence of characters
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
// Enough space so that appends work without problem
minCapacity(n, tellp());
std::streamsize count = 0;
while (count < n && pptr() < epptr())
{
*(pptr()) = *(s + count++);
pbump(1);
}
return count;
}
//- Initialize put buffer
void init_pbuffer(const std::streamsize n)
{
sync_pbuffer();
minCapacity(n);
}
public:
// Constructors
//- Default construct, with initial reserved number of bytes
dynbuf(size_t nbytes = 512)
:
storage_()
{
init_pbuffer(min_size(nbytes));
}
//- Move construct from List
dynbuf(List<char>&& buffer)
:
storage_(std::move(buffer))
{
init_pbuffer(block_);
}
//- Move construct from DynamicList.
template<int SizeMin>
dynbuf(DynamicList<char,SizeMin>&& buffer)
:
storage_(std::move(buffer))
{
init_pbuffer(block_);
}
// Member Functions
//- Return the current list output capacity
inline label capacity() const
{
return storage_.size();
}
//- Sync put buffer pointers to agree with list dimensions
// Sets put pointer to the begin (rewind).
inline void sync_pbuffer()
{
resetp(storage_.data(), storage_.size());
}
//- Clear storage
inline void clearStorage()
{
storage_.clear();
sync_pbuffer();
}
//- Shrink storage to addressed storage
inline void shrink()
{
const auto cur = tellp(); // Addressed area
storage_.resize(cur);
sync_pbuffer();
pbump(cur);
}
//- Transfer list contents to other List
inline void swap(List<char>& other)
{
const auto cur = tellp(); // Addressed area
storage_.swap(other);
storage_.resize(cur);
sync_pbuffer();
}
//- Transfer list contents to a DynamicList
template<int SizeMin>
inline void swap(DynamicList<char,SizeMin>& other)
{
const auto cur = tellp(); // Addressed area
storage_.swap(other); // Swap full list
other.setCapacity(other.size());
other.resize(cur);
sync_pbuffer();
}
};
protected:
// Protected Data
typedef std::ostream stream_type;
//- The stream buffer
dynbuf buf_;
//- The stream
stream_type stream_;
// Constructors
//- Default construct, with initial reserved number of bytes
OListStreamAllocator(size_t nbytes = 512)
:
buf_(nbytes),
stream_(&buf_)
{}
//- Move construct from List
OListStreamAllocator(List<char>&& buffer)
:
buf_(std::move(buffer)),
stream_(&buf_)
{}
//- Move construct from DynamicList
template<int SizeMin>
OListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
:
buf_(std::move(buffer)),
stream_(&buf_)
{}
// Protected Member Functions
void printBufInfo(Ostream& os) const
{
os << "put=" << buf_.tellp()
<< "/" << buf_.capacity()
<< " block=" << buf_.block_;
}
public:
// Member Functions
//- Const UList access to the characters written (shallow copy).
inline const UList<char> list() const
{
return buf_.list();
}
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> list()
{
return buf_.list();
}
//- The current list output capacity
inline label capacity() const
{
return buf_.capacity();
}
//- The current output position in the buffer,
//- which is also the addressed list size
inline label size() const
{
return buf_.tellp();
}
//- Reserve output space for at least this amount.
inline void reserve(const std::streamsize n)
{
// Also maintain current position when resizing
const auto cur = buf_.tellp();
if (n > cur)
{
buf_.minCapacity(n - cur, cur);
}
}
//- Adjust block size for output
inline void setBlockSize(int n)
{
return buf_.setBlockSize(n);
}
//- Transfer list contents to other List
inline void swap(List<char>& other)
{
buf_.swap(other);
}
//- Transfer list contents to a DynamicList
template<int SizeMin>
inline void swap(DynamicList<char,SizeMin>& other)
{
buf_.swap(other);
}
//- Shrink to addressed space, should not affect stream.
inline void shrink()
{
buf_.shrink();
}
//- Clear storage
void clearStorage()
{
buf_.clearStorage();
stream_.clear(); // for safety, clear any old errors
}
//- Move to buffer start, clear errors
void rewind()
{
buf_.pubseekpos(0, std::ios_base::out);
stream_.clear(); // for safety, clear any old errors
}
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class OListStream Declaration
\*---------------------------------------------------------------------------*/
//- An OSstream attached to a List
class OListStream
:
public Detail::OListStreamAllocator,
public OSstream
{
typedef Detail::OListStreamAllocator allocator_type;
public:
// Constructors
//- Default construct (empty output)
explicit OListStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Construct with initial reserved number of bytes
explicit OListStream
(
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(nbytes),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Move construct from an existing List
explicit OListStream
(
List<char>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(std::move(buffer)),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Move construct from an existing DynamicList
template<int SizeMin>
explicit OListStream
(
DynamicList<char,SizeMin>&& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(std::move(buffer)),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
// Member Functions
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
allocator_type::rewind();
setGood(); // resynchronize with internal state
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Additional constructors and methods (as per v2012 and earlier)
#ifdef Foam_IOstream_extras
//- Default construct (empty output)
explicit OListStream
(
IOstreamOption::streamFormat fmt
)
:
OListStream(IOstreamOption(fmt))
{}
//- Construct with initial reserved number of bytes
explicit OListStream
(
size_t nbytes,
IOstreamOption::streamFormat fmt
)
:
OListStream(nbytes, IOstreamOption(fmt))
{}
//- Move construct from an existing List
OListStream
(
List<char>&& buffer,
IOstreamOption::streamFormat fmt
)
:
OListStream(std::move(buffer), IOstreamOption(fmt))
{}
//- Move construct from an existing DynamicList
template<int SizeMin>
OListStream
(
DynamicList<char,SizeMin>&& buffer,
IOstreamOption::streamFormat fmt
)
:
OListStream(std::move(buffer), IOstreamOption(fmt))
{}
#endif /* Foam_IOstream_extras */
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,358 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-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/>.
Class
Foam::OSpanStream
Description
Similar to OStringStream but using an externally managed buffer for
its output.
This allows the output buffer to be reused and can make it easier when
writing out data. It is the user's responsibility to ensure proper
synchronization in the sizes. Provided that the external buffer is large
enough that overflow does not occur, the following usage pattern
works.
\code
DynamicList<char> buffer(4096); // allocate some large buffer
{
OSpanStream os(buffer);
os << "content1" << " and more content";
buffer.resize(os.size()); // synchronize sizes
}
something.write(buffer, buffer.size());
\endcode
Although the OSpanStream is quite lightweight, there may be cases
where it is preferable to reuse the stream as well.
\code
DynamicList<char> buffer(4096); // allocate some large buffer
OSpanStream os(buffer);
os << "content1" << " and more content";
buffer.resize(os.size()); // synchronize sizes
something.write(buffer, buffer.size());
os.rewind();
os << "content2";
buffer.resize(os.size()); // synchronize sizes
something.write(buffer, buffer.size());
// or simply using the output size directly (without sync)
os.rewind();
os << "content3";
something.write(buffer, os.size());
\endcode
See Also
Foam::ICharStream
Foam::ISpanStream
Foam::OCharStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_OSpanStream_H
#define Foam_OSpanStream_H
#include "memoryStreamBuffer.H"
#include "DynamicList.H"
#include "OSstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class ospanstream;
class OSpanStream;
// Older names (prior to 2023-08)
typedef OSpanStream UOListStream;
/*---------------------------------------------------------------------------*\
Class ospanstream Declaration
\*---------------------------------------------------------------------------*/
//- Similar to std::ostringstream, but with an externally managed output buffer
//- which makes it most similar to std::ospanstream (C++23)
class ospanstream
:
virtual public std::ios,
protected Foam::memorybuf::out_base,
public std::ostream
{
typedef Foam::memorybuf::out_base buffer_type;
typedef std::ostream stream_type;
public:
// Constructors
//- Default construct - empty
ospanstream()
:
buffer_type(),
stream_type(static_cast<buffer_type*>(this))
{}
//- Construct for character array and number of bytes
ospanstream(char* buffer, size_t nbytes)
:
buffer_type(buffer, nbytes),
stream_type(static_cast<buffer_type*>(this))
{}
// //- Construct (shallow copy) from span character content
// ospanstream(stdFoam::span<char> s)
// :
// buffer_type(const_cast<char*>(s.data()), s.size()),
// stream_type(static_cast<buffer_type*>(this))
// {}
// Member Functions
//- The current output position within the buffer (tellp)
std::streampos output_pos() const
{
return buffer_type::span_tellp();
}
//- The put buffer capacity
std::streamsize capacity() const
{
return buffer_type::span_capacity();
}
//- Span of the current output characters (is modifiable!)
UList<char> list() const
{
return buffer_type::span_list();
}
//- 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
}
//- Reset the put buffer area to use the data area from a string
void reset(std::string& s)
{
s.resize(s.capacity());
buffer_type::resetp(&s[0], s.size());
stream_type::clear(); // Clear any old errors
}
//- Some information about the output buffer position/capacity
void debug_info(Ostream& os) const
{
os << "put="
<< output_pos() << '/' << capacity();
}
};
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::OSpanStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An allocator for holding Foam::ospanstream
class OSpanStreamAllocator
{
protected:
// Protected Data
//- The stream
Foam::ospanstream stream_;
// Constructors
//- Default construct (empty)
OSpanStreamAllocator() = default;
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class OSpanStream Declaration
\*---------------------------------------------------------------------------*/
//- An OSstream attached to an unallocated external buffer
class OSpanStream
:
public Detail::OSpanStreamAllocator,
public Foam::OSstream
{
typedef Detail::OSpanStreamAllocator allocator_type;
public:
// Constructors
//- Default construct (empty output)
explicit OSpanStream
(
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Use data area from string content
explicit OSpanStream
(
std::string& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
OSpanStream(streamOpt)
{
stream_.reset(buffer);
}
//- Construct using specified buffer and number of bytes
OSpanStream
(
char* buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
OSpanStream(streamOpt)
{
stream_.reset(buffer, nbytes);
}
//- Construct using data area from a List and number of bytes
OSpanStream
(
::Foam::UList<char>& buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
OSpanStream(buffer.data(), nbytes, streamOpt)
{}
//- Construct using data area from a List and its inherent storage size
explicit OSpanStream
(
::Foam::UList<char>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
OSpanStream(buffer.data(), buffer.size(), streamOpt)
{}
//- Construct using full data area from DynamicList
template<int SizeMin>
explicit OSpanStream
(
::Foam::DynamicList<char,SizeMin>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
OSpanStream(buffer.data(), buffer.capacity(), streamOpt)
{
buffer.resize(buffer.capacity()); // Uses entire space
}
// Member Functions
//- Position of the put buffer
std::streampos tellp() const { return stream_.output_pos(); }
//- The current output position within the buffer (tellp)
std::streampos output_pos() const { return stream_.output_pos(); }
//- The current output size. Same as tellp(), output_pos()
label size() const { return label(stream_.output_pos()); }
//- The put buffer capacity
std::streamsize capacity() const { return stream_.capacity(); }
//- Span of the current output characters (is modifiable!)
UList<char> list() const { return stream_.list(); }
//- Reset the put area
void reset(char* buffer, size_t nbytes)
{
stream_.reset(buffer, nbytes);
syncState();
}
//- Reset the put buffer area to use the data area from a string
void reset(std::string& s)
{
stream_.reset(s);
syncState();
}
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
stream_.rewind();
syncState();
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,326 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2022 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/>.
Class
Foam::UIListStream
Description
Similar to IStringStream but using an externally managed buffer for its
input. This allows the input buffer to be filled (and refilled) from
various sources.
Note that this stream will normally be used as a "one-shot" reader.
Caution must be exercised that the referenced buffer remains valid and
without any intermediate resizing for the duration of the stream's use.
An example of possible use:
\code
DynamicList<char> buffer(4096); // allocate some large buffer
nread = something.read(buffer.data(),1024); // fill with content
buffer.resize(nread); // content size
// Construct dictionary, or something else
UIListStream is(buffer)
dictionary dict1(is);
// Sometime later
nread = something.read(buffer.data(),2048); // fill with content
buffer.resize(nread); // content size
// Without intermediate variable
dictionary dict2(UIListStream(buffer)());
\endcode
See Also
Foam::IListStream
Foam::OListStream
Foam::UOListStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_UIListStream_H
#define Foam_UIListStream_H
#include "UList.H"
#include "ISstream.H"
#include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class uiliststream Declaration
\*---------------------------------------------------------------------------*/
//- Similar to std::istringstream, but with an externally managed input buffer.
// This allows the input buffer to be filled or refilled from various sources
// without copying.
class uiliststream
:
virtual public std::ios,
protected memorybuf::in,
public std::istream
{
public:
//- Construct for character array and number of bytes
uiliststream(const char* buffer, size_t nbytes)
:
memorybuf::in(const_cast<char*>(buffer), nbytes),
std::istream(static_cast<memorybuf::in*>(this))
{}
//- Reset buffer pointers
inline void reset(char *buffer, size_t nbytes)
{
resetg(buffer, nbytes);
}
//- Rewind the stream, clearing any old errors
void rewind()
{
this->pubseekpos(0, std::ios_base::in);
clear(); // for safety, clear any old errors
}
};
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::UIListStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An stream/stream-buffer input allocator for a externally allocated list
class UIListStreamAllocator
{
protected:
// Protected Data
typedef std::istream stream_type;
//- The stream buffer
memorybuf::in buf_;
//- The stream
stream_type stream_;
// Constructors
//- Construct for character array and number of bytes
UIListStreamAllocator(char* buffer, size_t nbytes)
:
buf_(buffer, nbytes),
stream_(&buf_)
{}
// Protected Member Functions
//- Reset buffer pointers
inline void reset(char* buffer, size_t nbytes)
{
buf_.resetg(buffer, nbytes);
}
void printBufInfo(Ostream& os) const
{
buf_.printBufInfo(os);
}
public:
// Member Functions
//- Const UList access to the input characters (shallow copy).
inline const UList<char> list() const
{
return buf_.list();
}
//- Non-const UList access to the input characters (shallow copy).
inline UList<char> list()
{
return buf_.list();
}
//- The list size
inline label size() const
{
return buf_.capacity();
}
//- Position of the get buffer
std::streampos tellg() const
{
return buf_.tellg();
}
//- Move to buffer start, clear errors
void rewind()
{
buf_.pubseekpos(0, std::ios_base::in);
stream_.clear(); // for safety, clear any old errors
}
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class UIListStream Declaration
\*---------------------------------------------------------------------------*/
class UIListStream
:
public Detail::UIListStreamAllocator,
public ISstream
{
typedef Detail::UIListStreamAllocator allocator_type;
public:
// Constructors
//- Construct using specified buffer and number of bytes
UIListStream
(
const char* buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(const_cast<char*>(buffer), nbytes),
ISstream(stream_, "input", streamOpt.format(), streamOpt.version())
{}
//- Construct using data area from a List and number of bytes
UIListStream
(
const UList<char>& buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
UIListStream(buffer.cdata(), nbytes, streamOpt)
{}
//- Construct using data area from a List and its inherent storage size
// Uses addressed size, thus no special treatment for a DynamicList
explicit UIListStream
(
const UList<char>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
UIListStream(buffer.cdata(), buffer.size(), streamOpt)
{}
// Member Functions
//- Return the current get position in the buffer
std::streampos pos() const
{
return allocator_type::tellg();
}
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
allocator_type::rewind();
setGood(); // resynchronize with internal state
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Member Operators
//- A non-const reference to const Istream
// Needed for read-constructors where the stream argument is temporary
Istream& operator()() const
{
// Could also rewind
return const_cast<UIListStream&>(*this);
}
// Additional constructors and methods (as per v2012 and earlier)
#ifdef Foam_IOstream_extras
//- Construct using specified buffer and number of bytes
UIListStream
(
const char* buffer,
size_t nbytes,
IOstreamOption::streamFormat fmt
)
:
UIListStream(buffer, nbytes, IOstreamOption(fmt))
{}
//- Construct using data area from a List and number of bytes
UIListStream
(
const UList<char>& buffer,
size_t nbytes,
IOstreamOption::streamFormat fmt
)
:
UIListStream(buffer.cdata(), nbytes, IOstreamOption(fmt))
{}
//- Construct using data area from a List and its inherent storage size
// Uses addressed size, thus no special treatment for a DynamicList
UIListStream
(
const UList<char>& buf,
IOstreamOption::streamFormat fmt
)
:
UIListStream(buf.cdata(), buf.size(), IOstreamOption(fmt))
{}
#endif /* Foam_IOstream_extras */
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2017 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
Input/output streams with externally managed storage.
\*---------------------------------------------------------------------------*/
#ifndef UListStream_H
#define UListStream_H
#include "UIListStream.H"
#include "UOListStream.H"
#endif
// ************************************************************************* //

View File

@ -0,0 +1,326 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2022 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/>.
Class
Foam::UOListStream
Description
Similar to OStringStream but using an externally managed buffer for
its output.
This allows the output buffer to be reused and can make it easier when
writing out data. It is the user's responsibility to ensure proper
synchronization in the sizes. Provided that the external buffer is large
enough that overflow does not occur, the following usage pattern
works.
\code
DynamicList<char> buffer(4096); // allocate some large buffer
{
UOListStream os(buffer);
os << "content1" << " and more content";
buffer.resize(os.size()); // synchronize sizes
}
something.write(buffer, buffer.size());
\endcode
Although the UOListStream is quite lightweight, there may be cases
where it is preferable to reuse the stream as well.
\code
DynamicList<char> buffer(4096); // allocate some large buffer
UOListStream os(buffer);
os << "content1" << " and more content";
buffer.resize(os.size()); // synchronize sizes
something.write(buffer, buffer.size());
os.rewind();
os << "content2";
buffer.resize(os.size()); // synchronize sizes
something.write(buffer, buffer.size());
// or simply using the output size directly (without sync)
os.rewind();
os << "content3";
something.write(buffer, os.size());
\endcode
See Also
Foam::IListStream
Foam::OListStream
Foam::UIListStream
\*---------------------------------------------------------------------------*/
#ifndef Foam_UOListStream_H
#define Foam_UOListStream_H
#include "DynamicList.H"
#include "FixedList.H"
#include "OSstream.H"
#include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class Detail::UOListStreamAllocator Declaration
\*---------------------------------------------------------------------------*/
//- An stream/stream-buffer allocator for external buffers
class UOListStreamAllocator
{
protected:
// Protected Data
typedef std::ostream stream_type;
//- The stream buffer
memorybuf::out buf_;
//- The stream
stream_type stream_;
// Constructors
//- Construct for character array and number of bytes
UOListStreamAllocator(char* buffer, size_t nbytes)
:
buf_(buffer, nbytes),
stream_(&buf_)
{}
void printBufInfo(Ostream& os) const
{
buf_.printBufInfo(os);
}
public:
// Member Functions
//- Const UList access to the characters written (shallow copy).
inline const UList<char> list() const
{
return buf_.list();
}
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> list()
{
return buf_.list();
}
//- The current list output capacity
inline label capacity() const
{
return buf_.capacity();
}
//- The current output position in the buffer,
//- which is also the addressed list size
inline label size() const
{
return buf_.tellp();
}
//- Move to buffer start, clear errors
void rewind()
{
buf_.pubseekpos(0, std::ios_base::out);
stream_.clear(); // for safety, clear any old errors
}
};
} // End namespace Detail
/*---------------------------------------------------------------------------*\
Class UOListStream Declaration
\*---------------------------------------------------------------------------*/
//- An OSstream attached to an unallocated external buffer
class UOListStream
:
public Detail::UOListStreamAllocator,
public OSstream
{
typedef Detail::UOListStreamAllocator allocator_type;
public:
// Constructors
//- Construct using specified buffer and number of bytes
UOListStream
(
char* buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
allocator_type(buffer, nbytes),
OSstream(stream_, "output", streamOpt.format(), streamOpt.version())
{}
//- Construct using data area from a List and number of bytes
UOListStream
(
UList<char>& buffer,
size_t nbytes,
IOstreamOption streamOpt = IOstreamOption()
)
:
UOListStream(buffer.data(), nbytes, streamOpt)
{}
//- Construct using data area from a List and its inherent storage size
explicit UOListStream
(
UList<char>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
UOListStream(buffer.data(), buffer.size(), streamOpt)
{}
//- Construct using data area from a FixedList
template<unsigned N>
explicit UOListStream
(
FixedList<char, N>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
UOListStream(buffer.data(), N, streamOpt)
{}
//- Construct using data area from a DynamicList and its capacity
template<int SizeMin>
explicit UOListStream
(
DynamicList<char,SizeMin>& buffer,
IOstreamOption streamOpt = IOstreamOption()
)
:
UOListStream(buffer.data(), buffer.capacity(), streamOpt)
{}
// Member Functions
//- Rewind the stream, clearing any old errors
virtual void rewind()
{
allocator_type::rewind();
setGood(); // resynchronize with internal state
}
//- Print stream description to Ostream
virtual void print(Ostream& os) const;
// Additional constructors and methods (as per v2012 and earlier)
#ifdef Foam_IOstream_extras
//- Construct using specified buffer and number of bytes
UOListStream
(
char* buffer,
size_t nbytes,
IOstreamOption::streamFormat fmt
)
:
UOListStream(buffer, nbytes, IOstreamOption(fmt))
{}
//- Construct using data area from a List and number of bytes
UOListStream
(
UList<char>& buffer,
size_t nbytes,
IOstreamOption::streamFormat fmt
)
:
UOListStream(buffer.data(), nbytes, IOstreamOption(fmt))
{}
//- Construct using data area from a List and its inherent storage size
UOListStream
(
UList<char>& buffer,
IOstreamOption::streamFormat fmt
)
:
UOListStream(buffer.data(), buffer.size(), IOstreamOption(fmt))
{}
//- Construct using data area from a FixedList
template<unsigned N>
UOListStream
(
FixedList<char, N>& buffer,
IOstreamOption::streamFormat fmt
)
:
UOListStream(buffer.data(), N, IOstreamOption(fmt))
{}
//- Construct using data area from a DynamicList and its capacity
template<int SizeMin>
UOListStream
(
DynamicList<char,SizeMin>& buf,
IOstreamOption::streamFormat fmt
)
:
UOListStream(buf.data(), buf.capacity(), IOstreamOption(fmt))
{}
#endif /* Foam_IOstream_extras */
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,19 +28,16 @@ Class
Description
A std::streambuf used for memory buffer streams such as
ispanstream, ocharstream, etc.
UIListStream, UOListStream, etc.
\*---------------------------------------------------------------------------*/
#ifndef Foam_memoryStreamBuffer_H
#define Foam_memoryStreamBuffer_H
#include "stdFoam.H" // For span
#include "UList.H"
#include <memory>
#include <sstream> // Possibly want stringstream too...
#include <type_traits>
#include <sstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -51,7 +48,7 @@ namespace Foam
Class memorybuf Declaration
\*---------------------------------------------------------------------------*/
//- A streambuf for memory similar to std::spanbuf (C++23)
//- A streambuf for memory
class memorybuf
:
public std::streambuf
@ -109,11 +106,11 @@ protected:
if (testin)
{
return (gptr() - eback()); // span_tellg()
return (gptr() - eback()); // tellg()
}
if (testout)
{
return (pptr() - pbase()); // span_tellp()
return (pptr() - pbase()); // tellp()
}
return -1;
@ -130,322 +127,126 @@ protected:
return seekoff(pos, std::ios_base::beg, which);
}
//- \return the current buffer get position
inline std::streamsize tellg() const
{
return (gptr() - eback());
}
//- \return the current buffer put position
inline std::streamsize tellp() const
{
return (pptr() - pbase());
}
public:
// Forward Declarations
class in_base;
class in_dynamic;
class out_base;
class out_dynamic;
class in;
class out;
};
/*---------------------------------------------------------------------------*\
Class memorybuf::in_base Declaration
Class memorybuf::in Declaration
\*---------------------------------------------------------------------------*/
//- The base input streambuf with memory access
class memorybuf::in_base
//- An input streambuf for memory access
class memorybuf::in
:
public memorybuf
{
protected:
//- Get sequence of characters from a fixed region
//- Default construct
in() = default;
//- Get sequence of characters
virtual std::streamsize xsgetn(char* s, std::streamsize n)
{
std::streamsize count = 0;
while (count < n && gptr() < egptr())
{
*(s + count++) = *(gptr());
gbump(1);
}
return count;
}
public:
// Constructors
//- Construct for character array (can be nullptr) and number of bytes
in(char* s, std::streamsize n)
{
resetg(s, n);
}
//- Default construct
in_base() = default;
//- Construct for character array (can be nullptr) and number of bytes
in_base(char* s, std::streamsize n)
//- Reset for character array (can be nullptr) and number of bytes
// Sets get pointer to the begin.
inline void resetg(char* s, std::streamsize n)
{
if (s)
{
resetg(s, n);
setg(s, s, s + n);
}
// Member Functions
// //- Reset get buffer pointer to the beginning of existing span
// void rewind() { setg(eback(), eback(), egptr()); }
//- Reset get buffer with character data (can be nullptr) and count
// Sets get pointer to the begin.
void resetg(char* s, std::streamsize n)
else
{
if (s)
{
setg(s, s, s + n);
}
else
{
setg(nullptr, nullptr, nullptr);
}
setg(nullptr, nullptr, nullptr);
}
}
//- The current buffer get position
std::streamsize span_tellg() const { return (gptr() - eback()); }
//- The buffer get position
using memorybuf::tellg;
//- The get buffer capacity
std::streamsize span_capacity() const { return (egptr() - eback()); }
//- The buffer capacity
inline std::streamsize capacity() const
{
return (egptr() - eback());
}
//- The number of characters remaining in the get area
std::streamsize span_remaining() const
{
return (gptr() < egptr()) ? (egptr() - gptr()) : 0;
}
//- Const UList access to the input characters (shallow copy).
inline const UList<char> list() const
{
return UList<char>(eback(), (egptr() - eback()));
}
//- Span of the input characters (is modifiable!)
UList<char> span_list() const
{
return UList<char>(eback(), (egptr() - eback()));
}
//- Non-const UList access to the input characters (shallow copy).
inline UList<char> list()
{
return UList<char>(eback(), (egptr() - eback()));
}
// //- The span of input characters (is modifiable!)
// stdFoam::span<char> span() const
// {
// return stdFoam::span<char>(eback(), (egptr() - eback()));
// }
//- Some information about the input buffer position/capacity
void info(Ostream& os) const
{
os << "get=" << span_tellg() << '/' << span_capacity();
}
//- Some information about the input buffer position/capacity
inline void printBufInfo(Ostream& os) const
{
os << "get=" << (gptr() - eback()) // tellp()
<< "/" << (egptr() - eback()); // capacity
}
};
/*---------------------------------------------------------------------------*\
Class memorybuf::in_dynamic Declaration
Class memorybuf::out Declaration
\*---------------------------------------------------------------------------*/
//- An output streambuf for memory access
class memorybuf::in_dynamic
:
public memorybuf::in_base
{
private:
//- Character storage
List<char> storage_;
public:
// Constructors
//- Default construct - empty
in_dynamic() = default;
//- Copy construct from content
in_dynamic(const char* s, std::streamsize n)
{
if (s && n)
{
storage_.resize_nocopy(n);
std::copy(s, (s + n), storage_.data());
}
sync_gbuffer();
}
//- Move construct from List
in_dynamic(::Foam::List<char>&& buffer)
:
storage_(std::move(buffer))
{
sync_gbuffer();
}
//- Move construct from DynamicList (added length only)
template<int SizeMin>
in_dynamic(::Foam::DynamicList<char,SizeMin>&& buffer)
{
storage_.transfer(buffer);
sync_gbuffer();
}
// Member Functions
//- Sync get buffer pointers to agree with list dimensions
// Sets get pointer to the begin (rewind).
void sync_gbuffer()
{
resetg(storage_.data(), storage_.size());
}
//- Reset content (copy)
void reset(const char* s, std::streamsize n)
{
if (s && n)
{
storage_.resize_nocopy(n);
std::copy(s, (s + n), storage_.data());
}
else
{
storage_.clear();
}
sync_gbuffer();
}
//- Transfer list contents to List buffer
void swap(::Foam::List<char>& other)
{
storage_.swap(other); // Swap contents
sync_gbuffer();
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
void swap(DynamicList<char,SizeMin>& other)
{
List<char> tmp(std::move(storage_));
other.shrink(); // Use addressed length only
storage_.transfer(other);
other.transfer(tmp);
sync_gbuffer();
}
};
/*---------------------------------------------------------------------------*\
Class memorybuf::out_base Declaration
\*---------------------------------------------------------------------------*/
//- An output streambuf for memory access
class memorybuf::out_base
class memorybuf::out
:
public memorybuf
{
protected:
//- Put sequence of characters to a fixed region
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
std::streamsize count = 0;
while (count < n && pptr() < epptr())
{
*(pptr()) = *(s + count++);
pbump(1);
}
return count;
}
public:
// Constructors
//- Default construct
out_base() = default;
//- Construct for character array (can be nullptr) and number of bytes
out_base(char* s, std::streamsize n)
{
resetp(s, n);
}
// Member Functions
// //- Reset put buffer pointer to the beginning of existing span
// void rewind() { setp(pbase(), epptr()); }
//- Reset put buffer with character data (can be nullptr) and count
// Sets put pointer to the begin.
inline void resetp(char* s, std::streamsize n)
{
if (s)
{
// As per (std::ios_base::out && !std::ios_base::ate)
setp(s, s + n);
// No treatment for (std::ios_base::out && std::ios_base::ate)
}
else
{
setp(nullptr, nullptr);
}
}
//- The current buffer put position
std::streamsize span_tellp() const { return (pptr() - pbase()); }
//- The put buffer capacity
std::streamsize span_capacity() const { return (epptr() - pbase()); }
//- Span of the output characters (is modifiable!)
UList<char> span_list() const
{
return UList<char>(pbase(), (pptr() - pbase()));
}
//- The span of output characters (is modifiable!)
// stdFoam::span<char> span() const
// {
// return stdFoam::span<char>(pbase(), (pptr() - pbase()));
// }
//- Some information about the output buffer position/capacity
void info(Ostream& os) const
{
os << "put=" << span_tellp() << '/' << span_capacity();
}
};
/*---------------------------------------------------------------------------*\
Class memorybuf::out_dynamic Declaration
\*---------------------------------------------------------------------------*/
//- An output streambuf for memory access
class memorybuf::out_dynamic
:
public memorybuf::out_base
{
private:
//- Character storage.
// Internally manage like a DynamicList, with its capacity known
// from the list size and the addressable size known through the
// stream pointers.
List<char> storage_;
protected:
//- Handle overflow
virtual int overflow(int_type c = traits_type::eof())
{
if (c != traits_type::eof())
{
// Need more space?
reserve(1 + span_tellp());
*(pptr()) = c;
pbump(1);
}
return c;
}
//- Default construct
out() = default;
//- Put sequence of characters
virtual std::streamsize xsputn(const char* s, std::streamsize n)
{
// Enough space so that appends work without problem
reserve(n + span_tellp());
std::streamsize count = 0;
while (count < n && pptr() < epptr())
{
@ -459,111 +260,53 @@ protected:
public:
// Constructors
//- Construct for character array (can be nullptr) and number of bytes
out(char* s, std::streamsize n)
{
resetp(s, n);
}
//- 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)
:
storage_(label(nbytes))
//- Reset for character array (can be nullptr) and number of bytes.
// Sets put pointer to the begin.
inline void resetp(char* s, std::streamsize n)
{
if (s)
{
sync_pbuffer();
setp(s, s + n);
}
//- Move construct from List
out_dynamic(::Foam::List<char>&& buffer)
:
storage_(std::move(buffer))
else
{
sync_pbuffer();
setp(nullptr, nullptr);
}
}
//- Move construct from DynamicList (uses entire capacity)
template<int SizeMin>
out_dynamic(::Foam::DynamicList<char,SizeMin>&& buffer)
{
buffer.resize(buffer.capacity()); // Use entire space
storage_.transfer(buffer);
sync_pbuffer();
}
//- The buffer put position
using memorybuf::tellp;
//- The buffer capacity
inline std::streamsize capacity() const
{
return (epptr() - pbase());
}
// Member Functions
//- Const UList access to the characters written (shallow copy).
inline const UList<char> list() const
{
return UList<char>(pbase(), (pptr() - pbase()));
}
//- Increment capacity (if needed) and adjust buffer pointers
void reserve(const std::streamsize len)
{
if (storage_.size() < len)
{
const auto cur = span_tellp(); // Current location
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> list()
{
return UList<char>(pbase(), (pptr() - pbase()));
}
label newCapacity = 512;
if (newCapacity < len)
{
// Increase capacity (doubling)
newCapacity = max(len, label(2*storage_.size()));
}
// Info<<"request:" << len
// << " cur cap:" << storage_.size()
// << " new cap:" << newCapacity
// << " pos:" << cur << endl;
storage_.resize(newCapacity);
sync_pbuffer();
pbump(cur);
}
}
//- Sync put buffer pointers to agree with list dimensions
// Sets put pointer to the begin (rewind).
void sync_pbuffer()
{
resetp(storage_.data(), storage_.size());
}
//- Clear storage
void clearStorage()
{
storage_.clear();
sync_pbuffer();
}
//- Shrink storage to addressed storage
inline void shrink()
{
const auto cur = span_tellp(); // Addressed length
storage_.resize(cur);
sync_pbuffer();
pbump(cur);
}
//- Transfer list contents to List buffer
inline void swap(List<char>& other)
{
const auto cur = span_tellp(); // Addressed length
storage_.swap(other); // Swap contents
other.resize(cur); // Adjust to addressed length
sync_pbuffer();
}
//- Transfer list contents to a DynamicList buffer
template<int SizeMin>
inline void swap(DynamicList<char,SizeMin>& other)
{
const auto cur = span_tellp(); // Addressed length
List<char> tmp(std::move(storage_));
other.resize(other.capacity()); // Use entire space
storage_.transfer(other);
other.transfer(tmp);
other.resize(cur); // Adjust to addressed length
sync_pbuffer();
}
//- Some information about the output buffer position/capacity
inline void printBufInfo(Ostream& os) const
{
os << "put=" << (pptr() - pbase()) // tellp()
<< "/" << (epptr() - pbase()); // capacity
}
};

View File

@ -28,6 +28,7 @@ License
#include "dynamicCodeContext.H"
#include "stringOps.H"
#include "OSHA1stream.H"
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2014 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -37,24 +37,8 @@ Note
#include "StringStream.H"
#include "foamVersion.H"
#include "OSspecific.H"
#include "Enum.H"
#include "Switch.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::Enum
<
Foam::error::handlerTypes
>
Foam::error::handlerNames
({
{ handlerTypes::DEFAULT, "default" },
{ handlerTypes::IGNORE, "ignore" },
{ handlerTypes::WARN, "warn" },
{ handlerTypes::STRICT, "strict" },
});
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
bool Foam::error::master(const label communicator)

View File

@ -53,8 +53,8 @@ SeeAlso
\*---------------------------------------------------------------------------*/
#ifndef Foam_error_H
#define Foam_error_H
#ifndef error_H
#define error_H
#include "messageStream.H"
#include <memory>
@ -66,7 +66,6 @@ namespace Foam
// Forward Declarations
class OStringStream;
template<class EnumType> class Enum;
/*---------------------------------------------------------------------------*\
Class error Declaration
@ -102,21 +101,6 @@ protected:
public:
// Data Types
//- Handling of errors. The exact handling depends on the local context.
enum class handlerTypes : char
{
DEFAULT = 0, //!< Default behaviour (local meaning)
IGNORE, //!< Ignore on errors/problems
WARN, //!< Warn on errors/problems
STRICT //!< Fatal on errors/problems
};
//- Names of the error handler types
static const Enum<handlerTypes> handlerNames;
// Constructors
//- Construct from title string

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -44,7 +44,7 @@ License
/* * * * * * * * * * * * * * * Static Member Data * * * * * * * * * * * * * */
//- Max number of warnings (per functionObject)
static constexpr const unsigned maxWarnings = 10u;
static constexpr const uint32_t maxWarnings = 10u;
Foam::fileName Foam::functionObjectList::functionObjectDictPath
(
@ -52,6 +52,19 @@ Foam::fileName Foam::functionObjectList::functionObjectDictPath
);
const Foam::Enum
<
Foam::functionObjectList::errorHandlingType
>
Foam::functionObjectList::errorHandlingNames_
({
{ errorHandlingType::DEFAULT, "default" },
{ errorHandlingType::WARN, "warn" },
{ errorHandlingType::IGNORE, "ignore" },
{ errorHandlingType::STRICT, "strict" },
});
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
@ -337,12 +350,12 @@ bool Foam::functionObjectList::readFunctionObject
}
Foam::error::handlerTypes
Foam::functionObjectList::errorHandlingType
Foam::functionObjectList::getOrDefaultErrorHandling
(
const word& key,
const dictionary& dict,
const error::handlerTypes deflt
const errorHandlingType deflt
) const
{
const entry* eptr = dict.findEntry(key, keyType::LITERAL);
@ -359,16 +372,16 @@ Foam::functionObjectList::getOrDefaultErrorHandling
{
const word enumName(eptr->get<word>());
if (!error::handlerNames.found(enumName))
if (!errorHandlingNames_.found(enumName))
{
// Failed the name lookup
FatalIOErrorInFunction(dict)
<< enumName << " is not in enumeration: "
<< error::handlerNames << nl
<< errorHandlingNames_ << nl
<< exit(FatalIOError);
}
return error::handlerNames.get(enumName);
return errorHandlingNames_.get(enumName);
}
}
@ -627,15 +640,15 @@ bool Foam::functionObjectList::execute()
for (functionObject& funcObj : functions())
{
const auto errorHandling = *errIter;
const errorHandlingType errorHandling = *errIter;
++errIter;
const word& objName = funcObj.name();
if
(
errorHandling == error::handlerTypes::WARN
|| errorHandling == error::handlerTypes::IGNORE
errorHandling == errorHandlingType::WARN
|| errorHandling == errorHandlingType::IGNORE
)
{
// Throw FatalError, FatalIOError as exceptions
@ -659,12 +672,12 @@ bool Foam::functionObjectList::execute()
catch (const Foam::error& err)
{
// Treat IOerror and error identically
unsigned nWarnings;
uint32_t nWarnings;
hadError = true;
if
(
(errorHandling != error::handlerTypes::IGNORE)
errorHandling != errorHandlingType::IGNORE
&& (nWarnings = ++warnings_(objName)) <= maxWarnings
)
{
@ -705,11 +718,11 @@ bool Foam::functionObjectList::execute()
catch (const Foam::error& err)
{
// Treat IOerror and error identically
unsigned nWarnings;
uint32_t nWarnings;
if
(
(errorHandling != error::handlerTypes::IGNORE)
errorHandling != errorHandlingType::IGNORE
&& (nWarnings = ++warnings_(objName)) <= maxWarnings
)
{
@ -838,7 +851,7 @@ bool Foam::functionObjectList::end()
for (functionObject& funcObj : functions())
{
const auto errorHandling = *errIter;
const errorHandlingType errorHandling = *errIter;
++errIter;
const word& objName = funcObj.name();
@ -857,11 +870,11 @@ bool Foam::functionObjectList::end()
catch (const Foam::error& err)
{
// Treat IOerror and error identically
unsigned nWarnings;
uint32_t nWarnings;
if
(
(errorHandling != error::handlerTypes::IGNORE)
errorHandling != errorHandlingType::IGNORE
&& (nWarnings = ++warnings_(objName)) <= maxWarnings
)
{
@ -969,7 +982,7 @@ bool Foam::functionObjectList::read()
errorHandling_.resize
(
functionsDict.size(),
error::handlerTypes::DEFAULT
errorHandlingType::DEFAULT
);
HashTable<label> newIndices;
@ -985,12 +998,12 @@ bool Foam::functionObjectList::read()
);
// Top-level "errors" specification (optional)
const error::handlerTypes errorHandlingFallback =
const errorHandlingType errorHandlingFallback =
getOrDefaultErrorHandling
(
"errors",
functionsDict,
error::handlerTypes::DEFAULT
errorHandlingType::DEFAULT
);
label nFunc = 0;
@ -1032,7 +1045,7 @@ bool Foam::functionObjectList::read()
bool enabled = dict.getOrDefault("enabled", true);
// Per-function "errors" specification
const error::handlerTypes errorHandling =
const errorHandlingType errorHandling =
getOrDefaultErrorHandling
(
"errors",
@ -1122,16 +1135,16 @@ bool Foam::functionObjectList::read()
switch (errorHandling)
{
case error::handlerTypes::IGNORE:
case errorHandlingType::IGNORE:
break;
case error::handlerTypes::STRICT:
case errorHandlingType::STRICT:
{
exitNow(err);
break;
}
case error::handlerTypes::DEFAULT:
case errorHandlingType::DEFAULT:
{
if (isA<Foam::IOerror>(err))
{
@ -1144,7 +1157,7 @@ bool Foam::functionObjectList::read()
[[fallthrough]];
}
case error::handlerTypes::WARN:
case errorHandlingType::WARN:
{
// Trickery to get original message
err.write(Warning, false);

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2021 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -78,10 +78,11 @@ SourceFiles
\*---------------------------------------------------------------------------*/
#ifndef Foam_functionObjectList_H
#define Foam_functionObjectList_H
#ifndef functionObjectList_H
#define functionObjectList_H
#include "PtrList.H"
#include "Enum.H"
#include "functionObject.H"
#include "SHA1Digest.H"
#include "HashTable.H"
@ -107,10 +108,25 @@ class functionObjectList
:
private PtrList<functionObject>
{
// Data Types
//- Handling of construction or execution errors
enum class errorHandlingType : uint8_t
{
DEFAULT = 0, //!< Warn on construct, Fatal on runtime
WARN, //!< Warn on construct, Warn on runtime
IGNORE, //!< Ignore on construct, Ignore on runtime
STRICT, //!< Fatal on construct, Fatal on runtime
};
//- Names for error handling types
static const Enum<errorHandlingType> errorHandlingNames_;
// Private Data
//- A list of error/warning handling
List<error::handlerTypes> errorHandling_;
List<errorHandlingType> errorHandling_;
//- A list of SHA1 digests for the function object dictionaries
List<SHA1Digest> digests_;
@ -121,7 +137,7 @@ class functionObjectList
//- Track the number of warnings per function object and limit
// to a predefined number to avoid flooding the display.
// Clear on re-read of functions.
HashTable<unsigned> warnings_;
HashTable<uint32_t> warnings_;
//- Reference to Time
const Time& time_;
@ -171,11 +187,11 @@ class functionObjectList
//
// This additional treatment is to ensure that potentially existing
// code with an "errors" functionObject will continue to run.
error::handlerTypes getOrDefaultErrorHandling
errorHandlingType getOrDefaultErrorHandling
(
const word& key,
const dictionary& dict,
const error::handlerTypes deflt
const errorHandlingType deflt
) const;

View File

@ -27,6 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "argList.H"
#include "argListRedirect.H"
#include "OSspecific.H"
#include "Switch.H"
#include "clock.H"
@ -47,6 +48,7 @@ License
#include "stringListOps.H"
#include "fileOperation.H"
#include "fileOperationInitialise.H"
#include "fstreamPointer.H"
#include <cctype>
@ -911,7 +913,9 @@ Foam::argList::argList
runControl_(),
args_(argc),
options_(argc),
libs_()
libs_(),
stdout_(nullptr),
stderr_(nullptr)
{
// Pre-scan for some options needed for initial setup:
// -fileHandler (takes an argument)
@ -1018,6 +1022,53 @@ Foam::argList::argList
// ------------------------------------------------------------------------
// Capture stdout/stderr redirection names. Filters argv
Detail::redirectOutputs redirects(argc, argv);
// Perform output redirection
if (redirects.active())
{
word suffix;
if (redirects.ranks_ && parRunControl_.parRun())
{
suffix = Foam::name(Pstream::myProcNo());
}
if (!redirects.stdout_.empty())
{
fileName file(fileName::validate(redirects.stdout_));
file.ext(suffix);
stdout_.reset(ofstreamPointer(file).release());
}
if (!redirects.stderr_.empty())
{
fileName file(fileName::validate(redirects.stderr_));
file.ext(suffix);
stderr_.reset(ofstreamPointer(file).release());
}
if (stdout_)
{
Sout.attach(*stdout_);
Pout.attach(*stdout_);
}
if (stderr_)
{
Serr.attach(*stderr_);
Perr.attach(*stderr_);
}
else if (redirects.join_)
{
Serr.attach(Sout.stdStream());
Perr.attach(Sout.stdStream());
}
}
// Convert argv -> args_ and capture ( ... ) lists
regroupArgv(argc, argv);
@ -1172,6 +1223,8 @@ Foam::argList::argList
args_(args.args_),
options_(options),
libs_(),
stdout_(nullptr),
stderr_(nullptr),
executable_(args.executable_),
rootPath_(args.rootPath_),
globalCase_(args.globalCase_),

View File

@ -146,6 +146,12 @@ class argList
//- Additional libraries
mutable dlLibraryTable libs_;
//- File redirection for stdout (Sout, Pout)
std::unique_ptr<std::ostream> stdout_;
//- File redirection for stderr (Serr, Perr)
std::unique_ptr<std::ostream> stderr_;
word executable_;
fileName rootPath_;
fileName globalCase_;

View File

@ -425,6 +425,16 @@ void Foam::argList::printUsage(bool full) const
}
// Redirections
if (full)
{
printOption("stdout <file>", "Redirect stdout to file");
printOption("stderr <file>", "Redirect stderr to file");
printOption("join-stderr", "Join stderr to stdout");
printOption("append-rank", "Append stdout/stderr files with MPI-rank");
}
// Place documentation/help options at the end
printOption("doc", "Display documentation in browser");

View File

@ -0,0 +1,175 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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 "argListRedirect.H"
#include "IOstreams.H"
#include "boolList.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace
{
inline bool opt_join(const char* optName)
{
return strcmp(optName, "join-stderr") == 0;
}
inline bool opt_rank(const char* optName)
{
return strcmp(optName, "append-rank") == 0;
}
inline bool opt_stderr(const char* optName)
{
return strcmp(optName, "stderr") == 0;
}
inline bool opt_stdout(const char* optName)
{
return strcmp(optName, "stdout") == 0;
}
} // End anonymous namespace
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::Detail::redirectOutputs::redirectOutputs(int& argc, char**& argv)
:
stdout_(),
stderr_(),
join_(false),
ranks_(false)
{
List<bool> skip(label(argc), false);
bool filter = false;
for (int argi = 1; argi < argc-1; ++argi)
{
if (argv[argi][0] == '-')
{
const char *optName = &argv[argi][1];
if (opt_join(optName))
{
join_ = true;
filter = true;
skip[argi] = true;
}
else if (opt_rank(optName))
{
ranks_ = true;
filter = true;
skip[argi] = true;
}
else if (opt_stdout(optName))
{
stdout_ = argv[argi+1];
filter = true;
skip[argi] = true;
skip[argi+1] = true;
++argi;
}
else if (opt_stderr(optName))
{
stderr_ = argv[argi+1];
filter = true;
skip[argi] = true;
skip[argi+1] = true;
++argi;
}
}
}
// Test final arg separately
{
const int argi = argc-1;
if (argi > 0 && argv[argi][0] == '-')
{
const char *optName = &argv[argi][1];
if (opt_join(optName))
{
join_ = true;
filter = true;
skip[argi] = true;
}
else if (opt_rank(optName))
{
ranks_ = true;
filter = true;
skip[argi] = true;
}
}
}
if (filter)
{
int nArgs = 1;
for (int argi = 1; argi < argc; ++argi)
{
if (!skip[argi])
{
argv[nArgs] = argv[argi];
++nArgs;
}
}
argc = nArgs;
}
// Resolve potential conflicts
if (!stderr_.empty())
{
if (stdout_.empty())
{
join_ = false;
}
else if (stdout_ == stderr_)
{
join_ = true;
stderr_.clear();
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::Detail::redirectOutputs::active() const
{
return join_ || !stdout_.empty() || !stderr_.empty();
}
// ************************************************************************* //

View File

@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2020 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/>.
Class
Foam::Detail::redirectOutputs
Description
Helper class for redirecting outputs from within argList.
Handles the following options:
\verbatim
-stdout <file>
-stderr <file>
-join-stderr
-append-rank
\endverbatim
Note
Not intended for general use
SourceFiles
argListRedirect.C
\*---------------------------------------------------------------------------*/
#ifndef argListRedirect_H
#define argListRedirect_H
#include "string.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace Detail
{
/*---------------------------------------------------------------------------*\
Class redirectOutputs Declaration
\*---------------------------------------------------------------------------*/
struct redirectOutputs
{
string stdout_;
string stderr_;
bool join_;
bool ranks_;
redirectOutputs(int& argc, char**& argv);
bool active() const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Detail
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -73,11 +73,7 @@ static void broadcastFile_single
if (UPstream::master(comm))
{
// Read (see newIFstream)
auto fileLen = Foam::fileSize(srcName);
if (fileLen > 0)
{
lengthAndMode.first() = uint64_t(fileLen);
}
lengthAndMode.first() = Foam::fileSize(srcName);
lengthAndMode.second() = Foam::mode(srcName);
srcStream.reset

View File

@ -33,7 +33,7 @@ License
#include "Time.H"
#include "instant.H"
#include "IFstream.H"
#include "SpanStream.H"
#include "IListStream.H"
#include "masterOFstream.H"
#include "decomposedBlockData.H"
#include "registerSwitch.H"
@ -83,101 +83,6 @@ namespace fileOperations
}
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Get file contents (compressed or uncompressed)
static DynamicList<char> slurpFile(IFstream& ifs)
{
DynamicList<char> buffer;
auto& iss = ifs.stdStream();
const auto inputSize = ifs.fileSize();
if (IOstreamOption::COMPRESSED == ifs.compression())
{
// For compressed files, no idea how large the result will be.
// So read chunk-wise.
// Using the compressed size for the chunk size:
// 50% compression = 2 iterations
// 66% compression = 3 iterations
// ...
const uint64_t chunkSize =
(
(inputSize <= 1024)
? uint64_t(4096)
: uint64_t(2*inputSize)
);
uint64_t beg = 0;
for (int iter = 1; iter < 100000; ++iter)
{
// Manual resizing to use incremental vs doubling
buffer.setCapacity(label(iter * chunkSize));
buffer.resize(buffer.capacity());
ifs.readRaw(buffer.data() + beg, chunkSize);
const std::streamsize nread = iss.gcount();
if
(
nread < 0
|| nread == std::numeric_limits<std::streamsize>::max()
)
{
// Failed, but treat as normal 'done'
buffer.resize(label(beg));
break;
}
else
{
beg += uint64_t(nread);
if (nread >= 0 && uint64_t(nread) < chunkSize)
{
// normalExit = true;
buffer.resize(label(beg));
break;
}
}
}
}
else
{
if (inputSize >= 0)
{
buffer.setCapacity(label(inputSize));
buffer.resize(buffer.capacity());
ifs.readRaw(buffer.data(), buffer.size_bytes());
const std::streamsize nread = iss.gcount();
if
(
nread < 0
|| nread == std::numeric_limits<std::streamsize>::max()
)
{
// Failed, but treat as normal 'done'
buffer.clear();
}
else
{
buffer.resize(label(nread)); // Safety
}
}
}
return buffer;
}
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
Foam::word
@ -542,25 +447,56 @@ void Foam::fileOperations::masterUncollatedFileOperation::readAndSend
if (debug)
{
Info<< "masterUncollatedFileOperation::readAndSend :"
Pout<< "masterUncollatedFileOperation::readAndSend :"
<< " compressed:" << bool(ifs.compression()) << " "
<< filePath << endl;
}
// Read file contents (compressed or uncompressed) into a character buffer
DynamicList<char> buf(slurpFile(ifs));
for (const label proci : recvProcs)
if (ifs.compression() == IOstreamOption::COMPRESSED)
{
UOPstream os(proci, pBufs);
os.write(buf.cdata_bytes(), buf.size_bytes());
// Could use Foam::fileSize, estimate uncompressed size (eg, 2x)
// and then string reserve followed by string assign...
// Uncompress and read file contents into a character buffer
const std::string buf
(
std::istreambuf_iterator<char>(ifs.stdStream()),
std::istreambuf_iterator<char>()
);
for (const label proci : recvProcs)
{
UOPstream os(proci, pBufs);
os.write(buf.data(), buf.length());
}
if (debug)
{
Pout<< "masterUncollatedFileOperation::readStream :"
<< " From " << filePath << " sent " << buf.size()
<< " bytes" << endl;
}
}
if (debug)
else
{
Info<< "masterUncollatedFileOperation::readStream :"
<< " From " << filePath << " sent " << buf.size()
<< " bytes" << endl;
const off_t count(Foam::fileSize(filePath));
// Read file contents into a character buffer
List<char> buf(static_cast<label>(count));
ifs.stdStream().read(buf.data(), count);
for (const label proci : recvProcs)
{
UOPstream os(proci, pBufs);
os.write(buf.cdata(), count);
}
if (debug)
{
Pout<< "masterUncollatedFileOperation::readStream :"
<< " From " << filePath << " sent " << buf.size()
<< " bytes" << endl;
}
}
}
@ -694,7 +630,7 @@ Foam::fileOperations::masterUncollatedFileOperation::read
// Construct with same parameters (ASCII, current version)
// as the IFstream so that it has the same characteristics.
isPtr.reset(new ICharStream(std::move(buf)));
isPtr.reset(new IListStream(std::move(buf)));
// With the proper file name
isPtr->name() = filePaths[UPstream::myProcNo(comm)];
@ -2557,7 +2493,7 @@ Foam::fileOperations::masterUncollatedFileOperation::NewIFstream
// Construct with same parameters (ASCII, current version)
// as the IFstream so that it has the same characteristics.
isPtr.reset(new ICharStream(std::move(buf)));
isPtr.reset(new IListStream(std::move(buf)));
// With the proper file name
isPtr->name() = filePath;

View File

@ -148,13 +148,13 @@ void Foam::mapDistribute::printLayout(Ostream& os) const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistribute::mapDistribute() noexcept
Foam::mapDistribute::mapDistribute()
:
mapDistributeBase(UPstream::worldComm)
mapDistribute(UPstream::worldComm)
{}
Foam::mapDistribute::mapDistribute(const label comm) noexcept
Foam::mapDistribute::mapDistribute(const label comm)
:
mapDistributeBase(comm)
{}

View File

@ -328,10 +328,10 @@ public:
using mapDistributeBase::mapDistributeBase;
//- Default construct - uses worldComm
mapDistribute() noexcept;
mapDistribute();
//- Default construct with specified communicator
explicit mapDistribute(const label comm) noexcept;
explicit mapDistribute(const label comm);
//- Move construct from base, no transforms
explicit mapDistribute(mapDistributeBase&& map);

View File

@ -173,9 +173,9 @@ void Foam::mapDistributeBase::checkReceivedSize
if (receivedSize != expectedSize)
{
FatalErrorInFunction
<< "From processor " << proci
<< " : expected " << expectedSize
<< " but received " << receivedSize << " elements" << nl
<< "Expected from processor " << proci
<< " " << expectedSize << " but received "
<< receivedSize << " elements."
<< abort(FatalError);
}
}
@ -651,13 +651,13 @@ void Foam::mapDistributeBase::exchangeAddressing
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::mapDistributeBase::mapDistributeBase() noexcept
Foam::mapDistributeBase::mapDistributeBase()
:
mapDistributeBase(UPstream::worldComm)
{}
Foam::mapDistributeBase::mapDistributeBase(const label comm) noexcept
Foam::mapDistributeBase::mapDistributeBase(const label comm)
:
constructSize_(0),
subMap_(),
@ -1014,6 +1014,7 @@ Foam::labelList Foam::mapDistributeBase::subMapSizes() const
{
sizes[i] = subMap_[i].size();
}
return sizes;
}
@ -1025,32 +1026,11 @@ Foam::labelList Foam::mapDistributeBase::constructMapSizes() const
{
sizes[i] = constructMap_[i].size();
}
return sizes;
}
Foam::label Foam::mapDistributeBase::subMapTotalSize() const noexcept
{
label total = 0;
for (const auto& list : subMap_)
{
total += list.size();
}
return total;
}
Foam::label Foam::mapDistributeBase::constructMapTotalSize() const noexcept
{
label total = 0;
for (const auto& list : constructMap_)
{
total += list.size();
}
return total;
}
void Foam::mapDistributeBase::clear()
{
constructSize_ = 0;

View File

@ -147,7 +147,7 @@ protected:
// Protected Member Functions
//- Fatal if expected != received size
//- Fatal if expected and received size are not equal
static void checkReceivedSize
(
const label proci,
@ -229,39 +229,25 @@ protected:
);
//- Combine field values (after any flip negation operation)
//- into the specified mapped target locations
template<class T, class CombineOp, class NegateOp>
static void flipAndCombine
(
//! [in,out] The left of binary combine operation
List<T>& lhs,
//! The right of binary combine operation
const UList<T>& rhs,
//! The mapping indices
const labelUList& map,
//! Mapping indices include flip encoding
const bool hasFlip,
//! Binary combine operation
const UList<T>& rhs,
const CombineOp& cop,
//! Unary negation operation (for flipped indices)
const NegateOp& negOp
const NegateOp& negOp,
List<T>& lhs
);
//- Lookup field values at specified map indices and save
//- Lookup a field value at specified index and return its value
//- after any flip negation operations
template<class T, class NegateOp>
static void accessAndFlip
static T accessAndFlip
(
//! [out] The result values
List<T>& output,
//! [out] The input values
const UList<T>& values,
//! The mapping indices
const labelUList& map,
//! Mapping indices include flip encoding
const label index,
const bool hasFlip,
//! Unary negation operation (for flipped indices)
const NegateOp& negOp
);
@ -270,13 +256,9 @@ protected:
template<class T, class NegateOp>
static List<T> accessAndFlip
(
//! [out] The input values
const UList<T>& values,
//! The mapping indices
const labelUList& map,
//! Mapping indices include flip encoding
const labelUList& indices,
const bool hasFlip,
//! Unary negation operation (for flipped indices)
const NegateOp& negOp
);
@ -393,10 +375,10 @@ public:
// Constructors
//- Default construct (uses worldComm)
mapDistributeBase() noexcept;
mapDistributeBase();
//- Default construct with specified communicator
explicit mapDistributeBase(const label comm) noexcept;
explicit mapDistributeBase(const label comm);
//- Copy construct
mapDistributeBase(const mapDistributeBase& map);
@ -603,12 +585,6 @@ public:
//- The sizes of the constructMap lists
labelList constructMapSizes() const;
//- The sum of the subMap list sizes
label subMapTotalSize() const noexcept;
//- The sum of the constructMap list sizes
label constructMapTotalSize() const noexcept;
// Schedule
@ -831,52 +807,48 @@ public:
// Distribute
//- Distribute combine data with specified combine operation
//- and negate operator (for flips).
//
// If multiple processors write to same position,
// contributions are added using the combine cop.
//
// \note schedule only used for UPstream::commsTypes::scheduled,
// others just use send-to-all, receive-from-all.
template<class T, class CombineOp, class NegateOp>
static void distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
const labelListList& constructMap,
const bool constructHasFlip,
List<T>& field,
const T& nullValue,
const CombineOp& cop,
const NegateOp& negOp,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Distribute data with specified negate operator (for flips).
//
// \note schedule currently only used for
// Pstream::commsTypes::scheduled, all others just use
// send-to-all, receive-from-all.
template<class T, class NegateOp>
static void distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
const labelListList& constructMap,
const bool constructHasFlip,
List<T>& field,
const NegateOp& negOp,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Distribute assign data with specified negate operator (for flips).
//- Uses assignment for combine operation.
//
// \note schedule only used for UPstream::commsTypes::scheduled,
// others just use send-to-all, receive-from-all.
template<class T, class NegateOp>
static void distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
const labelListList& constructMap,
const bool constructHasFlip,
List<T>& field,
const NegateOp& negOp,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
//- Distribute data with specified combine operation
//
// If multiple processors writing to same
// position adds contributions using cop.
template<class T, class CombineOp, class NegateOp>
static void distribute
(
const UPstream::commsTypes commsType,
const List<labelPair>& schedule,
const label constructSize,
const labelListList& subMap,
const bool subHasFlip,
const labelListList& constructMap,
const bool constructHasFlip,
List<T>& field,
const T& nullValue,
const CombineOp& cop,
const NegateOp& negOp,
const int tag = UPstream::msgType(),
const label comm = UPstream::worldComm
);
// Distribute (simpler interface)
@ -1045,10 +1017,9 @@ public:
const labelListList& constructMap,
const bool constructHasFlip,
const UList<T>& field,
labelRange& sendRequests, //!< The send requests range
PtrList<List<T>>& sendFields, //!< The send fields storage
labelRange& recvRequests, //!< The recv requests range
PtrList<List<T>>& recvFields, //!< The recv fields storage
labelRange& requests,
PtrList<List<T>>& sendFields,
PtrList<List<T>>& recvFields,
const negateOp& negOp,
const int tag,
const label comm
@ -1059,22 +1030,22 @@ public:
void send
(
const UList<T>& field,
labelRange& sendRequests, //!< The send requests range
PtrList<List<T>>& sendFields, //!< The send fields storage
labelRange& recvRequests, //!< The recv requests range
PtrList<List<T>>& recvFields, //!< The recv fields storage
labelRange& requests,
PtrList<List<T>>& sendFields,
PtrList<List<T>>& recvFields,
const int tag = UPstream::msgType()
) const;
//- Wait for (receive) requests to finish and consume
//- Wait for requests to finish and consume
template<class T, class CombineOp, class negateOp>
static void receive
(
const label constructSize,
const labelListList& constructMap,
const bool constructHasFlip,
const labelRange& requests,
const UPtrList<List<T>>& sendFields,
const UPtrList<List<T>>& recvFields,
const labelRange& requests,
List<T>& field,
const CombineOp& cop,
const negateOp& negOp,
@ -1082,11 +1053,12 @@ public:
const label comm
);
//- Wait for (receive) requests to finish and consume
//- Wait for requests to finish and consume
template<class T>
void receive
(
const labelRange& requests,
const UPtrList<List<T>>& sendFields,
const UPtrList<List<T>>& recvFields,
List<T>& field,
const int tag = UPstream::msgType()

View File

@ -27,7 +27,7 @@ License
\*---------------------------------------------------------------------------*/
#include "labelRanges.H"
#include <numeric>
#include "ListOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -51,6 +51,7 @@ static Ostream& printRange(Ostream& os, const labelRange& range)
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::labelRanges::insertBefore
@ -59,7 +60,7 @@ void Foam::labelRanges::insertBefore
const labelRange& range
)
{
auto& list = ranges_;
auto& list = static_cast<StorageContainer&>(*this);
// Insert via copying up
label nElem = list.size();
@ -100,7 +101,7 @@ void Foam::labelRanges::insertBefore
void Foam::labelRanges::purgeEmpty()
{
auto& list = ranges_;
auto& list = static_cast<StorageContainer&>(*this);
// Purge empty ranges by copying down
label nElem = 0;
@ -134,18 +135,18 @@ Foam::labelRanges::labelRanges(Istream& is)
bool Foam::labelRanges::add(const labelRange& range)
{
auto& list = ranges_;
if (range.empty())
{
return false;
}
else if (list.empty())
else if (this->empty())
{
list.push_back(range);
this->push_back(range);
return true;
}
auto& list = static_cast<StorageContainer&>(*this);
// Find the correct place for insertion
forAll(list, elemi)
{
@ -157,7 +158,7 @@ bool Foam::labelRanges::add(const labelRange& range)
currRange.join(range);
// Might connect with the next following range(s)
for (; elemi < list.size()-1; ++elemi)
for (; elemi < this->size()-1; ++elemi)
{
labelRange& nextRange = list[elemi+1];
if (currRange.overlaps(nextRange, true))
@ -186,7 +187,7 @@ bool Foam::labelRanges::add(const labelRange& range)
// not found: simply append
list.push_back(range);
this->push_back(range);
return true;
}
@ -194,14 +195,14 @@ bool Foam::labelRanges::add(const labelRange& range)
bool Foam::labelRanges::remove(const labelRange& range)
{
auto& list = ranges_;
bool status = false;
if (range.empty() || list.empty())
if (range.empty() || this->empty())
{
return status;
}
auto& list = static_cast<StorageContainer&>(*this);
forAll(list, elemi)
{
labelRange& currRange = list[elemi];
@ -306,97 +307,19 @@ bool Foam::labelRanges::remove(const labelRange& range)
}
Foam::List<Foam::label> Foam::labelRanges::labels() const
{
label total = 0;
for (const labelRange& range : ranges_)
{
if (range.size() > 0) // Ignore negative size (paranoid)
{
total += range.size();
}
}
if (!total)
{
// Skip this check?
return List<label>();
}
List<label> result(total);
auto* iter = result.begin();
for (const labelRange& range : ranges_)
{
const label len = range.size();
if (len > 0) // Ignore negative size (paranoid)
{
std::iota(iter, (iter + len), range.start());
iter += len;
}
}
return result;
}
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
Foam::label Foam::labelRanges::operator[](const label i) const
{
if (i < 0) return -1;
label subIdx = i;
for (const labelRange& range : ranges_)
{
if (subIdx < range.size())
{
return (range.start() + subIdx);
}
else
{
subIdx -= range.size();
}
}
return -1; // Not found
}
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
Foam::Istream& Foam::labelRanges::readList(Istream& is)
Foam::Istream& Foam::operator>>(Istream& is, labelRanges& ranges)
{
return ranges_.readList(is);
is >> static_cast<labelRanges::StorageContainer&>(ranges);
return is;
}
Foam::Ostream& Foam::labelRanges::writeList
(
Ostream& os,
const label shortLen
) const
Foam::Ostream& Foam::operator<<(Ostream& os, const labelRanges& ranges)
{
return ranges_.writeList(os, shortLen);
}
Foam::Istream& Foam::operator>>(Istream& is, labelRanges& list)
{
return list.readList(is);
}
Foam::Ostream& Foam::operator<<(Ostream& os, const labelRanges& list)
{
return list.writeList
(
os,
Detail::ListPolicy::short_length<labelRange>::value
);
os << static_cast<const labelRanges::StorageContainer&>(ranges);
return os;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,10 +28,9 @@ Class
Foam::labelRanges
Description
A list of labelRange with constrained list capabilities.
A list of labelRange.
SourceFiles
labelRangesI.H
labelRanges.C
\*---------------------------------------------------------------------------*/
@ -57,11 +56,12 @@ Ostream& operator<<(Ostream& is, const labelRanges& ranges);
\*---------------------------------------------------------------------------*/
class labelRanges
:
private Foam::DynamicList<Foam::labelRange>
{
// Private Data
// Private Typedefs
//- The list of ranges
DynamicList<labelRange> ranges_;
typedef Foam::DynamicList<Foam::labelRange> StorageContainer;
// Private Member Functions
@ -76,69 +76,35 @@ public:
// STL type definitions
//- The value type the list contains
typedef labelRange value_type;
//- Input iterator with const access
class const_iterator;
// Generated Methods
// Constructors
//- Default construct
labelRanges() = default;
//- Default copy construct
labelRanges(const labelRanges&) = default;
//- Default move construct
labelRanges(labelRanges&&) = default;
//- Default copy assignment
labelRanges& operator=(const labelRanges&) = default;
//- Default move assignment
labelRanges& operator=(labelRanges&&) = default;
// Constructors
//- Construct an empty list with given initial capacity
inline explicit labelRanges(const label initialCapacity);
//- Copy construct from list of ranges
inline explicit labelRanges(const UList<labelRange>& list);
//- Move construct from list of ranges
inline labelRanges(List<labelRange>&& list);
//- Move construct from list of ranges
template<int AnySizeMin>
inline labelRanges(DynamicList<labelRange, AnySizeMin>&& list);
//- Construct given size
inline explicit labelRanges(const label nElem);
//- Construct from Istream.
explicit labelRanges(Istream& is);
labelRanges(Istream& is);
// Member Functions
//- The list of ranges
const UList<labelRange>& ranges() const noexcept { return ranges_; }
//- Clear the addressed list
using DynamicList<labelRange>::clear;
//- Clear the addressable list of ranges
void clear() noexcept { ranges_.clear(); }
//- True if list of ranges is empty
bool empty() const noexcept { return ranges_.empty(); }
//- Reserve space for at least this size
void reserve(const label len) { ranges_.reserve(len); }
//- The linear size (sum of all the element sizes)
inline label totalSize() const noexcept;
//- Return true if the list is empty
using DynamicList<labelRange>::empty;
//- True if the value is contained within any of the sub-ranges
inline bool contains(const label value) const noexcept;
inline bool contains(const label value) const;
//- True if the value is contained within any of the sub-ranges
bool found(const label value) const { return contains(value); }
//- Add the range to the list
bool add(const labelRange& range);
@ -146,31 +112,14 @@ public:
//- Remove the range from the list
bool remove(const labelRange& range);
//- Construct a range element at the end of the list,
//- return reference to the new element.
template<class... Args>
inline labelRange& emplace_back(Args&&... args);
//- Inplace sort of the range elements
inline void sort();
//- Return flattened list of all range labels
List<label> labels() const;
// Member Operators
//- Return the value at linear index 'i', -1 for out-of-range
label operator[](const label i) const;
// STL iterator
//- Forward input iterator with const access
class const_iterator
{
//- The list of ranges for which this is an iterator
const UList<labelRange>* list_;
//- The list for which this is an iterator
const labelRanges* list_;
//- The index into the list
label index_;
@ -182,12 +131,11 @@ public:
// Constructors
//- Construct from range list at given index (and sub-index)
//- Construct from range list at given index
inline explicit constexpr const_iterator
(
const UList<labelRange>* list,
const label idx = 0,
const label subIdx = 0
const labelRanges* list,
const label i = 0
) noexcept;
@ -220,39 +168,10 @@ public:
inline const const_iterator end() const noexcept;
//- Return const_iterator at linear offset i from begin,
//- clamped to [0,size] range
inline const_iterator cbegin(const label i) const;
//- Return const_iterator at linear offset i from begin,
//- clamped to [0,size] range
inline const_iterator begin(const label i) const;
// Reading/writing
//- Read List of labelRange from Istream, discarding contents
Istream& readList(Istream& is);
//- Write List of labelRange, with line-breaks in ASCII
//- when length exceeds shortLen.
// Using '0' suppresses line-breaks entirely.
Ostream& writeList(Ostream& os, const label shortLen=0) const;
// IOstream Operators
//- Use the readList() method to read contents from Istream.
friend Istream& operator>>(Istream& is, labelRanges& list);
//- Write to Ostream. Uses the writeList() method
friend Ostream& operator<<(Ostream& os, const labelRanges& list);
// Housekeeping
//- Same as contains()
bool found(const label value) const { return contains(value); }
friend Istream& operator>>(Istream& is, labelRanges& ranges);
friend Ostream& operator<<(Ostream& os, const labelRanges& ranges);
};

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2017-2023 OpenCFD Ltd.
Copyright (C) 2017-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -28,31 +28,9 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::labelRanges::labelRanges(const label initialCapacity)
inline Foam::labelRanges::labelRanges(const label nElem)
:
ranges_(initialCapacity)
{}
inline Foam::labelRanges::labelRanges(const UList<labelRange>& list)
:
ranges_(list)
{}
inline Foam::labelRanges::labelRanges(List<labelRange>&& list)
:
ranges_(std::move(list))
{}
template<int AnySizeMin>
inline Foam::labelRanges::labelRanges
(
DynamicList<labelRange, AnySizeMin>&& list
)
:
ranges_(std::move(list))
DynamicList<labelRange>(nElem)
{}
@ -61,14 +39,13 @@ inline Foam::labelRanges::labelRanges
inline constexpr Foam::labelRanges::const_iterator::
const_iterator
(
const UList<labelRange>* list,
const label idx,
const label subIdx
const labelRanges* list,
const label i
) noexcept
:
list_(list),
index_(idx),
subIndex_(subIdx)
index_(i),
subIndex_(0)
{}
@ -83,7 +60,6 @@ inline Foam::labelRanges::const_iterator&
Foam::labelRanges::const_iterator::
operator++()
{
// TBD: trap (index_ >= list_->size()) and make a no-op?
if (++subIndex_ >= (*list_)[index_].size())
{
// Move to the next range
@ -133,23 +109,41 @@ operator!=
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
inline Foam::label Foam::labelRanges::totalSize() const noexcept
inline Foam::labelRanges::const_iterator
Foam::labelRanges::cbegin() const noexcept
{
label total = 0;
for (const labelRange& range : ranges_)
{
if (range.size() > 0) // Ignore negative size (paranoid)
{
total += range.size();
}
}
return total;
return const_iterator(this);
}
inline bool Foam::labelRanges::contains(const label value) const noexcept
inline const Foam::labelRanges::const_iterator
Foam::labelRanges::cend() const noexcept
{
for (const labelRange& range : ranges_)
return const_iterator(this, this->size());
}
inline Foam::labelRanges::const_iterator
Foam::labelRanges::begin() const noexcept
{
return const_iterator(this);
}
inline const Foam::labelRanges::const_iterator
Foam::labelRanges::end() const noexcept
{
return const_iterator(this, this->size());
}
inline bool Foam::labelRanges::contains(const label value) const
{
for
(
const labelRange& range
: static_cast<const StorageContainer&>(*this)
)
{
if (range.contains(value))
{
@ -161,82 +155,4 @@ inline bool Foam::labelRanges::contains(const label value) const noexcept
}
template<class... Args>
inline Foam::labelRange& Foam::labelRanges::emplace_back(Args&&... args)
{
return ranges_.emplace_back(args...);
}
inline void Foam::labelRanges::sort()
{
Foam::sort(ranges_);
}
// * * * * * * * * * * * * * * * * Iterators * * * * * * * * * * * * * * * * //
inline Foam::labelRanges::const_iterator
Foam::labelRanges::cbegin() const noexcept
{
return const_iterator(&ranges_);
}
inline const Foam::labelRanges::const_iterator
Foam::labelRanges::cend() const noexcept
{
return const_iterator(&ranges_, ranges_.size());
}
inline Foam::labelRanges::const_iterator
Foam::labelRanges::begin() const noexcept
{
return const_iterator(&ranges_);
}
inline const Foam::labelRanges::const_iterator
Foam::labelRanges::end() const noexcept
{
return const_iterator(&ranges_, ranges_.size());
}
inline Foam::labelRanges::const_iterator
Foam::labelRanges::cbegin(const label i) const
{
if (i <= 0) return this->cbegin();
label idx = 0;
label subIdx = i;
for (const labelRange& range : ranges_)
{
if (subIdx < range.size())
{
return const_iterator(&ranges_, idx, subIdx);
}
else
{
++idx;
if (range.size() > 0) // Ignore negative size (paranoid)
{
subIdx -= range.size();
}
}
}
return this->cend();
}
inline Foam::labelRanges::const_iterator
Foam::labelRanges::begin(const label i) const
{
return this->cbegin(i);
}
// ************************************************************************* //

View File

@ -29,7 +29,7 @@ License
#include "IFstream.H"
#include "ListOps.H"
#include "stringOps.H"
#include "SpanStream.H"
#include "UIListStream.H"
#include "cellModel.H"
#include <cctype>
@ -328,15 +328,15 @@ Foam::fileFormats::ABAQUSCore::readHelper::readPoints
// Read nodes (points) until next "*Section"
while (is.peek() != '*' && is.peek() != EOF)
{
// Grab the line and wrap as spanstream
// Grab the line and wrap as string-stream
is.getLine(line);
UIListStream ss(line.data(), line.length());
if (line.empty())
{
// Not sure if we should terminate on blank lines?
continue;
}
ISpanStream ss(line);
// Parse line for ID, X, Y, Z
ss >> id >> sep >> p.x() >> sep >> p.y() >> sep >> p.z();

View File

@ -50,10 +50,12 @@ Foam::ensightReadFile::detectBinaryHeader(const fileName& pathname)
// Binary string is *exactly* 80 characters
string buf(size_t(80), '\0');
iss.read(&buf[0], 80);
const std::streamsize gcount = iss.gcount();
buf.erase(gcount <= 0 ? 0 : gcount); // Truncated?
// Could exit on truncated input, but no real advantage
if (!iss)
{
// Truncated?
buf.erase(iss.gcount());
}
// Truncate at the first embedded '\0'
const auto endp = buf.find('\0');
@ -117,13 +119,15 @@ Foam::Istream& Foam::ensightReadFile::read(string& value)
// Binary string is *exactly* 80 characters
value.resize(80, '\0');
iss.read(&value[0], 80);
const std::streamsize gcount = iss.gcount();
value.erase(gcount <= 0 ? 0 : gcount); // Truncated?
// Could exit on truncated input, but no real advantage
syncState();
if (!iss)
{
// Truncated - could also exit here, but no real advantage
value.erase(iss.gcount());
}
// Truncate at the first embedded '\0'
auto endp = value.find('\0');

View File

@ -112,8 +112,8 @@ public:
// Constructors
//- Construct with the estimated number of triangles in the STL
inline STLAsciiParse(const label nTrisEstimated);
//- From input stream and the approximate number of vertices in the STL
inline STLAsciiParse(const label approxNpoints);
// Member Functions

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2016-2023 OpenCFD Ltd.
Copyright (C) 2016-2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -89,10 +89,10 @@ public:
// Constructors
//- From input stream, with the estimated number of triangles in the STL
STLAsciiParseFlex(istream* is, const label nTrisEstimated)
//- From input stream and the approximate number of vertices in the STL
STLAsciiParseFlex(istream* is, const label approxNpoints)
:
Detail::STLAsciiParse(nTrisEstimated),
Detail::STLAsciiParse(approxNpoints),
yySTLFlexLexer(is)
{}
@ -306,8 +306,9 @@ endsolid {space}("endsolid"|"ENDSOLID")({some_space}{word})*
%%
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
//
// Member Function
//
bool Foam::fileFormats::STLReader::readAsciiFlex
(
const fileName& filename
@ -321,20 +322,8 @@ bool Foam::fileFormats::STLReader::readAsciiFlex
<< exit(FatalError);
}
// Create with estimated number of triangles in the STL.
// 180 bytes / triangle. For simplicity, ignore compression
const auto fileLen = is.fileSize();
const label nTrisEstimated =
(
(fileLen > 0)
? max(label(100), label(fileLen/180))
: label(100)
);
STLAsciiParseFlex lexer(&(is.stdStream()), nTrisEstimated);
// Create with approx number of vertices in the STL (from file size)
STLAsciiParseFlex lexer(&(is.stdStream()), Foam::fileSize(filename)/400);
lexer.execute();
transfer(lexer);
@ -342,5 +331,6 @@ bool Foam::fileFormats::STLReader::readAsciiFlex
return true;
}
// ************************************************************************* //
/* ------------------------------------------------------------------------ *\
------ End of STLReaderASCII.L
\* ------------------------------------------------------------------------ */

View File

@ -131,15 +131,15 @@ inline void Foam::Detail::STLAsciiParse::endFacet()
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
inline Foam::Detail::STLAsciiParse::STLAsciiParse(const label nTrisEstimated)
inline Foam::Detail::STLAsciiParse::STLAsciiParse(const label approxNpoints)
:
sorted_(true),
groupId_(-1),
lineNum_(1),
nFacetPoints_(0),
nVertexCmpt_(0),
points_(3*nTrisEstimated),
facets_(nTrisEstimated)
points_(approxNpoints),
facets_(approxNpoints/2)
{}

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -30,6 +30,7 @@ Description
#include "STLAsciiParse.H"
#include "STLReader.H"
#include "OSspecific.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
@ -126,10 +127,10 @@ class STLAsciiParseManual
public:
//- Construct with the estimated number of triangles in the STL
STLAsciiParseManual(const label nTrisEstimated)
//- From input stream and the approximate number of vertices in the STL
STLAsciiParseManual(const label approxNpoints)
:
Detail::STLAsciiParse(nTrisEstimated)
Detail::STLAsciiParse(approxNpoints)
{}
//- Execute parser
@ -178,7 +179,7 @@ void Foam::Detail::STLAsciiParseManual::execute(std::istream& is)
is.read(data, buflen);
const std::streamsize gcount = is.gcount();
if (gcount <= 0)
if (!gcount)
{
// EOF
// If scanning for next "solid" this is a valid way to exit, but
@ -397,8 +398,11 @@ void Foam::Detail::STLAsciiParseManual::execute(std::istream& is)
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// Member Function
//
bool Foam::fileFormats::STLReader::readAsciiManual
(
const fileName& filename
@ -412,20 +416,8 @@ bool Foam::fileFormats::STLReader::readAsciiManual
<< exit(FatalError);
}
// Create with estimated number of triangles in the STL.
// 180 bytes / triangle. For simplicity, ignore compression
const auto fileLen = is.fileSize();
const label nTrisEstimated =
(
(fileLen > 0)
? max(label(100), label(fileLen/180))
: label(100)
);
Detail::STLAsciiParseManual lexer(nTrisEstimated);
// Create with the approximate number of vertices in the STL from file size
Detail::STLAsciiParseManual lexer(Foam::fileSize(filename)/400);
lexer.execute(is.stdStream());
transfer(lexer);

View File

@ -7,7 +7,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -35,6 +35,7 @@ Description
#include "STLAsciiParse.H"
#include "STLReader.H"
#include "OSspecific.H"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wunused-const-variable"
@ -68,7 +69,6 @@ Description
// - Only look for initial 'facet '. Ignore 'normal ...'
// - Ignore name for 'endsolid'
//
// ------------------------------------------------------------------------- //
// Ragel machine definition
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
@ -121,10 +121,10 @@ class STLAsciiParseRagel
public:
//- From input stream, with the estimated number of triangles in the STL
STLAsciiParseRagel(const label nTrisEstimated)
//- From input stream and the approximate number of vertices in the STL
STLAsciiParseRagel(const label approxNpoints)
:
Detail::STLAsciiParse(nTrisEstimated)
Detail::STLAsciiParse(approxNpoints)
{}
//- Execute lexer
@ -184,7 +184,7 @@ void Foam::Detail::STLAsciiParseRagel::execute(std::istream& is)
is.read(data, buflen);
const std::streamsize gcount = is.gcount();
if (gcount <= 0)
if (!gcount)
{
break;
}
@ -2970,7 +2970,9 @@ void Foam::Detail::STLAsciiParseRagel::die
const char *pe
) const
{
FatalErrorInFunction
auto error = FatalErrorInFunction;
error
<< nl
<< "Parsing error at or near line " << lineNum_
<<", while parsing for " << what << nl
@ -2982,19 +2984,22 @@ void Foam::Detail::STLAsciiParseRagel::die
for (unsigned i=0; i < 80; ++i)
{
if (*parsing == '\n' || parsing == pe) break;
FatalError << *parsing;
error << *parsing;
++parsing;
}
}
FatalError
error
<< "'\n"
<< exit(FatalError);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// Member Function
//
bool Foam::fileFormats::STLReader::readAsciiRagel
(
const fileName& filename
@ -3008,20 +3013,8 @@ bool Foam::fileFormats::STLReader::readAsciiRagel
<< exit(FatalError);
}
// Create with estimated number of triangles in the STL.
// 180 bytes / triangle. For simplicity, ignore compression
const auto fileLen = is.fileSize();
const label nTrisEstimated =
(
(fileLen > 0)
? max(label(100), label(fileLen/180))
: label(100)
);
Detail::STLAsciiParseRagel lexer(nTrisEstimated);
// Create with approx number of vertices in the STL (from file size)
Detail::STLAsciiParseRagel lexer(Foam::fileSize(filename)/400);
lexer.execute(is.stdStream());
transfer(lexer);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,6 +33,7 @@ Description
#include "STLAsciiParse.H"
#include "STLReader.H"
#include "OSspecific.H"
#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
#pragma GCC diagnostic ignored "-Wunused-const-variable"
@ -66,7 +67,6 @@ Description
// - Only look for initial 'facet '. Ignore 'normal ...'
// - Ignore name for 'endsolid'
//
// ------------------------------------------------------------------------- //
// Ragel machine definition
// Ragel variables (p, pe, eof, cs, top, stack, ts, te, act) defined later...
@ -176,10 +176,10 @@ class STLAsciiParseRagel
public:
//- From input stream, with the estimated number of triangles in the STL
STLAsciiParseRagel(const label nTrisEstimated)
//- From input stream and the approximate number of vertices in the STL
STLAsciiParseRagel(const label approxNpoints)
:
Detail::STLAsciiParse(nTrisEstimated)
Detail::STLAsciiParse(approxNpoints)
{}
//- Execute lexer
@ -232,7 +232,7 @@ void Foam::Detail::STLAsciiParseRagel::execute(std::istream& is)
is.read(data, buflen);
const std::streamsize gcount = is.gcount();
if (gcount <= 0)
if (!gcount)
{
break;
}
@ -303,7 +303,9 @@ void Foam::Detail::STLAsciiParseRagel::die
const char *pe
) const
{
FatalErrorInFunction
auto error = FatalErrorInFunction;
error
<< nl
<< "Parsing error at or near line " << lineNum_
<<", while parsing for " << what << nl
@ -315,19 +317,22 @@ void Foam::Detail::STLAsciiParseRagel::die
for (unsigned i=0; i < 80; ++i)
{
if (*parsing == '\n' || parsing == pe) break;
FatalError << *parsing;
error << *parsing;
++parsing;
}
}
FatalError
error
<< "'\n"
<< exit(FatalError);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//
// Member Function
//
bool Foam::fileFormats::STLReader::readAsciiRagel
(
const fileName& filename
@ -341,20 +346,8 @@ bool Foam::fileFormats::STLReader::readAsciiRagel
<< exit(FatalError);
}
// Create with estimated number of triangles in the STL.
// 180 bytes / triangle. For simplicity, ignore compression
const auto fileLen = is.fileSize();
const label nTrisEstimated =
(
(fileLen > 0)
? max(label(100), label(fileLen/180))
: label(100)
);
Detail::STLAsciiParseRagel lexer(nTrisEstimated);
// Create with approx number of vertices in the STL (from file size)
Detail::STLAsciiParseRagel lexer(Foam::fileSize(filename)/400);
lexer.execute(is.stdStream());
transfer(lexer);

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2023 OpenCFD Ltd.
Copyright (C) 2018-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -645,8 +645,7 @@ Foam::label Foam::vtk::seriesWriter::scan
header.resize(1024);
is.read(&(header.front()), header.size());
const std::streamsize gcount = is.gcount();
header.erase(gcount <= 0 ? 0 : gcount);
header.resize(is.gcount());
// DebugInfo
// << "got header:\n=====\n" << header << "\n=====\n" << nl;

View File

@ -26,11 +26,9 @@ License
\*---------------------------------------------------------------------------*/
#include "cyclicAMIPolyPatch.H"
#include "mapDistributeBase.H"
#include "AMIInterpolation.H"
#include "fvMatrix.H"
#include "volFields.H"
//#include "cylicFvPatchField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -43,10 +41,7 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
:
cyclicAMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p)),
sendRequests_(0),
recvRequests_(0),
patchNeighbourFieldPtr_(nullptr)
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{}
@ -60,15 +55,12 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
:
cyclicAMILduInterfaceField(),
coupledFvPatchField<Type>(p, iF, dict, IOobjectOption::NO_READ),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p, dict)),
sendRequests_(0),
recvRequests_(0),
patchNeighbourFieldPtr_(nullptr)
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p, dict))
{
if (!isA<cyclicAMIFvPatch>(p))
{
FatalIOErrorInFunction(dict)
<< "\n patch type '" << p.type()
<< " patch type '" << p.type()
<< "' not constraint type '" << typeName << "'"
<< "\n for patch " << p.name()
<< " of field " << this->internalField().name()
@ -76,24 +68,12 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
<< exit(FatalIOError);
}
// Handle neighbour value first, before any evaluate()
const auto* hasNeighbValue =
dict.findEntry("neighbourValue", keyType::LITERAL);
if (hasNeighbValue)
{
patchNeighbourFieldPtr_.reset
(
new Field<Type>(*hasNeighbValue, p.size())
);
}
// Use 'value' supplied, or evaluate (if coupled) or set to internal field
// Use 'value' supplied, or set to coupled or internal field
if (!this->readValueEntry(dict))
{
if (this->coupled())
{
this->evaluate(UPstream::commsTypes::nonBlocking);
this->evaluate(Pstream::commsTypes::blocking);
}
else
{
@ -114,19 +94,8 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
:
cyclicAMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, p, iF, mapper),
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p)),
sendRequests_(0),
recvRequests_(0),
patchNeighbourFieldPtr_(nullptr)
cyclicAMIPatch_(refCast<const cyclicAMIFvPatch>(p))
{
if (ptf.patchNeighbourFieldPtr_)
{
patchNeighbourFieldPtr_.reset
(
new Field<Type>(ptf.patchNeighbourFieldPtr_(), mapper)
);
}
if (!isA<cyclicAMIFvPatch>(this->patch()))
{
FatalErrorInFunction
@ -137,12 +106,6 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
<< " in file " << this->internalField().objectPath()
<< exit(FatalError);
}
if (debug && !ptf.all_ready())
{
FatalErrorInFunction
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
<< abort(FatalError);
}
}
@ -154,18 +117,8 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
:
cyclicAMILduInterfaceField(),
coupledFvPatchField<Type>(ptf),
cyclicAMIPatch_(ptf.cyclicAMIPatch_),
sendRequests_(0),
recvRequests_(0),
patchNeighbourFieldPtr_(ptf.patchNeighbourFieldPtr_.clone())
{
if (debug && !ptf.all_ready())
{
FatalErrorInFunction
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
<< abort(FatalError);
}
}
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
{}
template<class Type>
@ -177,118 +130,16 @@ Foam::cyclicAMIFvPatchField<Type>::cyclicAMIFvPatchField
:
cyclicAMILduInterfaceField(),
coupledFvPatchField<Type>(ptf, iF),
cyclicAMIPatch_(ptf.cyclicAMIPatch_),
sendRequests_(0),
recvRequests_(0),
patchNeighbourFieldPtr_(ptf.patchNeighbourFieldPtr_.clone())
{
if (debug && !ptf.all_ready())
{
FatalErrorInFunction
<< "Outstanding request(s) on patch " << cyclicAMIPatch_.name()
<< abort(FatalError);
}
}
cyclicAMIPatch_(ptf.cyclicAMIPatch_)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::cyclicAMIFvPatchField<Type>::all_ready() const
bool Foam::cyclicAMIFvPatchField<Type>::coupled() const
{
int done = 0;
if
(
UPstream::finishedRequests
(
recvRequests_.start(),
recvRequests_.size()
)
)
{
recvRequests_.clear();
++done;
}
if
(
UPstream::finishedRequests
(
sendRequests_.start(),
sendRequests_.size()
)
)
{
sendRequests_.clear();
++done;
}
return (done == 2);
}
template<class Type>
bool Foam::cyclicAMIFvPatchField<Type>::ready() const
{
if
(
UPstream::finishedRequests
(
recvRequests_.start(),
recvRequests_.size()
)
)
{
recvRequests_.clear();
if
(
UPstream::finishedRequests
(
sendRequests_.start(),
sendRequests_.size()
)
)
{
sendRequests_.clear();
}
return true;
}
return false;
}
template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField
(
const Field<Type>& iField
) const
{
// Bypass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
// neighbPatch()
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
const labelUList& nbrFaceCells = neighbPatch.faceCells();
Field<Type> pnf(iField, nbrFaceCells);
Field<Type> defaultValues;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
defaultValues = Field<Type>(iField, cyclicAMIPatch_.faceCells());
}
tmp<Field<Type>> tpnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
if (doTransform())
{
transform(tpnf.ref(), forwardT(), tpnf());
}
return tpnf;
return cyclicAMIPatch_.coupled();
}
@ -296,33 +147,33 @@ template<class Type>
Foam::tmp<Foam::Field<Type>>
Foam::cyclicAMIFvPatchField<Type>::patchNeighbourField() const
{
if (this->ownerAMI().distributed())
{
if (!this->ready())
{
FatalErrorInFunction
<< "Outstanding recv request(s) on patch "
<< cyclicAMIPatch_.name()
<< " field " << this->internalField().name()
<< abort(FatalError);
}
const Field<Type>& iField = this->primitiveField();
// Initialise if not done in construct-from-dictionary
if (!patchNeighbourFieldPtr_)
{
// Do interpolation and store result
patchNeighbourFieldPtr_.reset
(
patchNeighbourField(this->primitiveField()).ptr()
);
}
return patchNeighbourFieldPtr_();
// By pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
// neighbPatch()
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
const labelUList& nbrFaceCells = neighbPatch.faceCells();
Field<Type> pnf(iField, nbrFaceCells);
tmp<Field<Type>> tpnf;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
Field<Type> pnfInternal(iField, cyclicAMIPatch_.faceCells());
tpnf = cyclicAMIPatch_.interpolate(pnf, pnfInternal);
}
else
{
// Do interpolation
return patchNeighbourField(this->primitiveField());
tpnf = cyclicAMIPatch_.interpolate(pnf);
}
if (doTransform())
{
transform(tpnf.ref(), forwardT(), tpnf());
}
return tpnf;
}
@ -343,150 +194,6 @@ Foam::cyclicAMIFvPatchField<Type>::neighbourPatchField() const
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::initEvaluate
(
const Pstream::commsTypes commsType
)
{
if (!this->updated())
{
this->updateCoeffs();
}
if (this->ownerAMI().distributed())
{
if (commsType != UPstream::commsTypes::nonBlocking)
{
// Invalidate old field - or flag as fatal?
patchNeighbourFieldPtr_.reset(nullptr);
return;
}
// Start sending
// By-pass polyPatch to get nbrId. Instead use cyclicAMIFvPatch virtual
// neighbPatch()
const cyclicAMIFvPatch& neighbPatch = cyclicAMIPatch_.neighbPatch();
const labelUList& nbrFaceCells = neighbPatch.faceCells();
const Field<Type> pnf(this->primitiveField(), nbrFaceCells);
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
cpp.initInterpolate
(
pnf,
sendRequests_,
sendBufs_,
recvRequests_,
recvBufs_
);
}
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::evaluate
(
const Pstream::commsTypes commsType
)
{
if (!this->updated())
{
this->updateCoeffs();
}
const auto& AMI = this->ownerAMI();
if (AMI.distributed())
{
// Calculate patchNeighbourField
if (commsType != UPstream::commsTypes::nonBlocking)
{
FatalErrorInFunction
<< "Can only evaluate distributed AMI with nonBlocking"
<< exit(FatalError);
}
patchNeighbourFieldPtr_.reset(nullptr);
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
Field<Type> defaultValues;
if (AMI.applyLowWeightCorrection())
{
defaultValues = this->patchInternalField();
}
patchNeighbourFieldPtr_.reset
(
cpp.interpolate
(
Field<Type>::null(), // Not used for distributed
recvRequests_,
recvBufs_,
defaultValues
).ptr()
);
auto& patchNeighbourField = patchNeighbourFieldPtr_.ref();
if (doTransform())
{
// In-place transform
transform(patchNeighbourField, forwardT(), patchNeighbourField);
}
}
// Use patchNeighbourField() and patchInternalField() to obtain face value
coupledFvPatchField<Type>::evaluate(commsType);
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
(
solveScalarField& result,
const bool add,
const lduAddressing& lduAddr,
const label patchId,
const solveScalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const
{
if (this->ownerAMI().distributed())
{
// Start sending
if (commsType != UPstream::commsTypes::nonBlocking)
{
FatalErrorInFunction
<< "Can only evaluate distributed AMI with nonBlocking"
<< exit(FatalError);
}
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
solveScalarField pnf(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
cpp.initInterpolate
(
pnf,
sendRequests_,
scalarSendBufs_,
recvRequests_,
scalarRecvBufs_
);
}
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
@ -497,63 +204,27 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
const solveScalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
const Pstream::commsTypes
) const
{
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
solveScalarField pnf(psiInternal, nbrFaceCells);
const labelUList& faceCells = lduAddr.patchAddr(patchId);
const auto& AMI =
(
cyclicAMIPatch_.owner()
? cyclicAMIPatch_.AMI()
: cyclicAMIPatch_.neighbPatch().AMI()
);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
solveScalarField pnf;
if (this->ownerAMI().distributed())
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
if (commsType != UPstream::commsTypes::nonBlocking)
{
FatalErrorInFunction
<< "Can only evaluate distributed AMI with nonBlocking"
<< exit(FatalError);
}
solveScalarField defaultValues;
if (AMI.applyLowWeightCorrection())
{
defaultValues = solveScalarField(psiInternal, faceCells);
}
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
pnf =
cpp.interpolate
(
solveScalarField::null(), // Not used for distributed
recvRequests_,
scalarRecvBufs_,
defaultValues
);
solveScalarField pif(psiInternal, faceCells);
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
}
else
{
solveScalarField defaultValues;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
defaultValues = solveScalarField(psiInternal, faceCells);
}
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
pnf = solveScalarField(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf, cmpt);
pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
pnf = cyclicAMIPatch_.interpolate(pnf);
}
// Multiply the field by coefficients and add into the result
@ -561,51 +232,6 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::initInterfaceMatrixUpdate
(
Field<Type>& result,
const bool add,
const lduAddressing& lduAddr,
const label patchId,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes commsType
) const
{
const auto& AMI = this->ownerAMI();
if (AMI.distributed())
{
if (commsType != UPstream::commsTypes::nonBlocking)
{
FatalErrorInFunction
<< "Can only evaluate distributed AMI with nonBlocking"
<< exit(FatalError);
}
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
Field<Type> pnf(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf);
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
cpp.initInterpolate
(
pnf,
sendRequests_,
sendBufs_,
recvRequests_,
recvBufs_
);
}
}
template<class Type>
void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
(
@ -615,60 +241,29 @@ void Foam::cyclicAMIFvPatchField<Type>::updateInterfaceMatrix
const label patchId,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes commsType
const Pstream::commsTypes
) const
{
const labelUList& faceCells = lduAddr.patchAddr(patchId);
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
const auto& AMI = this->ownerAMI();
Field<Type> pnf(psiInternal, nbrFaceCells);
Field<Type> pnf;
// Transform according to the transformation tensors
transformCoupleField(pnf);
if (AMI.distributed())
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
if (commsType != UPstream::commsTypes::nonBlocking)
{
FatalErrorInFunction
<< "Can only evaluate distributed AMI with nonBlocking"
<< exit(FatalError);
}
const cyclicAMIPolyPatch& cpp = cyclicAMIPatch_.cyclicAMIPatch();
Field<Type> defaultValues;
if (AMI.applyLowWeightCorrection())
{
defaultValues = Field<Type>(psiInternal, faceCells);
}
pnf =
cpp.interpolate
(
Field<Type>::null(), // Not used for distributed
recvRequests_,
recvBufs_,
defaultValues
);
Field<Type> pif(psiInternal, cyclicAMIPatch_.faceCells());
pnf = cyclicAMIPatch_.interpolate(pnf, pif);
}
else
{
const labelUList& nbrFaceCells =
lduAddr.patchAddr(cyclicAMIPatch_.neighbPatchID());
Field<Type> pnf(psiInternal, nbrFaceCells);
// Transform according to the transformation tensors
transformCoupleField(pnf);
Field<Type> defaultValues;
if (cyclicAMIPatch_.applyLowWeightCorrection())
{
defaultValues = Field<Type>(psiInternal, faceCells);
}
pnf = cyclicAMIPatch_.interpolate(pnf, defaultValues);
pnf = cyclicAMIPatch_.interpolate(pnf);
}
const labelUList& faceCells = lduAddr.patchAddr(patchId);
// Multiply the field by coefficients and add into the result
this->addToInternalField(result, !add, faceCells, coeffs, pnf);
}
@ -682,9 +277,10 @@ void Foam::cyclicAMIFvPatchField<Type>::manipulateMatrix
const direction cmpt
)
{
if (this->cyclicAMIPatch().owner())
{
const label index = this->patch().index();
label index = this->patch().index();
const label globalPatchID =
matrix.lduMeshAssembly().patchLocalToGlobalMap()[mat][index];
@ -780,8 +376,7 @@ Foam::cyclicAMIFvPatchField<Type>::coeffs
matrix.lduMeshAssembly().cellBoundMap()[mat][index].size()
);
auto tmapCoeffs = tmp<Field<scalar>>::New(nSubFaces, Zero);
auto& mapCoeffs = tmapCoeffs.ref();
Field<scalar> mapCoeffs(nSubFaces, Zero);
const scalarListList& srcWeight =
cyclicAMIPatch_.cyclicAMIPatch().AMI().srcWeights();
@ -799,7 +394,7 @@ Foam::cyclicAMIFvPatchField<Type>::coeffs
}
}
return tmapCoeffs;
return tmp<Field<scalar>>(new Field<scalar>(mapCoeffs));
}
@ -813,7 +408,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
List<Type2>& expandedData
)
{
expandedData.resize_nocopy(stencil.size());
expandedData.setSize(stencil.size());
if (mapPtr)
{
Type2 work(data);
@ -822,7 +417,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
forAll(stencil, facei)
{
const labelList& slots = stencil[facei];
expandedData[facei].push_back
expandedData[facei].append
(
UIndirectList<typename Type2::value_type>(work, slots)
);
@ -833,7 +428,7 @@ void Foam::cyclicAMIFvPatchField<Type>::collectStencilData
forAll(stencil, facei)
{
const labelList& slots = stencil[facei];
expandedData[facei].push_back
expandedData[facei].append
(
UIndirectList<typename Type2::value_type>(data, slots)
);
@ -847,12 +442,8 @@ void Foam::cyclicAMIFvPatchField<Type>::write(Ostream& os) const
{
fvPatchField<Type>::write(os);
fvPatchField<Type>::writeValueEntry(os);
if (patchNeighbourFieldPtr_)
{
patchNeighbourFieldPtr_->writeEntry("neighbourValue", os);
}
}
// ************************************************************************* //

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2019-2023 OpenCFD Ltd.
Copyright (C) 2019 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -41,24 +41,16 @@ Usage
<patchName>
{
type cyclicAMI;
value <initial value>;
neighbourValue <initial value of neighbour patch cells>;
}
\endverbatim
Note
The outer boundary of the patch pairs must be similar, i.e. if the owner
patch is transformed to the neighbour patch, the outer perimeter of each
patch is transformed to the neighbour patch, the outer perimiter of each
patch should be identical (or very similar).
The \c neighbourValue is only needed when running distributed,
i.e. the neighbour cells are on a different processor from the owner cells.
It guarantees consistent restart e.g. when doing a snGrad and avoids
additional communication.
See also
Foam::AMIInterpolation
Foam::processorFvPatchField
SourceFiles
cyclicAMIFvPatchField.C
@ -87,55 +79,14 @@ class cyclicAMIFvPatchField
virtual public cyclicAMILduInterfaceField,
public coupledFvPatchField<Type>
{
// Private Data
// Private data
//- Local reference cast into the cyclic patch
const cyclicAMIFvPatch& cyclicAMIPatch_;
// Sending and receiving (distributed AMI)
//- Current range of send requests (non-blocking)
mutable labelRange sendRequests_;
//- Current range of recv requests (non-blocking)
mutable labelRange recvRequests_;
//- Send buffers
mutable PtrList<List<Type>> sendBufs_;
//- Receive buffers_
mutable PtrList<List<Type>> recvBufs_;
//- Scalar send buffers
mutable PtrList<List<solveScalar>> scalarSendBufs_;
//- Scalar receive buffers
mutable PtrList<List<solveScalar>> scalarRecvBufs_;
//- Neighbour coupled internal cell data
mutable autoPtr<Field<Type>> patchNeighbourFieldPtr_;
// Private Member Functions
//- Return the AMI corresponding to the owner side
const AMIPatchToPatchInterpolation& ownerAMI() const
{
return
(
cyclicAMIPatch_.owner()
? cyclicAMIPatch_.AMI()
: cyclicAMIPatch_.neighbPatch().AMI()
);
}
//- All receive/send requests have completed
virtual bool all_ready() const;
//- Return neighbour coupled internal cell data
tmp<Field<Type>> patchNeighbourField(const Field<Type>&) const;
//- Return neighbour side field given internal fields
template<class Type2>
tmp<Field<Type2>> neighbourSideField
@ -152,6 +103,7 @@ class cyclicAMIFvPatchField
const label
) const;
template<class Type2>
void collectStencilData
(
@ -226,54 +178,28 @@ public:
}
// Member Functions
// Member functions
//- Return local reference cast into the cyclic AMI patch
const cyclicAMIFvPatch& cyclicAMIPatch() const noexcept
{
return cyclicAMIPatch_;
}
// Access
//- Return local reference cast into the cyclic AMI patch
const cyclicAMIFvPatch& cyclicAMIPatch() const
{
return cyclicAMIPatch_;
}
// Coupling
// Evaluation functions
//- Return true if coupled. Note that the underlying patch
// is not coupled() - the points don't align.
virtual bool coupled() const { return cyclicAMIPatch_.coupled(); }
//- Return true if coupled. Note that the underlying patch
// is not coupled() - the points don't align.
virtual bool coupled() const;
//- Are all (receive) data available?
virtual bool ready() const;
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Return neighbour coupled internal cell data
virtual tmp<Field<Type>> patchNeighbourField() const;
//- Return reference to neighbour patchField
const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;
// Evaluation
//- Initialise the evaluation of the patch field
virtual void initEvaluate(const Pstream::commsTypes commsType);
//- Evaluate the patch field
virtual void evaluate(const Pstream::commsTypes commsType);
// Coupled interface functionality
//- Initialise neighbour matrix update
virtual void initInterfaceMatrixUpdate
(
solveScalarField& result,
const bool add,
const lduAddressing& lduAddr,
const label patchId,
const solveScalarField& psiInternal,
const scalarField& coeffs,
const direction cmpt,
const Pstream::commsTypes commsType
) const;
//- Return reference to neighbour patchField
const cyclicAMIFvPatchField<Type>& neighbourPatchField() const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
@ -288,18 +214,6 @@ public:
const Pstream::commsTypes commsType
) const;
//- Initialise neighbour matrix update
virtual void initInterfaceMatrixUpdate
(
Field<Type>& result,
const bool add,
const lduAddressing& lduAddr,
const label patchId,
const Field<Type>& psiInternal,
const scalarField& coeffs,
const Pstream::commsTypes commsType
) const;
//- Update result field based on interface functionality
virtual void updateInterfaceMatrix
(
@ -322,7 +236,7 @@ public:
);
// Coupled interface functions
// Cyclic AMI coupled interface functions
//- Does the patch field perform the transformation
virtual bool doTransform() const

View File

@ -26,11 +26,8 @@ License
\*---------------------------------------------------------------------------*/
#include "cyclicAMIFvPatchFields.H"
#include "cyclicAMIPolyPatch.H"
#include "mapDistributeBase.H"
#include "AMIInterpolation.H"
#include "volFields.H"
#include "addToRunTimeSelectionTable.H"
#include "volFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -25,8 +25,8 @@ License
\*---------------------------------------------------------------------------*/
#ifndef Foam_cyclicAMIFvPatchFields_H
#define Foam_cyclicAMIFvPatchFields_H
#ifndef cyclicAMIFvPatchFields_H
#define cyclicAMIFvPatchFields_H
#include "cyclicAMIFvPatchField.H"
#include "fieldTypes.H"

View File

@ -37,9 +37,6 @@ License
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// Max number of warnings
static constexpr const unsigned maxWarnings = 10u;
namespace Foam
{
namespace functionObjects
@ -138,13 +135,39 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
mesh_.faceZones().indices(selectionNames_)
);
// Total number of faces that could be selected (before patch filtering)
// Total number of faces selected
label numFaces = 0;
for (const label zoneId : zoneIds)
{
numFaces += mesh_.faceZones()[zoneId].size();
}
if (zoneIds.empty())
{
FatalErrorInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " No matching face zone(s): "
<< flatOutput(selectionNames_) << nl
<< " Known face zones: "
<< flatOutput(mesh_.faceZones().names()) << nl
<< exit(FatalError);
}
// Could also check this
#if 0
if (!returnReduceOr(numFaces))
{
WarningInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " The faceZone specification: "
<< flatOutput(selectionNames_) << nl
<< " resulted in 0 faces" << nl
<< exit(FatalError);
}
#endif
faceId_.resize_nocopy(numFaces);
facePatchId_.resize_nocopy(numFaces);
faceFlip_.resize_nocopy(numFaces);
@ -200,75 +223,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setFaceZoneFaces()
faceId_.resize(numFaces);
facePatchId_.resize(numFaces);
faceFlip_.resize(numFaces);
nFaces_ = returnReduce(numFaces, sumOp<label>());
if (!nFaces_)
{
// Raise warning or error
refPtr<OSstream> os;
bool fatal = false;
++nWarnings_; // Always increment (even if ignore etc)
switch (emptySurfaceError_)
{
case error::handlerTypes::IGNORE:
{
break;
}
case error::handlerTypes::WARN:
{
if (nWarnings_ <= maxWarnings)
{
os.ref(WarningInFunction);
}
break;
}
// STRICT / DEFAULT
default:
{
os.ref(FatalErrorInFunction);
fatal = true;
break;
}
}
if (os)
{
os.ref()
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_]
<< '(' << regionName_ << "):" << nl;
if (zoneIds.empty())
{
os.ref()
<< " No matching face zones: "
<< flatOutput(selectionNames_) << nl
<< " Known face zones: "
<< flatOutput(mesh_.faceZones().names()) << nl;
}
else
{
os.ref()
<< " The face zones: "
<< flatOutput(selectionNames_) << nl
<< " resulted in 0 faces" << nl;
}
if (fatal)
{
FatalError<< exit(FatalError);
}
else if (nWarnings_ == maxWarnings)
{
os.ref()
<< "... suppressing further warnings." << nl;
}
}
}
nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
}
@ -328,7 +283,7 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
nGood = 0;
for (const label patchi : selected)
{
if (!bad.contains(patchi))
if (!bad.found(patchi))
{
patchIds[nGood] = patchi;
++nGood;
@ -340,10 +295,36 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
patchIds = std::move(selected);
}
faceId_.resize_nocopy(numFaces);
facePatchId_.resize_nocopy(numFaces);
faceFlip_.resize_nocopy(numFaces);
nFaces_ = returnReduce(numFaces, sumOp<label>());
if (patchIds.empty())
{
FatalErrorInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " No matching patch name(s): "
<< flatOutput(selectionNames_) << nl
<< " Known patch names:" << nl
<< mesh_.boundaryMesh().names() << nl
<< exit(FatalError);
}
// Could also check this
#if 0
if (!returnReduceOr(numFaces))
{
WarningInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " The patch specification: "
<< flatOutput(selectionNames_) << nl
<< " resulted in 0 faces" << nl
<< exit(FatalError);
}
#endif
faceId_.resize(numFaces);
facePatchId_.resize(numFaces);
faceFlip_.resize(numFaces);
nFaces_ = returnReduce(faceId_.size(), sumOp<label>());
numFaces = 0;
for (const label patchi : patchIds)
@ -357,74 +338,6 @@ void Foam::functionObjects::fieldValues::surfaceFieldValue::setPatchFaces()
numFaces += len;
}
if (!nFaces_)
{
// Raise warning or error
refPtr<OSstream> os;
bool fatal = false;
++nWarnings_; // Always increment (even if ignore etc)
switch (emptySurfaceError_)
{
case error::handlerTypes::IGNORE:
{
break;
}
case error::handlerTypes::WARN:
{
if (nWarnings_ <= maxWarnings)
{
os.ref(WarningInFunction);
}
break;
}
// STRICT / DEFAULT
default:
{
os.ref(FatalErrorInFunction);
fatal = true;
break;
}
}
if (os)
{
os.ref()
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_]
<< '(' << regionName_ << "):" << nl;
if (patchIds.empty())
{
os.ref()
<< " No matching patches: "
<< flatOutput(selectionNames_) << nl
<< " Known patch names:" << nl
<< mesh_.boundaryMesh().names() << nl;
}
else
{
os.ref()
<< " The patches: "
<< flatOutput(selectionNames_) << nl
<< " resulted in 0 faces" << nl;
}
if (fatal)
{
FatalError<< exit(FatalError);
}
else if (nWarnings_ == maxWarnings)
{
os.ref()
<< "... suppressing further warnings." << nl;
}
}
}
}
@ -598,30 +511,20 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::update()
return false;
}
// Reset some values
totalArea_ = 0;
nFaces_ = 0;
bool checkEmptyFaces = true;
switch (regionType_)
{
case stFaceZone:
{
// Raises warning or error internally, don't check again
setFaceZoneFaces();
checkEmptyFaces = false;
break;
}
case stPatch:
{
// Raises warning or error internally, don't check again
setPatchFaces();
checkEmptyFaces = false;
break;
}
case stObject:
{
// TBD: special handling of cast errors?
const auto& s = refCast<const polySurface>(obr());
nFaces_ = returnReduce(s.size(), sumOp<label>());
break;
@ -635,76 +538,23 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::update()
// Compiler warning if we forgot an enumeration
}
if (nFaces_)
if (nFaces_ == 0)
{
// Appears to be successful
needsUpdate_ = false;
totalArea_ = totalArea(); // Update the area
nWarnings_ = 0u; // Reset the warnings counter
FatalErrorInFunction
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_] << '(' << regionName_ << "):" << nl
<< " Region has no faces" << exit(FatalError);
}
else if (checkEmptyFaces)
{
// Raise warning or error
refPtr<OSstream> os;
bool fatal = false;
++nWarnings_; // Always increment (even if ignore etc)
switch (emptySurfaceError_)
{
case error::handlerTypes::IGNORE:
{
break;
}
case error::handlerTypes::WARN:
{
if (nWarnings_ <= maxWarnings)
{
os.ref(WarningInFunction);
}
break;
}
// STRICT / DEFAULT
default:
{
os.ref(FatalErrorInFunction);
fatal = true;
break;
}
}
if (os)
{
os.ref()
<< type() << ' ' << name() << ": "
<< regionTypeNames_[regionType_]
<< '(' << regionName_ << "):" << nl
<< " Region has no faces" << endl;
if (fatal)
{
FatalError<< exit(FatalError);
}
else if (nWarnings_ == maxWarnings)
{
os.ref()
<< "... suppressing further warnings." << nl;
}
}
}
totalArea_ = totalArea();
Log << " total faces = " << nFaces_ << nl
<< " total area = " << totalArea_ << nl
<< endl;
// Emit file header on success or change of state
if (nWarnings_ <= 1)
{
writeFileHeader(file());
}
writeFileHeader(file());
needsUpdate_ = false;
return true;
}
@ -1081,12 +931,10 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
),
needsUpdate_(true),
writeArea_(false),
emptySurfaceError_(error::handlerTypes::DEFAULT),
selectionNames_(),
weightFieldNames_(),
totalArea_(0),
nFaces_(0),
nWarnings_(0),
faceId_(),
facePatchId_(),
faceFlip_()
@ -1117,12 +965,10 @@ Foam::functionObjects::fieldValues::surfaceFieldValue::surfaceFieldValue
),
needsUpdate_(true),
writeArea_(false),
emptySurfaceError_(error::handlerTypes::DEFAULT),
selectionNames_(),
weightFieldNames_(),
totalArea_(0),
nFaces_(0),
nWarnings_(0),
faceId_(),
facePatchId_(),
faceFlip_()
@ -1149,21 +995,12 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
needsUpdate_ = true;
writeArea_ = dict.getOrDefault("writeArea", false);
emptySurfaceError_ = error::handlerNames.getOrDefault
(
"empty-surface",
dict,
error::handlerTypes::DEFAULT,
true // Failsafe behaviour
);
weightFieldNames_.clear();
// future?
// sampleFaceScheme_ = dict.getOrDefault<word>("sampleScheme", "cell");
totalArea_ = 0;
nFaces_ = 0;
nWarnings_ = 0;
faceId_.clear();
facePatchId_.clear();
faceFlip_.clear();
@ -1345,39 +1182,12 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::write()
writeCurrentTime(file());
}
// Handle ignore/warn about empty-surface
if (!nFaces_)
{
totalArea_ = 0; // Update the area (safety)
if (operation_ != opNone)
{
if (emptySurfaceError_ == error::handlerTypes::WARN)
{
if (writeArea_)
{
Log << " total area = " << totalArea_ << endl;
file() << tab << totalArea_;
}
file() << tab << "NaN";
Log << endl;
}
file() << endl;
}
// Early exit on error
return true;
}
if (writeArea_)
{
// Update the area
totalArea_ = totalArea();
Log << " total area = " << totalArea_ << endl;
if (operation_ != opNone && UPstream::master())
if (operation_ != opNone && Pstream::master())
{
file() << tab << totalArea_;
}

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -88,7 +88,6 @@ Usage
scaleFactor 1.0;
writeArea false;
surfaceFormat none;
empty-surface warn; // default | warn | ignore | strict
// Optional (inherited) entries
...
@ -112,7 +111,6 @@ Usage
writeArea | Write the surface area | bool | no | false
surfaceFormat | Output value format | word <!--
--> | conditional on writeFields | none
empty-surface | Error handling for empty surfaces | enum | no | default
\endtable
The inherited entries are elaborated in:
@ -402,9 +400,6 @@ protected:
//- Optionally write the area of the surfaceFieldValue
bool writeArea_;
//- Handling of empty surfaces (nFaces = 0). Default is Fatal.
error::handlerTypes emptySurfaceError_;
//- Extended selections
wordRes selectionNames_;
@ -417,9 +412,6 @@ protected:
//- Global number of faces
label nFaces_;
//- Number of warnings emitted since the last valid update
unsigned nWarnings_;
// If operating on mesh faces (faceZone, patch)

View File

@ -6,7 +6,7 @@
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2015-2023 OpenCFD Ltd.
Copyright (C) 2015-2022 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
@ -33,7 +33,6 @@ License
#include "profiling.H"
#include "triangle.H"
#include "OFstream.H"
#include <numeric> // For std::iota
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -170,7 +169,7 @@ void Foam::AMIInterpolation::normaliseWeights
addProfiling(ami, "AMIInterpolation::normaliseWeights");
// Normalise the weights
wghtSum.resize_nocopy(wght.size());
wghtSum.setSize(wght.size(), 0.0);
label nLowWeight = 0;
forAll(wght, facei)
@ -332,7 +331,7 @@ void Foam::AMIInterpolation::agglomerate
const labelList& elemsMap =
map.constructMap()[Pstream::myProcNo()];
labelList& newSubMap = tgtSubMap[proci];
newSubMap.resize_nocopy(elems.size());
newSubMap.setSize(elems.size());
labelList oldToNew(targetCoarseSize, -1);
label newi = 0;
@ -348,7 +347,7 @@ void Foam::AMIInterpolation::agglomerate
++newi;
}
}
newSubMap.resize(newi);
newSubMap.setSize(newi);
}
}
@ -393,7 +392,7 @@ void Foam::AMIInterpolation::agglomerate
const labelList& elems = map.constructMap()[proci];
labelList& newConstructMap = tgtConstructMap[proci];
newConstructMap.resize_nocopy(elems.size());
newConstructMap.setSize(elems.size());
if (elems.size())
{
@ -432,7 +431,7 @@ void Foam::AMIInterpolation::agglomerate
tgtCompactMap[fineElem] = newConstructMap[compacti];
}
}
newConstructMap.resize(newi);
newConstructMap.setSize(newi);
}
}
}
@ -762,27 +761,25 @@ bool Foam::AMIInterpolation::calculate
if (srcTotalSize == 0)
{
DebugInfo
<< "AMI: no source faces present - no addressing constructed"
DebugInfo<< "AMI: no source faces present - no addressing constructed"
<< endl;
return false;
}
Info<< indent
<< "AMI: Patch source faces: " << srcTotalSize << nl
<< "AMI: Patch target faces: " << tgtTotalSize << endl;
singlePatchProc_ = calcDistribution(srcPatch, tgtPatch);
Info<< indent << "AMI: Patch source faces: " << srcTotalSize << nl
<< indent << "AMI: Patch target faces: " << tgtTotalSize << nl;
if (distributed())
if (debug)
{
Info<< indent << "AMI: distributed" << endl;
Info<< "AMIInterpolation:" << nl
<< " singlePatchProc:" << singlePatchProc_ << nl
<< endl;
}
DebugInfo
<< "AMI: patch proc:" << singlePatchProc_
<< endl;
return true;
}
@ -805,13 +802,13 @@ void Foam::AMIInterpolation::reset
tgtWeights_.transfer(tgtWeights);
// Reset the sums of the weights
srcWeightsSum_.resize_nocopy(srcWeights_.size());
srcWeightsSum_.setSize(srcWeights_.size());
forAll(srcWeights_, facei)
{
srcWeightsSum_[facei] = sum(srcWeights_[facei]);
}
tgtWeightsSum_.resize_nocopy(tgtWeights_.size());
tgtWeightsSum_.setSize(tgtWeights_.size());
forAll(tgtWeights_, facei)
{
tgtWeightsSum_[facei] = sum(tgtWeights_[facei]);
@ -851,133 +848,121 @@ void Foam::AMIInterpolation::append
labelListList& newTgtSubMap = newPtr->tgtMapPtr_->subMap();
labelListList& newTgtConstructMap = newPtr->tgtMapPtr_->constructMap();
// Re-mapping/re-indexing - use max sizing
labelList oldMapMap
(
max
(
srcMapPtr_->constructMapTotalSize(),
tgtMapPtr_->constructMapTotalSize()
)
);
labelList newMapMap
(
max
(
newPtr->srcMapPtr_->constructMapTotalSize(),
newPtr->tgtMapPtr_->constructMapTotalSize()
)
);
// Re-calculate the source indices
{
label total = 0;
auto iter1 = oldMapMap.begin();
auto iter2 = newMapMap.begin();
labelList mapMap(0), newMapMap(0);
forAll(srcSubMap, proci)
{
mapMap.append
(
identity
(
srcConstructMap[proci].size(),
(mapMap.size() + newMapMap.size())
)
);
newMapMap.append
(
identity
(
newSrcConstructMap[proci].size(),
(mapMap.size() + newMapMap.size())
)
);
}
forAll(srcSubMap, proci)
{
const label len1 = srcConstructMap[proci].size();
const label len2 = newSrcConstructMap[proci].size();
std::iota(iter1, (iter1 + len1), total);
iter1 += len1;
total += len1;
std::iota(iter2, (iter2 + len2), total);
iter2 += len2;
total += len2;
}
}
// Renumber the source indices
{
for (labelList& list : srcConstructMap)
{
for (label& value : list)
forAll(srcConstructMap[proci], srci)
{
value = oldMapMap[value];
srcConstructMap[proci][srci] =
mapMap[srcConstructMap[proci][srci]];
}
}
for (labelList& list : newSrcConstructMap)
forAll(srcSubMap, proci)
{
for (label& value : list)
forAll(newSrcConstructMap[proci], srci)
{
value = newMapMap[value];
newSrcConstructMap[proci][srci] =
newMapMap[newSrcConstructMap[proci][srci]];
}
}
for (labelList& list : tgtAddress_)
forAll(tgtAddress_, tgti)
{
for (label& value : list)
forAll(tgtAddress_[tgti], tgtj)
{
value = oldMapMap[value];
tgtAddress_[tgti][tgtj] = mapMap[tgtAddress_[tgti][tgtj]];
}
}
for (labelList& list : newPtr->tgtAddress_)
forAll(newPtr->tgtAddress_, tgti)
{
for (label& value : list)
forAll(newPtr->tgtAddress_[tgti], tgtj)
{
value = newMapMap[value];
newPtr->tgtAddress_[tgti][tgtj] =
newMapMap[newPtr->tgtAddress_[tgti][tgtj]];
}
}
}
// Re-calculate the target indices
{
label total = 0;
auto iter1 = oldMapMap.begin();
auto iter2 = newMapMap.begin();
labelList mapMap(0), newMapMap(0);
forAll(srcSubMap, proci)
{
mapMap.append
(
identity
(
tgtConstructMap[proci].size(),
(mapMap.size() + newMapMap.size())
)
);
newMapMap.append
(
identity
(
newTgtConstructMap[proci].size(),
(mapMap.size() + newMapMap.size())
)
);
}
forAll(srcSubMap, proci)
{
const label len1 = tgtConstructMap[proci].size();
const label len2 = newTgtConstructMap[proci].size();
std::iota(iter1, (iter1 + len1), total);
iter1 += len1;
total += len1;
std::iota(iter2, (iter2 + len2), total);
iter2 += len2;
total += len2;
}
}
// Renumber the target indices
{
for (labelList& list : tgtConstructMap)
{
for (label& value : list)
forAll(tgtConstructMap[proci], tgti)
{
value = oldMapMap[value];
tgtConstructMap[proci][tgti] =
mapMap[tgtConstructMap[proci][tgti]];
}
}
for (labelList& list : newTgtConstructMap)
forAll(srcSubMap, proci)
{
for (label& value : list)
forAll(newTgtConstructMap[proci], tgti)
{
value = newMapMap[value];
newTgtConstructMap[proci][tgti] =
newMapMap[newTgtConstructMap[proci][tgti]];
}
}
for (labelList& list : srcAddress_)
forAll(srcAddress_, srci)
{
for (label& value : list)
forAll(srcAddress_[srci], srcj)
{
value = oldMapMap[value];
srcAddress_[srci][srcj] =
mapMap[srcAddress_[srci][srcj]];
}
}
for (labelList& list : newPtr->srcAddress_)
forAll(newPtr->srcAddress_, srci)
{
for (label& value : list)
forAll(newPtr->srcAddress_[srci], srcj)
{
value = newMapMap[value];
newPtr->srcAddress_[srci][srcj] =
newMapMap[newPtr->srcAddress_[srci][srcj]];
}
}
}
@ -989,27 +974,27 @@ void Foam::AMIInterpolation::append
// Combine the maps
forAll(srcSubMap, proci)
{
srcSubMap[proci].push_back(newSrcSubMap[proci]);
srcConstructMap[proci].push_back(newSrcConstructMap[proci]);
srcSubMap[proci].append(newSrcSubMap[proci]);
srcConstructMap[proci].append(newSrcConstructMap[proci]);
tgtSubMap[proci].push_back(newTgtSubMap[proci]);
tgtConstructMap[proci].push_back(newTgtConstructMap[proci]);
tgtSubMap[proci].append(newTgtSubMap[proci]);
tgtConstructMap[proci].append(newTgtConstructMap[proci]);
}
}
// Combine new and current source data
forAll(srcMagSf_, srcFacei)
{
srcAddress_[srcFacei].push_back(newPtr->srcAddress()[srcFacei]);
srcWeights_[srcFacei].push_back(newPtr->srcWeights()[srcFacei]);
srcAddress_[srcFacei].append(newPtr->srcAddress()[srcFacei]);
srcWeights_[srcFacei].append(newPtr->srcWeights()[srcFacei]);
srcWeightsSum_[srcFacei] += newPtr->srcWeightsSum()[srcFacei];
}
// Combine new and current target data
forAll(tgtMagSf_, tgtFacei)
{
tgtAddress_[tgtFacei].push_back(newPtr->tgtAddress()[tgtFacei]);
tgtWeights_[tgtFacei].push_back(newPtr->tgtWeights()[tgtFacei]);
tgtAddress_[tgtFacei].append(newPtr->tgtAddress()[tgtFacei]);
tgtWeights_[tgtFacei].append(newPtr->tgtWeights()[tgtFacei]);
tgtWeightsSum_[tgtFacei] += newPtr->tgtWeightsSum()[tgtFacei];
}
}

Some files were not shown because too many files have changed in this diff Show More