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/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/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 + +// ************************************************************************* //