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
This commit is contained in:
Mark Olesen
2018-01-22 09:42:06 +01:00
parent 0a5e4cf1b0
commit 23c9dd716d
9 changed files with 450 additions and 348 deletions

View File

@ -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<char>& 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<<nl << "directly written:";
printInfo(ibuf);
// But cannot easily swap in/out an entirely new list storage:
//
// List<char> 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<<nl << "after swap:";
// printInfo(ibuf);
// Swap in/out an entirely new list storage:
List<char> 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<<nl << "after swap:";
printInfo(ibuf);
Info<<nl << "swapped out:";
printInfo(newvalues);
Info<< "\nEnd\n" << endl;

View File

@ -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
@ -40,17 +40,26 @@ int main(int argc, char *argv[])
OCountStream cnt;
OStringStream str;
ocountstream plain;
for (label i = 0; i < 50; ++i)
{
str << 1002 << " " << "abcd" << " "
str
<< 1002 << " " << "abcd" << " "
<< "def" << " " << 3.14159 << ";\n";
cnt << 1002 << " " << "abcd" << " "
cnt
<< 1002 << " " << "abcd" << " "
<< "def" << " " << 3.14159 << ";\n";
plain
<< 1002 << " " << "abcd" << " "
<< "def" << " " << 3.14159 << ";\n";
}
cnt.print(Info);
Info<< "via string-stream: " << str.str().size() << " chars" << endl;
Info<< "via ocountstream: " << plain.size() << " chars" << endl;
Info<< "\nEnd\n" << endl;

View File

@ -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
@ -30,6 +30,9 @@ Description
#include "IOstreams.H"
#include "argList.H"
#include <sstream>
#include <vector>
using namespace Foam;
Ostream& toString(Ostream& os, const UList<char>& list)
@ -45,6 +48,19 @@ Ostream& toString(Ostream& os, const UList<char>& list)
}
Ostream& toString(Ostream& os, const std::vector<char>& list)
{
os << '"';
for (const char c : list)
{
os << c;
}
os << '"';
return os;
}
template<class BufType>
void printInfo(const BufType& buf)
{
@ -55,6 +71,15 @@ void printInfo(const BufType& buf)
}
template<>
void printInfo(const UList<char>& 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<char> 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,7 +117,7 @@ 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);
printTokens(ibuf);
@ -101,6 +126,64 @@ int main(int argc, char *argv[])
ibuf.rewind();
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<char> 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;

View File

