diff --git a/applications/test/ICharStream1/Make/files b/applications/test/ICharStream1/Make/files new file mode 100644 index 0000000000..e7f106f94a --- /dev/null +++ b/applications/test/ICharStream1/Make/files @@ -0,0 +1,3 @@ +Test-ICharStream1.C + +EXE = $(FOAM_USER_APPBIN)/Test-ICharStream1 diff --git a/applications/test/IListStream/Make/options b/applications/test/ICharStream1/Make/options similarity index 100% rename from applications/test/IListStream/Make/options rename to applications/test/ICharStream1/Make/options diff --git a/applications/test/IListStream/Test-IListStream.C b/applications/test/ICharStream1/Test-ICharStream1.C similarity index 70% rename from applications/test/IListStream/Test-IListStream.C rename to applications/test/ICharStream1/Test-ICharStream1.C index 4cce6e2fce..f4b18a1f43 100644 --- a/applications/test/IListStream/Test-IListStream.C +++ b/applications/test/ICharStream1/Test-ICharStream1.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2018 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,14 +27,46 @@ Description \*---------------------------------------------------------------------------*/ -#include "ListStream.H" -#include "UListStream.H" +#include "SpanStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" +#include +#include + using namespace Foam; +Ostream& writeList(Ostream& os, const UList& 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& list) { os << '"'; @@ -93,7 +125,7 @@ int main(int argc, char *argv[]) // Buffer storage DynamicList storage(16); - OListStream obuf(std::move(storage)); + OCharStream obuf(std::move(storage)); obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; // Move contents to output buffer @@ -104,9 +136,9 @@ int main(int argc, char *argv[]) Info<< "transfer contents to a List" << endl; - IListStream ibuf; + ICharStream ibuf; - // Reclaim data storage from OListStream -> IListStream + // Reclaim data storage from OCharStream -> ICharStream { List data; obuf.swap(data); @@ -161,6 +193,43 @@ int main(int argc, char *argv[]) Info< 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; diff --git a/applications/test/IListStream/Make/files b/applications/test/IListStream/Make/files deleted file mode 100644 index 7f0914970b..0000000000 --- a/applications/test/IListStream/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-IListStream.C - -EXE = $(FOAM_USER_APPBIN)/Test-IListStream diff --git a/applications/test/ITstream/Test-ITstream.C b/applications/test/ITstream/Test-ITstream.C index bbf9ff068f..d038d1bb47 100644 --- a/applications/test/ITstream/Test-ITstream.C +++ b/applications/test/ITstream/Test-ITstream.C @@ -28,8 +28,6 @@ Description \*---------------------------------------------------------------------------*/ #include "argList.H" -#include "ListStream.H" -#include "UListStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" diff --git a/applications/test/OCharStream1/Make/files b/applications/test/OCharStream1/Make/files new file mode 100644 index 0000000000..5613de82c1 --- /dev/null +++ b/applications/test/OCharStream1/Make/files @@ -0,0 +1,3 @@ +Test-OCharStream1.C + +EXE = $(FOAM_USER_APPBIN)/Test-OCharStream1 diff --git a/applications/test/OListStream/Make/options b/applications/test/OCharStream1/Make/options similarity index 100% rename from applications/test/OListStream/Make/options rename to applications/test/OCharStream1/Make/options diff --git a/applications/test/OListStream/Test-OListStream.C b/applications/test/OCharStream1/Test-OCharStream1.C similarity index 83% rename from applications/test/OListStream/Test-OListStream.C rename to applications/test/OCharStream1/Test-OCharStream1.C index c0e19de3cd..ccd663d30d 100644 --- a/applications/test/OListStream/Test-OListStream.C +++ b/applications/test/OCharStream1/Test-OCharStream1.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2021 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,13 +27,46 @@ Description \*---------------------------------------------------------------------------*/ -#include "ListStream.H" +#include "SpanStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" +#include +#include + using namespace Foam; +Ostream& writeList(Ostream& os, const UList& 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& list) { os << '"'; @@ -91,12 +124,12 @@ void outputDict(OS& os) int main(int argc, char *argv[]) { + #include "setRootCase.H" + // Buffer storage DynamicList storage(16); - OListStream obuf(std::move(storage)); - - obuf.setBlockSize(100); + OCharStream obuf(std::move(storage)); printInfo(obuf); @@ -140,10 +173,10 @@ int main(int argc, char *argv[]) Info<<"after overwrite" << nl; printInfo(obuf); - Info<< "transfer contents to a List or IListStream" << nl; + Info<< "transfer contents to a List or ICharStream" << nl; - IListStream ibuf; - // Reclaim data storage from OListStream -> IListStream + ICharStream ibuf; + // Reclaim data storage from OCharStream -> ICharStream { List data; obuf.swap(data); @@ -169,7 +202,7 @@ int main(int argc, char *argv[]) Info<<"input:"; toString(Info, list) << endl; - OListStream buf1(std::move(list)); + OCharStream buf1(std::move(list)); Info<<"orig:"; toString(Info, list) << endl; @@ -204,7 +237,7 @@ int main(int argc, char *argv[]) Info<< nl << "Test dictionary" << nl; { - OListStream os1; + OCharStream os1; outputDict(os1); @@ -213,7 +246,7 @@ int main(int argc, char *argv[]) } { - OListStream os2; + OCharStream os2; os2.indentSize(0); outputDict(os2); diff --git a/applications/test/OCountStream/Test-OCountStream.C b/applications/test/OCountStream/Test-OCountStream.C index ee0ebf19fa..95028ce9c2 100644 --- a/applications/test/OCountStream/Test-OCountStream.C +++ b/applications/test/OCountStream/Test-OCountStream.C @@ -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.size() << " chars" << endl; + << "via ocountstream: " << plain.count() << " chars" << endl; fileName outputName; args.readIfPresent("write", outputName); diff --git a/applications/test/OListStream/Make/files b/applications/test/OListStream/Make/files deleted file mode 100644 index 583b8e7f06..0000000000 --- a/applications/test/OListStream/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-OListStream.C - -EXE = $(FOAM_USER_APPBIN)/Test-OListStream diff --git a/applications/test/SpanStream1/Make/files b/applications/test/SpanStream1/Make/files new file mode 100644 index 0000000000..4af7ed78cd --- /dev/null +++ b/applications/test/SpanStream1/Make/files @@ -0,0 +1,3 @@ +Test-SpanStream1.C + +EXE = $(FOAM_USER_APPBIN)/Test-SpanStream1 diff --git a/applications/test/UIListStream/Make/options b/applications/test/SpanStream1/Make/options similarity index 100% rename from applications/test/UIListStream/Make/options rename to applications/test/SpanStream1/Make/options diff --git a/applications/test/UIListStream/Test-UIListStream.C b/applications/test/SpanStream1/Test-SpanStream1.C similarity index 80% rename from applications/test/UIListStream/Test-UIListStream.C rename to applications/test/SpanStream1/Test-SpanStream1.C index 205b1011ec..dede85f880 100644 --- a/applications/test/UIListStream/Test-UIListStream.C +++ b/applications/test/SpanStream1/Test-SpanStream1.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2018 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,16 +27,48 @@ Description \*---------------------------------------------------------------------------*/ -#include "UListStream.H" +#include "SpanStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" +#include +#include #include #include using namespace Foam; +Ostream& writeList(Ostream& os, const UList& 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& list) { os << '"'; @@ -108,7 +140,7 @@ int main(int argc, char *argv[]) // Buffer storage DynamicList storage(1000); - UOListStream obuf(storage); + OSpanStream obuf(storage); obuf << 1002 << "\n" << "abcd" << "\n" << "def" << "\n" << 3.14159 << ";\n"; obuf.print(Info); @@ -120,7 +152,7 @@ int main(int argc, char *argv[]) // Attach input buffer - could also do without previous resize { - UIListStream ibuf(storage); + ISpanStream ibuf(storage); printTokens(ibuf); @@ -135,13 +167,21 @@ int main(int argc, char *argv[]) { Info<< "parse as std::istream\n"; - uiliststream is(storage.cdata(), storage.size()); + 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; string tok; while (std::getline(is, tok)) { std::cerr << "tok: " << tok << nl; + Info<< "where: " << is.tellg() << endl; } Info<< nl << "Repeat..." << endl; @@ -170,7 +210,7 @@ int main(int argc, char *argv[]) toString(Info, chars); Info<< "----" << nl; - uiliststream is(chars.data(), chars.size()); + ispanstream is(chars.data(), chars.size()); string tok; std::cerr<< nl << "Parsed..." << nl; while (std::getline(is, tok)) diff --git a/applications/test/UIListStream/Make/files b/applications/test/UIListStream/Make/files deleted file mode 100644 index f60abd8967..0000000000 --- a/applications/test/UIListStream/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-UIListStream.C - -EXE = $(FOAM_USER_APPBIN)/Test-UIListStream diff --git a/applications/test/primitives/Test-primitives.C b/applications/test/primitives/Test-primitives.C index df381e3399..2ac56c7b25 100644 --- a/applications/test/primitives/Test-primitives.C +++ b/applications/test/primitives/Test-primitives.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017-2022 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -33,7 +33,7 @@ Description #include "scalar.H" #include "FlatOutput.H" -#include "ListStream.H" +#include "SpanStream.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 srcList(15); + forAll(srcList, i) { srcList[i] = 1 + 10*i; } - DynamicList buf; - - OListStream os(std::move(buf), IOstreamOption::BINARY); + OCharStream os(IOstreamOption::BINARY); os << srcList; - os.swap(buf); // Recover buffer + DynamicList buf; + os.swap(buf); // Recover written contents // Read back List dstList; - UIListStream is(buf, IOstreamOption::BINARY); + ISpanStream is(buf, IOstreamOption::BINARY); is.setScalarByteSize(sizeof(otherType)); Info<< "Stream scalar-size (" diff --git a/applications/test/readBroadcast1/Make/files b/applications/test/readBroadcast1/Make/files new file mode 100644 index 0000000000..5ad5573fab --- /dev/null +++ b/applications/test/readBroadcast1/Make/files @@ -0,0 +1,3 @@ +Test-readBroadcast1.C + +EXE = $(FOAM_USER_APPBIN)/Test-readBroadcast1 diff --git a/applications/test/readBroadcast1/Make/options b/applications/test/readBroadcast1/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/readBroadcast1/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/readBroadcast1/Test-readBroadcast1.C b/applications/test/readBroadcast1/Test-readBroadcast1.C new file mode 100644 index 0000000000..0cc407f61b --- /dev/null +++ b/applications/test/readBroadcast1/Test-readBroadcast1.C @@ -0,0 +1,297 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Description + Test file reading with broadcast + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "OSspecific.H" // For fileSize() +#include "Fstream.H" +#include "Pstream.H" +#include "SpanStream.H" +#include + +using namespace Foam; + +// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // + +bool optUseSeek = false; +bool optVerbose = false; + +// Get file contents. Usually master-only and broadcast +static List 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 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::max()); + + const std::streamsize nread = ifp->gcount(); + + if (nread == std::numeric_limits::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::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 off_t 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::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 off_t 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::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(1); + + if (srcName.has_ext("gz")) + { + srcName.remove_ext(); + Info<< "stripping extraneous .gz ending" << endl; + } + + ICharStream is; + + { + List 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; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index d08e7dde6e..a894406379 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -271,7 +271,7 @@ gzstream = $(Streams)/gzstream $(gzstream)/gzstream.C memstream = $(Streams)/memory -$(memstream)/ListStream.C +$(memstream)/SpanStreams.C Fstreams = $(Streams)/Fstreams $(Fstreams)/IFstream.C diff --git a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.C b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.C index e384dd1388..2076d0fde3 100644 --- a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.C +++ b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockData.C @@ -37,7 +37,7 @@ License #include "charList.H" #include "labelPair.H" #include "masterUncollatedFileOperation.H" -#include "ListStream.H" +#include "SpanStream.H" #include "StringStream.H" // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -403,7 +403,7 @@ Foam::decomposedBlockData::readBlock if (blocki == 0) { - realIsPtr.reset(new IListStream(std::move(data))); + realIsPtr.reset(new ICharStream(std::move(data))); realIsPtr->name() = is.name(); { @@ -422,7 +422,7 @@ Foam::decomposedBlockData::readBlock { { // Read header from first block - UIListStream headerStream(data); + ISpanStream 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 IListStream(std::move(data))); + realIsPtr.reset(new ICharStream(std::move(data))); realIsPtr->name() = is.name(); // Apply stream settings @@ -585,7 +585,7 @@ Foam::autoPtr Foam::decomposedBlockData::readBlocks // Read master data decomposedBlockData::readBlockEntry(is, data); - realIsPtr.reset(new IListStream(std::move(data))); + realIsPtr.reset(new ICharStream(std::move(data))); realIsPtr->name() = fName; { @@ -639,7 +639,7 @@ Foam::autoPtr Foam::decomposedBlockData::readBlocks ); is >> data; - realIsPtr.reset(new IListStream(std::move(data))); + realIsPtr.reset(new ICharStream(std::move(data))); realIsPtr->name() = fName; } } @@ -673,7 +673,7 @@ Foam::autoPtr Foam::decomposedBlockData::readBlocks UIPstream is(UPstream::masterNo(), pBufs); is >> data; - realIsPtr.reset(new IListStream(std::move(data))); + realIsPtr.reset(new ICharStream(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_)) { - UIListStream headerStream(contentData_); + ISpanStream headerStream(contentData_); io.readHeader(headerStream); verValue = headerStream.version().canonical(); diff --git a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C index 9778711775..25890e7d02 100644 --- a/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C +++ b/src/OpenFOAM/db/IOobjects/decomposedBlockData/decomposedBlockDataHeader.C @@ -29,7 +29,7 @@ License #include "dictionary.H" #include "foamVersion.H" #include "objectRegistry.H" -#include "ListStream.H" +#include "SpanStream.H" // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * // @@ -125,7 +125,7 @@ bool Foam::decomposedBlockData::readHeader(IOobject& io, Istream& is) List charData; decomposedBlockData::readBlockEntry(is, charData); - UIListStream headerStream(charData); + ISpanStream headerStream(charData); headerStream.name() = is.name(); ok = io.readHeader(headerStream); diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H index 77135a1487..3a0286347e 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H @@ -259,7 +259,6 @@ 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); } diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C index 7fab978198..09f5a52eb4 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C @@ -28,8 +28,8 @@ License #include "error.H" #include "ITstream.H" +#include "SpanStream.H" #include "StringStream.H" -#include "UIListStream.H" #include // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // @@ -94,7 +94,7 @@ Foam::tokenList Foam::ITstream::parse IOstreamOption streamOpt ) { - UIListStream is(input, streamOpt); + ISpanStream is(input, streamOpt); tokenList tokens; parseStream(is, tokens); @@ -108,7 +108,7 @@ Foam::tokenList Foam::ITstream::parse IOstreamOption streamOpt ) { - UIListStream is(input.data(), input.length(), streamOpt); + ISpanStream is(input, streamOpt); tokenList tokens; parseStream(is, tokens); @@ -122,7 +122,7 @@ Foam::tokenList Foam::ITstream::parse IOstreamOption streamOpt ) { - UIListStream is(input, strlen(input), streamOpt); + ISpanStream is(input, strlen(input), streamOpt); tokenList tokens; parseStream(is, tokens); @@ -261,7 +261,7 @@ Foam::ITstream::ITstream : ITstream(streamOpt, name) { - UIListStream is(input, streamOpt); + ISpanStream is(input, streamOpt); parseStream(is, static_cast(*this)); ITstream::seek(0); // rewind(), but bypasss virtual @@ -277,7 +277,7 @@ Foam::ITstream::ITstream : ITstream(streamOpt, name) { - UIListStream is(input.data(), input.length(), streamOpt); + ISpanStream is(input.data(), input.length(), streamOpt); parseStream(is, static_cast(*this)); ITstream::seek(0); // rewind(), but bypasss virtual @@ -293,7 +293,7 @@ Foam::ITstream::ITstream : ITstream(streamOpt, name) { - UIListStream is(input, strlen(input), streamOpt); + ISpanStream is(input, strlen(input), streamOpt); parseStream(is, static_cast(*this)); ITstream::seek(0); // rewind(), but bypasss virtual diff --git a/src/OpenFOAM/db/IOstreams/compat/IListStream.H b/src/OpenFOAM/db/IOstreams/compat/IListStream.H new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H b/src/OpenFOAM/db/IOstreams/compat/IStringStream.H similarity index 81% rename from src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H rename to src/OpenFOAM/db/IOstreams/compat/IStringStream.H index 5f77ca3d54..43d70ef36b 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/IStringStream.H +++ b/src/OpenFOAM/db/IOstreams/compat/IStringStream.H @@ -4,8 +4,8 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef IStringStream_H -#define IStringStream_H +#ifndef FoamCompat_IStringStream_H +#define FoamCompat_IStringStream_H #include "StringStream.H" diff --git a/src/OpenFOAM/db/IOstreams/compat/ListStream.H b/src/OpenFOAM/db/IOstreams/compat/ListStream.H new file mode 100644 index 0000000000..fbbf27efdb --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/compat/ListStream.H @@ -0,0 +1,10 @@ +// Compatibility include. + +#ifndef FoamCompat_ListStream_H +#define FoamCompat_ListStream_H + +#include "SpanStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/compat/OListStream.H b/src/OpenFOAM/db/IOstreams/compat/OListStream.H new file mode 100644 index 0000000000..0a810ecaa2 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/compat/OListStream.H @@ -0,0 +1,10 @@ +// Compatibility include. + +#ifndef FoamCompat_OListStream_H +#define FoamCompat_UListStream_H + +#include "SpanStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H b/src/OpenFOAM/db/IOstreams/compat/OStringStream.H similarity index 81% rename from src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H rename to src/OpenFOAM/db/IOstreams/compat/OStringStream.H index c4d79e11aa..3f85b5b772 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/OStringStream.H +++ b/src/OpenFOAM/db/IOstreams/compat/OStringStream.H @@ -4,8 +4,8 @@ Description \*---------------------------------------------------------------------------*/ -#ifndef OStringStream_H -#define OStringStream_H +#ifndef FoamCompat_OStringStream_H +#define FoamCompat_OStringStream_H #include "StringStream.H" diff --git a/src/OpenFOAM/db/IOstreams/compat/UIListStream.H b/src/OpenFOAM/db/IOstreams/compat/UIListStream.H new file mode 100644 index 0000000000..402180a755 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/compat/UIListStream.H @@ -0,0 +1,10 @@ +// Compatibility include. + +#ifndef FoamCompat_UIListStream_H +#define FoamCompat_UIListStream_H + +#include "SpanStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/compat/UListStream.H b/src/OpenFOAM/db/IOstreams/compat/UListStream.H new file mode 100644 index 0000000000..a88288e8da --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/compat/UListStream.H @@ -0,0 +1,10 @@ +// Compatibility include. + +#ifndef FoamCompat_UListStream_H +#define FoamCompat_UListStream_H + +#include "SpanStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/compat/UOListStream.H b/src/OpenFOAM/db/IOstreams/compat/UOListStream.H new file mode 100644 index 0000000000..146bc18471 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/compat/UOListStream.H @@ -0,0 +1,10 @@ +// Compatibility include. + +#ifndef FoamCompat_UOListStream_H +#define FoamCompat_UOListStream_H + +#include "SpanStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H index 5f359d5f37..bf13b73805 100644 --- a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H +++ b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2019-2022 OpenCFD Ltd. + Copyright (C) 2019-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -54,23 +54,21 @@ 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: - //- Handle overflow - virtual int overflow(int c = EOF) + //- Output overflow handling - append to SHA1 + virtual int overflow(int_type c = traits_type::eof()) { - if (c != EOF) sha1_.append(c); + if (c != traits_type::eof()) sha1_.append(c); return c; } - //- Put sequence of characters + //- Put sequence of characters - append to SHA1 virtual std::streamsize xsputn(const char* s, std::streamsize n) { if (n) sha1_.append(s, n); @@ -83,10 +81,7 @@ class osha1stream sha1buf() = default; //- Full access to the sha1 - SHA1& sha1() noexcept - { - return sha1_; - } + SHA1& sha1() noexcept { return sha1_; } }; @@ -100,25 +95,22 @@ 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(); - } + 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(); } }; @@ -129,48 +121,21 @@ namespace Detail Class Detail::OSHA1streamAllocator Declaration \*---------------------------------------------------------------------------*/ -//- Allocator for an osha1stream +//- An allocator for holding Foam::osha1stream class OSHA1streamAllocator { protected: // Protected Data - typedef osha1stream stream_type; - //- The output stream - stream_type stream_; + Foam::osha1stream 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 @@ -188,16 +153,15 @@ 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 @@ -211,6 +175,18 @@ 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. @@ -227,7 +203,7 @@ public: // \deprecated(2017-07) - use reset() method void rewind() { - sha1().clear(); + stream_.sha1().clear(); } diff --git a/src/OpenFOAM/db/IOstreams/memory/ICharStream.H b/src/OpenFOAM/db/IOstreams/memory/ICharStream.H new file mode 100644 index 0000000000..5100551dfb --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/ICharStream.H @@ -0,0 +1,352 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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(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 s) + // : + // icharstream() + // { + // reset(buffer, nbytes); + // } + + //- Move construct from List + icharstream(List&& buffer) + : + icharstream() + { + swap(buffer); + } + + //- Move construct from DynamicList + template + icharstream(DynamicList&& 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 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& other) + { + buffer_type::swap(other); + stream_type::clear(); // Clear old errors + } + + //- Transfer list contents to a DynamicList buffer + template + void swap(DynamicList& 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&& buffer, // Fully qualify (issue #1521) + IOstreamOption streamOpt = IOstreamOption() + ) + : + ICharStream(streamOpt) + { + stream_.swap(buffer); + } + + //- Move construct from DynamicList (uses current size) + template + explicit ICharStream + ( + DynamicList&& 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 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& other) + { + stream_.swap(other); + syncState(); + } + + //- Transfer list contents to a DynamicList buffer + template + void swap(DynamicList& 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(*this); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/IListStream.H b/src/OpenFOAM/db/IOstreams/memory/IListStream.H deleted file mode 100644 index cc25c1f665..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/IListStream.H +++ /dev/null @@ -1,261 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -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, - public UIListStreamAllocator -{ -protected: - - // Constructors - - //- Default construct - IListStreamAllocator() - : - List(), - UIListStreamAllocator(List::data(), List::size()) - {} - - //- Move construct from List - IListStreamAllocator(List&& buffer) - : - List(std::move(buffer)), - UIListStreamAllocator(List::data(), List::size()) - {} - - //- Move construct from DynamicList - template - IListStreamAllocator(DynamicList&& buffer) - : - List(std::move(buffer)), - UIListStreamAllocator(List::data(), List::size()) - {} - - - // Protected Member Functions - - //- Convenience method to address the underlying List storage - inline void reset_gbuffer() - { - UIListStreamAllocator::reset - ( - List::data(), - List::size() - ); - } - -public: - - // Member Functions - - //- The current get position in the buffer - using UIListStreamAllocator::size; - - //- Clear storage - inline void clearStorage() - { - List::clear(); - reset_gbuffer(); - } - - //- Transfer contents to other List - inline void swap(List& list) - { - List::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&& 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 - explicit IListStream - ( - DynamicList&& 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(*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&& buffer, // Fully qualify (issue #1521) - IOstreamOption::streamFormat fmt - ) - : - IListStream(std::move(buffer), IOstreamOption(fmt)) - {} - - - //- Move construct from DynamicList - template - explicit IListStream - ( - DynamicList&& buffer, - IOstreamOption::streamFormat fmt - ) - : - IListStream(std::move(buffer), IOstreamOption(fmt)) - {} - - #endif /* Foam_IOstream_extras */ -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H new file mode 100644 index 0000000000..5ff1e69531 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/ISpanStream.H @@ -0,0 +1,352 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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 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(this)) + {} + + //- Construct (shallow copy) for character array and number of bytes + ispanstream(const char* buffer, size_t nbytes) + : + buffer_type(const_cast(buffer), nbytes), + stream_type(static_cast(this)) + {} + + // //- Construct (shallow copy) from span character content + // ispanstream(stdFoam::span s) + // : + // buffer_type(const_cast(s.data()), s.size()), + // stream_type(static_cast(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 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(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(&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& 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& 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 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(*this); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OCharStream.H b/src/OpenFOAM/db/IOstreams/memory/OCharStream.H new file mode 100644 index 0000000000..fe086a5e3c --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/OCharStream.H @@ -0,0 +1,316 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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(this)) + {} + + //- Move construct from List + ocharstream(List&& buffer) + : + ocharstream() + { + swap(buffer); + } + + //- Move construct from DynamicList + template + ocharstream(DynamicList&& 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 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& other) + { + buffer_type::swap(other); + stream_type::clear(); // Clear old errors + } + + //- Transfer list contents to a DynamicList buffer + template + void swap(DynamicList& 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&& buffer, + IOstreamOption streamOpt = IOstreamOption() + ) + : + OCharStream(streamOpt) + { + stream_.swap(buffer); + } + + //- Move construct from a DynamicList (uses entire capacity) + template + explicit OCharStream + ( + ::Foam::DynamicList&& 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 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& other) + { + stream_.swap(other); + syncState(); + } + + //- Transfer list contents to a DynamicList buffer + template + void swap(DynamicList& 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 + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H index 697b6eece8..0e57bcb77f 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2021 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -42,103 +42,6 @@ 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 \*---------------------------------------------------------------------------*/ @@ -149,34 +52,124 @@ public: 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: - //- Default construct - ocountstream() - : - countstreambuf(), - std::ostream(static_cast(this)) - {} + // Constructors + + //- Default construct + ocountstream() : stream_type(&buf_) {} - //- \return The buffer put position == number of bytes counted. - using countstreambuf::tellp; + // Member Functions - //- \return The number of bytes counted - std::streamsize size() const - { - return countstreambuf::tellp(); - } + //- This hides both signatures of std::basic_ios::rdbuf() + countbuf* rdbuf() { return &buf_; } - //- Rewind the stream, reset the count - void rewind() - { - this->pubseekpos(0, std::ios_base::out); - clear(); // for safety, clear any old errors - } + //- \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(); + } }; @@ -187,55 +180,21 @@ namespace Detail Class Detail::OCountStreamAllocator Declaration \*---------------------------------------------------------------------------*/ -//- An stream/stream-buffer allocator for counting +//- An allocator for holding Foam::ocountstream class OCountStreamAllocator { protected: // Protected Data - typedef std::ostream stream_type; - - //- The stream buffer - countstreambuf buf_; - //- The output stream - stream_type stream_; + Foam::ocountstream stream_; // Constructors - //- 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 - } + //- Default construct + OCountStreamAllocator() = default; }; } // End namespace Detail @@ -270,35 +229,33 @@ public: //- Copy construct OCountStream(const OCountStream& str) : - allocator_type(str.size()), + allocator_type(), OSstream(stream_, str.name(), static_cast(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() { - allocator_type::rewind(); - setGood(); // resynchronize with internal state + stream_.reset(); + syncState(); } //- 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 */ }; diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H deleted file mode 100644 index 7e2824738f..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/OListStream.H +++ /dev/null @@ -1,522 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -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 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&& buffer) - : - storage_(std::move(buffer)) - { - init_pbuffer(block_); - } - - //- Move construct from DynamicList. - template - dynbuf(DynamicList&& 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& other) - { - const auto cur = tellp(); // Addressed area - - storage_.swap(other); - storage_.resize(cur); - sync_pbuffer(); - } - - //- Transfer list contents to a DynamicList - template - inline void swap(DynamicList& 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&& buffer) - : - buf_(std::move(buffer)), - stream_(&buf_) - {} - - //- Move construct from DynamicList - template - OListStreamAllocator(DynamicList&& 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 list() const - { - return buf_.list(); - } - - //- Non-const UList access to the characters written (shallow copy). - inline UList 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& other) - { - buf_.swap(other); - } - - //- Transfer list contents to a DynamicList - template - inline void swap(DynamicList& 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&& buffer, - IOstreamOption streamOpt = IOstreamOption() - ) - : - allocator_type(std::move(buffer)), - OSstream(stream_, "output", streamOpt.format(), streamOpt.version()) - {} - - //- Move construct from an existing DynamicList - template - explicit OListStream - ( - DynamicList&& 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&& buffer, - IOstreamOption::streamFormat fmt - ) - : - OListStream(std::move(buffer), IOstreamOption(fmt)) - {} - - //- Move construct from an existing DynamicList - template - OListStream - ( - DynamicList&& buffer, - IOstreamOption::streamFormat fmt - ) - : - OListStream(std::move(buffer), IOstreamOption(fmt)) - {} - - #endif /* Foam_IOstream_extras */ -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H b/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H new file mode 100644 index 0000000000..c1ce9935a5 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/OSpanStream.H @@ -0,0 +1,358 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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 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 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(this)) + {} + + //- Construct for character array and number of bytes + ospanstream(char* buffer, size_t nbytes) + : + buffer_type(buffer, nbytes), + stream_type(static_cast(this)) + {} + + // //- Construct (shallow copy) from span character content + // ospanstream(stdFoam::span s) + // : + // buffer_type(const_cast(s.data()), s.size()), + // stream_type(static_cast(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 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& 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& buffer, + IOstreamOption streamOpt = IOstreamOption() + ) + : + OSpanStream(buffer.data(), buffer.size(), streamOpt) + {} + + //- Construct using full data area from DynamicList + template + explicit OSpanStream + ( + ::Foam::DynamicList& 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 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 + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/ListStream.H b/src/OpenFOAM/db/IOstreams/memory/SpanStream.H similarity index 83% rename from src/OpenFOAM/db/IOstreams/memory/ListStream.H rename to src/OpenFOAM/db/IOstreams/memory/SpanStream.H index 3f56befc2d..cc66d013fb 100644 --- a/src/OpenFOAM/db/IOstreams/memory/ListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/SpanStream.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -24,15 +24,17 @@ License along with OpenFOAM. If not, see . Description - Input/output streams with managed List storage. + Input/output streams with (internal or external) character storage. \*---------------------------------------------------------------------------*/ -#ifndef ListStream_H -#define ListStream_H +#ifndef Foam_SpanStream_H +#define Foam_SpanStream_H -#include "IListStream.H" -#include "OListStream.H" +#include "ISpanStream.H" +#include "ICharStream.H" +#include "OSpanStream.H" +#include "OCharStream.H" #endif diff --git a/src/OpenFOAM/db/IOstreams/memory/ListStream.C b/src/OpenFOAM/db/IOstreams/memory/SpanStreams.C similarity index 74% rename from src/OpenFOAM/db/IOstreams/memory/ListStream.C rename to src/OpenFOAM/db/IOstreams/memory/SpanStreams.C index 7e1869fbf3..961aa44808 100644 --- a/src/OpenFOAM/db/IOstreams/memory/ListStream.C +++ b/src/OpenFOAM/db/IOstreams/memory/SpanStreams.C @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2017 OpenCFD Ltd. + Copyright (C) 2017-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -25,40 +25,39 @@ License \*---------------------------------------------------------------------------*/ -#include "UListStream.H" -#include "ListStream.H" +#include "SpanStream.H" #include "OCountStream.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::IListStream::print(Ostream& os) const +void Foam::ISpanStream::print(Ostream& os) const { - os << "IListStream: "; - printBufInfo(os); + os << "ISpanStream: "; + stream_.debug_info(os); os << Foam::endl; } -void Foam::UIListStream::print(Ostream& os) const +void Foam::OSpanStream::print(Ostream& os) const { - os << "UIListStream: "; - printBufInfo(os); + os << "OSpanStream: "; + stream_.debug_info(os); os << Foam::endl; } -void Foam::OListStream::print(Ostream& os) const +void Foam::ICharStream::print(Ostream& os) const { - os << "OListStream: "; - printBufInfo(os); + os << "ICharStream: "; + stream_.debug_info(os); os << Foam::endl; } -void Foam::UOListStream::print(Ostream& os) const +void Foam::OCharStream::print(Ostream& os) const { - os << "UOListStream: "; - printBufInfo(os); + os << "OCharStream: "; + stream_.debug_info(os); os << Foam::endl; } @@ -66,7 +65,8 @@ void Foam::UOListStream::print(Ostream& os) const void Foam::OCountStream::print(Ostream& os) const { os << "OCountStream: "; - printBufInfo(os); + // os << "count=" << stream_.count(); + stream_.debug_info(os); os << Foam::endl; } diff --git a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H deleted file mode 100644 index 68a4201fa8..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H +++ /dev/null @@ -1,326 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -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 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(buffer), nbytes), - std::istream(static_cast(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 list() const - { - return buf_.list(); - } - - //- Non-const UList access to the input characters (shallow copy). - inline UList 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(buffer), nbytes), - ISstream(stream_, "input", streamOpt.format(), streamOpt.version()) - {} - - //- Construct using data area from a List and number of bytes - UIListStream - ( - const UList& 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& 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(*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& 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& buf, - IOstreamOption::streamFormat fmt - ) - : - UIListStream(buf.cdata(), buf.size(), IOstreamOption(fmt)) - {} - - #endif /* Foam_IOstream_extras */ -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/UListStream.H b/src/OpenFOAM/db/IOstreams/memory/UListStream.H deleted file mode 100644 index da64ede752..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/UListStream.H +++ /dev/null @@ -1,39 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -Description - Input/output streams with externally managed storage. - -\*---------------------------------------------------------------------------*/ - -#ifndef UListStream_H -#define UListStream_H - -#include "UIListStream.H" -#include "UOListStream.H" - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/UOListStream.H b/src/OpenFOAM/db/IOstreams/memory/UOListStream.H deleted file mode 100644 index d970515443..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/UOListStream.H +++ /dev/null @@ -1,326 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -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 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 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 list() const - { - return buf_.list(); - } - - //- Non-const UList access to the characters written (shallow copy). - inline UList 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& 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& buffer, - IOstreamOption streamOpt = IOstreamOption() - ) - : - UOListStream(buffer.data(), buffer.size(), streamOpt) - {} - - //- Construct using data area from a FixedList - template - explicit UOListStream - ( - FixedList& buffer, - IOstreamOption streamOpt = IOstreamOption() - ) - : - UOListStream(buffer.data(), N, streamOpt) - {} - - //- Construct using data area from a DynamicList and its capacity - template - explicit UOListStream - ( - DynamicList& 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& 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& buffer, - IOstreamOption::streamFormat fmt - ) - : - UOListStream(buffer.data(), buffer.size(), IOstreamOption(fmt)) - {} - - //- Construct using data area from a FixedList - template - UOListStream - ( - FixedList& buffer, - IOstreamOption::streamFormat fmt - ) - : - UOListStream(buffer.data(), N, IOstreamOption(fmt)) - {} - - //- Construct using data area from a DynamicList and its capacity - template - UOListStream - ( - DynamicList& buf, - IOstreamOption::streamFormat fmt - ) - : - UOListStream(buf.data(), buf.capacity(), IOstreamOption(fmt)) - {} - - #endif /* Foam_IOstream_extras */ -}; - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -} // End namespace Foam - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -#endif - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H index 4bfc1daa08..be8b31aef9 100644 --- a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -5,7 +5,7 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2016-2020 OpenCFD Ltd. + Copyright (C) 2016-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -28,16 +28,19 @@ Class Description A std::streambuf used for memory buffer streams such as - UIListStream, UOListStream, etc. + ispanstream, ocharstream, etc. \*---------------------------------------------------------------------------*/ #ifndef Foam_memoryStreamBuffer_H #define Foam_memoryStreamBuffer_H +#include "stdFoam.H" // For span #include "UList.H" + +#include +#include // Possibly want stringstream too... #include -#include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -48,7 +51,7 @@ namespace Foam Class memorybuf Declaration \*---------------------------------------------------------------------------*/ -//- A streambuf for memory +//- A streambuf for memory similar to std::spanbuf (C++23) class memorybuf : public std::streambuf @@ -106,11 +109,11 @@ protected: if (testin) { - return (gptr() - eback()); // tellg() + return (gptr() - eback()); // span_tellg() } if (testout) { - return (pptr() - pbase()); // tellp() + return (pptr() - pbase()); // span_tellp() } return -1; @@ -127,126 +130,322 @@ 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; - class out; + class in_base; + class in_dynamic; + class out_base; + class out_dynamic; }; /*---------------------------------------------------------------------------*\ - Class memorybuf::in Declaration + Class memorybuf::in_base Declaration \*---------------------------------------------------------------------------*/ -//- An input streambuf for memory access -class memorybuf::in +//- The base input streambuf with memory access +class memorybuf::in_base : public memorybuf { protected: - //- Default construct - in() = default; - - //- Get sequence of characters + //- Get sequence of characters from a fixed region 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: - //- Construct for character array (can be nullptr) and number of bytes - in(char* s, std::streamsize n) - { - resetg(s, n); - } + // Constructors - //- 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) + //- Default construct + in_base() = default; + + //- Construct for character array (can be nullptr) and number of bytes + in_base(char* s, std::streamsize n) { - setg(s, s, s + n); + resetg(s, n); } - else + + + // 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) { - setg(nullptr, nullptr, nullptr); + if (s) + { + setg(s, s, s + n); + } + else + { + setg(nullptr, nullptr, nullptr); + } } - } - //- The buffer get position - using memorybuf::tellg; + //- The current buffer get position + std::streamsize span_tellg() const { return (gptr() - eback()); } - //- The buffer capacity - inline std::streamsize capacity() const - { - return (egptr() - eback()); - } + //- The get buffer capacity + std::streamsize span_capacity() const { return (egptr() - eback()); } - //- Const UList access to the input characters (shallow copy). - inline const UList list() const - { - return UList(eback(), (egptr() - eback())); - } + //- The number of characters remaining in the get area + std::streamsize span_remaining() const + { + return (gptr() < egptr()) ? (egptr() - gptr()) : 0; + } - //- Non-const UList access to the input characters (shallow copy). - inline UList list() - { - return UList(eback(), (egptr() - eback())); - } + //- Span of the input characters (is modifiable!) + UList span_list() const + { + return UList(eback(), (egptr() - eback())); + } - //- Some information about the input buffer position/capacity - inline void printBufInfo(Ostream& os) const - { - os << "get=" << (gptr() - eback()) // tellp() - << "/" << (egptr() - eback()); // capacity - } + // //- The span of input characters (is modifiable!) + // stdFoam::span span() const + // { + // return stdFoam::span(eback(), (egptr() - eback())); + // } + + //- Some information about the input buffer position/capacity + void info(Ostream& os) const + { + os << "get=" << span_tellg() << '/' << span_capacity(); + } }; /*---------------------------------------------------------------------------*\ - Class memorybuf::out Declaration + Class memorybuf::in_dynamic Declaration \*---------------------------------------------------------------------------*/ //- An output streambuf for memory access -class memorybuf::out +class memorybuf::in_dynamic +: + public memorybuf::in_base +{ +private: + + //- Character storage + List 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&& buffer) + : + storage_(std::move(buffer)) + { + sync_gbuffer(); + } + + //- Move construct from DynamicList (added length only) + template + in_dynamic(::Foam::DynamicList&& 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& other) + { + storage_.swap(other); // Swap contents + sync_gbuffer(); + } + + //- Transfer list contents to a DynamicList buffer + template + void swap(DynamicList& other) + { + List 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 : public memorybuf { protected: - //- Default construct - out() = default; + //- 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 span_list() const + { + return UList(pbase(), (pptr() - pbase())); + } + + //- The span of output characters (is modifiable!) + // stdFoam::span span() const + // { + // return stdFoam::span(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 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; + } //- 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()) { @@ -260,53 +459,111 @@ protected: public: - //- Construct for character array (can be nullptr) and number of bytes - out(char* s, std::streamsize n) - { - resetp(s, n); - } + // Constructors - //- 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) + //- 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)) { - setp(s, s + n); + sync_pbuffer(); } - else + + //- Move construct from List + out_dynamic(::Foam::List&& buffer) + : + storage_(std::move(buffer)) { - setp(nullptr, nullptr); + sync_pbuffer(); } - } - //- The buffer put position - using memorybuf::tellp; + //- Move construct from DynamicList (uses entire capacity) + template + out_dynamic(::Foam::DynamicList&& buffer) + { + buffer.resize(buffer.capacity()); // Use entire space + storage_.transfer(buffer); + sync_pbuffer(); + } - //- The buffer capacity - inline std::streamsize capacity() const - { - return (epptr() - pbase()); - } - //- Const UList access to the characters written (shallow copy). - inline const UList list() const - { - return UList(pbase(), (pptr() - pbase())); - } + // Member Functions - //- Non-const UList access to the characters written (shallow copy). - inline UList list() - { - return UList(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 - //- Some information about the output buffer position/capacity - inline void printBufInfo(Ostream& os) const - { - os << "put=" << (pptr() - pbase()) // tellp() - << "/" << (epptr() - pbase()); // capacity - } + 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& 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 + inline void swap(DynamicList& other) + { + const auto cur = span_tellp(); // Addressed length + List 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(); + } }; diff --git a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C index c5ee670639..c398f09fd0 100644 --- a/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C +++ b/src/OpenFOAM/db/dynamicLibrary/dynamicCode/dynamicCodeContext.C @@ -28,7 +28,6 @@ License #include "dynamicCodeContext.H" #include "stringOps.H" -#include "OSHA1stream.H" // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // diff --git a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C index 7db6427ffa..5ad84f497c 100644 --- a/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C +++ b/src/OpenFOAM/global/fileOperations/masterUncollatedFileOperation/masterUncollatedFileOperation.C @@ -33,7 +33,7 @@ License #include "Time.H" #include "instant.H" #include "IFstream.H" -#include "IListStream.H" +#include "SpanStream.H" #include "masterOFstream.H" #include "decomposedBlockData.H" #include "registerSwitch.H" @@ -630,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 IListStream(std::move(buf))); + isPtr.reset(new ICharStream(std::move(buf))); // With the proper file name isPtr->name() = filePaths[UPstream::myProcNo(comm)]; @@ -2493,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 IListStream(std::move(buf))); + isPtr.reset(new ICharStream(std::move(buf))); // With the proper file name isPtr->name() = filePath; diff --git a/src/fileFormats/abaqus/ABAQUSCore.C b/src/fileFormats/abaqus/ABAQUSCore.C index b9c685b34d..a5422ab898 100644 --- a/src/fileFormats/abaqus/ABAQUSCore.C +++ b/src/fileFormats/abaqus/ABAQUSCore.C @@ -29,7 +29,7 @@ License #include "IFstream.H" #include "ListOps.H" #include "stringOps.H" -#include "UIListStream.H" +#include "SpanStream.H" #include "cellModel.H" #include @@ -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 string-stream + // Grab the line and wrap as spanstream 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(); diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C b/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C index b64e05bb16..8f6dbbb8af 100644 --- a/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C +++ b/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C @@ -25,7 +25,7 @@ License \*---------------------------------------------------------------------------*/ -#include "UIListStream.H" +#include "SpanStream.H" #include "ensightPTraits.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -52,7 +52,7 @@ void Foam::ensightSurfaceReader::readFromLine Type& value ) const { - UIListStream is(buffer.data(), buffer.length()); + ISpanStream is(buffer.data(), buffer.length()); readFromLine(nSkip, is, value); }