BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlsb_overflowmemoutput.h
Go to the documentation of this file.
1/// @file bdlsb_overflowmemoutput.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlsb_overflowmemoutput.h -*-C++-*-
8#ifndef INCLUDED_BDLSB_OVERFLOWMEMOUTPUT
9#define INCLUDED_BDLSB_OVERFLOWMEMOUTPUT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlsb_overflowmemoutput bdlsb_overflowmemoutput
15/// @brief Provide an overflowable output `streambuf` using a client buffer.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlsb
19/// @{
20/// @addtogroup bdlsb_overflowmemoutput
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlsb_overflowmemoutput-purpose"> Purpose</a>
25/// * <a href="#bdlsb_overflowmemoutput-classes"> Classes </a>
26/// * <a href="#bdlsb_overflowmemoutput-description"> Description </a>
27/// * <a href="#bdlsb_overflowmemoutput-overflow-buffer"> Overflow Buffer </a>
28/// * <a href="#bdlsb_overflowmemoutput-streaming-architecture"> Streaming Architecture </a>
29/// * <a href="#bdlsb_overflowmemoutput-usage"> Usage </a>
30/// * <a href="#bdlsb_overflowmemoutput-example-1-basic-use-of-bdlsb-overflowmemoutput"> Example 1: Basic Use of bdlsb::OverflowMemOutput </a>
31///
32/// # Purpose {#bdlsb_overflowmemoutput-purpose}
33/// Provide an overflowable output `streambuf` using a client buffer.
34///
35/// # Classes {#bdlsb_overflowmemoutput-classes}
36///
37/// - bdlsb::OverflowMemOutput: overflowable output stream buffer
38///
39/// @see bdlsb_fixedmemoutput, bdlsb_overflowmemoutstreambuf
40///
41/// # Description {#bdlsb_overflowmemoutput-description}
42/// This component provides a mechanism,
43/// `bdlsb::OverflowMemOutput`, that implements the output portion of the
44/// `bsl::basic_streambuf` protocol using a user-supplied memory buffer and a
45/// managed, allocator-supplied overflow buffer that is created when the
46/// client-supplied buffer runs out. Method names necessarily correspond to the
47/// protocol-specified method names. As with @ref bdlsb_overflowmemoutstreambuf ,
48/// clients supply the character buffer at construction. Unlike
49/// @ref bdlsb_fixedmemoutput , they can no longer reinitialize the stream buffer
50/// with a different character buffer by calling the `pubsetbuf` method;
51/// instead, if that buffer runs out, the `bdlsb::OverflowMemOutput` will
52/// allocate another buffer (see @ref bdlsb_overflowmemoutput-overflow-buffer ). The only difference
53/// between this component and @ref bdlsb_overflowmemoutstreambuf is that the class
54/// `bdlsb::OverflowMemOutput` does *not* derive from `bsl::streambuf` and does
55/// not support locales. This is advantageous for performance reasons, as the
56/// overhead of the initialization and virtual function calls of a
57/// `bsl::streambuf` can be undesirable. The `bdlsb::OverflowMemOutput` is
58/// designed to be used by generic template code that must be instantiated on a
59/// type that matches the interface of `bsl::streambuf`, but does not require an
60/// actual `bsl::streambuf`, in particular @ref bslx_genericoutstream .
61///
62/// ## Overflow Buffer {#bdlsb_overflowmemoutput-overflow-buffer}
63///
64///
65/// This output stream buffer uses the initial buffer (supplied at construction)
66/// as its output buffer. If an overflow of the initial buffer were to occur,
67/// an additional buffer (the overflow buffer) will be allocated. If this
68/// overflow buffer ever becomes full, it will be automatically grown. The
69/// overflow buffer grows geometrically (to twice the current overflow buffer
70/// size) whenever the amount of data written exceeds the amount of space
71/// available. On growth, the old overflow buffer is copied over to the newly
72/// allocated overflow buffer, and then deallocated, thus after any write one
73/// cannot assume that the overflow buffer is still the same memory. Data in
74/// the overflow buffer beyond the reach of the current write position is not
75/// guaranteed to be preserved after a growth operation.
76///
77/// ## Streaming Architecture {#bdlsb_overflowmemoutput-streaming-architecture}
78///
79///
80/// Stream buffers are designed to decouple device handling from content
81/// formatting, providing the requisite device handling and possible buffering
82/// services, and leaving the formatting to the client stream. The standard C++
83/// IOStreams library further partitions streaming into input streaming and
84/// output streaming, separating responsibilities for each at both the stream
85/// layer and the stream buffer layer. The BDE streaming library for `blsx`,
86/// including all of `bdlsb`, follows this model.
87///
88/// ## Usage {#bdlsb_overflowmemoutput-usage}
89///
90///
91/// This section illustrates intended use of this component.
92///
93/// ### Example 1: Basic Use of bdlsb::OverflowMemOutput {#bdlsb_overflowmemoutput-example-1-basic-use-of-bdlsb-overflowmemoutput}
94///
95///
96/// This example demonstrates instantiating a template,
97/// `bslx::GenericOutStream`, on a `bdlsb::OverflowMemOutput` object and using
98/// the `bslx::GenericOutStream` object to stream out some data.
99///
100/// First, we create a stream buffer, `streamBuf`, and supply it stack allocated
101/// memory as its initial buffer:
102/// @code
103/// enum { k_STREAMBUF_CAPACITY = 8 };
104///
105/// char buffer[k_STREAMBUF_CAPACITY];
106/// bdlsb::OverflowMemOutput streamBuf(buffer, k_STREAMBUF_CAPACITY);
107/// @endcode
108/// Then, we create an instance of `bslx::GenericOutStream` using `streamBuf`,
109/// with an arbitrary value for its `versionSelector`, and serialize some data:
110/// @code
111/// bslx::GenericOutStream<bdlsb::OverflowMemOutput> outStream(&streamBuf,
112/// 20150707);
113/// int MAGIC = 0x1812;
114/// outStream.putInt32(MAGIC);
115/// outStream.putInt32(MAGIC+1);
116/// @endcode
117/// Next, we verify that the data was correctly serialized and completely filled
118/// initial buffer supplied at the stream buffer construction:
119/// @code
120/// assert(outStream.isValid());
121/// assert(8 == streamBuf.dataLength());
122/// assert(0 == bsl::memcmp(streamBuf.initialBuffer(),
123/// "\x00\x00\x18\x12\x00\x00\x18\x13",
124/// 8));
125/// assert(0 == bsl::memcmp(buffer, "\x00\x00\x18\x12\x00\x00\x18\x13", 8));
126/// assert(0 == streamBuf.overflowBuffer());
127/// assert(0 == streamBuf.overflowBufferSize());
128/// @endcode
129/// Then, we serialize some more data to trigger allocation of the internal
130/// overflow buffer:
131/// @code
132/// outStream.putString(bsl::string("test"));
133/// @endcode
134/// Finally, we verify that the additional data was serialized correctly and
135/// landed into dynamically allocated overflow buffer:
136/// @code
137/// assert(outStream.isValid());
138/// assert(13 == streamBuf.dataLength());
139/// assert(0 != streamBuf.overflowBuffer());
140/// assert(5 == streamBuf.dataLengthInOverflowBuffer());
141/// assert(0 == bsl::memcmp(streamBuf.overflowBuffer(), "\x04test", 5));
142/// @endcode
143/// @}
144/** @} */
145/** @} */
146
147/** @addtogroup bdl
148 * @{
149 */
150/** @addtogroup bdlsb
151 * @{
152 */
153/** @addtogroup bdlsb_overflowmemoutput
154 * @{
155 */
156
157#include <bdlscm_version.h>
158
159#include <bslma_allocator.h>
161
163
164#include <bsl_cstddef.h>
165#include <bsl_ios.h>
166#include <bsl_iosfwd.h>
167
168
169namespace bdlsb {
170
171 // =======================
172 // class OverflowMemOutput
173 // =======================
174
175/// This class, like `bdlsb::OverflowMemOutStreamBuf`, implements the output
176/// functionality of the `bsl::basic_streambuf` interface, using a
177/// client-supplied buffer and allocator-supplied overflow buffer if additional
178/// memory is needed. It has an interface similar to
179/// `bdlsb::OverflowMemOutStreamBuf` but does **not** inherit from
180/// `bsl::streambuf`. Thus, it is suitable for use as template parameter to
181/// `bslx::GenericByteOutStream` (but not to `bslx::ByteOutStream` or `bslx::ByteOutStreamFormatter`).
182///
183/// \note Note that this class is not designed to
184/// be derived from.
185///
186/// See @ref bdlsb_overflowmemoutput
188
189 // DATA
190
191 // The order of the data members is determined by our usage pattern for
192 // cache efficiency. Do not reorder them.
193
194 bsl::size_t d_dataLength; // total data length
195
196 char *d_put_p; // current put pointer
197
198 char *d_initialBuffer_p; // user-supplied buffer (held,
199 // not owned)
200
201 bsl::size_t d_initialBufferSize; // size of 'd_initialBuffer_p'
202 // buffer
203
204 bool d_inOverflowBufferFlag; // true if 'd_put_p' points into
205 // the overflow buffer
206
207 char *d_overflowBuffer_p; // overflow buffer (owned)
208
209 bsl::size_t d_overflowBufferSize; // size of 'd_overflowBuffer_p'
210 // buffer
211
212 bslma::Allocator *d_allocator_p; // memory allocator (held, not
213 // owned)
214
215 private:
216 // NOT IMPLEMENTED
218 OverflowMemOutput& operator=(const OverflowMemOutput&);
219
220 private:
221 // PRIVATE MANIPULATORS
222
223 /// Replace the overflow buffer with another buffer, larger then the
224 /// current buffer by at least the specified `numBytes`, by growing
225 /// geometrically by a factor of two. Optionally specify a `copyOrigin`
226 /// indicating whether the content of the overflow buffer should be copied into new location.
227 ///
228 /// \note Note that `d_put_p` is not updated, and may be
229 /// pointing to deallocated memory when the method returns.
230 void grow(bsl::size_t numBytes, bool copyOrigin = true);
231
232 public:
233 // TRAITS
236
237 // TYPES
238 typedef char char_type;
239 typedef bsl::char_traits<char> traits_type;
240 typedef traits_type::int_type int_type;
241 typedef traits_type::pos_type pos_type;
242 typedef traits_type::off_type off_type;
243
244 // CREATORS
245
246 /// Create an `OverflowMemOutput` using the specified `buffer` of the
247 /// specified `length` as the initial output buffer. Optionally specify
248 /// a `basicAllocator` used to supply memory. If `basicAllocator` is 0,
249 /// the currently installed default allocator is used.
250 ///
251 /// \pre The behavior is undefined unless `buffer != 0 && length > 0`.
252 /// \note Note that this stream
253 /// buffer does not assume ownership of `buffer`.
254 OverflowMemOutput(char *buffer,
255 bsl::size_t length,
256 bslma::Allocator *basicAllocator = 0);
257
258 /// Destroy this stream buffer.
260
261 // MANIPULATORS
262 // *** 27.5.2.2.2 buffer and positioning ***
263
264 /// Set the position indicator to the relative specified `offset` from the
265 /// base position indicated by the specified `way` and return the resulting
266 /// absolute position on success or pos_type(-1) on failure. Optionally
267 /// specify `which` area of the stream buffer. The seek operation will
268 /// fail if `which` does not include the flag `bsl::ios_base::out` or if
269 /// the resulting absolute position is less than zero.
271 bsl::ios_base::seekdir way,
272 bsl::ios_base::openmode which = bsl::ios_base::out);
273
274 /// Set the position indicator to the specified `position` and return the
275 /// resulting absolute position on success or pos_type(-1) on failure.
276 /// Optionally specify `which` area of the stream buffer. The `seekpos`
277 /// operation will fail if `which` does not include the flag
278 /// `bsl::ios_base::out` or if `position` is less then zero.
280 bsl::ios_base::openmode which = bsl::ios_base::out);
281
282 /// Reinitialize this stream buffer to use the specified character `buffer`
283 /// having the specified `length`. Return a pointer providing modifiable
284 /// access to this stream buffer. This stream buffer does not support
285 /// reinitialization of the internal character buffer.
286 OverflowMemOutput *pubsetbuf(char *buffer, bsl::streamsize length);
287
288 /// Synchronize this stream buffer with associated character sequence.
289 /// Operation has no effect. Return `0` unconditionally.
290 int pubsync();
291
292 // *** 27.5.2.2.5 put area ***
293
294 /// Write the specified character `c` at the current write position and
295 /// advance write position of this buffer. Return `c`, or
296 /// `traits_type::eof()` if the end of the write buffer is reached.
298
299 /// Write the specified `length` characters from the specified `source`
300 /// to this buffer. Return the number of characters written, which is
301 /// either `length` or the distance from the current write position to
302 /// the end of the write buffer, whichever is smaller, and move the
303 /// write cursor position by this amount.
304 ///
305 /// \pre The behaviour is undefined unless `source != 0 || length > 0`.
306 bsl::streamsize sputn(const char *source, bsl::streamsize length);
307
308 // ACCESSORS
309
310 /// Return the number of bytes that have been written to this object.
311 bsl::size_t dataLength() const;
312
313 /// Return the length of data in the initial buffer, i.e., `dataLength()`
314 /// if there is no overflow buffer, or `initialBufferSize()` if there is
315 /// one.
316 bsl::size_t dataLengthInInitialBuffer() const;
317
318 /// Return the length of the data in the overflow buffer, i.e., 0 if there
319 /// is no overflow buffer, or `dataLength() - initialBufferSize()` if there
320 /// is one.
321 bsl::size_t dataLengthInOverflowBuffer() const;
322
323 /// Return a pointer providing non-modifiable access to the character
324 /// buffer held by this stream buffer (specified at construction).
325 const char *initialBuffer() const;
326
327 /// Return the size of the initial buffer held by this stream buffer.
328 bsl::size_t initialBufferSize() const;
329
330 /// Return a pointer providing non-modifiable access to the overflow buffer
331 /// if there is one, or 0 otherwise.
332 const char *overflowBuffer() const;
333
334 /// Return the size of the overflow buffer, or 0 if there is no overflow
335 /// buffer.
336 bsl::size_t overflowBufferSize() const;
337};
338
339// ============================================================================
340// INLINE DEFINITIONS
341// ============================================================================
342
343 // -----------------------
344 // class OverflowMemOutput
345 // -----------------------
346
347// CREATORS
348inline
350{
351 d_allocator_p->deallocate(d_overflowBuffer_p);
352}
353
354// MANIPULATORS
355inline
357OverflowMemOutput::pubseekpos(pos_type position, bsl::ios_base::openmode which)
358{
359 return pubseekoff(off_type(position), bsl::ios_base::beg, which);
360}
361
362inline
364{
365 return this;
366}
367
368inline
370{
371 return 0;
372}
373
374// ACCESSORS
375inline
377{
378 return d_dataLength;
379}
380
381inline
383{
384 return d_inOverflowBufferFlag ? d_initialBufferSize : d_dataLength;
385}
386
387inline
389{
390 return d_inOverflowBufferFlag ? d_dataLength - d_initialBufferSize : 0;
391}
392
393inline
395{
396 return d_initialBuffer_p;
397}
398
399inline
401{
402 return d_initialBufferSize;
403}
404
405inline
407{
408 return d_overflowBuffer_p;
409}
410
411inline
413{
414 return d_overflowBufferSize;
415}
416
417} // close package namespace
418
419
420#endif
421
422// ----------------------------------------------------------------------------
423// Copyright 2015 Bloomberg Finance L.P.
424//
425// Licensed under the Apache License, Version 2.0 (the "License");
426// you may not use this file except in compliance with the License.
427// You may obtain a copy of the License at
428//
429// http://www.apache.org/licenses/LICENSE-2.0
430//
431// Unless required by applicable law or agreed to in writing, software
432// distributed under the License is distributed on an "AS IS" BASIS,
433// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
434// See the License for the specific language governing permissions and
435// limitations under the License.
436// ----------------------------- END-OF-FILE ----------------------------------
437
438/** @} */
439/** @} */
440/** @} */
Definition bdlsb_overflowmemoutput.h:187
bsl::streamsize sputn(const char *source, bsl::streamsize length)
OverflowMemOutput * pubsetbuf(char *buffer, bsl::streamsize length)
Definition bdlsb_overflowmemoutput.h:363
const char * overflowBuffer() const
Definition bdlsb_overflowmemoutput.h:406
bsl::size_t initialBufferSize() const
Return the size of the initial buffer held by this stream buffer.
Definition bdlsb_overflowmemoutput.h:400
bsl::size_t dataLength() const
Return the number of bytes that have been written to this object.
Definition bdlsb_overflowmemoutput.h:376
traits_type::pos_type pos_type
Definition bdlsb_overflowmemoutput.h:241
bsl::size_t dataLengthInInitialBuffer() const
Definition bdlsb_overflowmemoutput.h:382
const char * initialBuffer() const
Definition bdlsb_overflowmemoutput.h:394
pos_type pubseekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::out)
Definition bdlsb_overflowmemoutput.h:357
BSLMF_NESTED_TRAIT_DECLARATION(OverflowMemOutput, bslma::UsesBslmaAllocator)
OverflowMemOutput(char *buffer, bsl::size_t length, bslma::Allocator *basicAllocator=0)
bsl::size_t overflowBufferSize() const
Definition bdlsb_overflowmemoutput.h:412
int pubsync()
Definition bdlsb_overflowmemoutput.h:369
traits_type::off_type off_type
Definition bdlsb_overflowmemoutput.h:242
~OverflowMemOutput()
Destroy this stream buffer.
Definition bdlsb_overflowmemoutput.h:349
int_type sputc(char c)
pos_type pubseekoff(off_type offset, bsl::ios_base::seekdir way, bsl::ios_base::openmode which=bsl::ios_base::out)
bsl::char_traits< char > traits_type
Definition bdlsb_overflowmemoutput.h:239
bsl::size_t dataLengthInOverflowBuffer() const
Definition bdlsb_overflowmemoutput.h:388
traits_type::int_type int_type
Definition bdlsb_overflowmemoutput.h:240
char char_type
Definition bdlsb_overflowmemoutput.h:238
Definition bslma_allocator.h:545
virtual void deallocate(void *address)=0
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bdlsb_fixedmeminput.h:145
Definition bslma_usesbslmaallocator.h:344