Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlsb_overflowmemoutput
[Package bdlsb]

Provide an overflowable output streambuf using a client buffer. More...

Namespaces

namespace  bdlsb

Detailed Description

Outline
Purpose:
Provide an overflowable output streambuf using a client buffer.
Classes:
bdlsb::OverflowMemOutput overflowable output stream buffer
See also:
Component bdlsb_fixedmemoutput, Component bdlsb_overflowmemoutstreambuf
Description:
This component provides a mechanism, bdlsb::OverflowMemOutput, that implements the output portion of the bsl::basic_streambuf protocol using a user-supplied memory buffer and a managed, allocator-supplied overflow buffer that is created when the client-supplied buffer runs out. Method names necessarily correspond to the protocol-specified method names. As with bdlsb_overflowmemoutstreambuf, clients supply the character buffer at construction. Unlike bdlsb_fixedmemoutput, they can no longer reinitialize the stream buffer with a different character buffer by calling the pubsetbuf method; instead, if that buffer runs out, the bdlsb::OverflowMemOutput will allocate another buffer (see "Overflow Buffer" below). The only difference between this component and bdlsb_overflowmemoutstreambuf is that the class bdlsb::OverflowMemOutput does not derive from bsl::streambuf and does not support locales. This is advantageous for performance reasons, as the overhead of the initialization and virtual function calls of a bsl::streambuf can be undesirable. The bdlsb::OverflowMemOutput is designed to be used by generic template code that must be instantiated on a type that matches the interface of bsl::streambuf, but does not require an actual bsl::streambuf, in particular bslx_genericoutstream.
Overflow Buffer:
This output stream buffer uses the initial buffer (supplied at construction) as its output buffer. If an overflow of the initial buffer were to occur, an additional buffer (the overflow buffer) will be allocated. If this overflow buffer ever becomes full, it will be automatically grown. The overflow buffer grows geometrically (to twice the current overflow buffer size) whenever the amount of data written exceeds the amount of space available. On growth, the old overflow buffer is copied over to the newly allocated overflow buffer, and then deallocated, thus after any write one cannot assume that the overflow buffer is still the same memory. Data in the overflow buffer beyond the reach of the current write position is not guaranteed to be preserved after a growth operation.
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. The BDE streaming library for blsx, including all of bdlsb, follows this model.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Use of bdlsb::OverflowMemOutput:
This example demonstrates instantiating a template, bslx::GenericOutStream, on a bdlsb::OverflowMemOutput object and using the bslx::GenericOutStream object to stream out some data.
First, we create a stream buffer, streamBuf, and supply it stack allocated memory as its initial buffer:
  enum { k_STREAMBUF_CAPACITY = 8 };

  char                     buffer[k_STREAMBUF_CAPACITY];
  bdlsb::OverflowMemOutput streamBuf(buffer, k_STREAMBUF_CAPACITY);
Then, we create an instance of bslx::GenericOutStream using streamBuf, with an arbitrary value for its versionSelector, and serialize some data:
  bslx::GenericOutStream<bdlsb::OverflowMemOutput> outStream(&streamBuf,
                                                             20150707);
  int MAGIC = 0x1812;
  outStream.putInt32(MAGIC);
  outStream.putInt32(MAGIC+1);
Next, we verify that the data was correctly serialized and completely filled initial buffer supplied at the stream buffer construction:
  assert(outStream.isValid());
  assert(8 == streamBuf.dataLength());
  assert(0 == bsl::memcmp(streamBuf.initialBuffer(),
                          "\x00\x00\x18\x12\x00\x00\x18\x13",
                          8));
  assert(0 == bsl::memcmp(buffer, "\x00\x00\x18\x12\x00\x00\x18\x13", 8));
  assert(0 == streamBuf.overflowBuffer());
  assert(0 == streamBuf.overflowBufferSize());
Then, we serialize some more data to trigger allocation of the internal overflow buffer:
  outStream.putString(bsl::string("test"));
Finally, we verify that the additional data was serialized correctly and landed into dynamically allocated overflow buffer:
  assert(outStream.isValid());
  assert(13 == streamBuf.dataLength());
  assert(0  != streamBuf.overflowBuffer());
  assert(5  == streamBuf.dataLengthInOverflowBuffer());
  assert(0  == bsl::memcmp(streamBuf.overflowBuffer(), "\x04test", 5));