#ifndef STRING_STREAM_H
#define STRING_STREAM_H
#include <iostream>
template<typename StringT>
class String_streambuf : public std::streambuf {
// typedefs
typedef std::streambuf inherited;
typedef std::char_traits<char> traits;
typedef inherited::int_type int_type;
typedef std::streamsize streamsize;
// data
StringT& _str;
char _buf[128];
public:
String_streambuf(StringT& str);
virtual ~String_streambuf();
protected:
virtual int sync();
virtual int_type overflow(int_type c = traits::eof());
};
//
// IOStreams
//
template<typename StringT>
class iString_stream : public std::istream {
// types
typedef std::istream inherited;
// data
String_streambuf<StringT> _streambuf;
public:
iString_stream(StringT& str);
~iString_stream();
};
template<typename StringT>
class oString_stream : public std::ostream {
// types
typedef std::ostream inherited;
// data
String_streambuf<StringT> _streambuf;
public:
oString_stream(StringT& str);
~oString_stream();
};
template<typename StringT>
class String_stream : public std::iostream {
// types
typedef std::IOStream inherited;
// data
String_streambuf<StringT> _streambuf;
public:
String_stream(StringT& str);
~String_stream();
};
//
// implementation
//
template<typename StringT>
String_streambuf<StringT>::String_streambuf(StringT& str)
: _str(str)
{
char* gbuf = const_cast<char*>(_str.data());
setg(gbuf, gbuf, gbuf+_str.size());
setp(_buf, _buf + sizeof(_buf));
}
template<typename StringT>
String_streambuf<StringT>::~String_streambuf()
{
// empty
}
template<typename StringT>
int
String_streambuf<StringT>::sync()
{
size_t l = pptr() - pbase();
if (l > 0) {
size_t pos = gptr() - eback(); // remember the get position
_str.append(_buf, l);
setp(_buf, _buf+sizeof(_buf));
char* gbuf = const_cast<char*>(_str.data());
setg(gbuf, gbuf+pos, gbuf+_str.size()); // reset the get buffer
}
return 0;
}
template<typename StringT>
typename String_streambuf<StringT>::int_type
String_streambuf<StringT>::overflow(int_type c)
{
sync();
if (c != traits::eof()) {
*_buf = c;
pbump(1);
return c;
}
return traits::not_eof(c);
}
template<typename StringT>
iString_stream<StringT>::iString_stream(StringT& str)
: inherited(0),
_streambuf(str)
{
init(&_streambuf);
}
template<typename StringT>
iString_stream<StringT>::~iString_stream()
{
// empty
}
template<typename StringT>
oString_stream<StringT>::oString_stream(StringT& str)
: inherited(0),
_streambuf(str)
{
init(&_streambuf);
}
template<typename StringT>
oString_stream<StringT>::~oString_stream()
{
// empty
}
template<typename StringT>
String_stream<StringT>::String_stream(StringT& str)
: inherited(0),
_streambuf(str)
{
init(&_streambuf);
}
template<typename StringT>
String_stream<StringT>::~String_stream()
{
// empty
}
#endif