From 23c9dd716d780cd202a868a4a2e0952b0909b6e4 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Mon, 22 Jan 2018 09:42:06 +0100 Subject: [PATCH] ENH: coding cleanup for memory streams - simplify structure. - protect against nullptr when resetting memory streams - make UIListStream swappable - add uiliststream as an example of using a plain std::istream --- .../test/IListStream/Test-IListStream.C | 40 +++-- .../test/OCountStream/Test-OCountStream.C | 15 +- .../test/UIListStream/Test-UIListStream.C | 97 ++++++++++- .../db/IOstreams/memory/IListStream.H | 48 +++--- .../db/IOstreams/memory/OCountStream.H | 97 ++++------- .../db/IOstreams/memory/OListStream.H | 156 +++++++++--------- .../db/IOstreams/memory/UIListStream.H | 122 ++++++-------- .../db/IOstreams/memory/UOListStream.H | 105 +++--------- .../db/IOstreams/memory/memoryStreamBuffer.H | 118 +++++++++++-- 9 files changed, 450 insertions(+), 348 deletions(-) diff --git a/applications/test/IListStream/Test-IListStream.C b/applications/test/IListStream/Test-IListStream.C index 588550a7a9..42c5e03883 100644 --- a/applications/test/IListStream/Test-IListStream.C +++ b/applications/test/IListStream/Test-IListStream.C @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -56,6 +56,15 @@ void printInfo(const BufType& buf) } +template<> +void printInfo(const List& buf) +{ + Info<< nl << "=========================" << endl; + toString(Info, buf); + Info<< nl << "=========================" << endl; +} + + void printTokens(Istream& is) { label count = 0; @@ -126,21 +135,22 @@ int main(int argc, char *argv[]) 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< 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< +#include + using namespace Foam; Ostream& toString(Ostream& os, const UList& list) @@ -45,6 +48,19 @@ Ostream& toString(Ostream& os, const UList& list) } +Ostream& toString(Ostream& os, const std::vector& list) +{ + os << '"'; + for (const char c : list) + { + os << c; + } + os << '"'; + + return os; +} + + template void printInfo(const BufType& buf) { @@ -55,6 +71,15 @@ void printInfo(const BufType& buf) } +template<> +void printInfo(const UList& buf) +{ + Info<< nl << "=========================" << endl; + toString(Info, buf); + Info<< nl << "=========================" << endl; +} + + void printTokens(Istream& is) { label count = 0; @@ -82,7 +107,7 @@ int main(int argc, char *argv[]) DynamicList storage(1000); UOListStream obuf(storage); - obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n"; + obuf << 1002 << "\n" << "abcd" << "\n" << "def" << "\n" << 3.14159 << ";\n"; obuf.print(Info); @@ -92,15 +117,73 @@ int main(int argc, char *argv[]) Info<<"as string: " << string(storage.cdata(), storage.size()) << endl; // Attach input buffer - could also do without previous resize + { + UIListStream ibuf(storage); - UIListStream ibuf(storage); + printTokens(ibuf); - printTokens(ibuf); + Info<< nl << "Repeat..." << endl; + ibuf.rewind(); - Info<< nl << "Repeat..." << endl; - ibuf.rewind(); + printTokens(ibuf); + } - printTokens(ibuf); + + // Attach input buffer - could also do without previous resize + { + Info<< "parse as std::istream\n"; + + uiliststream is(storage.cdata(), storage.size()); + + string tok; + + while (std::getline(is, tok)) + { + std::cerr << "tok: " << tok << nl; + } + + Info<< nl << "Repeat..." << endl; + + is.rewind(); + while (std::getline(is, tok)) + { + std::cerr << "tok: " << tok << nl; + } + } + + + // Simple test using stl items only + { + std::vector chars; + chars.reserve(1024); + + for (int i=0; i < 10; ++i) + { + chars.push_back('A' + i); + chars.push_back('0' + i); + chars.push_back('\n'); + } + + Info<< "parse std::vector of char: "; + toString(Info, chars); + Info<< "----" << nl; + + uiliststream is(chars.data(), chars.size()); + string tok; + std::cerr<< nl << "Parsed..." << nl; + while (std::getline(is, tok)) + { + std::cerr << "tok: " << tok << nl; + } + + Info<< nl << "Repeat..." << endl; + + is.rewind(); + while (std::getline(is, tok)) + { + std::cerr << "tok: " << tok << nl; + } + } Info<< "\nEnd\n" << endl; diff --git a/src/OpenFOAM/db/IOstreams/memory/IListStream.H b/src/OpenFOAM/db/IOstreams/memory/IListStream.H index 553a803bc3..6f20eeb765 100644 --- a/src/OpenFOAM/db/IOstreams/memory/IListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/IListStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -51,7 +51,7 @@ namespace Foam Class IListStreamAllocator Declaration \*---------------------------------------------------------------------------*/ -//- An stream/stream-buffer input allocator for with List storage +//- An stream/stream-buffer input allocator with List storage class IListStreamAllocator : private List, @@ -61,43 +61,46 @@ protected: // Constructors - //- Construct with an empty list + //- Construct empty IListStreamAllocator() : List(), - UIListStreamAllocator(list_storage()) + UIListStreamAllocator(List::data(), List::size()) {} - //- Move construct from an existing List + //- Move construct from List IListStreamAllocator(List&& buffer) : List(std::move(buffer)), - UIListStreamAllocator(list_storage()) + UIListStreamAllocator(List::data(), List::size()) {} - - //- Move construct from an existing DynamicList + //- Move construct from DynamicList template IListStreamAllocator(DynamicList&& buffer) : List(std::move(buffer)), - UIListStreamAllocator(list_storage()) + UIListStreamAllocator(List::data(), List::size()) {} //- Transfer (move) construct IListStreamAllocator(const Xfer>& buffer) : List(buffer), - UIListStreamAllocator(list_storage()) + UIListStreamAllocator(List::data(), List::size()) {} // Protected Member Functions //- Convenience method to address the underlying List storage - inline List& list_storage() + inline void reset_gbuffer() { - return static_cast&>(*this); + UIListStreamAllocator::reset + ( + List::data(), + List::size() + ); } public: @@ -107,21 +110,24 @@ public: //- The current get position in the buffer using UIListStreamAllocator::size; + inline void swap(List& list) + { + List::swap(list); + reset_gbuffer(); + } + //- Clear storage inline void clearStorage() { - list_storage().clear(); - sync_gbuffer_to_list(); + List::clear(); + reset_gbuffer(); } //- 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 - + Xfer> moved = List::xfer(); + reset_gbuffer(); return moved; } }; @@ -156,7 +162,7 @@ public: {} - //- Move construct from an existing List + //- Move construct from List IListStream ( List&& buffer, @@ -170,7 +176,7 @@ public: {} - //- Move construct from an existing DynamicList + //- Move construct from DynamicList template IListStream ( diff --git a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H index 3ae0311667..dde12a6dfb 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OCountStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OCountStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -49,14 +49,12 @@ class countstreambuf : public std::streambuf { - // Private data - - //- The number of bytes - std::streamsize size_; + //- The number of bytes counted + std::streamsize size_; protected: - //- Simply handle output counting via overflow + //- Handle output counting via overflow virtual int overflow(int c = EOF) { if (c != EOF) @@ -79,25 +77,25 @@ protected: return 0; } - public: - // Constructors + //- Construct null, or with precount size + countstreambuf(std::streamsize precount=0) + : + size_(precount) + {} - //- Construct null, or with precount size - countstreambuf(std::streamsize precount=0) - : - size_(precount) - {} + //- \return The number of bytes counted + std::streamsize size() const + { + return size_; + } - - // Access - - //- Number of bytes counted - std::streamsize size() const - { - return size_; - } + //- Some information about the number of bytes counted + inline void printBufInfo(Ostream& os) const + { + os << "count=" << size_; + } }; @@ -105,53 +103,30 @@ public: 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 +//- Trivial output stream for calculating byte counts. +// Since all output values are discarded, it can be used as a /dev/null +// output buffer as well. class ocountstream : virtual public std::ios, + protected countstreambuf, public std::ostream { - // Private data - - countstreambuf buf_; - public: - // Constructors + //- Construct null + ocountstream() + : + countstreambuf(), + std::ostream(static_cast(this)) + {} - //- 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 - } + //- Rewind the stream, reset the count + void rewind() + { + this->pubseekpos(0, std::ios_base::out); + clear(); // for safety, clear any old errors + } }; @@ -189,7 +164,7 @@ protected: void printBufInfo(Ostream& os) const { - os << "count=" << buf_.size(); + buf_.printBufInfo(os); } public: diff --git a/src/OpenFOAM/db/IOstreams/memory/OListStream.H b/src/OpenFOAM/db/IOstreams/memory/OListStream.H index 78796b338c..aa1776dc80 100644 --- a/src/OpenFOAM/db/IOstreams/memory/OListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/OListStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2017-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -29,9 +29,9 @@ Description 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. + The default list size is 512-bytes with a 256-byte block increment. + These values can be changed after construction using the reserve() and + the setBlockSize() methods. See Also Foam::IListStream @@ -45,6 +45,7 @@ See Also #include "DynamicList.H" #include "OSstream.H" +#include "stdFoam.H" #include "memoryStreamBuffer.H" // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -52,43 +53,39 @@ See Also namespace Foam { -// Forward declaration -class OListStreamAllocator; - /*---------------------------------------------------------------------------*\ Class OListStreamAllocator Declaration \*---------------------------------------------------------------------------*/ -//- An stream/stream-buffer output allocator for lists +//- An stream/stream-buffer output allocator with DynamicList-like storage class OListStreamAllocator { - //- A streambuf adapter to output to a List - class listbuf + //- A streambuf adapter with resizing similar to DynamicList + class dynbuf : public memorybuf::out { - friend OListStreamAllocator; + friend class OListStreamAllocator; - //- Helper for setting the block size. - // Small list minimum of 64 bytes. - static int min_size(int n) + //- Helper for block size - small list minimum of 64 bytes. + constexpr static int min_size(int n) { - return max(64, n); + return stdFoam::max(64, n); } //- 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. + // Internally manage like a DynamicList, with its capacity known + // from the list size and the addressable size known through the + // stream pointers. List storage_; - protected: - //- Increment capacity directly and - // adjust buffer pointers to agree with list dimensions + //- Increment capacity directly and adjust buffer pointers to + //- correspond with the storage size. inline void minCapacity ( const std::streamsize n, @@ -115,8 +112,8 @@ class OListStreamAllocator // << " pos:" << cur // << " incr:" << incr << endl; - storage_.setSize(newCapacity); - sync_pbuffer_to_list(); + storage_.resize(newCapacity); + sync_pbuffer(); pbump(cur); } } @@ -167,34 +164,34 @@ class OListStreamAllocator //- Initialize put buffer void init_pbuffer(const std::streamsize n) { - set_pbuffer(storage_); + sync_pbuffer(); minCapacity(n); } public: - // Constructors + // Constructors //- Construct with an empty list, or specified number of reserved bytes - listbuf(size_t nbytes = 512) + dynbuf(size_t nbytes = 512) : storage_() { init_pbuffer(min_size(nbytes)); } - //- Move construct content from an existing List - listbuf(List&& buffer) + //- Move construct from List + dynbuf(List&& buffer) : storage_(std::move(buffer)) { init_pbuffer(block_); } - //- Move construct content from an existing DynamicList + //- Move construct from DynamicList template - listbuf(DynamicList&& buffer) + dynbuf(DynamicList&& buffer) : storage_(std::move(buffer)) { @@ -202,7 +199,7 @@ class OListStreamAllocator } //- Transfer (move) construct - listbuf(const Xfer>& buffer) + dynbuf(const Xfer>& buffer) : storage_(buffer) { @@ -210,7 +207,7 @@ class OListStreamAllocator } - // Member Functions + // Member Functions //- Return the current list output capacity inline label capacity() const @@ -219,26 +216,36 @@ class OListStreamAllocator } //- Sync put buffer pointers to agree with list dimensions - inline void sync_pbuffer_to_list() + inline void sync_pbuffer() { - set_pbuffer(storage_); + resetp(storage_.data(), storage_.size()); } //- Clear storage inline void clearStorage() { storage_.clear(); - sync_pbuffer_to_list(); + sync_pbuffer(); } //- Shrink to addressed storage inline void shrink() { const auto cur = tellp(); - storage_.setSize(cur); - sync_pbuffer_to_list(); + storage_.resize(cur); + sync_pbuffer(); pbump(cur); } + + //- Transfer contents to the Xfer container as a plain List + inline Xfer> xfer() + { + const auto cur = tellp(); // Addressed area + storage_.resize(cur); + auto lst = storage_.xfer(); + sync_pbuffer(); + return lst; + } }; protected: @@ -248,7 +255,7 @@ protected: typedef std::ostream stream_type; //- The stream buffer - listbuf buf_; + dynbuf buf_; //- The stream stream_type stream_; @@ -263,14 +270,14 @@ protected: stream_(&buf_) {} - //- Move construct from an existing List + //- Move construct from List OListStreamAllocator(List&& buffer) : buf_(std::move(buffer)), stream_(&buf_) {} - //- Move construct from an existing DynamicList + //- Move construct from DynamicList template OListStreamAllocator(DynamicList&& buffer) : @@ -290,8 +297,8 @@ protected: void printBufInfo(Ostream& os) const { - os << "pos=" << buf_.tellp() - << " capacity=" << buf_.capacity() + os << "put=" << buf_.tellp() + << "/" << buf_.capacity() << " block=" << buf_.block_; } @@ -299,12 +306,30 @@ public: // Member Functions + //- Const UList access to the characters written (shallow copy). + inline const UList list() const + { + return buf_.list(); + } + + //- Non-const UList access to the characters written (shallow copy). + inline UList list() + { + return buf_.list(); + } + //- The current list output capacity inline label capacity() const { return buf_.capacity(); } + //- The current output position in the buffer, + //- which is also the addressed list size + inline label size() const + { + return buf_.tellp(); + } //- Reserve output space for at least this amount. inline void reserve(const std::streamsize n) @@ -317,55 +342,16 @@ public: } } - //- 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_.tellp() - ); - } - - - //- Non-const access to written contents as a list of characters - inline UList list() - { - return UList(buf_.storage_.data(), buf_.tellp()); - } - - //- Transfer contents to the Xfer container as a plain List inline Xfer> xfer() { - 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_.pubseekpos(0, std::ios_base::out); - stream_.clear(); // for safety, clear any old errors + return buf_.xfer(); } //- Shrink to addressed space, should not affect stream. @@ -381,6 +367,12 @@ public: stream_.clear(); // for safety, clear any old errors } + //- Move to buffer start, clear errors + void rewind() + { + buf_.pubseekpos(0, std::ios_base::out); + stream_.clear(); // for safety, clear any old errors + } }; @@ -464,7 +456,7 @@ public: {} - // Member functions + // Member Functions //- Rewind the stream, clearing any old errors virtual void rewind() diff --git a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H index 8235b2edd5..2ddeeea500 100644 --- a/src/OpenFOAM/db/IOstreams/memory/UIListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/UIListStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -35,10 +35,10 @@ Description An example of possible use: \code - DynamicList buffer(4096); // allocate some large buffer + DynamicList buffer(4096); // allocate some large buffer nread = something.read(buffer.data(),1024); // fill with content - buffer.setSize(nread); // content size + buffer.resize(nread); // content size // construct dictionary, or something else UIListStream is(buffer) @@ -46,7 +46,7 @@ Description // sometime later nread = something.read(buffer.data(),2048); // fill with content - buffer.setSize(nread); // content size + buffer.resize(nread); // content size // without intermediate variable dictionary dict2(UIListStream(buffer)()); @@ -73,47 +73,49 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class UIListAllocator Declaration + Class uiliststream Declaration \*---------------------------------------------------------------------------*/ -//- An stream/stream-buffer input allocator for a externally allocated lists +//- Similar to std::istringstream, but with an externally managed input buffer. +// This allows the input buffer to be filled or refilled from various sources +// without copying. +class uiliststream +: + virtual public std::ios, + protected memorybuf::in, + public std::istream +{ +public: + + //- Construct for character array and number of bytes + uiliststream(const char* buffer, size_t nbytes) + : + memorybuf::in(const_cast(buffer), nbytes), + std::istream(static_cast(this)) + {} + + //- Reset buffer pointers + inline void reset(char *buffer, size_t nbytes) + { + resetg(buffer, nbytes); + } + + //- Rewind the stream, clearing any old errors + void rewind() + { + this->pubseekpos(0, std::ios_base::in); + clear(); // for safety, clear any old errors + } +}; + + +/*---------------------------------------------------------------------------*\ + Class UIListStreamAllocator Declaration +\*---------------------------------------------------------------------------*/ + +//- An stream/stream-buffer input allocator for a externally allocated list class UIListStreamAllocator { - //- A streambuf class for input from UList or equivalent - class ulistbuf - : - public memorybuf::in - { - 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 @@ -121,7 +123,7 @@ protected: typedef std::istream stream_type; //- The stream buffer - ulistbuf buf_; + memorybuf::in buf_; //- The stream stream_type stream_; @@ -129,14 +131,7 @@ protected: // Constructors - //- Construct with list buffer - UIListStreamAllocator(UList& list) - : - buf_(list), - stream_(&buf_) - {} - - //- Construct with buffer and number of bytes + //- Construct for character array and number of bytes UIListStreamAllocator(char *buffer, size_t nbytes) : buf_(buffer, nbytes), @@ -146,50 +141,45 @@ protected: // Protected Member Functions - //- Sync get buffer pointers to agree with list dimensions - inline void sync_gbuffer_to_list() + //- Reset buffer pointers + inline void reset(char *buffer, size_t nbytes) { - buf_.sync_gbuffer_to_list(); + buf_.resetg(buffer, nbytes); } void printBufInfo(Ostream& os) const { - os << "pos=" << buf_.tellg() - << " size=" << buf_.list_.size(); + buf_.printBufInfo(os); } public: // Public Member Functions - //- Const access to available contents as a list of characters - inline const UList& list() const + //- Const UList access to the input characters (shallow copy). + inline const UList list() const { - return buf_.list_; + return buf_.list(); } - - //- Non-const access to available contents as a list of characters + //- Non-const UList access to the input characters (shallow copy). inline UList list() { - return buf_.list_; + return buf_.list(); } - //- The list size inline label size() const { - return buf_.list_.size(); + return buf_.capacity(); } - //- Position of the get buffer std::streampos tellg() const { return buf_.tellg(); } - //- Move to buffer start, clear errors void rewind() { @@ -278,7 +268,6 @@ public: return allocator_type::tellg(); } - //- Rewind the stream, clearing any old errors virtual void rewind() { @@ -286,7 +275,6 @@ public: setGood(); // resynchronize with internal state } - //- Print description to Ostream virtual void print(Ostream& os) const; diff --git a/src/OpenFOAM/db/IOstreams/memory/UOListStream.H b/src/OpenFOAM/db/IOstreams/memory/UOListStream.H index df255cd92e..45e3dda0ed 100644 --- a/src/OpenFOAM/db/IOstreams/memory/UOListStream.H +++ b/src/OpenFOAM/db/IOstreams/memory/UOListStream.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -40,7 +40,7 @@ Description { UOListStream os(buffer); os << "content1" << " and more content"; - buffer.setSize(os.size()); // synchronize sizes + buffer.resize(os.size()); // synchronize sizes } something.write(buffer, buffer.size()); @@ -53,13 +53,13 @@ Description UOListStream os(buffer); os << "content1" << " and more content"; - buffer.setSize(os.size()); // synchronize sizes + buffer.resize(os.size()); // synchronize sizes something.write(buffer, buffer.size()); os.rewind(); os << "content2"; - buffer.setSize(os.size()); // synchronize sizes + buffer.resize(os.size()); // synchronize sizes something.write(buffer, buffer.size()); @@ -91,51 +91,12 @@ namespace Foam { /*---------------------------------------------------------------------------*\ - Class UOListAllocator Declaration + Class UOListStreamAllocator Declaration \*---------------------------------------------------------------------------*/ //- An stream/stream-buffer allocator for external buffers -class UOListAllocator +class UOListStreamAllocator { - //- A streambuf adapter for output to UList or equivalent - class ulistbuf - : - public memorybuf::out - { - 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 @@ -143,7 +104,7 @@ protected: typedef std::ostream stream_type; //- The stream buffer - ulistbuf buf_; + memorybuf::out buf_; //- The stream stream_type stream_; @@ -151,63 +112,47 @@ protected: // Constructors - //- Construct with buffer and number of bytes - UOListAllocator(char *buffer, size_t nbytes) + //- Construct for character array and number of bytes + UOListStreamAllocator(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(); + buf_.printBufInfo(os); } public: // Public Member Functions + //- Const UList access to the characters written (shallow copy). + inline const UList list() const + { + return buf_.list(); + } + + //- Non-const UList access to the characters written (shallow copy). + inline UList list() + { + return buf_.list(); + } + //- The current list output capacity inline label capacity() const { return buf_.capacity(); } - //- The current output position in the buffer, - // which is also the addressed list size + //- 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() { @@ -224,10 +169,10 @@ public: //- An OSstream attached to an unallocated external buffer class UOListStream : - public UOListAllocator, + public UOListStreamAllocator, public OSstream { - typedef UOListAllocator allocator_type; + typedef UOListStreamAllocator allocator_type; public: diff --git a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H index 48bfd45ddb..0a3ef59356 100644 --- a/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H +++ b/src/OpenFOAM/db/IOstreams/memory/memoryStreamBuffer.H @@ -2,7 +2,7 @@ ========= | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox \\ / O peration | - \\ / A nd | Copyright (C) 2016-2017 OpenCFD Ltd. + \\ / A nd | Copyright (C) 2016-2018 OpenCFD Ltd. \\/ M anipulation | ------------------------------------------------------------------------------- License @@ -42,6 +42,9 @@ Description namespace Foam { +// Forward declarations +class Ostream; + /*---------------------------------------------------------------------------*\ Class memorybuf Declaration \*---------------------------------------------------------------------------*/ @@ -126,6 +129,19 @@ protected: } + //- \return the current buffer get position + inline std::streamsize tellg() const + { + return (gptr() - eback()); + } + + //- \return the current buffer put position + inline std::streamsize tellp() const + { + return (pptr() - pbase()); + } + + public: // Forward declarations @@ -145,6 +161,9 @@ class memorybuf::in { protected: + //- Default construct null + in() = default; + //- Get sequence of characters virtual std::streamsize xsgetn(char* s, std::streamsize n) { @@ -159,17 +178,53 @@ protected: return count; } +public: - //- The buffer get position - inline std::streamsize tellg() const + //- Construct for character array and number of bytes + in(char* s, std::streamsize n) { - return (gptr() - eback()); + resetg(s, n); } - //- Sync get buffer pointers to agree with list dimensions - inline void set_gbuffer(UList& list) + //- Reset for character array and number of bytes + inline void resetg(char* s, std::streamsize n) { - setg(list.begin(), list.begin(), list.end()); + if (s) + { + setg(s, s, s + n); + } + else + { + setg(nullptr, nullptr, nullptr); + } + } + + //- The buffer get position + using memorybuf::tellg; + + //- The buffer capacity + inline std::streamsize capacity() const + { + return (egptr() - eback()); + } + + //- Const UList access to the input characters (shallow copy). + inline const UList list() const + { + return UList(eback(), (egptr() - eback())); + } + + //- Non-const UList access to the input characters (shallow copy). + inline UList list() + { + return UList(eback(), (egptr() - eback())); + } + + //- Some information about the input buffer position/capacity + inline void printBufInfo(Ostream& os) const + { + os << "get=" << (gptr() - eback()) // tellp() + << "/" << (egptr() - eback()); // capacity } }; @@ -185,6 +240,9 @@ class memorybuf::out { protected: + //- Default construct null + out() = default; + //- Put sequence of characters virtual std::streamsize xsputn(const char* s, std::streamsize n) { @@ -198,18 +256,54 @@ protected: return count; } +public: + + //- Construct for character array and number of bytes + out(char* s, std::streamsize n) + { + resetp(s, n); + } + + //- Reset for character array and number of bytes + inline void resetp(char* s, std::streamsize n) + { + if (s) + { + setp(s, s + n); + } + else + { + setp(nullptr, nullptr); + } + } + //- The buffer put position - inline std::streamsize tellp() const + using memorybuf::tellp; + + //- The buffer capacity + inline std::streamsize capacity() const { - return (pptr() - pbase()); + return (epptr() - pbase()); } - //- Sync put buffer pointers to agree with list dimensions - inline void set_pbuffer(UList& list) + //- Const UList access to the characters written (shallow copy). + inline const UList list() const { - setp(list.begin(), list.end()); + return UList(pbase(), (pptr() - pbase())); } + //- Non-const UList access to the characters written (shallow copy). + inline UList list() + { + return UList(pbase(), (pptr() - pbase())); + } + + //- Some information about the output buffer position/capacity + inline void printBufInfo(Ostream& os) const + { + os << "put=" << (pptr() - pbase()) // tellp() + << "/" << (epptr() - pbase()); // capacity + } };