BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlsb_fixedmemoutstreambuf

Detailed Description

Outline

Purpose

Provide an output basic_streambuf using a client buffer.

Classes

See also
bdlsb_memoutstreambuf, 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);
Definition bdlsb_fixedmemoutstreambuf.h:201

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));