Boost logo

Boost :

From: Hamish Mackenzie (hamish_at_[hidden])
Date: 2002-11-28 07:35:22


On Wed, 2002-11-27 at 19:13, Boris Schäling wrote:
> I use std::string as a buffer which grows when needed. This is sufficient
> for what I do but may not what others need. You are right that there should
> be better control of the buffers and/or an on_flush() method to notify the
> observer when the buffer has been (partly) flushed and how much space is
> available for another writen().

It might help if I fill in some of the blanks. Here how I see on_write
working....

template< typename Char_Type >
class observer_base
{
public:
  typedef Char_Type char_type;

  observer_base()
    : buffer_( default_buffer_size ),
      buffer_contains_( 0 ),
      buffer_pos_( 0 ) {}

  virtual std::streamsize on_write(
        char_type * buffer, streamsize buffer_size ) = 0;

  virtual void on_write()
  {
    int result = 0;

    while( result != would_block )
    {
        // Refill local buffer if it is empty
        if( buffer_pos_ == buffer_contains_ )
        {
            buffer_pos_ = 0;
            buffer_contains_ = observer.on_write(
                &buffer_[0], buffer_.size() );
        }

        if( buffer_contains_ != 0 )
        {
            // Try to write the data we have
            result = raw_stream().write(
                &buffer_[buffer_pos_],
                buffer_contains_ - buffer_pos_ );
        
            if( result == would_block )
            {
                // TODO : Re-register event handler here
            }
            else
            {
                buffer_pos_ += result;
            }
        }
        else
        {
            // No more data to write
            // TODO : unregister event handler here
                break;
        }
    }
  }

...

private:
  std::vector< char_type > buffer_;
  std::streamsize buffer_contains_;
  std::streamsize buffer_pos_;
};

class observer : public observer_base
{
public:
  virtual std::istream & write_stream() = 0;

  virtual std::streamsize on_write(
          char_type * buffer, streamsize buffer_size )
  {
      std::streamsize size = 0;

      try
      {
          size = write_stream().read_some( buffer, buffer_size );
          if( size == 0 )
          {
              write_stream().peek(); // May block here
              size = write_stream().read_some( buffer, buffer_size );
          }
      }
      catch( std::ios_base::failure & )
      {
          if( !write_stream().eof() )
          {
              throw;
          }
      }

      return size;
  }

...

};

-- 
Hamish Mackenzie <hamish_at_[hidden]>

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk