I've been trying to use Boost.Iostreams, with mixed success. I've got a
few more stumbling blocks that hopefully I can get some help with :-).
First, I have a socket class, which I've used Boost.Iostreams to create a nice interface for. Quick details:
class winsock_device {
typedef boost::iostreams::bidirectional_device_tag category;
//..implementation..
};
class winsock_socket {
typedef winsock_device stream_device_type;
typedef boost::iostreams::stream_buffer< stream_device_type > stream_buffer_type;
typedef std::iostream stream_type;
stream_device_type m_stream_device;
stream_buffer_type m_stream_buffer;
stream_type m_stream;
public:
winsock_socket( SOCKET raw_socket )
: m_stream_device( raw_socket )
, m_stream_buffer( m_stream_device )
, m_stream( & m_stream_buffer )
{}
stream_type & stream() { return m_stream; }
//..more implementation..
};
The implementation seems to work, tests show it to be working fine for input and output (with output needing to be flushed).
Only problem is that the newlines are mismatched - a simple telnet chat
client gets supurflous \r characters using std::getline, so I decided
to wrap around the stream using a
boost::iostreams::filtering_stream< boost::iostreams::bidirectional
>, which is where things fall apart. I took my simple example, and
replaced:
std::iostream & ios = socket->stream();
with:
namespace bios = boost::iostreams;
bios::filtering_stream< bios::bidirectional > ios;
ios.push( socket->stream() );
both with the same testing code:
std::string nickname;
ios << "Welcome, user - please enter a nickname:\n" << std::flush; socket->stream().flush();
std::getline( ios , nickname );
ios << "Welcome, " << nickname << "\n";
ios << "*** actual chatting not yet implemented ***\n";
ios << "Disconnecting you now, bye " << nickname << " !!!\n" << std::flush; socket->stream().flush();
This failed to work at all at first, eventually I figured out I needed
to flush first the ios stream, and then the underlying
socket->stream. This brings me to:
question 1: Is there a workaround to allow an ending stream of
(std::iostream &) to be flushed automatically by flushing
filtering_stream?
Even with no filters installed, however, the program freezes (until I
shut down the telnet client) when I attempt to read a line from the
stream, even after entering multiple newlines - I'm not exactly sure
what's happening here. This brings me to:
question 2: How can I get the input moving through my stream? Do I need
to start a seperate thread to constantly flush() the stream that the
main thread is blocked on i/o for?
Thanks,
-Mike