@ -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<char>,
@ -61,43 +61,46 @@ protected:
// Constructors
//- Construct with an empty list
//- Construct empty
IListStreamAllocator()
:
List<char>(),
UIListStreamAllocator(list_storage())
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
//- Move construct from an existing List
//- Move construct from List
IListStreamAllocator(List<char>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(list_storage())
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
//- Move construct from an existing DynamicList
//- Move construct from DynamicList
template<int SizeMin>
IListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(list_storage())
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
//- Transfer (move) construct
IListStreamAllocator(const Xfer<List<char>>& buffer)
:
List<char>(buffer),
UIListStreamAllocator(list_storage())
UIListStreamAllocator(List<char>::data(), List<char>::size())
{}
// Protected Member Functions
//- Convenience method to address the underlying List storage
inline List<char>& list_storage()
inline void reset_gbuffer()
{
return static_cast<List<char>&>(*this);
UIListStreamAllocator::reset
(
List<char>::data(),
List<char>::size()
);
}
public:
@ -107,21 +110,24 @@ public:
//- The current get position in the buffer
using UIListStreamAllocator::size;
inline void swap(List<char>& list)
{
List<char>::swap(list);
reset_gbuffer();
}
//- Clear storage
inline void clearStorage()
{
list_storage().clear();
sync_gbuffer_to_list();
List<char>::clear();
reset_gbuffer();
}
//- Transfer contents to the Xfer container as a plain List
inline Xfer<List<char>> xfer()
{
Xfer<List<char>> moved = list_storage().xfer();
// Update buffer pointers for remaining (zero) size list
sync_gbuffer_to_list(); // or rewind
Xfer<List<char>> moved = List<char>::xfer();
reset_gbuffer();
return moved;
}
};
@ -156,7 +162,7 @@ public:
{}
//- Move construct from an existing List
//- Move construct from List
IListStream
(
List<char>&& buffer,
@ -170,7 +176,7 @@ public:
{}
//- Move construct from an existing DynamicList
//- Move construct from DynamicList
template<int SizeMin>
IListStream
(

View File

@ -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
//- 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)
{}
// Access
//- Number of bytes counted
//- \return The 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,51 +103,28 @@ 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()
:
std::ostream(&buf_)
countstreambuf(),
std::ostream(static_cast<countstreambuf*>(this))
{}
// 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);
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:

View File

@ -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<char> 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,7 +164,7 @@ class OListStreamAllocator
//- Initialize put buffer
void init_pbuffer(const std::streamsize n)
{
set_pbuffer(storage_);
sync_pbuffer();
minCapacity(n);
}
@ -177,24 +174,24 @@ class OListStreamAllocator
// 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<char>&& buffer)
//- Move construct from List
dynbuf(List<char>&& buffer)
:
storage_(std::move(buffer))
{
init_pbuffer(block_);
}
//- Move construct content from an existing DynamicList
//- Move construct from DynamicList
template<int AnySize>
listbuf(DynamicList<char,AnySize>&& buffer)
dynbuf(DynamicList<char,AnySize>&& buffer)
:
storage_(std::move(buffer))
{
@ -202,7 +199,7 @@ class OListStreamAllocator
}
//- Transfer (move) construct
listbuf(const Xfer<List<char>>& buffer)
dynbuf(const Xfer<List<char>>& buffer)
:
storage_(buffer)
{
@ -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<List<char>> 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<char>&& buffer)
:
buf_(std::move(buffer)),
stream_(&buf_)
{}
//- Move construct from an existing DynamicList
//- Move construct from DynamicList
template<int SizeMin>
OListStreamAllocator(DynamicList<char,SizeMin>&& 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<char> list() const
{
return buf_.list();
}
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> 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<char> list() const
{
return UList<char>
(
const_cast<char*>(buf_.storage_.cdata()),
buf_.tellp()
);
}
//- Non-const access to written contents as a list of characters
inline UList<char> list()
{
return UList<char>(buf_.storage_.data(), buf_.tellp());
}
//- Transfer contents to the Xfer container as a plain List
inline Xfer<List<char>> 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()

View File

@ -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
@ -38,7 +38,7 @@ Description
DynamicList<char> 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<char*>(buffer), nbytes),
std::istream(static_cast<memorybuf::in*>(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<char> list_;
public:
//- Construct for specified buffer
ulistbuf(UList<char>& 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<char>& 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<char>& list() const
//- Const UList access to the input characters (shallow copy).
inline const UList<char> 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<char> 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;

View File

@ -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<char> 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<char> list() const
{
return buf_.list();
}
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> 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<char> list() const
{
return UList<char>
(
const_cast<char*>(buf_.list_.cdata()),
buf_.tellp()
);
}
//- Non-const access to written contents as a list of characters
inline UList<char> list()
{
return UList<char>
(
const_cast<char*>(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:

View File

@ -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<char>& 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<char> list() const
{
return UList<char>(eback(), (egptr() - eback()));
}
//- Non-const UList access to the input characters (shallow copy).
inline UList<char> list()
{
return UList<char>(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<char>& list)
//- Const UList access to the characters written (shallow copy).
inline const UList<char> list() const
{
setp(list.begin(), list.end());
return UList<char>(pbase(), (pptr() - pbase()));
}
//- Non-const UList access to the characters written (shallow copy).
inline UList<char> list()
{
return UList<char>(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
}
};