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

Detailed Description

Outline

Purpose

Provide an output basic_streambuf using managed memory.

Classes

See also
bdlsb_fixedmemoutstreambuf, 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 'bdlsb::MemOutStreamBuf):

/// This class capitalizes lower-case ASCII characters that are output.
class CapitalizingStream {
// DATA
bsl::streambuf *d_streamBuffer_p; // pointer to a stream buffer
// FRIENDS
friend CapitalizingStream& operator<<(CapitalizingStream& stream,
const char *data);
public:
// CREATORS
/// Create a capitalizing stream using the specified `streamBuffer`
/// as underlying stream buffer to the stream.
explicit CapitalizingStream(bsl::streambuf *streamBuffer);
};
// FREE OPERATORS
/// Write the specified `data` in capitalized form to the specified
/// `stream`.
CapitalizingStream& operator<<(CapitalizingStream& stream,
const char *data);
CapitalizingStream::CapitalizingStream(bsl::streambuf *streamBuffer)
: d_streamBuffer_p(streamBuffer)
{
}
bsl::ostream & operator<<(bsl::ostream &stream, const bdlat_AttributeInfo &attributeInfo)

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:

/// Return the upper-case equivalent to the specified `input` character.
static unsigned char ucharToUpper(unsigned char input)
{
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;
}
Definition bslstl_string.h:1281

Now, we create an instance of bdlsb::MemOutStreamBuf that will serve as underlying stream buffer for our CapitalingStream:

Definition bdlsb_memoutstreambuf.h:212

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()));
bsl::size_t length() const
Return the number of valid characters in this stream buffer.
Definition bdlsb_memoutstreambuf.h:400
const char * data() const
Definition bdlsb_memoutstreambuf.h:394