Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlsb_memoutstreambuf
[Package bdlsb]

Provide an output basic_streambuf using managed memory. More...

Namespaces

namespace  bdlsb

Detailed Description

Outline
Purpose:
Provide an output basic_streambuf using managed memory.
Classes:
bdlsb::MemOutStreamBuf output stream buffer using memory allocator
See also:
Component bdlsb_fixedmemoutstreambuf, Component bdlsb_fixedmeminstreambuf
Description:
This component provides a mechanism, bdlsb::MemOutStreamBuf, that implements the output portion of the bsl::basic_streambuf protocol using a managed, allocator-supplied memory buffer. Method names necessarily correspond to those specified by the protocol.
This component provides none of the input-related functionality of basic_streambuf (see "Streaming Architecture", below), nor does it use locales in any way.
Because the underlying buffer is always obtained from the client-specified allocator, the pubsetbuf method in this component has no effect.
Note that this component has an unspecified minimum allocation size, and therefore users trying to limit themselves to a fixed buffer should use bdlsb_fixedmemoutstreambuf.
Streaming Architecture:
Stream buffers are designed to decouple device handling from content formatting, providing the requisite device handling and possible buffering services, and leaving the formatting to the client stream. The standard C++ IOStreams library further partitions streaming into input streaming and output streaming, separating responsibilities for each at both the stream layer and the stream buffer layer.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Use of bdlsb::MemOutStreamBuf:
This example demonstrates using a bdlsb::MemOutStreamBuf in order to test a user defined stream type, CapitalizingStream. In this example, we'll define a simple example stream type CapitalizingStream that capitalizing lower-case ASCII data written to the stream. In order to test this CapitalizingStream type, we'll create an instance, and supply it a bdlsb::MemOutStreamBuf object as its stream buffer; after we write some character data to the CapitalizingStream we'll inspect the buffer of the bdlsb::MemOutStreamBuf and verify its contents match our expected output. Note that to simplify the example, we do not include the functions for streaming non-character data, e.g., numeric values.
First, we define our example stream class, CapitalizingStream (which we will later test using 'bdlsbMemOutStreamBuf):
  class CapitalizingStream {
      // This class capitalizes lower-case ASCII characters that are output.

      // DATA
      bsl::streambuf  *d_streamBuffer_p;   // pointer to a stream buffer

      // FRIENDS
      friend CapitalizingStream& operator<<(CapitalizingStream&  stream,
                                            const char          *data);
    public:
      // CREATORS
      explicit CapitalizingStream(bsl::streambuf *streamBuffer);
          // Create a capitalizing stream using the specified 'streamBuffer'
          // as underlying stream buffer to the stream.
  };

  // FREE OPERATORS
  CapitalizingStream& operator<<(CapitalizingStream&  stream,
                                 const char          *data);
      // Write the specified 'data' in capitalized form to the specified
      // 'stream'.

  CapitalizingStream::CapitalizingStream(bsl::streambuf *streamBuffer)
  : d_streamBuffer_p(streamBuffer)
  {
  }
As is typical, the streaming operators are made friends of the class.
Note that we cannot directly use bsl::toupper to capitalize each individual character, because bsl::toupper operates on int instead of char. Instead, we call a function ucharToUpper that works in terms of unsigned char. some care must be made to avoid undefined and implementation-specific behavior during the conversions to and from int. Therefore we wrap bsl::toupper in an interface that works in terms of unsigned char:
  static unsigned char ucharToUpper(unsigned char input)
      // Return the upper-case equivalent to the specified 'input' character.
  {
      return static_cast<unsigned char>(bsl::toupper(input));
  }
Finally, we use the transform algorithm to convert lower-case characters to upper-case.
  // FREE OPERATORS
  CapitalizingStream& operator<<(CapitalizingStream&  stream,
                                 const char          *data)
  {
      bsl::string tmp(data);
      bsl::transform(tmp.begin(),
                     tmp.end(),
                     tmp.begin(),
                     ucharToUpper);
      stream.d_streamBuffer_p->sputn(tmp.data(), tmp.length());
      return stream;
  }
Now, we create an instance of bdlsb::MemOutStreamBuf that will serve as underlying stream buffer for our CapitalingStream:
  bdlsb::MemOutStreamBuf streamBuffer;
Now, we test our CapitalingStream by supplying the created instance of bdlsb::MemOutStreamBuf and using it to inspect the output of the stream:
  CapitalizingStream  testStream(&streamBuffer);
  testStream << "Hello world.";
Finally, we verify that the streamed data has been capitalized and placed into dynamically allocated buffer:
  assert(12 == streamBuffer.length());
  assert(0  == bsl::strncmp("HELLO WORLD.",
                            streamBuffer.data(),
                            streamBuffer.length()));