diff --git a/applications/test/IStringStream/Test-IStringStream.C b/applications/test/IStringStream/Test-IStringStream.C index cd8ba0e2a6165cba7df6db65c52fb59aa27e2874..b265b15a61f747492bd13552a1bd941cabb0e8df 100644 --- a/applications/test/IStringStream/Test-IStringStream.C +++ b/applications/test/IStringStream/Test-IStringStream.C @@ -36,20 +36,22 @@ using namespace Foam; int main(int argc, char *argv[]) { - IStringStream testStream(Foam::string("1002 sfsd sdfsd")); + IStringStream testStream(Foam::string(" 1002 abcd defg;")); label i(readLabel(testStream)); - Info<< i << endl; + Info<< "label=" << i << nl; - word bla(testStream); - word bla2(testStream); + word w1(testStream); + word w2(testStream); - Info<< bla << tab << bla2 << endl; + Info<< "word=" << w1 << nl; + Info<< "word=" << w2 << nl; - wordList wl(IStringStream("(hello1")()); + testStream.reset("(hello1)"); - Info<< wl << endl; + wordList wl(testStream); + Info<< wl << nl; Info<< "\nEnd\n" << endl; diff --git a/applications/test/IndirectList/Test-IndirectList.C b/applications/test/IndirectList/Test-IndirectList.C index 4727ed52484299843af5648239a65488ba177fa9..449af8ca7d412c6becc83f27026df6cdabdbd296 100644 --- a/applications/test/IndirectList/Test-IndirectList.C +++ b/applications/test/IndirectList/Test-IndirectList.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,15 +27,18 @@ Description #include "IndirectList.H" #include "IOstreams.H" +#include "Fstream.H" #include "ListOps.H" #include "labelIndList.H" +#include "argList.H" using namespace Foam; template<class ListType> void printInfo(const ListType& lst) { - Info<< "addr: " << flatOutput(lst.addressing()) << nl + Info<< "full: " << flatOutput(lst.completeList()) << nl + << "addr: " << flatOutput(lst.addressing()) << nl << "list: " << flatOutput(lst) << nl << endl; } @@ -61,6 +64,15 @@ void testFind(const T& val, const ListType& lst) int main(int argc, char *argv[]) { + argList::addOption + ( + "binary", + "file", + "write lists in binary to specified file" + ); + + argList args(argc, argv); + List<label> completeList(20); forAll(completeList, i) @@ -104,6 +116,55 @@ int main(int argc, char *argv[]) printInfo(idl2); printInfo(idl3); + fileName binaryOutput; + if (args.optionReadIfPresent("binary", binaryOutput)) + { + Info<<"Writing output to " << binaryOutput << endl; + + OFstream os(binaryOutput, IOstream::BINARY); + + os.writeEntry("idl1", idl1); + os.writeEntry("idl2", idl2); + os.writeEntry("idl3", idl3); + } + + if (Pstream::parRun()) + { + if (Pstream::master()) + { + Pout<< "full: " << flatOutput(idl3.completeList()) << nl + << "send: " << flatOutput(idl3) << endl; + + for + ( + int slave = Pstream::firstSlave(); + slave <= Pstream::lastSlave(); + ++slave + ) + { + OPstream toSlave(Pstream::commsTypes::scheduled, slave); + toSlave << idl3; + } + } + else + { + // From master + IPstream fromMaster + ( + Pstream::commsTypes::scheduled, + Pstream::masterNo() + ); + + List<label> recv(fromMaster); + + Pout<<"recv: " << flatOutput(recv) << endl; + } + + // MPI barrier + bool barrier = true; + Pstream::scatter(barrier); + } + Info<< "End\n" << endl; return 0; diff --git a/applications/test/OListStream/Make/files b/applications/test/OListStream/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..583b8e7f0699df33e7deb8b5a2487d7e39c37f43 --- /dev/null +++ b/applications/test/OListStream/Make/files @@ -0,0 +1,3 @@ +Test-OListStream.C + +EXE = $(FOAM_USER_APPBIN)/Test-OListStream diff --git a/applications/test/OListStream/Make/options b/applications/test/OListStream/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..4e772fdf9d7bc94221d127458f9d2ca32850fe69 --- /dev/null +++ b/applications/test/OListStream/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */ +/* EXE_LIBS = -lfiniteVolume */ diff --git a/applications/test/OListStream/Test-OListStream.C b/applications/test/OListStream/Test-OListStream.C new file mode 100644 index 0000000000000000000000000000000000000000..adbbc722d596072b691b89a3f0bb93b197e79a45 --- /dev/null +++ b/applications/test/OListStream/Test-OListStream.C @@ -0,0 +1,79 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Description + +\*---------------------------------------------------------------------------*/ + +#include "OListStream.H" +#include "wordList.H" +#include "IOstreams.H" +#include "argList.H" + +using namespace Foam; + +Ostream& toString(Ostream& os, const UList<char>& list) +{ + os << '"'; + for (const char c : list) + { + os << c; + } + os << '"'; + + return os; +} + + +void printInfo(const OListStream& buf) +{ + Info<< nl << buf.size() << " chars (" << buf.capacity() << " capacity) "; + toString(Info, buf.list()) << endl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + // Buffer storage + DynamicList<char> storage(8); + + OListStream obuf(std::move(storage)); + obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; + + printInfo(obuf); + + obuf.rewind(); + obuf << 100; + + printInfo(obuf); + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/UIBufStream/Make/files b/applications/test/UIBufStream/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..611f5337be73caa53f9565cf46683f476625dfa5 --- /dev/null +++ b/applications/test/UIBufStream/Make/files @@ -0,0 +1,3 @@ +Test-UIBufStream.C + +EXE = $(FOAM_USER_APPBIN)/Test-UIBufStream diff --git a/applications/test/UIBufStream/Make/options b/applications/test/UIBufStream/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..4e772fdf9d7bc94221d127458f9d2ca32850fe69 --- /dev/null +++ b/applications/test/UIBufStream/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */ +/* EXE_LIBS = -lfiniteVolume */ diff --git a/applications/test/UIBufStream/Test-UIBufStream.C b/applications/test/UIBufStream/Test-UIBufStream.C new file mode 100644 index 0000000000000000000000000000000000000000..f183d623ab7983eec345005e3108f0e3c17e5f58 --- /dev/null +++ b/applications/test/UIBufStream/Test-UIBufStream.C @@ -0,0 +1,88 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Description + +\*---------------------------------------------------------------------------*/ + +#include "UIBufStream.H" +#include "UOBufStream.H" +#include "wordList.H" +#include "IOstreams.H" +#include "argList.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + // Buffer storage + DynamicList<char> storage(1000); + + UOBufStream obuf(storage); + obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; + + Info<<"formatted: " << obuf.size() << " chars" << endl; + + // Match size + storage.resize(obuf.size()); + + Info<<"as string: " << string(storage.cdata(), storage.size()) << endl; + + // Attach input buffer - could also do without previous resize + + UIBufStream ibuf(storage, storage.size()); + + token t; + + while (ibuf.good()) + { + ibuf >> t; + if (t.good()) + { + Info<<"token: " << t << endl; + } + } + + Info<< nl << "Repeat..." << endl; + ibuf.rewind(); + + while (ibuf.good()) + { + ibuf >> t; + if (t.good()) + { + Info<<"token: " << t << endl; + } + } + + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C b/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C index 6d1d65b20e21c2f2b7583fdcda1dfd2a54cf0579..87851fcef4a2ee0e9e0c110a8249c2de2a0043f0 100644 --- a/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C +++ b/src/OpenFOAM/containers/Lists/FixedList/FixedListIO.C @@ -91,10 +91,10 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList // Write size (so it is valid dictionary entry) and start delimiter os << Size << token::BEGIN_BLOCK; - // Write contents + // Contents os << L[0]; - // Write end delimiter + // End delimiter os << token::END_BLOCK; } else if @@ -103,31 +103,31 @@ Foam::Ostream& Foam::FixedList<T, Size>::writeList || (Size <= unsigned(shortListLen) && contiguous<T>()) ) { - // Write start delimiter + // Start delimiter os << token::BEGIN_LIST; - // Write contents + // Contents forAll(L, i) { if (i) os << token::SPACE; os << L[i]; } - // Write end delimiter + // End delimiter os << token::END_LIST; } else { - // Write start delimiter + // Start delimiter os << nl << token::BEGIN_LIST << nl; - // Write contents + // Contents forAll(L, i) { os << L[i] << nl; } - // Write end delimiter + // End delimiter os << token::END_LIST << nl; } } diff --git a/src/OpenFOAM/containers/Lists/List/ListIO.C b/src/OpenFOAM/containers/Lists/List/ListIO.C index b21b6a86648404ed633256ba9d503cf0ec84781f..b29418c24a1c3986fbaebd9a7c2ad54d99e212b8 100644 --- a/src/OpenFOAM/containers/Lists/List/ListIO.C +++ b/src/OpenFOAM/containers/Lists/List/ListIO.C @@ -64,10 +64,10 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) } else if (firstToken.isLabel()) { - const label s = firstToken.labelToken(); + const label sz = firstToken.labelToken(); // Set list length to that read - L.setSize(s); + L.setSize(sz); // Read list contents depending on data format @@ -76,11 +76,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) // Read beginning of contents const char delimiter = is.readBeginList("List"); - if (s) + if (sz) { if (delimiter == token::BEGIN_LIST) { - for (label i=0; i<s; ++i) + for (label i=0; i<sz; ++i) { is >> L[i]; @@ -103,7 +103,7 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) "reading the single entry" ); - for (label i=0; i<s; ++i) + for (label i=0; i<sz; ++i) { L[i] = element; } @@ -115,11 +115,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& L) } else { - // contents are binary and contiguous + // Contents are binary and contiguous - if (s) + if (sz) { - is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T)); + is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T)); is.fatalCheck ( diff --git a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C b/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C index 6aff9ed81e06d6d7578419172a584f261250f73f..594aa01e4dd0171902b2d53726b71c77f6d08c0f 100644 --- a/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C +++ b/src/OpenFOAM/containers/Lists/PtrList/PtrListIO.C @@ -48,19 +48,19 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt) if (firstToken.isLabel()) { // Read size of list - const label s = firstToken.labelToken(); + const label sz = firstToken.labelToken(); // Set list length to that read - setSize(s); + setSize(sz); // Read beginning of contents const char delimiter = is.readBeginList("PtrList"); - if (s) + if (sz) { if (delimiter == token::BEGIN_LIST) { - forAll(*this, i) + for (label i=0; i<sz; ++i) { set(i, inewt(is)); @@ -82,7 +82,7 @@ void Foam::PtrList<T>::read(Istream& is, const INew& inewt) "reading the single entry" ); - for (label i=1; i<s; ++i) + for (label i=1; i<sz; ++i) { set(i, tPtr->clone()); } diff --git a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C index de49fc74a0cfbba2a7ff382c4733f142716c46b3..b990952e2d44c9d9501b0f0e53553fea3a2f3031 100644 --- a/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C +++ b/src/OpenFOAM/containers/Lists/UIndirectList/UIndirectListIO.C @@ -39,14 +39,16 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList { const UIndirectList<T>& L = *this; + const label sz = L.size(); + // Write list contents depending on data format if (os.format() == IOstream::ASCII || !contiguous<T>()) { // Can the contents be considered 'uniform' (ie, identical)? - bool uniform = (L.size() > 1 && contiguous<T>()); + bool uniform = (sz > 1 && contiguous<T>()); if (uniform) { - forAll(L, i) + for (label i=1; i < sz; ++i) { if (L[i] != L[0]) { @@ -58,65 +60,72 @@ Foam::Ostream& Foam::UIndirectList<T>::writeList if (uniform) { - // Write size and start delimiter - os << L.size() << token::BEGIN_BLOCK; + // Size and start delimiter + os << sz << token::BEGIN_BLOCK; - // Write contents + // Contents os << L[0]; - // Write end delimiter + // End delimiter os << token::END_BLOCK; } else if ( - L.size() <= 1 || !shortListLen - || (L.size() <= shortListLen && contiguous<T>()) + sz <= 1 || !shortListLen + || (sz <= shortListLen && contiguous<T>()) ) { - // Write size and start delimiter - os << L.size() << token::BEGIN_LIST; + // Size and start delimiter + os << sz << token::BEGIN_LIST; - // Write contents - forAll(L, i) + // Contents + for (label i=0; i < sz; ++i) { if (i) os << token::SPACE; os << L[i]; } - // Write end delimiter + // End delimiter os << token::END_LIST; } else { - // Write size and start delimiter - os << nl << L.size() << nl << token::BEGIN_LIST << nl; + // Size and start delimiter + os << nl << sz << nl << token::BEGIN_LIST << nl; - // Write contents - forAll(L, i) + // Contents + for (label i=0; i < sz; ++i) { os << L[i] << nl; } - // Write end delimiter + // End delimiter os << token::END_LIST << nl; } } else { // Contents are binary and contiguous - os << nl << L.size() << nl; + os << nl << sz << nl; - if (L.size()) + if (sz) { - // This is annoying, and wasteful, but currently no alternative - List<T> lst = L(); - - // write(...) includes surrounding start/end delimiters - os.write - ( - reinterpret_cast<const char*>(lst.cdata()), - lst.byteSize() - ); + // The TOTAL number of bytes to be written. + // - possibly add start delimiter + os.beginRaw(sz*sizeof(T)); + + // Contents + for (label i=0; i < sz; ++i) + { + os.writeRaw + ( + reinterpret_cast<const char*>(&(L[i])), + sizeof(T) + ); + } + + // End delimiter and/or cleanup. + os.endRaw(); } } diff --git a/src/OpenFOAM/containers/Lists/UList/UListIO.C b/src/OpenFOAM/containers/Lists/UList/UListIO.C index efb2ad3ffce3935884d40209ef04f8909eef907e..08d18569172a5261f630f292afe40bb69b69883a 100644 --- a/src/OpenFOAM/containers/Lists/UList/UListIO.C +++ b/src/OpenFOAM/containers/Lists/UList/UListIO.C @@ -76,14 +76,16 @@ Foam::Ostream& Foam::UList<T>::writeList { const UList<T>& L = *this; + const label sz = L.size(); + // Write list contents depending on data format if (os.format() == IOstream::ASCII || !contiguous<T>()) { // Can the contents be considered 'uniform' (ie, identical)? - bool uniform = (L.size() > 1 && contiguous<T>()); + bool uniform = (sz > 1 && contiguous<T>()); if (uniform) { - forAll(L, i) + for (label i=1; i < sz; ++i) { if (L[i] != L[0]) { @@ -95,58 +97,62 @@ Foam::Ostream& Foam::UList<T>::writeList if (uniform) { - // Write size and start delimiter - os << L.size() << token::BEGIN_BLOCK; + // Size and start delimiter + os << sz << token::BEGIN_BLOCK; - // Write contents + // Contents os << L[0]; - // Write end delimiter + // End delimiter os << token::END_BLOCK; } else if ( - L.size() <= 1 || !shortListLen - || (L.size() <= shortListLen && contiguous<T>()) + sz <= 1 || !shortListLen + || (sz <= shortListLen && contiguous<T>()) ) { - // Write size and start delimiter - os << L.size() << token::BEGIN_LIST; + // Size and start delimiter + os << sz << token::BEGIN_LIST; - // Write contents - forAll(L, i) + // Contents + for (label i=0; i < sz; ++i) { if (i) os << token::SPACE; os << L[i]; } - // Write end delimiter + // End delimiter os << token::END_LIST; } else { - // Write size and start delimiter - os << nl << L.size() << nl << token::BEGIN_LIST << nl; + // Size and start delimiter + os << nl << sz << nl << token::BEGIN_LIST << nl; - // Write contents - forAll(L, i) + // Contents + for (label i=0; i < sz; ++i) { os << L[i] << nl; } - // Write end delimiter + // End delimiter os << token::END_LIST << nl; } } else { // Contents are binary and contiguous - os << nl << L.size() << nl; + os << nl << sz << nl; - if (L.size()) + if (sz) { // write(...) includes surrounding start/end delimiters - os.write(reinterpret_cast<const char*>(L.cdata()), L.byteSize()); + os.write + ( + reinterpret_cast<const char*>(L.cdata()), + L.byteSize() + ); } } @@ -184,29 +190,29 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) ) ); // Check list length - const label s = elems.size(); + const label sz = elems.size(); - if (s != L.size()) + if (sz != L.size()) { FatalIOErrorInFunction(is) - << "incorrect length for UList. Read " << s + << "incorrect length for UList. Read " << sz << " expected " << L.size() << exit(FatalIOError); } - for (label i=0; i<s; ++i) + for (label i=0; i<sz; ++i) { L[i] = elems[i]; } } else if (firstToken.isLabel()) { - const label s = firstToken.labelToken(); + const label sz = firstToken.labelToken(); // Set list length to that read - if (s != L.size()) + if (sz != L.size()) { FatalIOErrorInFunction(is) - << "incorrect length for UList. Read " << s + << "incorrect length for UList. Read " << sz << " expected " << L.size() << exit(FatalIOError); } @@ -218,11 +224,11 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) // Read beginning of contents const char delimiter = is.readBeginList("List"); - if (s) + if (sz) { if (delimiter == token::BEGIN_LIST) { - for (label i=0; i<s; ++i) + for (label i=0; i<sz; ++i) { is >> L[i]; @@ -245,7 +251,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) "reading the single entry" ); - for (label i=0; i<s; ++i) + for (label i=0; i<sz; ++i) { L[i] = element; } @@ -259,9 +265,9 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) { // contents are binary and contiguous - if (s) + if (sz) { - is.read(reinterpret_cast<char*>(L.data()), s*sizeof(T)); + is.read(reinterpret_cast<char*>(L.data()), sz*sizeof(T)); is.fatalCheck ( diff --git a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C b/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C index 2852654dda0f7bf017089075463441f9e7d0044f..33ff3d9878ec65fe9bb7ea869b2d0298c8761157 100644 --- a/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C +++ b/src/OpenFOAM/containers/Lists/UPtrList/UPtrListIO.C @@ -31,18 +31,20 @@ License template<class T> Foam::Ostream& Foam::operator<<(Ostream& os, const UPtrList<T>& L) { - // Write size and start delimiter - os << nl << indent << L.size() << nl - << indent << token::BEGIN_LIST << incrIndent; + const label sz = L.size(); - // Write contents - forAll(L, i) + // Size and start delimiter + os << nl << indent << sz << nl + << indent << token::BEGIN_LIST << incrIndent << nl; + + // Contents + for (label i=0; i < sz; ++i) { - os << nl << L[i]; + os << L[i] << nl; } - // Write end delimiter - os << nl << decrIndent << indent << token::END_LIST << nl; + // End delimiter + os << decrIndent << indent << token::END_LIST << nl; os.check(FUNCTION_NAME); return os; diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C index fd3889618ea47660ed761cb72e81277653730c61..f1c97306ed5bbde3abdb9dc21521ddc58f469cff 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.C @@ -167,7 +167,7 @@ const std::istream& Foam::IFstream::stdStream() const } -Foam::Istream& Foam::IFstream::rewind() +void Foam::IFstream::rewind() { lineNumber_ = 1; // Reset line number @@ -195,8 +195,6 @@ Foam::Istream& Foam::IFstream::rewind() { ISstream::rewind(); } - - return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H index 72f89873c58a92447f7de8320ceac5609d0ee7d5..34f7c7c94838139b7a9e5662b09221d4aeb6549c 100644 --- a/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H +++ b/src/OpenFOAM/db/IOstreams/Fstreams/IFstream.H @@ -130,7 +130,7 @@ public: virtual const std::istream& stdStream() const; //- Rewind the stream so that it may be read again - virtual Istream& rewind(); + virtual void rewind(); // Print diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H index 77131761969e0ca866f446bbdf277864f912ae3e..24df823bdda34e50b606e0c79a4ead1e8cd270d2 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams/Istream.H @@ -131,8 +131,8 @@ public: //- Read binary block virtual Istream& read(char*, std::streamsize) = 0; - //- Rewind and return the stream so that it may be read again - virtual Istream& rewind() = 0; + //- Rewind the stream so that it may be read again + virtual void rewind() = 0; // Read List punctuation tokens diff --git a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H index 3604a22d0be60e68812e83f64e6b015aeb04cfb2..916bae2278706c16b128c258c721aa6c8e1e45be 100644 --- a/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H +++ b/src/OpenFOAM/db/IOstreams/IOstreams/Ostream.H @@ -97,47 +97,62 @@ public: // Write functions //- Write next token to stream - virtual Ostream& write(const token&) = 0; + virtual Ostream& write(const token& t) = 0; //- Write character - virtual Ostream& write(const char) = 0; + virtual Ostream& write(const char c) = 0; //- Write character string - virtual Ostream& write(const char*) = 0; + virtual Ostream& write(const char* str) = 0; //- Write word - virtual Ostream& write(const word&) = 0; + virtual Ostream& write(const word& str) = 0; //- Write keyType // A plain word is written unquoted. // A regular expression is written as a quoted string. - virtual Ostream& write(const keyType&); + virtual Ostream& write(const keyType& kw); //- Write string - virtual Ostream& write(const string&) = 0; + virtual Ostream& write(const string& str) = 0; //- Write std::string surrounded by quotes. // Optional write without quotes. virtual Ostream& writeQuoted ( - const std::string&, + const std::string& str, const bool quoted=true ) = 0; //- Write int32_t - virtual Ostream& write(const int32_t) = 0; + virtual Ostream& write(const int32_t val) = 0; //- Write int64_t - virtual Ostream& write(const int64_t) = 0; + virtual Ostream& write(const int64_t val) = 0; //- Write floatScalar - virtual Ostream& write(const floatScalar) = 0; + virtual Ostream& write(const floatScalar val) = 0; //- Write doubleScalar - virtual Ostream& write(const doubleScalar) = 0; + virtual Ostream& write(const doubleScalar val) = 0; - //- Write binary block - virtual Ostream& write(const char*, std::streamsize) = 0; + //- Write binary block. + virtual Ostream& write(const char* data, std::streamsize count) = 0; + + //- Emit begin marker for low-level raw binary output. + // The count should indicate the number of bytes for subsequent + // writeRaw calls. + virtual Ostream& beginRaw(std::streamsize count) = 0; + + //- Low-level raw binary output. + virtual Ostream& writeRaw + ( + const char* data, + std::streamsize count + ) = 0; + + //- Emit end marker for low-level raw binary output. + virtual Ostream& endRaw() = 0; //- Add indentation characters virtual void indent() = 0; @@ -164,11 +179,11 @@ public: void decrIndent(); //- Write the keyword followed by an appropriate indentation - virtual Ostream& writeKeyword(const keyType&); + virtual Ostream& writeKeyword(const keyType& kw); //- Write begin block group with the given name // Increments indentation, adds newline. - virtual Ostream& beginBlock(const keyType&); + virtual Ostream& beginBlock(const keyType& keyword); //- Write begin block group without a name // Increments indentation, adds newline. diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C index 333aeca259c72b0a1b8edbc98155725df7aab477..21b412fce39e6779cb8ac03dfeae043a10fdf5c0 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.C @@ -329,10 +329,9 @@ Foam::Istream& Foam::UIPstream::read(char* data, std::streamsize count) } -Foam::Istream& Foam::UIPstream::rewind() +void Foam::UIPstream::rewind() { externalBufPosition_ = 0; - return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H index 4913693741f8b24e50f858947f6ec90b5943a3bd..d0c0f86552985eae47197f514059bdb90e900223 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UIPstream.H @@ -171,8 +171,8 @@ public: //- Read binary block with 8-byte alignment. Istream& read(char* data, const std::streamsize count); - //- Rewind and return the stream so that it may be read again - Istream& rewind(); + //- Rewind the stream so that it may be read again + void rewind(); // Edit diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C index 6667389b742231d9e691716d6dc487a3503db62a..eb54b5ea61abc2fcb9dad6c4210f0e0f1f846ebc 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.C @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2017 OpenFOAM Foundation - \\/ M anipulation | Copyright (C) 2016 OpenCFD Ltd. + \\/ M anipulation | Copyright (C) 2016-2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -26,15 +26,42 @@ License #include "UOPstream.H" #include "int.H" #include "token.H" - #include <cctype> // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // +inline void Foam::UOPstream::prepareBuffer +( + const size_t count, + const size_t align +) +{ + if (!count) + { + return; + } + + // The current output position + label pos = sendBuf_.size(); + + if (align > 1) + { + // Align output position. Pads sendBuf_.size() - oldPos characters. + pos = align + ((pos - 1) & ~(align - 1)); + } + + // Extend buffer (as required) + sendBuf_.reserve(max(1000, label(pos + count))); + + // Move to the aligned output position + sendBuf_.setSize(pos); +} + + template<class T> -inline void Foam::UOPstream::writeToBuffer(const T& t) +inline void Foam::UOPstream::writeToBuffer(const T& val) { - writeToBuffer(&t, sizeof(T), sizeof(T)); + writeToBuffer(&val, sizeof(T), sizeof(T)); } @@ -55,25 +82,26 @@ inline void Foam::UOPstream::writeToBuffer const size_t align ) { - if (!sendBuf_.capacity()) + if (!count) { - sendBuf_.setCapacity(1000); + return; } - label alignedPos = sendBuf_.size(); + prepareBuffer(count, align); - if (align > 1) - { - // Align bufPosition. Pads sendBuf_.size() - oldPos characters. - alignedPos = align + ((sendBuf_.size() - 1) & ~(align - 1)); - } + // The aligned output position + const label pos = sendBuf_.size(); + + // Extend the addressable range for direct pointer access + sendBuf_.setSize(pos + count); - // Extend if necessary - sendBuf_.setSize(alignedPos + count); + char* const __restrict__ buf = (sendBuf_.begin() + pos); + const char* const __restrict__ input = reinterpret_cast<const char*>(data); - const char* dataPtr = reinterpret_cast<const char*>(data); - size_t i = count; - while (i--) sendBuf_[alignedPos++] = *dataPtr++; + for (size_t i = 0; i < count; ++i) + { + buf[i] = input[i]; + } } @@ -135,7 +163,7 @@ Foam::UOPstream::~UOPstream() { if ( - !UOPstream::write + !UOPstream::write ( commsType_, toProcNo_, @@ -298,6 +326,41 @@ Foam::Ostream& Foam::UOPstream::write } +Foam::Ostream& Foam::UOPstream::beginRaw +( + const std::streamsize count +) +{ + if (format() != BINARY) + { + FatalErrorInFunction + << "stream format not binary" + << Foam::abort(FatalError); + } + + // Alignment = 8, as per write(const char*, streamsize) + prepareBuffer(count, 8); + + return *this; +} + + +Foam::Ostream& Foam::UOPstream::writeRaw +( + const char* data, + const std::streamsize count +) +{ + // No check for format() == BINARY since this is either done in the + // beginRaw() method, or the caller knows what they are doing. + + // Previously aligned and sizes reserved via beginRaw() + writeToBuffer(data, count, 1); + + return *this; +} + + void Foam::UOPstream::print(Ostream& os) const { os << "Writing from processor " << toProcNo_ diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H index 6ee40e03781dc5042ca3b36d08bcaa639d425671..364b10ccddacf3346cbd593c99f898a0e94b2b00 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UOPstream.H @@ -3,7 +3,7 @@ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | \\ / A nd | Copyright (C) 2011-2014 OpenFOAM Foundation - \\/ M anipulation | + \\/ M anipulation | Copyright (C) 2017 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -72,9 +72,12 @@ class UOPstream // Private Member Functions - //- Write a T to the transfer buffer + //- Prepare buffer for count bytes of output at specified alignment. + inline void prepareBuffer(const size_t count, const size_t align); + + //- Write data to the transfer buffer template<class T> - inline void writeToBuffer(const T& t); + inline void writeToBuffer(const T& val); //- Write a char to the transfer buffer inline void writeToBuffer(const char& c); @@ -182,6 +185,24 @@ public: //- Write binary block with 8-byte alignment. Ostream& write(const char* data, const std::streamsize count); + //- Begin marker for low-level raw binary output. + // The count should indicate the number of bytes for subsequent + // writeRaw calls. + Ostream& beginRaw(const std::streamsize count); + + //- Low-level raw binary output. + Ostream& writeRaw + ( + const char* data, + const std::streamsize count + ); + + //- End marker for low-level raw binary output. + Ostream& endRaw() + { + return *this; + } + //- Add indentation characters void indent() {} diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C index 40c2d8e5950f39b6bc7d929944eb8d4a33f92c23..15ad568f18f0f50f226745b3c9a6d60499c9b91a 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.C @@ -798,7 +798,7 @@ Foam::Istream& Foam::ISstream::read(char* buf, std::streamsize count) } -Foam::Istream& Foam::ISstream::rewind() +void Foam::ISstream::rewind() { lineNumber_ = 1; // Reset line number @@ -807,8 +807,6 @@ Foam::Istream& Foam::ISstream::rewind() // pubseekpos() rather than seekg() so that it works with gzstream stdStream().rdbuf()->pubseekpos(0, std::ios_base::in); - - return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H index 18890e208734385fb266bfb9aec79d5039c8ac6e..4a2b510b5b16e0313d48a10c3220490715f569a5 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/ISstream.H @@ -82,7 +82,7 @@ public: // Constructors - //- Construct as wrapper around istream + //- Construct as wrapper around std::istream inline ISstream ( std::istream& is, @@ -163,8 +163,8 @@ public: //- Read binary block virtual Istream& read(char* buf, std::streamsize count); - //- Rewind and return the stream so that it may be read again - virtual Istream& rewind(); + //- Rewind the stream so that it may be read again + virtual void rewind(); // Stream state functions diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C index 5dc8a3e6bd9078250ae44ea908c37b79cd015444..5c6f14103e77dd22d074937fc6a3146bbf58d0d8 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.C @@ -210,7 +210,24 @@ Foam::Ostream& Foam::OSstream::write(const doubleScalar val) } -Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count) +Foam::Ostream& Foam::OSstream::write +( + const char* data, + const std::streamsize count +) +{ + beginRaw(count); + writeRaw(data, count); + endRaw(); + + return *this; +} + + +Foam::Ostream& Foam::OSstream::beginRaw +( + const std::streamsize count +) { if (format() != BINARY) { @@ -220,8 +237,6 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count) } os_ << token::BEGIN_LIST; - os_.write(buf, count); - os_ << token::END_LIST; setState(os_.rdstate()); @@ -229,9 +244,34 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count) } +Foam::Ostream& Foam::OSstream::writeRaw +( + const char* data, + std::streamsize count +) +{ + // No check for format() == BINARY since this is either done in the + // beginRaw() method, or the caller knows what they are doing. + + os_.write(data, count); + setState(os_.rdstate()); + + return *this; +} + + +Foam::Ostream& Foam::OSstream::endRaw() +{ + os_ << token::END_LIST; + setState(os_.rdstate()); + + return *this; +} + + void Foam::OSstream::indent() { - for (unsigned short i = 0; i < indentLevel_*indentSize_; i++) + for (unsigned short i = 0; i < indentLevel_*indentSize_; ++i) { os_ << ' '; } diff --git a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H index 4c6e97fd59386ae6c3c599daaf009fb82e25c107..2dd13c50fb2eb67c5dd8f5aa8582298ce4dd7056 100644 --- a/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H +++ b/src/OpenFOAM/db/IOstreams/Sstreams/OSstream.H @@ -69,7 +69,7 @@ public: // Constructors - //- Construct and set stream status + //- Construct as wrapper around std::ostream and set stream status OSstream ( std::ostream& os, @@ -143,7 +143,26 @@ public: virtual Ostream& write(const doubleScalar val); //- Write binary block - virtual Ostream& write(const char* buf, std::streamsize count); + virtual Ostream& write + ( + const char* data, + const std::streamsize count + ); + + //- Begin marker for low-level raw binary output. + // The count should indicate the number of bytes for subsequent + // writeRaw calls. + virtual Ostream& beginRaw(const std::streamsize count); + + //- Low-level raw binary output. + virtual Ostream& writeRaw + ( + const char* data, + const std::streamsize count + ); + + //- End marker for low-level raw binary output. + virtual Ostream& endRaw(); //- Add indentation characters virtual void indent(); diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H index 1bdbad9adb7dbe9c13c4c7ae3258ce7e61ad7bc5..cee86b47bb61becdd5df0af68b98825c6bd07d61 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H @@ -56,8 +56,11 @@ protected: // Member Data - //- The allocated stream pointer. - StreamType* allocatedPtr_; + //- The stream type + typedef StreamType stream_type; + + //- The input/output stream. + stream_type stream_; // Constructors @@ -65,56 +68,36 @@ protected: //- Construct null StringStreamAllocator() : - allocatedPtr_(new StreamType()) + stream_() {} - //- Construct from pointer, taking ownership - StringStreamAllocator(StreamType* ptr) - : - allocatedPtr_(ptr) - {} - //- Construct from string + //- Copy construct from string StringStreamAllocator(const std::string& buffer) : - allocatedPtr_(new StreamType(buffer)) + stream_(buffer) {} //- Destructor ~StringStreamAllocator() - { - deallocate(); - } - - - // Protected Member Functions - - //- Delete the stream pointer - void deallocate() - { - if (allocatedPtr_) - { - delete allocatedPtr_; - allocatedPtr_ = nullptr; - } - } + {} public: // Public Member Functions - //- Get the string + //- Get the string - as Foam::string rather than std::string Foam::string str() const { - return allocatedPtr_->str(); + return Foam::string(stream_.str()); } //- Set the string void str(const std::string& s) { - allocatedPtr_->str(s); + stream_.str(s); } }; @@ -143,7 +126,7 @@ public: ) : StringStreamAllocator<std::istringstream>(buffer), - ISstream(*allocatedPtr_, name, format, version) + ISstream(stream_, name, format, version) {} @@ -157,7 +140,15 @@ public: ) : StringStreamAllocator<std::istringstream>(buffer), - ISstream(*allocatedPtr_, name, format, version) + ISstream(stream_, name, format, version) + {} + + + //- Construct as copy of content + IStringStream(const IStringStream& str) + : + StringStreamAllocator<std::istringstream>(str.str()), + ISstream(stream_, str.name(), str.format(), str.version()) {} @@ -171,12 +162,18 @@ public: //- Print description to Ostream void print(Ostream& os) const; + //- Reset the input buffer and rewind the stream + void reset(const std::string& s) + { + this->str(s); + this->rewind(); + } + // Member operators //- Return a non-const reference to const Istream - // Needed for read-constructors where the stream argument is temporary: - // e.g. thing thisThing(IFstream("thingFileName")()); + // Needed for read-constructors where the stream argument is temporary. Istream& operator()() const { return const_cast<IStringStream&>(*this); @@ -207,14 +204,15 @@ public: ) : StringStreamAllocator<std::ostringstream>(), - OSstream(*allocatedPtr_, "output", format, version) + OSstream(stream_, "output", format, version) {} - //- Construct as copy - OStringStream(const OStringStream& oss) + + //- Construct as copy of content + OStringStream(const OStringStream& str) : - StringStreamAllocator<std::ostringstream>(oss.str()), - OSstream(*allocatedPtr_, oss.name(), oss.format(), oss.version()) + StringStreamAllocator<std::ostringstream>(str.str()), + OSstream(stream_, str.name(), str.format(), str.version()) {} @@ -236,7 +234,7 @@ public: void rewind() { // pubseekpos() instead of seekp() for symmetry with other classes - allocatedPtr_->rdbuf()->pubseekpos(0, std::ios_base::out); + stream_.rdbuf()->pubseekpos(0, std::ios_base::out); } //- Print description to Ostream diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C index c9dae1229471051a350ac5b68b579104bbf4bbdc..c0890dad9d521caeb0935411f7f99e30cadc5741 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.C @@ -154,7 +154,7 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize) } -Foam::Istream& Foam::ITstream::rewind() +void Foam::ITstream::rewind() { tokenIndex_ = 0; @@ -164,8 +164,6 @@ Foam::Istream& Foam::ITstream::rewind() } setGood(); - - return *this; } diff --git a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H index 26617cb37e6f01edddf7a75c738f1311c21331d7..b8414cc4f23110271be652be7090b583c9a1afed 100644 --- a/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H +++ b/src/OpenFOAM/db/IOstreams/Tstreams/ITstream.H @@ -188,8 +188,8 @@ public: //- Read binary block virtual Istream& read(char*, std::streamsize); - //- Rewind and return the stream so that it may be read again - virtual Istream& rewind(); + //- Rewind the stream so that it may be read again + virtual void rewind(); // Edit diff --git a/src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H similarity index 96% rename from src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H rename to src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H index 9477b087914408dc993a15bb5de59fdda198e995..fa0b441dc2da06f19c48af4b38bfeaaede14cad1 100644 --- a/src/OpenFOAM/db/IOstreams/dummyISstream/dummyISstream.H +++ b/src/OpenFOAM/db/IOstreams/dummy/dummyISstream.H @@ -126,11 +126,10 @@ public: return *this; } - //- Rewind and return the stream so that it may be read again - virtual Istream& rewind() + //- Rewind the stream so that it may be read again + virtual void rewind() { NotImplemented; - return *this; } //- Return flags of stream diff --git a/src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H b/src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H similarity index 97% rename from src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H rename to src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H index 9e8549820db4869fff8b7a11347a90a97614ebd2..b15f892ec21d9955ed41cfc285e26e37d464caa4 100644 --- a/src/OpenFOAM/db/IOstreams/dummyIstream/dummyIstream.H +++ b/src/OpenFOAM/db/IOstreams/dummy/dummyIstream.H @@ -127,8 +127,8 @@ public: return *this; } - //- Rewind and return the stream so that it may be read again - virtual Istream& rewind() + //- Rewind the stream so that it may be read again + virtual void rewind() { NotImplemented; return *this; diff --git a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H index 8a43d3d7b1561245f55a7216698173ae56140242..414259c7951cd0acb0c60c9400fe86ac7b829090 100644 --- a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H +++ b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H @@ -47,55 +47,57 @@ class osha1stream; class OSHA1stream; /*---------------------------------------------------------------------------*\ - Class sha1streambuf Declaration + Class osha1stream Declaration \*---------------------------------------------------------------------------*/ -//- A streambuf class for calculating SHA1 digests -class sha1streambuf +//- A basic output stream for calculating SHA1 digests +class osha1stream : - public std::streambuf + virtual public std::ios, + public std::ostream { - // Private data + //- A streambuf class for calculating SHA1 digests + class sha1buf + : + public std::streambuf + { + //- This does all the work and has its own buffering + SHA1 sha1_; - //- This does all the work and has its own buffering - SHA1 sha1_; + protected: + // Protected members - friend class osha1stream; + //- Put sequence of characters + virtual std::streamsize xsputn(const char* str, std::streamsize n) + { + sha1_.append(str, n); + return n; + } -public: - // Constructors + public: - //- Construct null - sha1streambuf() - {} + // Constructors - // Member Functions + //- Construct null + sha1buf() + {} - // Write - //- Process unbuffered - virtual std::streamsize xsputn(const char* str, std::streamsize n) - { - sha1_.append(str, n); - return n; - } -}; + // Public member functions + //- Full access to the sha1 + inline SHA1& sha1() + { + return sha1_; + } + }; -/*---------------------------------------------------------------------------*\ - Class osha1stream Declaration -\*---------------------------------------------------------------------------*/ -//- A basic output stream for calculating SHA1 digests -class osha1stream -: - virtual public std::ios, - public std::ostream -{ // Private data - sha1streambuf sbuf_; + //- Reference to the underlying buffer + sha1buf buf_; public: @@ -104,23 +106,24 @@ public: //- Construct null osha1stream() : - std::ostream(&sbuf_) + std::ostream(&buf_) {} + // Member Functions // Access //- This hides both signatures of std::basic_ios::rdbuf() - sha1streambuf* rdbuf() + sha1buf* rdbuf() { - return &sbuf_; + return &buf_; } //- Full access to the sha1 SHA1& sha1() { - return sbuf_.sha1_; + return buf_.sha1(); } }; @@ -135,10 +138,12 @@ class OSHA1streamAllocator { protected: - // Member data + // Protected data + + typedef osha1stream stream_type; - //- The allocated stream pointer - osha1stream* allocatedPtr_; + //- The output stream + stream_type stream_; // Constructors @@ -146,36 +151,37 @@ protected: //- Construct null OSHA1streamAllocator() : - allocatedPtr_(new osha1stream()) + stream_() {} //- Destructor ~OSHA1streamAllocator() - { - deallocate(); - } + {} +public: + // Member Functions - //- Delete the stream pointer - void deallocate() + //- Full access to the sha1 + SHA1& sha1() { - if (allocatedPtr_) - { - delete allocatedPtr_; - allocatedPtr_ = nullptr; - } + return stream_.sha1(); } -public: + //- Return SHA1::Digest for the data processed until now + SHA1Digest digest() + { + return stream_.sha1().digest(); + } - //- Full access to the sha1 - SHA1& sha1() + + //- Clear the SHA1 calculation + void reset() { - return allocatedPtr_->sha1(); + return stream_.sha1().clear(); } }; @@ -191,6 +197,7 @@ class OSHA1stream public OSHA1streamAllocator, public OSstream { + typedef OSHA1streamAllocator allocator_type; // Private Member Functions @@ -211,8 +218,8 @@ public: versionNumber version=currentVersion ) : - OSHA1streamAllocator(), - OSstream(*allocatedPtr_, "OSHA1stream", format, version) + allocator_type(), + OSstream(stream_, "sha1", format, version) {} @@ -223,23 +230,6 @@ public: // Member functions - // Access - - //- Return SHA1::Digest for the data processed until now - SHA1Digest digest() - { - return sha1().digest(); - } - - - // Edit - - //- Clear the SHA1 calculation - void reset() - { - sha1().clear(); - } - //- Clear the SHA1 calculation // \deprecated use reset instead (deprecated Jul 2017) void rewind() diff --git a/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H b/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H new file mode 100644 index 0000000000000000000000000000000000000000..0696e1a943007b28abac9eba4f540512311f1925 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H @@ -0,0 +1,266 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::BufStreamAllocator + +Description + Helper for memory buffer streams such as UIBufStream, UOBufStream + +\*---------------------------------------------------------------------------*/ + +#ifndef BufStreamAllocator_H +#define BufStreamAllocator_H + +#include <type_traits> +#include <sstream> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class memorybuf Declaration +\*---------------------------------------------------------------------------*/ + +//- A streambuf class for using externally allocated memory for its buffer +class memorybuf +: + public std::streambuf +{ +protected: + + // Protected members + + //- 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 + ) + { + const bool testin = which & std::ios_base::in; + const bool testout = which & std::ios_base::out; + + if (way == std::ios_base::beg) + { + if (testin) + { + setg(eback(), eback(), egptr()); + gbump(off); + } + if (testout) + { + setp(pbase(), epptr()); + pbump(off); + } + + return off; + } + + if (way == std::ios_base::cur) + { + if (testin) + { + gbump(off); + } + if (testout) + { + pbump(off); + } + } + else if (way == std::ios_base::end) + { + if (testin) + { + gbump(off); + } + if (testout) + { + pbump(off); + } + } + + if (testin) + { + return gptr() - eback(); + } + if (testout) + { + return pptr() - pbase(); + } + + return -1; + } + + + //- Set position pointer to absolute position + 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); + } + + + //- Get sequence of characters + virtual std::streamsize xsgetn(char* s, std::streamsize n) + { + std::streamsize count = 0; + + // some optimization could be possible here + while (count < n && gptr() < egptr()) + { + *(s + count++) = *(gptr()); + gbump(1); + } + + return count; + } + + + //- Put sequence of characters + virtual std::streamsize xsputn(const char* s, std::streamsize n) + { + std::streamsize count = 0; + + // some optimization could be possible here + while (count < n && pptr() < epptr()) + { + *(pptr()) = *(s + count++); + pbump(1); + } + + return count; + } + + +public: + + // Constructors + + //- Construct for specified buffer + memorybuf(char* buffer, std::streamsize num) + { + setg(buffer, buffer, buffer + num); + setp(buffer, buffer + num); + } + +}; + + +/*---------------------------------------------------------------------------*\ + Class BufStreamAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer allocator for external buffers +template<class StreamType, bool Manage=false> +class BufStreamAllocator +{ + // Private data + + //- Storage + char *storage_; + + //- The number of bytes in the storage + std::streamsize len_; + + //- Reference to the underlying buffer + memorybuf buf_; + +protected: + + // Protected data + + typedef StreamType stream_type; + + //- The stream pointer + stream_type stream_; + + + // Constructors + + //- Construct with buffer and number of bytes + BufStreamAllocator(char *buffer, size_t nbytes) + : + storage_(buffer), + len_(nbytes), + buf_(storage_, len_), + stream_(&buf_) + {} + + + //- Destructor + ~BufStreamAllocator() + { + // Possible cleanup of storage + if (Manage && storage_) + { + delete storage_; + storage_ = nullptr; + } + } + + + // Protected Member Functions + + + //- Position of the get buffer + std::streampos tellg() const + { + return const_cast<stream_type&>(stream_).tellg(); + } + + //- Position of the put buffer + std::streampos tellp() const + { + return const_cast<stream_type&>(stream_).tellp(); + } + + +public: + + // Public Member Functions + + //- Move to buffer start, clear errors + void rewind() + { + stream_.rdbuf()->pubseekpos(0); + stream_.clear(); // for safety, clear any old errors + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H new file mode 100644 index 0000000000000000000000000000000000000000..b3ce64b16957a440a0be1ef6e801641760785ae9 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H @@ -0,0 +1,230 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::OSCountStream + +Description + An output stream for calculating byte counts. + +\*---------------------------------------------------------------------------*/ + +#ifndef OScountStream_H +#define OScountStream_H + +#include "OSstream.H" +#include <iostream> + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class countstreambuf Declaration +\*---------------------------------------------------------------------------*/ + +//- A streambuf class for determining byte counts +class countstreambuf +: + public std::streambuf +{ + // Private data + + //- The number of bytes + std::streamsize n_; + +protected: + // Protected members + + //- Put sequence of characters + virtual std::streamsize xsputn(const char* s, std::streamsize num) + { + n_ += num; + return num; + } + + + //- Set position pointer to absolute position + // For the counter, any positioning is ignored and it always acts like + // seekpos(0), which resets the count. + virtual std::streampos seekpos + ( + std::streampos sp, + std::ios_base::openmode which = std::ios_base::in|std::ios_base::out + ) + { + n_ = 0; + return 0; + } + + +public: + + // Constructors + + //- Construct null + countstreambuf() + : + n_(0) + {} + + + // Access + + //- Get number of bytes counted + std::streamsize size() const + { + return n_; + } +}; + + +/*---------------------------------------------------------------------------*\ + Class ocountstream Declaration +\*---------------------------------------------------------------------------*/ + +//- Trivial output stream for calculating byte counts +// Since all output values are discarded, it can also be used as a /dev/null +// output buffer as well +class ocountstream +: + virtual public std::ios, + public std::ostream +{ + // Private data + + countstreambuf buf_; + +public: + + // Constructors + + //- Construct null + ocountstream() + : + std::ostream(&buf_) + {} + + + // Member Functions + + // Access + + //- This hides both signatures of std::basic_ios::rdbuf() + countstreambuf* rdbuf() + { + return &buf_; + } + + + //- Get number of bytes counted + std::streamsize size() const + { + return buf_.size(); + } + + + //- Rewind the stream, reset the count + void rewind() + { + buf_.pubseekpos(0); + clear(); // for safety, clear any old errors + } +}; + + +/*---------------------------------------------------------------------------*\ + Class OCountStream Declaration +\*---------------------------------------------------------------------------*/ + +//- An output stream for calculating byte counts +class OCountStream +: + private ocountstream, + public OSstream +{ + + // Private Member Functions + + //- Disallow default bitwise copy construct + OCountStream(const OCountStream&) = delete; + + //- Disallow default bitwise assignment + void operator=(const OCountStream&) = delete; + +public: + + // Constructors + + //- Construct and set stream status + OCountStream + ( + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + ocountstream(), + OSstream + ( + static_cast<ocountstream&>(*this), + "output", + format, + version + ) + {} + + + //- Destructor + ~OCountStream() + {} + + + // Member functions + + // Access + + //- Return the number of bytes counted + using ocountstream::size; + + + // Edit + + //- Rewind the stream, reset the count, clearing any old errors + void rewind() + { + ocountstream::rewind(); + setGood(); // resynchronize with internal state + } + +}; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H new file mode 100644 index 0000000000000000000000000000000000000000..b76b7f6f7fa7b65cd6c46753ee39d0765a3be3c0 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/OListStream.H @@ -0,0 +1,416 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::OListStream + +Description + An output stream that writes to a DynamicList. + +\*---------------------------------------------------------------------------*/ + +#ifndef OListStream_H +#define OListStream_H + +#include <sstream> +#include "DynamicList.H" +#include "OSstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration +class OListStreamAllocator; + +/*---------------------------------------------------------------------------*\ + Class OListStreamAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer allocator for external buffers +class OListStreamAllocator +{ + //- A streambuf adapter to output to a DynamicList + class olistbuf + : + public std::streambuf + { + friend OListStreamAllocator; + + //- Underlying list storage + DynamicList<char,512> storage_; + + + //- Adjust buffer pointers to agree with list sizes + inline void syncBufferPointers() + { + setp(storage_.data(), storage_.data() + storage_.capacity()); + pbump(storage_.size()); + } + + //- Adjust addressed list size to agree with buffer pointers + inline void syncListSize() + { + storage_.setSize(pptr() - pbase()); + } + + + protected: + + // Protected members + + //- 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::out + ) + { + const bool testout = which & std::ios_base::out; + + if (way == std::ios_base::beg) + { + if (testout) + { + setp(pbase(), epptr()); + pbump(off); + } + + return off; + } + + if (way == std::ios_base::cur) + { + if (testout) + { + pbump(off); + } + } + else if (way == std::ios_base::end) + { + if (testout) + { + pbump(off); + } + } + + if (testout) + { + return pptr() - pbase(); + } + + return -1; + } + + + //- Set position pointer to absolute position + virtual std::streampos seekpos + ( + std::streampos pos, + std::ios_base::openmode which = std::ios_base::out + ) + { + if (which & std::ios_base::out) + { + setp(pbase(), epptr()); + pbump(pos); + + return pptr() - pbase(); + } + + return -1; + } + + + //- Put sequence of characters + virtual std::streamsize xsputn(const char* s, std::streamsize n) + { + const std::streamsize newlen = n + storage_.size(); + + if (newlen > storage_.capacity()) + { + // Either use reserve(), or setCapacity() directly + // with finer control over growth + storage_.reserve(newlen); + syncBufferPointers(); + } + + std::streamsize count = 0; + while (count < n && pptr() < epptr()) + { + *(pptr()) = *(s + count++); + pbump(1); + } + + // Synchronize list size with output + syncListSize(); + + return count; + } + + + public: + + // Constructors + + //- Construct with an empty list + olistbuf() + : + storage_(1024) + { + syncBufferPointers(); + } + + + //- Construct with a specified number of reserved bytes + olistbuf(size_t nbytes) + : + storage_() + { + storage_.reserve(std::max(label(nbytes),1024)); + syncBufferPointers(); + } + + + //- Move construct from an existing List + olistbuf(List<char>&& buffer) + : + storage_(std::move(buffer)) + { + syncBufferPointers(); + } + + + //- Move construct from an existing DynamicList + template<int AnySize> + olistbuf(DynamicList<char,AnySize>&& buffer) + : + storage_(std::move(buffer)) + { + syncBufferPointers(); + } + }; + + + // Private data + + //- Reference to the underlying buffer + olistbuf buf_; + + +protected: + + // Protected data + + typedef std::ostream stream_type; + + //- The output stream + stream_type stream_; + + + // Constructors + + //- Construct with an empty list + OListStreamAllocator() + : + buf_(), + stream_(&buf_) + {} + + + //- Construct with a specified number of reserved bytes + OListStreamAllocator(size_t nbytes) + : + buf_(nbytes), + stream_(&buf_) + {} + + + //- Move construct from an existing List + OListStreamAllocator(List<char>&& buffer) + : + buf_(std::move(buffer)), + stream_(&buf_) + {} + + + //- Move construct from an existing DynamicList + template<int SizeMin> + OListStreamAllocator(DynamicList<char,SizeMin>&& buffer) + : + buf_(std::move(buffer)), + stream_(&buf_) + {} + + + //- Destructor + ~OListStreamAllocator() + {} + + +public: + + // Member Functions + + //- Content as a list of characters + UList<char> list() const + { + return UList<char> + ( + const_cast<char*>(buf_.storage_.cdata()), + buf_.storage_.size() + ); + } + + + //- Content as a list of characters + UList<char>& list() + { + return static_cast<UList<char>&>(buf_.storage_); + } + + //- Return the current list capacity + inline label capacity() const + { + return buf_.storage_.capacity(); + } + + + //- Reserve allocation space for at least this size. + inline void reserve(const label nElem) + { + buf_.storage_.reserve(nElem); + buf_.syncBufferPointers(); + } + + + //- Return the current output position in the buffer + // The same as the DynamicList::size() + std::streampos size() const + { + return const_cast<stream_type&>(stream_).tellp(); + } + + + //- Move to buffer start, clear errors + void rewind() + { + buf_.storage_.clear(); + buf_.syncBufferPointers(); + stream_.clear(); // for safety, clear any old errors + } +}; + + +/*---------------------------------------------------------------------------*\ + Class OListStream Declaration +\*----------------------------------------------d-----------------------------*/ + +//- An OSstream attached a DynamicList +class OListStream +: + public OListStreamAllocator, + public OSstream +{ + typedef OListStreamAllocator allocator_type; + +public: + + // Constructors + + //- Construct with an empty list + OListStream + ( + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(), + OSstream(stream_, "output", format,version) + {} + + + //- Construct with a specified number of reserved bytes + OListStream + ( + size_t nbytes, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(nbytes), + OSstream(stream_, "output", format, version) + {} + + + //- Move construct from an existing List + OListStream + ( + List<char>&& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(std::move(buffer)), + OSstream(stream_, "output", format, version) + {} + + + //- Move construct from an existing DynamicList + template<int SizeMin> + OListStream + ( + DynamicList<char,SizeMin>&& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(std::move(buffer)), + OSstream(stream_, "output", format, version) + {} + + + //- Destructor + ~OListStream() + {} + + + // Member functions + + //- Rewind the stream, clearing any old errors + using allocator_type::rewind; + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H new file mode 100644 index 0000000000000000000000000000000000000000..e02929f181f7b4c5430b8e24138cc39afa5fcdca --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H @@ -0,0 +1,168 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::UIBufStream + +Description + Similar to IStringStream but using an externally managed buffer for its + input. This allows the input buffer to be filled (and refilled) from + various sources. + + Note that this stream will normally be used as a "one-shot" reader. + Caution must be exercised that the referenced buffer remains valid and + without any intermediate resizing for the duration of the stream's use. + + An example of possible use: + \code + DynamicList<char> buffer(4096); // allocate some large buffer + + nread = something.read(buffer.data(),1024); // fill with content + buffer.setSize(nread); // content size + + // construct dictionary, or something else + UIBufStream is(buffer) + dictionary dict1(is); + + // sometime later + nread = something.read(buffer.data(),2048); // fill with content + buffer.setSize(nread); // content size + + // without intermediate variable + dictionary dict2(UIBufStream(buffer)()); + \endcode + +\*---------------------------------------------------------------------------*/ + +#ifndef UIBufStream_H +#define UIBufStream_H + +#include "BufStreamAllocator.H" +#include "ISstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class UIBufStream Declaration +\*---------------------------------------------------------------------------*/ + +class UIBufStream +: + public BufStreamAllocator<std::istream,false>, + public ISstream +{ + typedef BufStreamAllocator<std::istream,false> allocator_type; + +public: + + // Constructors + + //- Construct using specified buffer and number of bytes + UIBufStream + ( + const char* buffer, + size_t nbytes, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + allocator_type(const_cast<char*>(buffer), nbytes), + ISstream(stream_, name, format, version) + {} + + + //- Construct using data area from a List and number of bytes + UIBufStream + ( + const UList<char>& buffer, + label size, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + UIBufStream(buffer.cdata(), size, format,version,name) + {} + + + //- Construct using data area from a List and its inherent storage size + // Uses addressed size, thus no special treatment for a DynamicList + UIBufStream + ( + const UList<char>& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + UIBufStream(buffer.cdata(), buffer.size(), format,version,name) + {} + + + //- Destructor + ~UIBufStream() + {} + + + // 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 + } + + + // Member operators + + //- A non-const reference to const Istream + // Needed for read-constructors where the stream argument is temporary + Istream& operator()() const + { + return const_cast<Istream&>(static_cast<const Istream&>(*this)); + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H new file mode 100644 index 0000000000000000000000000000000000000000..6a8df54e7aea3b3eee4f97ff55a7fffc6d10596d --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H @@ -0,0 +1,190 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\/ M anipulation | +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::UOBufStream + +Description + Similar to OStringStream but using an externally managed buffer for + its output. + + This allows the output buffer to be reused and can make it easier when + writing out data. It is the user's responsibility to ensure proper + synchronization in the sizes. Provided that the external buffer is large + enough that overflow does not occur, the following usage pattern + works. + + \code + DynamicList<char> buffer(4096); // allocate some large buffer + + { + UOBufStream os(buffer); + os << "content1" << " and more content"; + buffer.setSize(os.size()); // synchronize sizes + } + + something.write(buffer, buffer.size()); + \endcode + + Although the UOBufStream is quite lightweight, there may be cases + where it is preferable to reuse the stream as well. + \code + DynamicList<char> buffer(4096); // allocate some large buffer + + UOBufStream os(buffer); + os << "content1" << " and more content"; + buffer.setSize(os.size()); // synchronize sizes + + something.write(buffer, buffer.size()); + + os.rewind(); + os << "content2"; + buffer.setSize(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 + +\*---------------------------------------------------------------------------*/ + +#ifndef UOBufStream_H +#define UOBufStream_H + +#include "BufStreamAllocator.H" +#include "OSstream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +// Forward declaration +template<class T, int SizeMin> class DynamicList; + + +/*---------------------------------------------------------------------------*\ + Class UOBufStream Declaration +\*---------------------------------------------------------------------------*/ + +//- An OSstream attached to an unallocated external buffer +class UOBufStream +: + public BufStreamAllocator<std::ostream,false>, + public OSstream +{ + typedef BufStreamAllocator<std::ostream,false> allocator_type; + +public: + + // Constructors + + //- Construct using specified buffer and number of bytes + UOBufStream + ( + char* buffer, + size_t nbytes, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(buffer, nbytes), + OSstream(stream_, "output", format,version) + {} + + + //- Construct using data area from a List and number of bytes + UOBufStream + ( + UList<char>& buffer, + size_t size, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + UOBufStream(buffer.data(), size, format,version) + {} + + + //- Construct using data area from a List and its inherent storage size + UOBufStream + ( + UList<char>& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + UOBufStream(buffer.data(), buffer.size(), format,version) + {} + + + //- Construct using data area from a DynamicList and its capacity + template<int SizeMin> + UOBufStream + ( + DynamicList<char,SizeMin>& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + UOBufStream(buffer.data(), buffer.capacity(), format,version) + {} + + + //- Destructor + ~UOBufStream() + {} + + + // Member functions + + //- Return the current output position in the buffer + std::streampos size() const + { + return allocator_type::tellp(); + } + + + //- Rewind the stream, clearing any old errors + void rewind() + { + allocator_type::rewind(); + setGood(); // resynchronize with internal state + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //