diff --git a/applications/test/IListStream/Make/files b/applications/test/IListStream/Make/files new file mode 100644 index 0000000000..7f0914970b --- /dev/null +++ b/applications/test/IListStream/Make/files @@ -0,0 +1,3 @@ +Test-IListStream.C + +EXE = $(FOAM_USER_APPBIN)/Test-IListStream diff --git a/applications/test/IListStream/Make/options b/applications/test/IListStream/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/IListStream/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/IListStream/Test-IListStream.C b/applications/test/IListStream/Test-IListStream.C new file mode 100644 index 0000000000..588550a7a9 --- /dev/null +++ b/applications/test/IListStream/Test-IListStream.C @@ -0,0 +1,151 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Description + +\*---------------------------------------------------------------------------*/ + +#include "ListStream.H" +#include "UListStream.H" +#include "wordList.H" +#include "IOstreams.H" +#include "argList.H" + +using namespace Foam; + +Ostream& toString(Ostream& os, const UList& list) +{ + os << '"'; + for (const char c : list) + { + os << c; + } + os << '"'; + + return os; +} + + +template +void printInfo(const BufType& buf) +{ + Info<< nl << "=========================" << endl; + buf.print(Info); + toString(Info, buf.list()); + Info<< nl << "=========================" << endl; +} + + +void printTokens(Istream& is) +{ + label count = 0; + token t; + while (is.good()) + { + is >> t; + if (t.good()) + { + ++count; + Info<<"token: " << t << endl; + } + } + + Info<< count << " tokens" << endl; +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + // Buffer storage + DynamicList storage(16); + + OListStream obuf(std::move(storage)); + obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; + + // Move contents to output buffer + printInfo(obuf); + + Info< newvalues(52); + // { + // for (int i=0; i<26; ++i) + // { + // newvalues[2*i+0] = char('a' + i); + // newvalues[2*i+1] = char('A' + i); + // } + // } + // ibuf.swap(newvalues); + // + // Info<. + +Description + +\*---------------------------------------------------------------------------*/ + +#include "OCountStream.H" +#include "StringStream.H" +#include "IOstreams.H" +#include "argList.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + OCountStream cnt; + OStringStream str; + + for (label i = 0; i < 50; ++i) + { + str << 1002 << " " << "abcd" << " " + << "def" << " " << 3.14159 << ";\n"; + + cnt << 1002 << " " << "abcd" << " " + << "def" << " " << 3.14159 << ";\n"; + } + + cnt.print(Info); + Info<< "via string-stream: " << str.str().size() << " chars" << endl; + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/test/OListStream/Make/options b/applications/test/OListStream/Make/options index 4e772fdf9d..18e6fe47af 100644 --- a/applications/test/OListStream/Make/options +++ b/applications/test/OListStream/Make/options @@ -1,2 +1,2 @@ -/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */ -/* EXE_LIBS = -lfiniteVolume */ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/OListStream/Test-OListStream.C b/applications/test/OListStream/Test-OListStream.C index adbbc722d5..4c3a758f0f 100644 --- a/applications/test/OListStream/Test-OListStream.C +++ b/applications/test/OListStream/Test-OListStream.C @@ -25,7 +25,7 @@ Description \*---------------------------------------------------------------------------*/ -#include "OListStream.H" +#include "ListStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" @@ -45,10 +45,31 @@ Ostream& toString(Ostream& os, const UList& list) } -void printInfo(const OListStream& buf) +template +void printInfo(const BufType& buf) { - Info<< nl << buf.size() << " chars (" << buf.capacity() << " capacity) "; - toString(Info, buf.list()) << endl; + Info<< nl << "=========================" << endl; + buf.print(Info); + toString(Info, buf.list()); + Info<< nl << "=========================" << endl; +} + + +void printTokens(Istream& is) +{ + label count = 0; + token t; + while (is.good()) + { + is >> t; + if (t.good()) + { + ++count; + Info<<"token: " << t << endl; + } + } + + Info<< count << " tokens" << endl; } @@ -58,18 +79,126 @@ void printInfo(const OListStream& buf) int main(int argc, char *argv[]) { // Buffer storage - DynamicList storage(8); + DynamicList storage(16); OListStream obuf(std::move(storage)); - obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; + + obuf.setBlockSize(100); + + printInfo(obuf); + + // Fill with some content + for (label i = 0; i < 50; ++i) + { + obuf<< 1002 << " " << "abcd" << " " + << "def" << " " << 3.14159 << ";\n"; + } printInfo(obuf); obuf.rewind(); - obuf << 100; + printInfo(obuf); + + for (label i=0; i < 10; ++i) + { + obuf << "item" << i << "\n"; + } printInfo(obuf); + obuf.shrink(); + + Info<< "after shrink" << nl; + printInfo(obuf); + + // Add some more + for (label i=10; i < 15; ++i) + { + obuf << "more" << i << nl; + } + + Info<< "appended more" << nl; + printInfo(obuf); + + // Overwrite at some position + obuf.stdStream().rdbuf()->pubseekpos(0.60 * obuf.size()); + obuf << "<" << nl << "OVERWRITE" << nl; + + Info<<"after overwrite" << nl; + printInfo(obuf); + + Info<< "transfer contents to a List or IListStream" << nl; + + IListStream ibuf(obuf.xfer()); + + Info<<"original:"; + printInfo(obuf); + + Info<<"new input:" << nl; + printInfo(ibuf); + + printTokens(ibuf); + + // Create from other storage types + + Info<< nl; + { + Info<<"create std::move(List)" << endl; + List list(16, 'A'); + + Info<<"input:"; + toString(Info, list) << endl; + + OListStream buf1(std::move(list)); + for (label i = 0; i < 26; ++i) + { + buf1 << char('A' +i); + } + for (label i = 0; i < 26; ++i) + { + buf1 << char('a' +i); + } + + Info<<"orig:"; + toString(Info, list) << endl; + + printInfo(buf1); + } + + Info<< nl; + + List written; + { + Info<<"create List.xfer()" << endl; + List list(16, 'B'); + + Info<<"input:"; + toString(Info, list) << endl; + + OListStream buf1(list.xfer()); + for (label i = 0; i < 26; ++i) + { + buf1 << char('A' + i); + } + for (label i = 0; i < 26; ++i) + { + buf1 << char('a' +i); + } + + Info<<"orig:"; + toString(Info, list) << endl; + + printInfo(buf1); + + // Move back to written + written = buf1.xfer(); + + printInfo(buf1); + } + Info<<"'captured' content "; + toString(Info, written); + + Info<< "\nEnd\n" << endl; return 0; diff --git a/applications/test/UIBufStream/Make/files b/applications/test/UIBufStream/Make/files deleted file mode 100644 index 611f5337be..0000000000 --- a/applications/test/UIBufStream/Make/files +++ /dev/null @@ -1,3 +0,0 @@ -Test-UIBufStream.C - -EXE = $(FOAM_USER_APPBIN)/Test-UIBufStream diff --git a/applications/test/UIBufStream/Make/options b/applications/test/UIBufStream/Make/options deleted file mode 100644 index 4e772fdf9d..0000000000 --- a/applications/test/UIBufStream/Make/options +++ /dev/null @@ -1,2 +0,0 @@ -/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */ -/* EXE_LIBS = -lfiniteVolume */ diff --git a/applications/test/UIListStream/Make/files b/applications/test/UIListStream/Make/files new file mode 100644 index 0000000000..f60abd8967 --- /dev/null +++ b/applications/test/UIListStream/Make/files @@ -0,0 +1,3 @@ +Test-UIListStream.C + +EXE = $(FOAM_USER_APPBIN)/Test-UIListStream diff --git a/applications/test/UIListStream/Make/options b/applications/test/UIListStream/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/UIListStream/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/UIBufStream/Test-UIBufStream.C b/applications/test/UIListStream/Test-UIListStream.C similarity index 74% rename from applications/test/UIBufStream/Test-UIBufStream.C rename to applications/test/UIListStream/Test-UIListStream.C index f183d623ab..fb0a1f378c 100644 --- a/applications/test/UIBufStream/Test-UIBufStream.C +++ b/applications/test/UIListStream/Test-UIListStream.C @@ -25,14 +25,54 @@ Description \*---------------------------------------------------------------------------*/ -#include "UIBufStream.H" -#include "UOBufStream.H" +#include "UListStream.H" #include "wordList.H" #include "IOstreams.H" #include "argList.H" using namespace Foam; +Ostream& toString(Ostream& os, const UList& list) +{ + os << '"'; + for (const char c : list) + { + os << c; + } + os << '"'; + + return os; +} + + +template +void printInfo(const BufType& buf) +{ + Info<< nl << "=========================" << endl; + buf.print(Info); + toString(Info, buf.list()); + Info<< nl << "=========================" << endl; +} + + +void printTokens(Istream& is) +{ + label count = 0; + token t; + while (is.good()) + { + is >> t; + if (t.good()) + { + ++count; + Info<<"token: " << t << endl; + } + } + + Info<< count << " tokens" << endl; +} + + // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: @@ -41,10 +81,10 @@ int main(int argc, char *argv[]) // Buffer storage DynamicList storage(1000); - UOBufStream obuf(storage); + UOListStream obuf(storage); obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; - Info<<"formatted: " << obuf.size() << " chars" << endl; + obuf.print(Info); // Match size storage.resize(obuf.size()); @@ -53,31 +93,14 @@ int main(int argc, char *argv[]) // Attach input buffer - could also do without previous resize - UIBufStream ibuf(storage, storage.size()); + UIListStream ibuf(storage); - token t; - - while (ibuf.good()) - { - ibuf >> t; - if (t.good()) - { - Info<<"token: " << t << endl; - } - } + printTokens(ibuf); Info<< nl << "Repeat..." << endl; ibuf.rewind(); - while (ibuf.good()) - { - ibuf >> t; - if (t.good()) - { - Info<<"token: " << t << endl; - } - } - + printTokens(ibuf); Info<< "\nEnd\n" << endl; diff --git a/src/OpenFOAM/Make/files b/src/OpenFOAM/Make/files index cc59794bae..acf60a63d0 100644 --- a/src/OpenFOAM/Make/files +++ b/src/OpenFOAM/Make/files @@ -175,6 +175,9 @@ $(hashes)/base64Layer.C gzstream = $(Streams)/gzstream $(gzstream)/gzstream.C +memstream = $(Streams)/memory +$(memstream)/ListStream.C + Fstreams = $(Streams)/Fstreams $(Fstreams)/IFstream.C $(Fstreams)/OFstream.C diff --git a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H index cee86b47bb..ab9f335612 100644 --- a/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H +++ b/src/OpenFOAM/db/IOstreams/StringStreams/StringStream.H @@ -79,11 +79,6 @@ protected: {} - //- Destructor - ~StringStreamAllocator() - {} - - public: // Public Member Functions @@ -112,6 +107,8 @@ class IStringStream public StringStreamAllocator, public ISstream { + typedef StringStreamAllocator allocator_type; + public: // Constructors @@ -125,7 +122,7 @@ public: const Foam::string& name="input" ) : - StringStreamAllocator(buffer), + allocator_type(buffer), ISstream(stream_, name, format, version) {} @@ -139,7 +136,7 @@ public: const Foam::string& name="input" ) : - StringStreamAllocator(buffer), + allocator_type(buffer), ISstream(stream_, name, format, version) {} @@ -147,28 +144,23 @@ public: //- Construct as copy of content IStringStream(const IStringStream& str) : - StringStreamAllocator(str.str()), + allocator_type(str.str()), ISstream(stream_, str.name(), str.format(), str.version()) {} - //- Destructor - ~IStringStream() - {} - - // Member Functions - //- Print description to Ostream - void print(Ostream& os) const; - //- Reset the input buffer and rewind the stream - void reset(const std::string& s) + virtual void reset(const std::string& s) { this->str(s); this->rewind(); } + //- Print description to Ostream + virtual void print(Ostream& os) const; + // Member operators @@ -192,6 +184,8 @@ class OStringStream public StringStreamAllocator, public OSstream { + typedef StringStreamAllocator allocator_type; + public: // Constructors @@ -203,7 +197,7 @@ public: versionNumber version=currentVersion ) : - StringStreamAllocator(), + allocator_type(), OSstream(stream_, "output", format, version) {} @@ -211,16 +205,11 @@ public: //- Construct as copy of content OStringStream(const OStringStream& str) : - StringStreamAllocator(str.str()), + allocator_type(str.str()), OSstream(stream_, str.name(), str.format(), str.version()) {} - //- Destructor - ~OStringStream() - {} - - // Member Functions //- Reset the output buffer and rewind the stream @@ -231,14 +220,14 @@ public: } //- Rewind the output stream - void rewind() + virtual void rewind() { // pubseekpos() instead of seekp() for symmetry with other classes stream_.rdbuf()->pubseekpos(0, std::ios_base::out); } //- Print description to Ostream - void print(Ostream& os) const; + virtual void print(Ostream& os) const; }; diff --git a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H index 414259c795..6b9688b73a 100644 --- a/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H +++ b/src/OpenFOAM/db/IOstreams/hashes/OSHA1stream.H @@ -112,8 +112,6 @@ public: // Member Functions - // Access - //- This hides both signatures of std::basic_ios::rdbuf() sha1buf* rdbuf() { @@ -155,11 +153,6 @@ protected: {} - //- Destructor - ~OSHA1streamAllocator() - {} - - public: // Member Functions @@ -223,11 +216,6 @@ public: {} - //- Destructor - ~OSHA1stream() - {} - - // Member functions //- Clear the SHA1 calculation diff --git a/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H b/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H deleted file mode 100644 index 0696e1a943..0000000000 --- a/src/OpenFOAM/db/IOstreams/memory/BufStreamAllocator.H +++ /dev/null @@ -1,266 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / 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 . - -Class - Foam::BufStreamAllocator - -Description - Helper for memory buffer streams such as UIBufStream, UOBufStream - -\*---------------------------------------------------------------------------*/ - -#ifndef BufStreamAllocator_H -#define BufStreamAllocator_H - -#include -#include - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -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 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_).tellg(); - } - - //- Position of the put buffer - std::streampos tellp() const - { - return const_cast(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/IListStream.H b/src/OpenFOAM/db/IOstreams/memory/IListStream.H new file mode 100644 index 0000000000..553a803bc3 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/IListStream.H @@ -0,0 +1,245 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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 IListStream_H +#define IListStream_H + +#include "List.H" +#include "UIListStream.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class IListStreamAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer input allocator for with List storage +class IListStreamAllocator +: + private List, + public UIListStreamAllocator +{ +protected: + + // Constructors + + //- Construct with an empty list + IListStreamAllocator() + : + List(), + UIListStreamAllocator(list_storage()) + {} + + //- Move construct from an existing List + IListStreamAllocator(List&& buffer) + : + List(std::move(buffer)), + UIListStreamAllocator(list_storage()) + {} + + + //- Move construct from an existing DynamicList + template + IListStreamAllocator(DynamicList&& buffer) + : + List(std::move(buffer)), + UIListStreamAllocator(list_storage()) + {} + + //- Transfer (move) construct + IListStreamAllocator(const Xfer>& buffer) + : + List(buffer), + UIListStreamAllocator(list_storage()) + {} + + + // Protected Member Functions + + //- Convenience method to address the underlying List storage + inline List& list_storage() + { + return static_cast&>(*this); + } + +public: + + // Member Functions + + //- The current get position in the buffer + using UIListStreamAllocator::size; + + //- Clear storage + inline void clearStorage() + { + list_storage().clear(); + sync_gbuffer_to_list(); + } + + //- Transfer contents to the Xfer container as a plain List + inline Xfer> xfer() + { + Xfer> moved = list_storage().xfer(); + + // Update buffer pointers for remaining (zero) size list + sync_gbuffer_to_list(); // or rewind + + return moved; + } +}; + + +/*---------------------------------------------------------------------------*\ + Class IListStream Declaration +\*----------------------------------------------d-----------------------------*/ + +//- An ISstream with internal List storage +class IListStream +: + public IListStreamAllocator, + public ISstream +{ + typedef IListStreamAllocator allocator_type; + +public: + + // Constructors + + //- Construct with an empty list + IListStream + ( + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + allocator_type(), + ISstream(stream_, name, format, version) + {} + + + //- Move construct from an existing List + IListStream + ( + List&& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + allocator_type(std::move(buffer)), + ISstream(stream_, name, format, version) + {} + + + //- Move construct from an existing DynamicList + template + IListStream + ( + DynamicList&& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + allocator_type(std::move(buffer)), + ISstream(stream_, name, format, version) + {} + + + //- Transfer (move) construct + IListStream + ( + const Xfer>& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + allocator_type(buffer), + ISstream(stream_, name, format, 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 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 + { + return const_cast(static_cast(*this)); + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/ListStream.C b/src/OpenFOAM/db/IOstreams/memory/ListStream.C new file mode 100644 index 0000000000..0275000177 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/ListStream.C @@ -0,0 +1,72 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +\*---------------------------------------------------------------------------*/ + +#include "UListStream.H" +#include "ListStream.H" +#include "OCountStream.H" + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::IListStream::print(Ostream& os) const +{ + os << "IListStream: "; + printBufInfo(os); + os << Foam::endl; +} + + +void Foam::UIListStream::print(Ostream& os) const +{ + os << "UIListStream: "; + printBufInfo(os); + os << Foam::endl; +} + + +void Foam::OListStream::print(Ostream& os) const +{ + os << "OListStream: "; + printBufInfo(os); + os << Foam::endl; +} + + +void Foam::UOListStream::print(Ostream& os) const +{ + os << "UOListStream: "; + printBufInfo(os); + os << Foam::endl; +} + + +void Foam::OCountStream::print(Ostream& os) const +{ + os << "OCountStream: "; + printBufInfo(os); + os << Foam::endl; +} + + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/ListStream.H b/src/OpenFOAM/db/IOstreams/memory/ListStream.H new file mode 100644 index 0000000000..6ef7518ca0 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/ListStream.H @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Description + Input/output streams with managed List storage. + +\*---------------------------------------------------------------------------*/ + +#ifndef ListStream_H +#define ListStream_H + +#include "IListStream.H" +#include "OListStream.H" + +#endif + +// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H index b3ce64b169..3ae0311667 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H @@ -52,50 +52,51 @@ class countstreambuf // Private data //- The number of bytes - std::streamsize n_; + std::streamsize size_; protected: - // Protected members - //- Put sequence of characters - virtual std::streamsize xsputn(const char* s, std::streamsize num) + //- Simply handle output counting via overflow + virtual int overflow(int c = EOF) + { + if (c != EOF) { - n_ += num; - return num; + ++size_; } + return c; + } - - //- 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; - } + //- 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, + std::ios_base::openmode which = std::ios_base::in|std::ios_base::out + ) + { + size_ = 0; + return 0; + } public: // Constructors - //- Construct null - countstreambuf() + //- Construct null, or with precount size + countstreambuf(std::streamsize precount=0) : - n_(0) + size_(precount) {} // Access - //- Get number of bytes counted + //- Number of bytes counted std::streamsize size() const { - return n_; + return size_; } }; @@ -154,6 +155,62 @@ public: }; +/*---------------------------------------------------------------------------*\ + Class OCountStreamAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer allocator for counting +class OCountStreamAllocator +{ +protected: + + // Protected data + + typedef std::ostream stream_type; + + //- The stream buffer + countstreambuf buf_; + + //- The output stream + stream_type stream_; + + + // Constructors + + //- Construct null, or with precount size + OCountStreamAllocator(std::streamsize precount=0) + : + buf_(precount), + stream_(&buf_) + {} + + + // Protected Member Functions + + void printBufInfo(Ostream& os) const + { + os << "count=" << buf_.size(); + } + +public: + + // Member Functions + + //- The number of bytes counted + std::streamsize size() const + { + return buf_.size(); + } + + //- Rewind the stream, reset the count + void rewind() + { + buf_.pubseekpos(0); + stream_.clear(); // for safety, clear any old errors + } +}; + + /*---------------------------------------------------------------------------*\ Class OCountStream Declaration \*---------------------------------------------------------------------------*/ @@ -161,17 +218,10 @@ public: //- An output stream for calculating byte counts class OCountStream : - private ocountstream, + public OCountStreamAllocator, public OSstream { - - // Private Member Functions - - //- Disallow default bitwise copy construct - OCountStream(const OCountStream&) = delete; - - //- Disallow default bitwise assignment - void operator=(const OCountStream&) = delete; + typedef OCountStreamAllocator allocator_type; public: @@ -184,39 +234,30 @@ public: versionNumber version=currentVersion ) : - ocountstream(), - OSstream - ( - static_cast(*this), - "output", - format, - version - ) + allocator_type(), + OSstream(stream_, "output", format, version) {} - - //- Destructor - ~OCountStream() - {} + //- Copy construct + OCountStream(const OCountStream& os) + : + allocator_type(os.size()), + OSstream(stream_, os.name(), os.format(), os.version()) + {} // 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() + virtual void rewind() { - ocountstream::rewind(); + allocator_type::rewind(); setGood(); // resynchronize with internal state } + //- Print description to Ostream + virtual void print(Ostream& os) const; + }; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H index b76b7f6f7f..756394e6fa 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OListStream.H @@ -25,16 +25,27 @@ Class Foam::OListStream Description - An output stream that writes to a DynamicList. + 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 with a 256 byte block increment. + These values can be changed on construction of via the + reserve() and setBlockSize() methods. + +See Also + Foam::IListStream + Foam::UOListStream + Foam::UIListStream \*---------------------------------------------------------------------------*/ #ifndef OListStream_H #define OListStream_H -#include #include "DynamicList.H" #include "OSstream.H" +#include "memoryStreamBuffer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -48,206 +59,210 @@ class OListStreamAllocator; Class OListStreamAllocator Declaration \*---------------------------------------------------------------------------*/ -//- An stream/stream-buffer allocator for external buffers +//- An stream/stream-buffer output allocator for lists class OListStreamAllocator { - //- A streambuf adapter to output to a DynamicList - class olistbuf + //- A streambuf adapter to output to a List + class listbuf : - public std::streambuf + public memorybuf::output { friend OListStreamAllocator; - //- Underlying list storage - DynamicList storage_; - - - //- Adjust buffer pointers to agree with list sizes - inline void syncBufferPointers() + //- Helper for setting the block size. + // Small list minimum of 64 bytes. + static int min_size(int n) { - setp(storage_.data(), storage_.data() + storage_.capacity()); - pbump(storage_.size()); + return max(64, n); } - //- Adjust addressed list size to agree with buffer pointers - inline void syncListSize() - { - storage_.setSize(pptr() - pbase()); - } + //- Block size when resizing the list + int block_ = 256; + + //- Underlying list storage. + // Internally manage like a DynamicList, but the addressable size + // is known through the stream pointers. + List storage_; 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 - ) + //- Increment capacity directly and + // adjust buffer pointers to agree with list dimensions + inline void minCapacity + ( + const std::streamsize n, + const std::streamsize cur = 0 + ) + { + const auto newEnd = n + cur; + if (newEnd > storage_.size()) { - const bool testout = which & std::ios_base::out; + auto newCapacity = + ( + (storage_.size() + block_) + - (storage_.size() % block_) + ); - if (way == std::ios_base::beg) + while (newCapacity < newEnd) { - if (testout) - { - setp(pbase(), epptr()); - pbump(off); - } - - return off; + newCapacity += block_; } - if (way == std::ios_base::cur) - { - if (testout) - { - pbump(off); - } - } - else if (way == std::ios_base::end) - { - if (testout) - { - pbump(off); - } - } + // Info<<"request:" << newEnd + // << " cur cap:" << storage_.size() + // << " new cap:" << newCapacity + // << " pos:" << cur + // << " incr:" << incr << endl; - if (testout) - { - return pptr() - pbase(); - } + storage_.setSize(newCapacity); + sync_pbuffer_to_list(); + pbump(cur); + } + } - return -1; + //- 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; + } - //- 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; - } + //- Initialize put buffer + void init_pbuffer(const std::streamsize n) + { + set_pbuffer(storage_); + minCapacity(n); + } public: - // Constructors + // Constructors - //- Construct with an empty list - olistbuf() - : - storage_(1024) - { - syncBufferPointers(); - } + //- Construct with an empty list, or specified number of reserved bytes + listbuf(size_t nbytes = 512) + : + storage_() + { + init_pbuffer(min_size(nbytes)); + } + + //- Move construct content from an existing List + listbuf(List&& buffer) + : + storage_(std::move(buffer)) + { + init_pbuffer(block_); + } + + //- Move construct content from an existing DynamicList + template + listbuf(DynamicList&& buffer) + : + storage_(std::move(buffer)) + { + init_pbuffer(block_); + } + + //- Transfer (move) construct + listbuf(const Xfer>& buffer) + : + storage_(buffer) + { + init_pbuffer(block_); + } - //- Construct with a specified number of reserved bytes - olistbuf(size_t nbytes) - : - storage_() - { - storage_.reserve(std::max(label(nbytes),1024)); - syncBufferPointers(); - } + // Member Functions + //- Return the current list output capacity + inline label capacity() const + { + return storage_.size(); + } - //- Move construct from an existing List - olistbuf(List&& buffer) - : - storage_(std::move(buffer)) - { - syncBufferPointers(); - } + //- Sync put buffer pointers to agree with list dimensions + inline void sync_pbuffer_to_list() + { + set_pbuffer(storage_); + } + //- Clear storage + inline void clearStorage() + { + storage_.clear(); + sync_pbuffer_to_list(); + } - //- Move construct from an existing DynamicList - template - olistbuf(DynamicList&& buffer) - : - storage_(std::move(buffer)) - { - syncBufferPointers(); - } + //- Shrink to addressed storage + inline void shrink() + { + const auto cur = tellp(); + storage_.setSize(cur); + sync_pbuffer_to_list(); + pbump(cur); + } }; - - // Private data - - //- Reference to the underlying buffer - olistbuf buf_; - - protected: // Protected data typedef std::ostream stream_type; - //- The output stream + //- The stream buffer + listbuf buf_; + + //- The 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) + //- Construct with an empty list or specified number of reserved bytes + OListStreamAllocator(size_t nbytes = 512) : buf_(nbytes), stream_(&buf_) {} - //- Move construct from an existing List OListStreamAllocator(List&& buffer) : @@ -255,7 +270,6 @@ protected: stream_(&buf_) {} - //- Move construct from an existing DynamicList template OListStreamAllocator(DynamicList&& buffer) @@ -264,71 +278,117 @@ protected: stream_(&buf_) {} + //- Transfer (move) construct + OListStreamAllocator(const Xfer>& buffer) + : + buf_(buffer), + stream_(&buf_) + {} - //- Destructor - ~OListStreamAllocator() - {} + // Protected Member Functions + + void printBufInfo(Ostream& os) const + { + os << "pos=" << buf_.tellp() + << " capacity=" << buf_.capacity() + << " block=" << buf_.block_; + } public: // Member Functions - //- Content as a list of characters - UList list() const + //- The current list output capacity + inline label capacity() const + { + return buf_.capacity(); + } + + + //- 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); + } + + + //- The current output position in the buffer, + // which is also the addressed list size + inline label size() const + { + return buf_.tellp(); + } + + + //- Const access to written contents as a list of characters + inline const UList list() const { return UList ( const_cast(buf_.storage_.cdata()), - buf_.storage_.size() + buf_.tellp() ); } - //- Content as a list of characters - UList& list() + //- Non-const access to written contents as a list of characters + inline UList list() { - return static_cast&>(buf_.storage_); - } - - //- Return the current list capacity - inline label capacity() const - { - return buf_.storage_.capacity(); + return UList(buf_.storage_.data(), buf_.tellp()); } - //- Reserve allocation space for at least this size. - inline void reserve(const label nElem) + //- Transfer contents to the Xfer container as a plain List + inline Xfer> xfer() { - 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_).tellp(); + buf_.shrink(); // Shrink to addressed area + auto lst = buf_.storage_.xfer(); + buf_.sync_pbuffer_to_list(); + return lst; } //- Move to buffer start, clear errors void rewind() { - buf_.storage_.clear(); - buf_.syncBufferPointers(); + buf_.pubseekpos(0, std::ios_base::out); stream_.clear(); // for safety, clear any old errors } + + //- 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 + } + }; /*---------------------------------------------------------------------------*\ Class OListStream Declaration -\*----------------------------------------------d-----------------------------*/ +\*---------------------------------------------------------------------------*/ -//- An OSstream attached a DynamicList +//- An OSstream attached to a List class OListStream : public OListStreamAllocator, @@ -348,7 +408,7 @@ public: ) : allocator_type(), - OSstream(stream_, "output", format,version) + OSstream(stream_, "output", format, version) {} @@ -391,16 +451,30 @@ public: OSstream(stream_, "output", format, version) {} - - //- Destructor - ~OListStream() - {} + //- Transfer (move) construct + OListStream + ( + const Xfer>& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + allocator_type(buffer), + OSstream(stream_, "output", format, version) + {} // Member functions //- Rewind the stream, clearing any old errors - using allocator_type::rewind; + virtual void rewind() + { + allocator_type::rewind(); + setGood(); // resynchronize with internal state + } + + //- Print description to Ostream + virtual void print(Ostream& os) const; }; diff --git a/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H similarity index 52% rename from src/OpenFOAM/db/IOstreams/memory/UIBufStream.H rename to src/OpenFOAM/db/IOstreams/memory/UIListStream.H index e02929f181..e7db211c1d 100644 --- a/src/OpenFOAM/db/IOstreams/memory/UIBufStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see . Class - Foam::UIBufStream + Foam::UIListStream Description Similar to IStringStream but using an externally managed buffer for its @@ -41,7 +41,7 @@ Description buffer.setSize(nread); // content size // construct dictionary, or something else - UIBufStream is(buffer) + UIListStream is(buffer) dictionary dict1(is); // sometime later @@ -49,16 +49,23 @@ Description buffer.setSize(nread); // content size // without intermediate variable - dictionary dict2(UIBufStream(buffer)()); + dictionary dict2(UIListStream(buffer)()); \endcode +See Also + Foam::IListStream + Foam::OListStream + Foam::UOListStream + \*---------------------------------------------------------------------------*/ -#ifndef UIBufStream_H -#define UIBufStream_H +#ifndef UIListStream_H +#define UIListStream_H -#include "BufStreamAllocator.H" +#include "FixedList.H" +#include "UList.H" #include "ISstream.H" +#include "memoryStreamBuffer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -66,22 +73,149 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class UIBufStream Declaration + Class UIListAllocator Declaration \*---------------------------------------------------------------------------*/ -class UIBufStream +//- An stream/stream-buffer input allocator for a externally allocated lists +class UIListStreamAllocator +{ + //- A streambuf class for input from UList or equivalent + class ulistbuf + : + public memorybuf::input + { + friend UIListStreamAllocator; + + //- Underlying list storage + UList list_; + + public: + + //- Construct for specified buffer + ulistbuf(UList& buffer) + : + list_(buffer) + { + set_gbuffer(list_); + } + + //- Construct for specified buffer + ulistbuf(char* buffer, std::streamsize num) + : + list_(buffer, num) + { + set_gbuffer(list_); + } + + //- Sync get buffer pointers to agree with list dimensions + inline void sync_gbuffer_to_list() + { + set_gbuffer(list_); + } + }; + +protected: + + // Protected data + + typedef std::istream stream_type; + + //- The stream buffer + ulistbuf buf_; + + //- The stream + stream_type stream_; + + + // Constructors + + //- Construct with list buffer + UIListStreamAllocator(UList& list) + : + buf_(list), + stream_(&buf_) + {} + + //- Construct with buffer and number of bytes + UIListStreamAllocator(char *buffer, size_t nbytes) + : + buf_(buffer, nbytes), + stream_(&buf_) + {} + + + // Protected Member Functions + + //- Sync get buffer pointers to agree with list dimensions + inline void sync_gbuffer_to_list() + { + buf_.sync_gbuffer_to_list(); + } + + void printBufInfo(Ostream& os) const + { + os << "pos=" << buf_.tellg() + << " size=" << buf_.list_.size(); + } + +public: + + // Public Member Functions + + //- Const access to available contents as a list of characters + inline const UList& list() const + { + return buf_.list_; + } + + + //- Non-const access to available contents as a list of characters + inline UList list() + { + return buf_.list_; + } + + + //- The list size + inline label size() const + { + return buf_.list_.size(); + } + + + //- 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 + } +}; + + +/*---------------------------------------------------------------------------*\ + Class UIListStream Declaration +\*---------------------------------------------------------------------------*/ + +class UIListStream : - public BufStreamAllocator, + public UIListStreamAllocator, public ISstream { - typedef BufStreamAllocator allocator_type; + typedef UIListStreamAllocator allocator_type; public: // Constructors //- Construct using specified buffer and number of bytes - UIBufStream + UIListStream ( const char* buffer, size_t nbytes, @@ -95,8 +229,21 @@ public: {} + //- Construct using data area from a FixedList + template + UIListStream + ( + const FixedList& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion, + const Foam::string& name="input" + ) + : + UIListStream(buffer.cdata(), FixedSize, format, version, name) + {} + //- Construct using data area from a List and number of bytes - UIBufStream + UIListStream ( const UList& buffer, label size, @@ -105,13 +252,13 @@ public: const Foam::string& name="input" ) : - UIBufStream(buffer.cdata(), size, format,version,name) + UIListStream(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 + UIListStream ( const UList& buffer, streamFormat format=ASCII, @@ -119,15 +266,10 @@ public: const Foam::string& name="input" ) : - UIBufStream(buffer.cdata(), buffer.size(), format,version,name) + UIListStream(buffer.cdata(), buffer.size(), format, version, name) {} - //- Destructor - ~UIBufStream() - {} - - // Member functions //- Return the current get position in the buffer @@ -145,6 +287,10 @@ public: } + //- Print description to Ostream + virtual void print(Ostream& os) const; + + // Member operators //- A non-const reference to const Istream diff --git a/src/OpenFOAM/db/IOstreams/memory/UListStream.H b/src/OpenFOAM/db/IOstreams/memory/UListStream.H new file mode 100644 index 0000000000..132dc81212 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/UListStream.H @@ -0,0 +1,37 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +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/UOBufStream.H b/src/OpenFOAM/db/IOstreams/memory/UOListStream.H similarity index 52% rename from src/OpenFOAM/db/IOstreams/memory/UOBufStream.H rename to src/OpenFOAM/db/IOstreams/memory/UOListStream.H index 6a8df54e7a..5500fb5383 100644 --- a/src/OpenFOAM/db/IOstreams/memory/UOBufStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/UOListStream.H @@ -22,7 +22,7 @@ License along with OpenFOAM. If not, see . Class - Foam::UOBufStream + Foam::UOListStream Description Similar to OStringStream but using an externally managed buffer for @@ -38,7 +38,7 @@ Description DynamicList buffer(4096); // allocate some large buffer { - UOBufStream os(buffer); + UOListStream os(buffer); os << "content1" << " and more content"; buffer.setSize(os.size()); // synchronize sizes } @@ -46,12 +46,12 @@ Description something.write(buffer, buffer.size()); \endcode - Although the UOBufStream is quite lightweight, there may be cases + 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 - UOBufStream os(buffer); + UOListStream os(buffer); os << "content1" << " and more content"; buffer.setSize(os.size()); // synchronize sizes @@ -70,41 +70,171 @@ Description something.write(buffer, os.size()); \endcode +See Also + Foam::IListStream + Foam::OListStream + Foam::UIListStream + \*---------------------------------------------------------------------------*/ -#ifndef UOBufStream_H -#define UOBufStream_H +#ifndef UOListStream_H +#define UOListStream_H -#include "BufStreamAllocator.H" +#include "DynamicList.H" +#include "FixedList.H" #include "OSstream.H" +#include "memoryStreamBuffer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // namespace Foam { -// Forward declaration -template class DynamicList; +/*---------------------------------------------------------------------------*\ + Class UOListAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer allocator for external buffers +class UOListAllocator +{ + //- A streambuf adapter for output to UList or equivalent + class ulistbuf + : + public memorybuf::output + { + friend UOListAllocator; + + //- Underlying list storage + UList list_; + + public: + + // Constructors + + //- Construct for specified buffer + ulistbuf(char* buffer, std::streamsize num) + : + list_(buffer, num) + { + set_pbuffer(list_); + } + + + // Member Functions + + //- Return the current list output capacity + inline label capacity() const + { + return list_.size(); + } + + //- Sync put buffer pointers to agree with list dimensions + inline void sync_pbuffer_to_list() + { + set_pbuffer(list_); + } + }; + + +protected: + + // Protected data + + typedef std::ostream stream_type; + + //- The stream buffer + ulistbuf buf_; + + //- The stream + stream_type stream_; + + + // Constructors + + //- Construct with buffer and number of bytes + UOListAllocator(char *buffer, size_t nbytes) + : + buf_(buffer, nbytes), + stream_(&buf_) + {} + + + // Protected Member Functions + + void printBufInfo(Ostream& os) const + { + os << "pos=" << buf_.tellp() + << " capacity=" << buf_.capacity(); + } + +public: + + // Public Member Functions + + //- 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(); + } + + + //- Const access to written contents as a list of characters + inline const UList list() const + { + return UList + ( + const_cast(buf_.list_.cdata()), + buf_.tellp() + ); + } + + + //- Non-const access to written contents as a list of characters + inline UList list() + { + return UList + ( + const_cast(buf_.list_.cdata()), + 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 + } +}; /*---------------------------------------------------------------------------*\ - Class UOBufStream Declaration + Class UOListStream Declaration \*---------------------------------------------------------------------------*/ //- An OSstream attached to an unallocated external buffer -class UOBufStream +class UOListStream : - public BufStreamAllocator, + public UOListAllocator, public OSstream { - typedef BufStreamAllocator allocator_type; + typedef UOListAllocator allocator_type; public: // Constructors //- Construct using specified buffer and number of bytes - UOBufStream + UOListStream ( char* buffer, size_t nbytes, @@ -113,12 +243,12 @@ public: ) : allocator_type(buffer, nbytes), - OSstream(stream_, "output", format,version) + OSstream(stream_, "output", format, version) {} //- Construct using data area from a List and number of bytes - UOBufStream + UOListStream ( UList& buffer, size_t size, @@ -126,56 +256,58 @@ public: versionNumber version=currentVersion ) : - UOBufStream(buffer.data(), size, format,version) + UOListStream(buffer.data(), size, format, version) {} + //- Construct using data area from a FixedList + template + UOListStream + ( + FixedList& buffer, + streamFormat format=ASCII, + versionNumber version=currentVersion + ) + : + UOListStream(buffer.data(), FixedSize, format, version) + {} //- Construct using data area from a List and its inherent storage size - UOBufStream + UOListStream ( UList& buffer, streamFormat format=ASCII, versionNumber version=currentVersion ) : - UOBufStream(buffer.data(), buffer.size(), format,version) + UOListStream(buffer.data(), buffer.size(), format, version) {} //- Construct using data area from a DynamicList and its capacity template - UOBufStream + UOListStream ( DynamicList& buffer, streamFormat format=ASCII, versionNumber version=currentVersion ) : - UOBufStream(buffer.data(), buffer.capacity(), format,version) + UOListStream(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() + virtual void rewind() { allocator_type::rewind(); setGood(); // resynchronize with internal state } + //- Print description to Ostream + virtual void print(Ostream& os) const; + }; diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H new file mode 100644 index 0000000000..d0f412f1a4 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -0,0 +1,224 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / 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 . + +Class + Foam::memorybuf + +Description + A std::streambuf used for memory buffer streams such as + UIListStream, UOListStream, etc. + +\*---------------------------------------------------------------------------*/ + +#ifndef memoryStreamBuffer_H +#define memoryStreamBuffer_H + +#include "UList.H" +#include +#include + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class memorybuf Declaration +\*---------------------------------------------------------------------------*/ + +//- A streambuf for memory +class memorybuf +: + public std::streambuf +{ +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 + ) + { + 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); + } + } + else if (way == std::ios_base::cur) + { + if (testin) + { + gbump(off); + } + if (testout) + { + pbump(off); + } + } + else if (way == std::ios_base::end) + { + if (testin) + { + setg(eback(), eback(), egptr()); + gbump(egptr() - eback() - off); + } + if (testout) + { + setp(pbase(), epptr()); + pbump(epptr() - pbase() - off); + } + } + + if (testin) + { + return (gptr() - eback()); // tellg() + } + if (testout) + { + return (pptr() - pbase()); // tellp() + } + + 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); + } + + +public: + + // Forward declarations + class input; + class output; +}; + + +/*---------------------------------------------------------------------------*\ + Class memorybuf::input Declaration +\*---------------------------------------------------------------------------*/ + +//- An output streambuf for memory access +class memorybuf::input +: + public memorybuf +{ +protected: + + //- Get sequence of characters + virtual std::streamsize xsgetn(char* s, std::streamsize n) + { + std::streamsize count = 0; + + while (count < n && gptr() < egptr()) + { + *(s + count++) = *(gptr()); + gbump(1); + } + + return count; + } + + + //- The buffer get position + inline std::streamsize tellg() const + { + return (gptr() - eback()); + } + + //- Sync get buffer pointers to agree with list dimensions + inline void set_gbuffer(UList& list) + { + setg(list.begin(), list.begin(), list.end()); + } +}; + + +/*---------------------------------------------------------------------------*\ + Class memorybuf::output Declaration +\*---------------------------------------------------------------------------*/ + +//- An output streambuf for memory access +class memorybuf::output +: + public memorybuf +{ +protected: + + //- Put sequence of characters + 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; + } + + //- The buffer put position + inline std::streamsize tellp() const + { + return (pptr() - pbase()); + } + + //- Sync put buffer pointers to agree with list dimensions + inline void set_pbuffer(UList& list) + { + setp(list.begin(), list.end()); + } + +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //