ENH: cleanup and rationalize memory-backed streams

- more consistent naming:
  * Versions that hold and manage their own memory:
      IListStream, OListStream

  * Versions that reference a fixed size external memory:
      UIListStream, UOListStream

- use List storage instead of DynamicList within OListStream.
  Avoids duplicate bookkeeping, more direct handling of resizing.
This commit is contained in:
Mark Olesen
2017-10-26 12:09:47 +02:00
parent 5c1ec7ecb8
commit 2bd2f83f6e
26 changed files with 1735 additions and 639 deletions

View File

@ -0,0 +1,3 @@
Test-IListStream.C
EXE = $(FOAM_USER_APPBIN)/Test-IListStream

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -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 <http://www.gnu.org/licenses/>.
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<char>& list)
{
os << '"';
for (const char c : list)
{
os << c;
}
os << '"';
return os;
}
template<class BufType>
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<char> storage(16);
OListStream obuf(std::move(storage));
obuf << 1002 << " " << "abcd" << " " << "def" << " " << 3.14159 << ";\n";
// Move contents to output buffer
printInfo(obuf);
Info<<nl << "as string: ";
toString(Info, obuf.list()) << endl;
Info<< "transfer contents to a List" << endl;
IListStream ibuf(obuf.xfer());
Info<< nl;
Info<< nl << "input string:";
printInfo(ibuf);
Info<< nl << "orig output:";
printInfo(obuf);
printTokens(ibuf);
Info<<nl << "after:";
printInfo(ibuf);
// This should also work
ibuf.list() = 'X';
Info<<nl << "overwritten with const value:";
printInfo(ibuf);
// Can also change content like this:
{
const int n = min(26, ibuf.size());
for (int i=0; i<n; ++i)
{
ibuf.list()[i] = 'A' + i;
}
}
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);
Info<< "\nEnd\n" << endl;
return 0;
}
// ************************************************************************* //

View File

@ -0,0 +1,3 @@
Test-OCountStream.C
EXE = $(FOAM_USER_APPBIN)/Test-OCountStream

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -0,0 +1,61 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "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;
}
// ************************************************************************* //

View File

@ -1,2 +1,2 @@
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -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<char>& list)
}
void printInfo(const OListStream& buf)
template<class BufType>
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<char> storage(8);
DynamicList<char> 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<char> 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<char> written;
{
Info<<"create List.xfer()" << endl;
List<char> 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;

View File

@ -1,3 +0,0 @@
Test-UIBufStream.C
EXE = $(FOAM_USER_APPBIN)/Test-UIBufStream

View File

@ -1,2 +0,0 @@
/* EXE_INC = -I$(LIB_SRC)/finiteVolume/lnInclude */
/* EXE_LIBS = -lfiniteVolume */

View File

@ -0,0 +1,3 @@
Test-UIListStream.C
EXE = $(FOAM_USER_APPBIN)/Test-UIListStream

View File

@ -0,0 +1,2 @@
/* EXE_INC = */
/* EXE_LIBS = */

View File

@ -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<char>& list)
{
os << '"';
for (const char c : list)
{
os << c;
}
os << '"';
return os;
}
template<class BufType>
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<char> 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;

View File

@ -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

View File

