BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlsb_memoutstreambuf.h
Go to the documentation of this file.
1/// @file bdlsb_memoutstreambuf.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlsb_memoutstreambuf.h -*-C++-*-
8#ifndef INCLUDED_BDLSB_MEMOUTSTREAMBUF
9#define INCLUDED_BDLSB_MEMOUTSTREAMBUF
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlsb_memoutstreambuf bdlsb_memoutstreambuf
15/// @brief Provide an output `basic_streambuf` using managed memory.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlsb
19/// @{
20/// @addtogroup bdlsb_memoutstreambuf
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlsb_memoutstreambuf-purpose"> Purpose</a>
25/// * <a href="#bdlsb_memoutstreambuf-classes"> Classes </a>
26/// * <a href="#bdlsb_memoutstreambuf-description"> Description </a>
27/// * <a href="#bdlsb_memoutstreambuf-streaming-architecture"> Streaming Architecture </a>
28/// * <a href="#bdlsb_memoutstreambuf-usage"> Usage </a>
29/// * <a href="#bdlsb_memoutstreambuf-example-1-basic-use-of-bdlsb-memoutstreambuf"> Example 1: Basic Use of bdlsb::MemOutStreamBuf </a>
30///
31/// # Purpose {#bdlsb_memoutstreambuf-purpose}
32/// Provide an output @ref basic_streambuf using managed memory.
33///
34/// # Classes {#bdlsb_memoutstreambuf-classes}
35///
36/// - bdlsb::MemOutStreamBuf: output stream buffer using memory allocator
37///
38/// @see bdlsb_fixedmemoutstreambuf, bdlsb_fixedmeminstreambuf
39///
40/// # Description {#bdlsb_memoutstreambuf-description}
41/// This component provides a mechanism, `bdlsb::MemOutStreamBuf`,
42/// that implements the output portion of the `bsl::basic_streambuf` protocol
43/// using a managed, allocator-supplied memory buffer. Method names necessarily
44/// correspond to those specified by the protocol.
45///
46/// This component provides none of the input-related functionality of
47/// @ref basic_streambuf (see "Streaming Architecture", below), nor does it use
48/// locales in any way.
49///
50/// Because the underlying buffer is always obtained from the client-specified
51/// allocator, the `pubsetbuf` method in this component has no effect.
52///
53/// Note that this component has an unspecified minimum allocation size, and
54/// therefore users trying to limit themselves to a fixed buffer should use
55/// bdlsb_fixedmemoutstreambuf.
56///
57/// ## Streaming Architecture {#bdlsb_memoutstreambuf-streaming-architecture}
58///
59///
60/// Stream buffers are designed to decouple device handling from content
61/// formatting, providing the requisite device handling and possible buffering
62/// services, and leaving the formatting to the client stream. The standard C++
63/// IOStreams library further partitions streaming into input streaming and
64/// output streaming, separating responsibilities for each at both the stream
65/// layer and the stream buffer layer.
66///
67/// ## Usage {#bdlsb_memoutstreambuf-usage}
68///
69///
70/// This section illustrates intended use of this component.
71///
72/// ### Example 1: Basic Use of bdlsb::MemOutStreamBuf {#bdlsb_memoutstreambuf-example-1-basic-use-of-bdlsb-memoutstreambuf}
73///
74///
75/// This example demonstrates using a `bdlsb::MemOutStreamBuf` in order to test
76/// a user defined stream type, `CapitalizingStream`. In this example, we'll
77/// define a simple example stream type `CapitalizingStream` that capitalizing
78/// lower-case ASCII data written to the stream. In order to test this
79/// `CapitalizingStream` type, we'll create an instance, and supply it a
80/// `bdlsb::MemOutStreamBuf` object as its stream buffer; after we write some
81/// character data to the `CapitalizingStream` we'll inspect the buffer of the
82/// `bdlsb::MemOutStreamBuf` and verify its contents match our expected output.
83/// Note that to simplify the example, we do not include the functions for
84/// streaming non-character data, e.g., numeric values.
85///
86/// First, we define our example stream class, `CapitalizingStream` (which we
87/// will later test using 'bdlsb::MemOutStreamBuf):
88/// @code
89/// /// This class capitalizes lower-case ASCII characters that are output.
90/// class CapitalizingStream {
91///
92/// // DATA
93/// bsl::streambuf *d_streamBuffer_p; // pointer to a stream buffer
94///
95/// // FRIENDS
96/// friend CapitalizingStream& operator<<(CapitalizingStream& stream,
97/// const char *data);
98/// public:
99/// // CREATORS
100///
101/// /// Create a capitalizing stream using the specified `streamBuffer`
102/// /// as underlying stream buffer to the stream.
103/// explicit CapitalizingStream(bsl::streambuf *streamBuffer);
104/// };
105///
106/// // FREE OPERATORS
107///
108/// /// Write the specified `data` in capitalized form to the specified
109/// /// `stream`.
110/// CapitalizingStream& operator<<(CapitalizingStream& stream,
111/// const char *data);
112///
113/// CapitalizingStream::CapitalizingStream(bsl::streambuf *streamBuffer)
114/// : d_streamBuffer_p(streamBuffer)
115/// {
116/// }
117/// @endcode
118/// As is typical, the streaming operators are made friends of the class.
119///
120/// Note that we cannot directly use `bsl::toupper` to capitalize each
121/// individual character, because `bsl::toupper` operates on `int` instead of
122/// `char`. Instead, we call a function `ucharToUpper` that works in terms of
123/// `unsigned char`. some care must be made to avoid undefined and
124/// implementation-specific behavior during the conversions to and from `int`.
125/// Therefore we wrap `bsl::toupper` in an interface that works in terms of
126/// `unsigned char`:
127/// @code
128/// /// Return the upper-case equivalent to the specified `input` character.
129/// static unsigned char ucharToUpper(unsigned char input)
130/// {
131/// return static_cast<unsigned char>(bsl::toupper(input));
132/// }
133/// @endcode
134/// Finally, we use the `transform` algorithm to convert lower-case characters
135/// to upper-case.
136/// @code
137/// // FREE OPERATORS
138/// CapitalizingStream& operator<<(CapitalizingStream& stream,
139/// const char *data)
140/// {
141/// bsl::string tmp(data);
142/// bsl::transform(tmp.begin(),
143/// tmp.end(),
144/// tmp.begin(),
145/// ucharToUpper);
146/// stream.d_streamBuffer_p->sputn(tmp.data(), tmp.length());
147/// return stream;
148/// }
149/// @endcode
150/// Now, we create an instance of `bdlsb::MemOutStreamBuf` that will serve as
151/// underlying stream buffer for our `CapitalingStream`:
152/// @code
153/// bdlsb::MemOutStreamBuf streamBuffer;
154/// @endcode
155/// Now, we test our `CapitalingStream` by supplying the created instance of
156/// `bdlsb::MemOutStreamBuf` and using it to inspect the output of the stream:
157/// @code
158/// CapitalizingStream testStream(&streamBuffer);
159/// testStream << "Hello world.";
160/// @endcode
161/// Finally, we verify that the streamed data has been capitalized and placed
162/// into dynamically allocated buffer:
163/// @code
164/// assert(12 == streamBuffer.length());
165/// assert(0 == bsl::strncmp("HELLO WORLD.",
166/// streamBuffer.data(),
167/// streamBuffer.length()));
168/// @endcode
169/// @}
170/** @} */
171/** @} */
172
173/** @addtogroup bdl
174 * @{
175 */
176/** @addtogroup bdlsb
177 * @{
178 */
179/** @addtogroup bdlsb_memoutstreambuf
180 * @{
181 */
182
183#include <bdlscm_version.h>
184
185#include <bslma_allocator.h>
186#include <bslma_default.h>
188
190
191#include <bsls_keyword.h>
192#include <bsls_types.h>
193
194#include <bsl_cstddef.h>
195#include <bsl_cstdlib.h>
196#include <bsl_cstring.h>
197#include <bsl_ios.h>
198#include <bsl_streambuf.h> // (char|int|pos|off|traits)_type
199
200
201namespace bdlsb {
202
203 // =====================
204 // class MemOutStreamBuf
205 // =====================
206
207/// This `class` implements the output functionality of the
208/// @ref basic_streambuf protocol, using a user-supplied or default `bslma`
209/// allocator to supply memory.
210///
211/// See @ref bdlsb_memoutstreambuf
212class MemOutStreamBuf : public bsl::streambuf {
213
214 // PRIVATE CONSTANTS
215 enum {
216 k_INITIAL_BUFFER_SIZE = 256, // default initial buffer size
217
218 k_GROWTH_FACTOR = 2 // geometric growth factor to use when
219 // resizing internal buffer
220
221#ifndef BDE_OMIT_INTERNAL_DEPRECATED
222 , BDESB_INITIAL_BUFFER_SIZE = k_INITIAL_BUFFER_SIZE
223 , BDESB_GROWTH_FACTOR = k_GROWTH_FACTOR
224 , INITIAL_BUFFER_SIZE = k_INITIAL_BUFFER_SIZE
225 , GROWTH_FACTOR = k_GROWTH_FACTOR
226#endif // BDE_OMIT_INTERNAL_DEPRECATED
227 };
228
229 // DATA
230 bslma::Allocator *d_allocator_p; // memory source for buffer memory
231 // (held, not owned)
232
233 private:
234 // NOT IMPLEMENTED
235 MemOutStreamBuf(const MemOutStreamBuf&); // = delete;
236 MemOutStreamBuf& operator=(const MemOutStreamBuf&); // = delete;
237
238 private:
239 // PRIVATE MANIPULATORS
240
241 /// Grow the size of the internal buffer to be at least large enough to
242 /// fit the specified `newLength` characters. The buffer size is grown
243 /// by the minimum power of `k_GROWTH_FACTOR` needed to accommodate the
244 /// new length, but with a final size not less than
245 /// `k_INITIAL_BUFFER_SIZE`. This method has no effect if 'newLength <=
246 /// capacity()' holds before the call.
247 void grow(bsl::size_t newLength);
248
249 protected:
250 // PROTECTED MANIPULATORS
251
252 /// Append the optionally specified `insertionChar` to this stream
253 /// buffer's character buffer and return `insertionChar`. If
254 /// `insertionChar` is not specified, `traits_type::eof()` is appended
255 /// instead.
256 int_type overflow(
257 int_type insertionChar = bsl::streambuf::traits_type::eof())
259
260 /// Set the position indicator to the relative specified `offset` from
261 /// the base position indicated by the specified `way` and return the
262 /// resulting absolute position on success or pos_type(-1) on failure.
263 /// Optionally specify `which` area of the stream buffer. The seek
264 /// operation will fail if `which` does not include the flag
265 /// `bsl::ios_base::out` or if the resulting absolute position is less
266 /// than zero or greater then `length()`.
267 pos_type seekoff(off_type offset,
268 bsl::ios_base::seekdir way,
269 bsl::ios_base::openmode which = bsl::ios_base::in
270 | bsl::ios_base::out)
272
273 /// Set the position indicator to the specified `position` and return
274 /// the resulting absolute position on success or pos_type(-1) on
275 /// failure. Optionally specify `which` area of the stream buffer. The
276 /// `seekpos` operation will fail if `which` does not include the flag
277 /// `bsl::ios_base::out` or if `position` is less then zero or greater
278 /// than `length()`.
279 pos_type seekpos(pos_type position,
280 bsl::ios_base::openmode which = bsl::ios_base::in
281 | bsl::ios_base::out)
283
284 /// Write the specified `numChars` characters from the specified
285 /// `source` to the stream buffer. Return the number of characters
286 /// successfully written. The behavior is undefined unless '(source &&
287 /// 0 < numChars) || 0 == numChars'.
288 bsl::streamsize xsputn(const char_type *source,
289 bsl::streamsize numChars) BSLS_KEYWORD_OVERRIDE;
290
291 public:
292 // TRAITS
294 bslma::UsesBslmaAllocator);
295
296 // CREATORS
297
298 /// Create an empty stream buffer. Optionally specify a `basicAllocator`
299 /// used to supply memory. If `basicAllocator` is 0, the currently
300 /// installed default allocator is used.
301 explicit
302 MemOutStreamBuf(bslma::Allocator *basicAllocator = 0);
303
304 /// Create an empty stream buffer with sufficient initial capacity to
305 /// accommodate up to the specified `numElements` characters without
306 /// subsequent reallocation. If `numElements == 0`, an
307 /// implementation-defined initial capacity is used. Optionally specify a
308 /// `basicAllocator` used to supply memory. If `basicAllocator` is 0, the
309 /// currently installed default allocator is used.
310 explicit
311 MemOutStreamBuf(bsl::size_t numElements,
312 bslma::Allocator *basicAllocator = 0);
313
314 /// Destroy this stream buffer.
316
317 // MANIPULATORS
318
319 /// Reserve sufficient internal capacity to store at least the specified
320 /// `numCharacters` characters without reallocation. Note that if the
321 /// storage size specified is less than the number of characters already in
322 /// the buffer, this method has no effect.
323 void reserveCapacity(bsl::size_t numCharacters);
324
325 /// Destroy the contents of this stream buffer, return all allocated memory
326 /// to the allocator, and reset the buffer to the default constructed
327 /// state. Note that `length() == 0` holds following a call to this
328 /// method.
329 void reset();
330
331 // ACCESSORS
332
333 /// Return the current capacity of the buffer managed by this stream
334 /// buffer.
335 bsl::size_t capacity() const;
336
337 /// Return the address of the non-modifiable character buffer managed by
338 /// this stream buffer.
339 const char *data() const;
340
341 /// Return the number of valid characters in this stream buffer.
342 bsl::size_t length() const;
343};
344
345// ============================================================================
346// INLINE DEFINITIONS
347// ============================================================================
348
349 // ---------------------
350 // class MemOutStreamBuf
351 // ---------------------
352
353// CREATORS
354inline
355MemOutStreamBuf::MemOutStreamBuf(bslma::Allocator *basicAllocator)
356: d_allocator_p(bslma::Default::allocator(basicAllocator))
357{
358 setp(0, 0);
359}
360
361inline
362MemOutStreamBuf::MemOutStreamBuf(bsl::size_t numElements,
363 bslma::Allocator *basicAllocator)
364: d_allocator_p(bslma::Default::allocator(basicAllocator))
365{
366 setp(0, 0);
367 reserveCapacity(numElements == 0
368 ? static_cast<bsl::streamsize>(k_INITIAL_BUFFER_SIZE)
369 : numElements);
370}
371
372inline
374{
375 d_allocator_p->deallocate(pbase());
376}
377
378// MANIPULATORS
379inline
381{
382 d_allocator_p->deallocate(pbase());
383 setp(0, 0);
384}
385
386// ACCESSORS
387inline
388bsl::size_t MemOutStreamBuf::capacity() const
389{
390 return epptr() - pbase();
391}
392
393inline
394const char *MemOutStreamBuf::data() const
395{
396 return pbase();
397}
398
399inline
400bsl::size_t MemOutStreamBuf::length() const
401{
402 return pptr() - pbase();
403}
404
405} // close package namespace
406
407
408#endif
409
410// ----------------------------------------------------------------------------
411// Copyright 2015 Bloomberg Finance L.P.
412//
413// Licensed under the Apache License, Version 2.0 (the "License");
414// you may not use this file except in compliance with the License.
415// You may obtain a copy of the License at
416//
417// http://www.apache.org/licenses/LICENSE-2.0
418//
419// Unless required by applicable law or agreed to in writing, software
420// distributed under the License is distributed on an "AS IS" BASIS,
421// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
422// See the License for the specific language governing permissions and
423// limitations under the License.
424// ----------------------------- END-OF-FILE ----------------------------------
425
426/** @} */
427/** @} */
428/** @} */
#define BSLMF_NESTED_TRAIT_DECLARATION(t_TYPE, t_TRAIT)
Definition bslmf_nestedtraitdeclaration.h:231
Definition bdlsb_memoutstreambuf.h:212
pos_type seekoff(off_type offset, bsl::ios_base::seekdir way, bsl::ios_base::openmode which=bsl::ios_base::in|bsl::ios_base::out) BSLS_KEYWORD_OVERRIDE
bsl::streamsize xsputn(const char_type *source, bsl::streamsize numChars) BSLS_KEYWORD_OVERRIDE
int_type overflow(int_type insertionChar=bsl::streambuf::traits_type::eof()) BSLS_KEYWORD_OVERRIDE
bsl::size_t capacity() const
Definition bdlsb_memoutstreambuf.h:388
~MemOutStreamBuf() BSLS_KEYWORD_OVERRIDE
Destroy this stream buffer.
Definition bdlsb_memoutstreambuf.h:373
void reserveCapacity(bsl::size_t numCharacters)
bsl::size_t length() const
Return the number of valid characters in this stream buffer.
Definition bdlsb_memoutstreambuf.h:400
void reset()
Definition bdlsb_memoutstreambuf.h:380
pos_type seekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::in|bsl::ios_base::out) BSLS_KEYWORD_OVERRIDE
const char * data() const
Definition bdlsb_memoutstreambuf.h:394
Definition bslma_allocator.h:457
virtual void deallocate(void *address)=0
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:653
Definition bdlsb_fixedmeminput.h:145
Definition bdlb_printmethods.h:283
Definition balxml_encoderoptions.h:68