BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlsb_fixedmeminstreambuf.h
Go to the documentation of this file.
1/// @file bdlsb_fixedmeminstreambuf.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlsb_fixedmeminstreambuf.h -*-C++-*-
8#ifndef INCLUDED_BDLSB_FIXEDMEMINSTREAMBUF
9#define INCLUDED_BDLSB_FIXEDMEMINSTREAMBUF
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlsb_fixedmeminstreambuf bdlsb_fixedmeminstreambuf
15/// @brief Provide an input `basic_streambuf` using a client buffer.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlsb
19/// @{
20/// @addtogroup bdlsb_fixedmeminstreambuf
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlsb_fixedmeminstreambuf-purpose"> Purpose</a>
25/// * <a href="#bdlsb_fixedmeminstreambuf-classes"> Classes </a>
26/// * <a href="#bdlsb_fixedmeminstreambuf-description"> Description </a>
27/// * <a href="#bdlsb_fixedmeminstreambuf-streaming-architecture"> Streaming Architecture </a>
28/// * <a href="#bdlsb_fixedmeminstreambuf-usage"> Usage </a>
29/// * <a href="#bdlsb_fixedmeminstreambuf-example-1-basic-use-of-the-bdlsb-fixedmeminstreambuf"> Example 1: Basic Use of the bdlsb::FixedMemInStreamBuf </a>
30/// * <a href="#bdlsb_fixedmeminstreambuf-example-2-scanning-input-data"> Example 2: Scanning Input Data </a>
31///
32/// # Purpose {#bdlsb_fixedmeminstreambuf-purpose}
33/// Provide an input @ref basic_streambuf using a client buffer.
34///
35/// # Classes {#bdlsb_fixedmeminstreambuf-classes}
36///
37/// - bdlsb::FixedMemInStreamBuf: input stream buffer using client memory
38///
39/// @see bdlsb_fixedmemoutstreambuf, bdlsb_memoutstreambuf
40///
41/// # Description {#bdlsb_fixedmeminstreambuf-description}
42/// This component defines a class, `bdlsb::FixedMemInStreamBuf`,
43/// that implements the input portion of the `bsl::basic_streambuf` protocol
44/// using a client-supplied memory buffer. Method names necessarily correspond
45/// to the protocol-specified method names. Clients supply the character buffer
46/// at stream buffer construction, and can later reinitialize the stream buffer
47/// with a different character buffer by calling the `pubsetbuf` method.
48///
49/// This component provides none of the output-related functionality of
50/// @ref basic_streambuf (see Streaming Architecture, below), nor does it use
51/// locales in any way.
52///
53/// ## Streaming Architecture {#bdlsb_fixedmeminstreambuf-streaming-architecture}
54///
55///
56/// Stream buffers are designed to decouple device handling from content
57/// formatting, providing the requisite device handling and possible buffering
58/// services, and leaving the formatting to the client stream. The standard
59/// C++ IOStreams library further partitions streaming into input streaming and
60/// output streaming, separating responsibilities for each at both the stream
61/// layer and the stream buffer layer. The BDE streaming library for `bdex`,
62/// including all of `bdlsb`, follows this model.
63///
64/// ## Usage {#bdlsb_fixedmeminstreambuf-usage}
65///
66///
67/// This section illustrates intended use of this component.
68///
69/// ### Example 1: Basic Use of the bdlsb::FixedMemInStreamBuf {#bdlsb_fixedmeminstreambuf-example-1-basic-use-of-the-bdlsb-fixedmeminstreambuf}
70///
71///
72/// `bdlsb::FixedMemInStreamBuf` can be used in situations when you already
73/// have an array of bytes in memory and you'd like to wrap it in an input
74/// stream to extract data in a formatted manner. A
75/// `bdlsb::FixedMemInStreamBuf` object refers to an externally managed buffer
76/// that is supplied either at construction, or using the `pubsetbuf` method of
77/// the `bsl::streambuf` base-class.
78///
79/// First, we create an array of characters to provide data that needs to be
80/// parsed, and construct `bdlsb::FixedMemInStreamBuf` on that array:
81/// @code
82/// {
83/// const char *inputText = "1 1 2 3 5 8 13 21";
84/// bdlsb::FixedMemInStreamBuf buffer(inputText, strlen(inputText));
85/// @endcode
86/// Notice that `bdlsb::FixedMemInStreamBuf` can be used with buffers referring
87/// to stack memory or to heap memory.
88///
89/// Then, we use `buffer` to construct a `bsl::istream`:
90/// @code
91/// bsl::istream stream(&buffer);
92/// @endcode
93/// Finally, we can input the data from the stream in a formatted manner:
94/// @code
95/// int value;
96/// while (stream >> value) {
97/// cout << "Value is: " << value << endl;
98/// }
99/// }
100/// @endcode
101///
102/// ### Example 2: Scanning Input Data {#bdlsb_fixedmeminstreambuf-example-2-scanning-input-data}
103///
104///
105/// This example illustrates scanning of the input stream buffer for particular
106/// pattern ( digits, in our case ) and then using stream to read out found
107/// number.
108///
109/// First, we create an array of characters to provide data that needs to be
110/// parsed, and construct `bdlsb::FixedMemInStreamBuf` on that array:
111/// @code
112/// {
113/// const char *inputText = "The answer is: 42.";
114/// bdlsb::FixedMemInStreamBuf buffer(inputText, strlen(inputText));
115/// @endcode
116/// Then, we use `buffer` to construct a `bsl::istream` that will be used later
117/// to read found number:
118/// @code
119/// bsl::istream stream(&buffer);
120/// @endcode
121/// Next, we scan input buffer one character at a time searching for the first
122/// digit:
123/// @code
124/// int res;
125/// while ((res = buffer.sbumpc()) != EOF) {
126/// char ch = static_cast<char>(res);
127///
128/// if ( (ch >= '0') && (ch <= '9') ) {
129/// @endcode
130/// Now, when the digit character is found, we return the first digit into the
131/// input stream buffer for subsequent read:
132/// @code
133/// buffer.sputbackc(ch);
134/// int n;
135/// @endcode
136/// Finally, we read out the whole number:
137/// @code
138/// stream >> n;
139/// assert( 42 == n );
140/// cout << "The answer is " << n << " indeed..." << endl;
141/// break;
142/// }
143/// }
144/// }
145/// @endcode
146/// @}
147/** @} */
148/** @} */
149
150/** @addtogroup bdl
151 * @{
152 */
153/** @addtogroup bdlsb
154 * @{
155 */
156/** @addtogroup bdlsb_fixedmeminstreambuf
157 * @{
158 */
159
160#include <bdlscm_version.h>
161
162#include <bsls_assert.h>
163#include <bsls_keyword.h>
164#include <bsls_platform.h>
165#include <bsls_review.h>
166
167#include <bsl_cstring.h>
168#include <bsl_ios.h> // for 'bsl::streamsize'
169#include <bsl_streambuf.h>
170
171#if defined(BSLS_PLATFORM_CMP_MSVC) && defined(min)
172 // Note: on Windows -> WinDef.h:#define min(a,b) ...
173#undef min
174#endif
175
176
177namespace bdlsb {
178
179 // =========================
180 // class FixedMemInStreamBuf
181 // =========================
182
183/// This class implements the input functionality of the @ref basic_streambuf
184/// protocol, using client-supplied `char *` memory.
185///
186/// See @ref bdlsb_fixedmeminstreambuf
187class FixedMemInStreamBuf : public bsl::streambuf {
188
189 // DATA
190 char *d_buffer_p; // buffer (held, not owned)
191 bsl::size_t d_bufferSize; // length of buffer
192
193 private:
194 // NOT IMPLEMENTED
196 FixedMemInStreamBuf& operator=(const FixedMemInStreamBuf&);
197
198 protected:
199 // PROTECTED MANIPULATORS
200
201 /// Set the position indicator to the relative specified `offset` from the
202 /// base position indicated by the specified `way` and return the resulting
203 /// absolute position on success or pos_type(-1) on failure. Optionally
204 /// specify `which` area of the stream buffer. The seek operation will
205 /// fail if `which` does not include the flag `bsl::ios_base::in` or if the
206 /// resulting absolute position is less than zero or greater than the value
207 /// returned by `length`.
208 pos_type seekoff(off_type offset,
209 bsl::ios_base::seekdir way,
210 bsl::ios_base::openmode which = bsl::ios_base::in)
212
213 /// Set the position indicator to the specified `position` and return the
214 /// resulting absolute position on success or pos_type(-1) on failure.
215 /// Optionally specify `which` area of the stream buffer. The `seekpos`
216 /// operation will fail if `which` does not include the flag
217 /// `bsl::ios_base::in` or if position is less then zero or greater than
218 /// the value returned by `length`.
219 pos_type seekpos(pos_type position,
220 bsl::ios_base::openmode which = bsl::ios_base::in)
222
223 FixedMemInStreamBuf *setbuf(char *buffer,
224 bsl::streamsize length) BSLS_KEYWORD_OVERRIDE;
225
226 /// Reinitialize this stream buffer to use the specified character `buffer`
227 /// having the specified `length`. Return the pointer providing modifiable access to this stream buffer.
228 ///
229 /// \pre The behavior is undefined unless `buffer
230 /// != 0 && length > 0` or `length == 0`. Upon re-initialization for use
231 /// of the new buffer, neither the content nor the next input position indicator are preserved.
232 ///
233 /// \note Note that `buffer` is held but not owned.
234 FixedMemInStreamBuf *setbuf(const char *buffer, bsl::streamsize length);
235
236 /// Return the number of characters currently available for reading from
237 /// this stream buffer, or -1 if there are none.
238 bsl::streamsize showmanyc() BSLS_KEYWORD_OVERRIDE;
239
240 /// Read the specified `length` number of characters into the specified
241 /// `destination`. Return the number of characters successfully read.
242 ///
243 /// \pre The behavior is undefined unless `0 <= length`.
244 bsl::streamsize xsgetn(char_type *destination,
245 bsl::streamsize length) BSLS_KEYWORD_OVERRIDE;
246
247 public:
248 // CREATORS
249
250 /// Create a `FixedMemInStreamBuf` that provides access to the character
251 /// sequence in the specified `buffer` of the specified `length`.
252 ///
253 /// \pre The behavior is undefined unless `buffer != 0 && length > 0` or
254 /// `length == 0`.
255 FixedMemInStreamBuf(const char *buffer, bsl::size_t length);
256
257 /// Destroy this stream buffer.
259
260 // MANIPULATORS
261
262 /// Reinitialize this stream buffer to use the specified character
263 /// `buffer` having the specified `length`. Return the address of this modifiable stream buffer.
264 ///
265 /// \pre The behavior is undefined unless
266 /// `buffer != 0 && length > 0` or `length == 0`. Upon reinitialization
267 /// for use of the new buffer, neither the content nor the next input position indicator is preserved.
268 ///
269 /// \note Note that `buffer` is held but not
270 /// owned.
271 FixedMemInStreamBuf *pubsetbuf(char *buffer,
272 bsl::streamsize length);
273 FixedMemInStreamBuf *pubsetbuf(const char *buffer,
274 bsl::streamsize length);
275
276 // ACCESSORS
277
278 /// Return the address of the non-modifiable character buffer held by this
279 /// stream buffer.
280 const char *data() const;
281
282 /// Return the number of characters from the current input position to the
283 /// end of the stream buffer. The function returns the same value as
284 /// `seekoff(0, bsl::ios_base::beg)`. The length is modified by a call to
285 /// `seekpos`, `seekoff` or by reading characters from the buffer.
286 bsl::size_t length() const;
287};
288
289// ============================================================================
290// INLINE DEFINITIONS
291// ============================================================================
292
293 // -------------------------
294 // class FixedMemInStreamBuf
295 // -------------------------
296
297// PROTECTED MANIPULATORS
298inline
299FixedMemInStreamBuf::pos_type
300FixedMemInStreamBuf::seekpos(pos_type position,
301 bsl::ios_base::openmode which)
302{
303 return seekoff(static_cast<off_type>(position), bsl::ios_base::beg, which);
304}
305
306
307inline
309 bsl::streamsize length)
310
311{
312 BSLS_ASSERT(buffer || 0 == length);
313 BSLS_ASSERT(0 <= length);
314
315 // Reset pointers and length.
316 d_buffer_p = buffer;
317 d_bufferSize = static_cast<bsl::size_t>(length);
318 setg(d_buffer_p, d_buffer_p, d_buffer_p + d_bufferSize);
319 return this;
320}
321
322inline
324 bsl::streamsize length)
325{
326 BSLS_ASSERT(buffer || 0 == length);
327 BSLS_ASSERT(0 <= length);
328
329 return setbuf(const_cast<char *>(buffer), length);
330}
331
332inline
334{
335 bsl::streamsize numChars = egptr() - gptr();
336 if (0 == numChars) {
337 return -1; // RETURN
338 }
339 return numChars;
340}
341
342inline
343bsl::streamsize FixedMemInStreamBuf::xsgetn(char_type *destination,
344 bsl::streamsize length)
345{
346 BSLS_ASSERT(destination);
347 BSLS_ASSERT(0 <= length);
348
349 bsl::streamsize charsLeft = egptr() - gptr();
350
351 bsl::streamsize canCopy = charsLeft < length ? charsLeft : length;
352
353 bsl::memcpy(destination, gptr(), static_cast<bsl::size_t>(canCopy));
354 gbump(static_cast<int>(canCopy));
355 return canCopy;
356}
357
358// CREATORS
359inline
360FixedMemInStreamBuf::FixedMemInStreamBuf(const char *buffer,
361 bsl::size_t length)
362: d_buffer_p(const_cast<char *>(buffer))
363, d_bufferSize(length)
364{
365 BSLS_ASSERT(buffer || 0 == length);
366
367 setg(d_buffer_p, d_buffer_p, d_buffer_p + d_bufferSize);
368}
369
370inline
374
375// MANIPULATORS
376inline
378 bsl::streamsize length)
379{
380 BSLS_ASSERT(buffer || 0 == length);
381 BSLS_ASSERT(0 <= length);
382
383 return setbuf(buffer, length);
384}
385
386inline
388 bsl::streamsize length)
389{
390 BSLS_ASSERT(buffer || 0 == length);
391 BSLS_ASSERT(0 <= length);
392
393 return setbuf(buffer, length);
394}
395
396// ACCESSORS
397inline
398const char *FixedMemInStreamBuf::data() const
399{
400 return d_buffer_p;
401}
402
403inline
405{
406 return egptr() - gptr();
407}
408
409} // close package namespace
410
411
412#endif
413
414// ----------------------------------------------------------------------------
415// Copyright 2015 Bloomberg Finance L.P.
416//
417// Licensed under the Apache License, Version 2.0 (the "License");
418// you may not use this file except in compliance with the License.
419// You may obtain a copy of the License at
420//
421// http://www.apache.org/licenses/LICENSE-2.0
422//
423// Unless required by applicable law or agreed to in writing, software
424// distributed under the License is distributed on an "AS IS" BASIS,
425// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
426// See the License for the specific language governing permissions and
427// limitations under the License.
428// ----------------------------- END-OF-FILE ----------------------------------
429
430/** @} */
431/** @} */
432/** @} */
Definition bdlsb_fixedmeminstreambuf.h:187
FixedMemInStreamBuf * setbuf(char *buffer, bsl::streamsize length) BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:308
const char * data() const
Definition bdlsb_fixedmeminstreambuf.h:398
pos_type seekoff(off_type offset, bsl::ios_base::seekdir way, bsl::ios_base::openmode which=bsl::ios_base::in) BSLS_KEYWORD_OVERRIDE
bsl::streamsize xsgetn(char_type *destination, bsl::streamsize length) BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:343
pos_type seekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::in) BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:300
~FixedMemInStreamBuf() BSLS_KEYWORD_OVERRIDE
Destroy this stream buffer.
Definition bdlsb_fixedmeminstreambuf.h:371
FixedMemInStreamBuf * pubsetbuf(char *buffer, bsl::streamsize length)
Definition bdlsb_fixedmeminstreambuf.h:387
bsl::size_t length() const
Definition bdlsb_fixedmeminstreambuf.h:404
bsl::streamsize showmanyc() BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:333
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1976
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
#define BSLS_KEYWORD_OVERRIDE
Definition bsls_keyword.h:695
Definition bdlsb_fixedmeminput.h:145
Definition bdlat_valuetypefunctions.h:939