@ -79,11 +79,6 @@ protected:
{}
//- Destructor
~StringStreamAllocator()
{}
public:
// Public Member Functions
@ -112,6 +107,8 @@ class IStringStream
public StringStreamAllocator<std::istringstream>,
public ISstream
{
typedef StringStreamAllocator<std::istringstream> allocator_type;
public:
// Constructors
@ -125,7 +122,7 @@ public:
const Foam::string& name="input"
)
:
StringStreamAllocator<std::istringstream>(buffer),
allocator_type(buffer),
ISstream(stream_, name, format, version)
{}
@ -139,7 +136,7 @@ public:
const Foam::string& name="input"
)
:
StringStreamAllocator<std::istringstream>(buffer),
allocator_type(buffer),
ISstream(stream_, name, format, version)
{}
@ -147,28 +144,23 @@ public:
//- Construct as copy of content
IStringStream(const IStringStream& str)
:
StringStreamAllocator<std::istringstream>(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<std::ostringstream>,
public OSstream
{
typedef StringStreamAllocator<std::ostringstream> allocator_type;
public:
// Constructors
@ -203,7 +197,7 @@ public:
versionNumber version=currentVersion
)
:
StringStreamAllocator<std::ostringstream>(),
allocator_type(),
OSstream(stream_, "output", format, version)
{}
@ -211,16 +205,11 @@ public:
//- Construct as copy of content
OStringStream(const OStringStream& str)
:
StringStreamAllocator<std::ostringstream>(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;
};

View File

@ -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

View File

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

View File

@ -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 <http://www.gnu.org/licenses/>.
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<char>,
public UIListStreamAllocator
{
protected:
// Constructors
//- Construct with an empty list
IListStreamAllocator()
:
List<char>(),
UIListStreamAllocator(list_storage())
{}
//- Move construct from an existing List
IListStreamAllocator(List<char>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(list_storage())
{}
//- Move construct from an existing DynamicList
template<int SizeMin>
IListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
:
List<char>(std::move(buffer)),
UIListStreamAllocator(list_storage())
{}
//- Transfer (move) construct
IListStreamAllocator(const Xfer<List<char>>& buffer)
:
List<char>(buffer),
UIListStreamAllocator(list_storage())
{}
// Protected Member Functions
//- Convenience method to address the underlying List storage
inline List<char>& list_storage()
{
return static_cast<List<char>&>(*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<List<char>> xfer()
{
Xfer<List<char>> 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<char>&& 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<int SizeMin>
IListStream
(
DynamicList<char,SizeMin>&& 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<List<char>>& 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<Istream&>(static_cast<const Istream&>(*this));
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#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;
}
// ************************************************************************* //

View File

@ -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 <http://www.gnu.org/licenses/>.
Description
Input/output streams with managed List storage.
\*---------------------------------------------------------------------------*/
#ifndef ListStream_H
#define ListStream_H
#include "IListStream.H"
#include "OListStream.H"
#endif
// ************************************************************************* //

View File

@ -52,29 +52,30 @@ 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)
{
n_ += num;
return num;
if (c != EOF)
{
++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::streampos,
std::ios_base::openmode which = std::ios_base::in|std::ios_base::out
)
{
n_ = 0;
size_ = 0;
return 0;
}
@ -83,19 +84,19 @@ 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<ocountstream&>(*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;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -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 <sstream>
#include "DynamicList.H"
#include "OSstream.H"
#include "memoryStreamBuffer.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,114 +59,100 @@ 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<char,512> 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<char> storage_;
protected:
// Protected members
//- Set position pointer to relative position
virtual std::streampos seekoff
//- Increment capacity directly and
// adjust buffer pointers to agree with list dimensions
inline void minCapacity
(
std::streamoff off,
std::ios_base::seekdir way,
std::ios_base::openmode which = std::ios_base::out
const std::streamsize n,
const std::streamsize cur = 0
)
{
const bool testout = which & std::ios_base::out;
if (way == std::ios_base::beg)
const auto newEnd = n + cur;
if (newEnd > storage_.size())
{
if (testout)
{
setp(pbase(), epptr());
pbump(off);
}
return off;
}
if (way == std::ios_base::cur)
{
if (testout)
{
pbump(off);
}
}
else if (way == std::ios_base::end)
{
if (testout)
{
pbump(off);
}
}
if (testout)
{
return pptr() - pbase();
}
return -1;
}
//- Set position pointer to absolute position
virtual std::streampos seekpos
auto newCapacity =
(
std::streampos pos,
std::ios_base::openmode which = std::ios_base::out
)
{
if (which & std::ios_base::out)
{
setp(pbase(), epptr());
pbump(pos);
(storage_.size() + block_)
- (storage_.size() % block_)
);
return pptr() - pbase();
while (newCapacity < newEnd)
{
newCapacity += block_;
}
return -1;
// Info<<"request:" << newEnd
// << " cur cap:" << storage_.size()
// << " new cap:" << newCapacity
// << " pos:" << cur
// << " incr:" << incr << endl;
storage_.setSize(newCapacity);
sync_pbuffer_to_list();
pbump(cur);
}
}
//- 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)
{
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();
}
// Enough space so that appends work without problem
minCapacity(n, tellp());
std::streamsize count = 0;
while (count < n && pptr() < epptr())
@ -164,90 +161,108 @@ class OListStreamAllocator
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
//- Construct with an empty list
olistbuf()
:
storage_(1024)
{
syncBufferPointers();
}
//- Construct with a specified number of reserved bytes
olistbuf(size_t nbytes)
//- Construct with an empty list, or specified number of reserved bytes
listbuf(size_t nbytes = 512)
:
storage_()
{
storage_.reserve(std::max(label(nbytes),1024));
syncBufferPointers();
init_pbuffer(min_size(nbytes));
}
//- Move construct from an existing List
olistbuf(List<char>&& buffer)
//- Move construct content from an existing List
listbuf(List<char>&& buffer)
:
storage_(std::move(buffer))
{
syncBufferPointers();
init_pbuffer(block_);
}
//- Move construct from an existing DynamicList
//- Move construct content from an existing DynamicList
template<int AnySize>
olistbuf(DynamicList<char,AnySize>&& buffer)
listbuf(DynamicList<char,AnySize>&& buffer)
:
storage_(std::move(buffer))
{
syncBufferPointers();
init_pbuffer(block_);
}
//- Transfer (move) construct
listbuf(const Xfer<List<char>>& buffer)
:
storage_(buffer)
{
init_pbuffer(block_);
}
// Member Functions
//- Return the current list output capacity
inline label capacity() const
{
return storage_.size();
}
//- 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();
}
//- 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<char>&& buffer)
:
@ -255,7 +270,6 @@ protected:
stream_(&buf_)
{}
//- Move construct from an existing DynamicList
template<int SizeMin>
OListStreamAllocator(DynamicList<char,SizeMin>&& buffer)
@ -264,71 +278,117 @@ protected:
stream_(&buf_)
{}
//- Destructor
~OListStreamAllocator()
//- Transfer (move) construct
OListStreamAllocator(const Xfer<List<char>>& buffer)
:
buf_(buffer),
stream_(&buf_)
{}
// 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<char> 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<char> list() const
{
return UList<char>
(
const_cast<char*>(buf_.storage_.cdata()),
buf_.storage_.size()
buf_.tellp()
);
}
//- Content as a list of characters
UList<char>& list()
//- Non-const access to written contents as a list of characters
inline UList<char> list()
{
return static_cast<UList<char>&>(buf_.storage_);
}
//- Return the current list capacity
inline label capacity() const
{
return buf_.storage_.capacity();
return UList<char>(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<List<char>> 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_type&>(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<List<char>>& 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;
};

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
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<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
typedef std::istream stream_type;
//- The stream buffer
ulistbuf buf_;
//- The stream
stream_type stream_;
// Constructors
//- Construct with list buffer
UIListStreamAllocator(UList<char>& 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<char>& list() const
{
return buf_.list_;
}
//- Non-const access to available contents as a list of characters
inline UList<char> 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<std::istream,false>,
public UIListStreamAllocator,
public ISstream
{
typedef BufStreamAllocator<std::istream,false> 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<unsigned FixedSize>
UIListStream
(
const FixedList<char,FixedSize>& 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<char>& 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<char>& buffer,
streamFormat format=ASCII,
@ -119,12 +266,7 @@ public:
const Foam::string& name="input"
)
:
UIBufStream(buffer.cdata(), buffer.size(), format,version,name)
{}
//- Destructor
~UIBufStream()
UIListStream(buffer.cdata(), buffer.size(), format, version, name)
{}
@ -145,6 +287,10 @@ public:
}
//- Print description to Ostream
virtual void print(Ostream& os) const;
// Member operators
//- A non-const reference to const Istream

View File

@ -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 <http://www.gnu.org/licenses/>.
Description
Input/output streams with externally managed storage.
\*---------------------------------------------------------------------------*/
#ifndef UListStream_H
#define UListStream_H
#include "UIListStream.H"
#include "UOListStream.H"
#endif
// ************************************************************************* //

View File

@ -22,7 +22,7 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::UOBufStream
Foam::UOListStream
Description
Similar to OStringStream but using an externally managed buffer for
@ -38,7 +38,7 @@ Description
DynamicList<char> 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<char> 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 T, int SizeMin> 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<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
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<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()
{
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<std::ostream,false>,
public UOListAllocator,
public OSstream
{
typedef BufStreamAllocator<std::ostream,false> 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<char>& 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<unsigned FixedSize>
UOListStream
(
FixedList<char,FixedSize>& 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<char>& 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<int SizeMin>
UOBufStream
UOListStream
(
DynamicList<char,SizeMin>& buffer,
streamFormat format=ASCII,
versionNumber version=currentVersion
)
:
UOBufStream(buffer.data(), buffer.capacity(), format,version)
{}
//- Destructor
~UOBufStream()
UOListStream(buffer.data(), buffer.capacity(), format, version)
{}
// 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;
};

View File

@ -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 <http://www.gnu.org/licenses/>.
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 <type_traits>
#include <sstream>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
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<char>& 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<char>& list)
{
setp(list.begin(), list.end());
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //