#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;
size_t _pos;
public:
String_streambuf(StringT& str);
virtual ~String_streambuf();
protected:
virtual inherited* setbuf(char* s, streamsize n);
virtual int_type underflow();
virtual int_type uflow();
virtual int_type pbackfail(int_type c = traits::eof());
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),
_pos(0)
{
// empty
}
template<typename StringT>
String_streambuf<StringT>::~String_streambuf()
{
// empty
}
template<typename StringT>
String_streambuf<StringT>::inherited*
String_streambuf<StringT>::setbuf(char* s, streamsize n)
{
return this;
}
template<typename StringT>
typename String_streambuf<StringT>::int_type
String_streambuf<StringT>::underflow()
{
if (_pos < _str.size())
return _str[_pos];
return traits::eof();
}
template<typename StringT>
typename String_streambuf<StringT>::int_type
String_streambuf<StringT>::uflow()
{
if (_pos < _str.size())
return _str[_pos++];
return traits::eof();
}
template<typename StringT>
typename String_streambuf<StringT>::int_type
String_streambuf<StringT>::pbackfail(int_type c)
{
if (_pos > 0 && _str[_pos-1] == c) {
--_pos;
return c;
}
return traits::eof();
}
template<typename StringT>
typename String_streambuf<StringT>::int_type
String_streambuf<StringT>::overflow(int_type c)
{
if (c != traits::eof()) {
_str += c;
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