Question

Can someone write some sample code to explain this concept? I know what a buffered stream is used for, but I also would like to know how to implement that.

Thanks in advance!

Was it helpful?

Solution

You can look into your platform's implementation, the C++ standard or "Standard C++ IOstreams and Locales" by Angelika Langer and Klaus Kreft.

Be prepared for quite a learning curve. Streams are old and a complicated matter. (Francis Glassborow: "I have very few doubts that I/O libraries are amongst the most difficult aspects of any language.")

OTHER TIPS

Veeeery schematically, for an "input" stream:

class BufferedInputStream
{
public:
  BufferedInputStream(SomeExternalDevice d)
  : m_Device(d),
    m_Current(m_Buffer),
    m_End(m_Buffer)
  {}

  char get(){
    if (!IsDataAvailableInBuffer()){
      ReadAChunkFromDiskAndPutItInBuffer();
    }
    return PopByteFromBuffer();
  }

private:

  bool IsDataAvailableInBuffer()const{
    return m_Current != m_End;
  }

  void ReadAChunkFromDiskAndPutItInBuffer(){
    // Buffer must be empty
    assert(!IsDataAvailableInBuffer());

    // Read bytes from the device
    bytes_read = Read(m_Device, m_Buffer, BufferSize);

    // Reposition the "begin" and "end" pointers
    m_Current = m_Buffer;
    m_End = m_Buffer + bytes_read;
  }

  char PopByteFromBuffer(){
    assert(IsDataAvailableInBuffer());
    return *m_Current++;
  }

  // For example, an OS file handle
  SomeExternalDevice m_Device;

  // The buffer itself
  char m_Buffer[BufferSize];

  // Begin of buffer contents
  char* m_Current;

  // End of buffer contents
  char* m_End;
};

That way, data is read from disk in chunks of the size of the buffer, and most calls to "get()" don't have to end up in calls to the OS, as they can simply return a byte from the buffer.

Take a look at the STL implementation for sstream and sstream.tcc (links to SGI STL implementation).

The base stringstream class is basic_stringstream, which implements the basic_iostream interface.

  // [27.7.4] Template class basic_stringstream
  /**
   *  @brief  Controlling input and output for std::string.
   *
   *  This class supports reading from and writing to objects of type
   *  std::basic_string, using the inherited functions from
   *  std::basic_iostream.  To control the associated sequence, an instance
   *  of std::basic_stringbuf is used, which this page refers to as @c sb.
  */

There is the base class basic_stringbuf which derives from basic_streambuf. This holds the buffer.

  // [27.7.1] template class basic_stringbuf
  /**
   *  @brief  The actual work of input and output (for std::string).
   *
   *  This class associates either or both of its input and output sequences
   *  with a sequence of characters, which can be initialized from, or made
   *  available as, a @c std::basic_string.  (Paraphrased from [27.7.1]/1.)
   *
   *  For this class, open modes (of type @c ios_base::openmode) have
   *  @c in set if the input sequence can be read, and @c out set if the
   *  output sequence can be written.
  */
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top