Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlsb_fixedmemoutstreambuf
[Package bdlsb]

Provide an output basic_streambuf using a client buffer. More...

Namespaces

namespace  bdlsb

Detailed Description

Outline
Purpose:
Provide an output basic_streambuf using a client buffer.
Classes:
bdlsb::FixedMemOutStreamBuf output stream buffer using client memory
See also:
Component bdlsb_memoutstreambuf, Component bdlsb_fixedmeminstreambuf
Description:
This component defines a class bdlsb::FixedMemOutStreamBuf that implements the output portion of the bsl::basic_streambuf protocol using a client-supplied memory buffer. Method names necessarily correspond to the protocol-specified method names. Clients supply the character buffer at stream buffer construction, and can later reinitialize the stream buffer with a different character buffer by calling the pubsetbuf method.
This component provides none of the input-related functionality of basic_streambuf (see Streaming Architecture, below), nor does it use locales in any way.
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 bdex, including all of bdesb, follows this model.
Usage:
This section illustrates intended use of this component.
Example 1: Directly Observing Stream Buffer Contents:
Unlike most implementations of the bsl::basic_streambuf concept, bdlsb::FixedMemOutStreamBuf gives the user direct access to the stream's storage, both through the data accessor and through the buffer originally supplied to the constructor. Note that this can be useful in many contexts, such as when we need to perform extra security validation on buffer during the streaming process.
First, we create an array to provide storage for the stream buffer, and construct a bdlsb::FixedMemOutStreamBuf on that array:
  const int                   STORAGE_SIZE = 64;
  char                        storage[STORAGE_SIZE];
  bdlsb::FixedMemOutStreamBuf buffer(storage, STORAGE_SIZE);
Notice that storage is on the stack. bdlsb::FixedMemOutStreamBuf can be easily used without resorting to dynamic memory allocation.
Then, we observe that buffer already has a capacity of 64. Note that this capacity is fixed at construction:
  assert(STORAGE_SIZE == buffer.capacity());
  assert( 0 == buffer.length());
  assert(buffer.data() == storage);
Next, we use buffer to construct a bsl::ostream:
  bsl::ostream stream(&buffer);
Now, we output some data to the stream:
  stream << "The answer is " << 42 << ".";
Finally, we observe that the data is present in the storage array that we supplied to buffer:
  assert(17 == buffer.length());
  assert(buffer.length() < STORAGE_SIZE);
  assert(0 == strncmp("The answer is 42.", storage, 17));
Example 2: Fixed Buffer Size:
Unlike most implementations of the bsl::basic_streambuf concept, bdlsb::FixedMemOutStreamBuf uses a buffer of limited size, provided to the constructor together with the address of the storage buffer. That limit will not be exceeded even in case of superfluous data. Symbols beyond this limit will be ignored. Note that this can be useful if memory allocation should be strictly controlled.
First, we create an array to provide storage for the stream buffer, fill it with some data and construct a bdlsb::FixedMemOutStreamBuf on the part of that array:
  const unsigned int SMALL_STORAGE_SIZE = 16;
  const unsigned int SMALL_BUFFER_CAPACITY = SMALL_STORAGE_SIZE/2;
  char               smallStorage[SMALL_STORAGE_SIZE];
  memset(smallStorage, 'Z', SMALL_STORAGE_SIZE);

  bdlsb::FixedMemOutStreamBuf smallBuffer(smallStorage,
                                          SMALL_BUFFER_CAPACITY);
Next, we write some characters to the buffer and check that it handles them correctly and superfluous data is ignored:
  bsl::streamsize returnedSize = smallBuffer.sputn("The answer is 42.", 17);
  assert(SMALL_BUFFER_CAPACITY == returnedSize);
  assert(SMALL_BUFFER_CAPACITY == smallBuffer.length());
  assert('Z' == smallStorage[smallBuffer.length()]);
Then, we reset position indicator to the beginning of storage:
  smallBuffer.pubseekpos(0,bsl::ios_base::out);
  assert(0 == smallBuffer.length());
Now, we write another string, containing fewer characters than the storage capacity:
  returnedSize = smallBuffer.sputn("Truth.", 6);
Finally, we observe that given string has been successfully placed to buffer:
  assert(6 == returnedSize);
  assert(6 == smallBuffer.length());
  assert(0 == strncmp("Truth.", smallStorage, 6));