BDE 4.14.0 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/// char ch;
125/// do {
126/// ch = static_cast<char>(buffer.sbumpc());
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/// } while ( ch != EOF );
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 // NOT IMPLEMENTED
195 FixedMemInStreamBuf& operator=(const FixedMemInStreamBuf&);
196
197 protected:
198 // PROTECTED MANIPULATORS
199
200 /// Set the position indicator to the relative specified `offset` from the
201 /// base position indicated by the specified `way` and return the resulting
202 /// absolute position on success or pos_type(-1) on failure. Optionally
203 /// specify `which` area of the stream buffer. The seek operation will
204 /// fail if `which` does not include the flag `bsl::ios_base::in` or if the
205 /// resulting absolute position is less than zero or greater than the value
206 /// returned by `length`.
207 pos_type seekoff(off_type offset,
208 bsl::ios_base::seekdir way,
209 bsl::ios_base::openmode which = bsl::ios_base::in)
211
212 /// Set the position indicator to the specified `position` and return the
213 /// resulting absolute position on success or pos_type(-1) on failure.
214 /// Optionally specify `which` area of the stream buffer. The `seekpos`
215 /// operation will fail if `which` does not include the flag
216 /// `bsl::ios_base::in` or if position is less then zero or greater than
217 /// the value returned by `length`.
218 pos_type seekpos(pos_type position,
219 bsl::ios_base::openmode which = bsl::ios_base::in)
221
222 FixedMemInStreamBuf *setbuf(char *buffer,
223 bsl::streamsize length) BSLS_KEYWORD_OVERRIDE;
224
225 /// Reinitialize this stream buffer to use the specified character `buffer`
226 /// having the specified `length`. Return the pointer providing modifiable
227 /// access to this stream buffer. The behavior is undefined unless `buffer
228 /// != 0 && length > 0` or `length == 0`. Upon re-initialization for use
229 /// of the new buffer, neither the content nor the next input position
230 /// indicator are preserved. Note that `buffer` is held but not owned.
231 FixedMemInStreamBuf *setbuf(const char *buffer, bsl::streamsize length);
232
233 /// Return the number of characters currently available for reading from
234 /// this stream buffer, or -1 if there are none.
235 bsl::streamsize showmanyc() BSLS_KEYWORD_OVERRIDE;
236
237 /// Read the specified `length` number of characters into the specified
238 /// `destination`. Return the number of characters successfully read.
239 /// The behavior is undefined unless `0 <= length`.
240 bsl::streamsize xsgetn(char_type *destination,
241 bsl::streamsize length) BSLS_KEYWORD_OVERRIDE;
242
243 public:
244 // CREATORS
245
246 /// Create a `FixedMemInStreamBuf` that provides access to the character
247 /// sequence in the specified `buffer` of the specified `length`. The
248 /// behavior is undefined unless `buffer != 0 && length > 0` or
249 /// `length == 0`.
250 FixedMemInStreamBuf(const char *buffer, bsl::size_t length);
251
252 /// Destroy this stream buffer.
254
255 // MANIPULATORS
256
257 /// Reinitialize this stream buffer to use the specified character
258 /// `buffer` having the specified `length`. Return the address of this
259 /// modifiable stream buffer. The behavior is undefined unless
260 /// `buffer != 0 && length > 0` or `length == 0`. Upon reinitialization
261 /// for use of the new buffer, neither the content nor the next input
262 /// position indicator is preserved. Note that `buffer` is held but not
263 /// owned.
264 FixedMemInStreamBuf *pubsetbuf(char *buffer,
265 bsl::streamsize length);
266 FixedMemInStreamBuf *pubsetbuf(const char *buffer,
267 bsl::streamsize length);
268
269 // ACCESSORS
270
271 /// Return the address of the non-modifiable character buffer held by this
272 /// stream buffer.
273 const char *data() const;
274
275 /// Return the number of characters from the current input position to the
276 /// end of the stream buffer. The function returns the same value as
277 /// `seekoff(0, bsl::ios_base::beg)`. The length is modified by a call to
278 /// `seekpos`, `seekoff` or by reading characters from the buffer.
279 bsl::size_t length() const;
280};
281
282// ============================================================================
283// INLINE DEFINITIONS
284// ============================================================================
285
286 // -------------------------
287 // class FixedMemInStreamBuf
288 // -------------------------
289
290// PROTECTED MANIPULATORS
291inline
292FixedMemInStreamBuf::pos_type
293FixedMemInStreamBuf::seekpos(pos_type position,
294 bsl::ios_base::openmode which)
295{
296 return seekoff(static_cast<off_type>(position), bsl::ios_base::beg, which);
297}
298
299
300inline
302 bsl::streamsize length)
303
304{
305 BSLS_ASSERT(buffer || 0 == length);
306 BSLS_ASSERT(0 <= length);
307
308 // Reset pointers and length.
309 d_buffer_p = buffer;
310 d_bufferSize = static_cast<bsl::size_t>(length);
311 setg(d_buffer_p, d_buffer_p, d_buffer_p + d_bufferSize);
312 return this;
313}
314
315inline
317 bsl::streamsize length)
318{
319 BSLS_ASSERT(buffer || 0 == length);
320 BSLS_ASSERT(0 <= length);
321
322 return setbuf(const_cast<char *>(buffer), length);
323}
324
325inline
327{
328 bsl::streamsize numChars = egptr() - gptr();
329 if (0 == numChars) {
330 return -1; // RETURN
331 }
332 return numChars;
333}
334
335inline
336bsl::streamsize FixedMemInStreamBuf::xsgetn(char_type *destination,
337 bsl::streamsize length)
338{
339 BSLS_ASSERT(destination);
340 BSLS_ASSERT(0 <= length);
341
342 bsl::streamsize charsLeft = egptr() - gptr();
343
344 bsl::streamsize canCopy = charsLeft < length ? charsLeft : length;
345
346 bsl::memcpy(destination, gptr(), static_cast<bsl::size_t>(canCopy));
347 gbump(static_cast<int>(canCopy));
348 return canCopy;
349}
350
351// CREATORS
352inline
353FixedMemInStreamBuf::FixedMemInStreamBuf(const char *buffer,
354 bsl::size_t length)
355: d_buffer_p(const_cast<char *>(buffer))
356, d_bufferSize(length)
357{
358 BSLS_ASSERT(buffer || 0 == length);
359
360 setg(d_buffer_p, d_buffer_p, d_buffer_p + d_bufferSize);
361}
362
363inline
367
368// MANIPULATORS
369inline
371 bsl::streamsize length)
372{
373 BSLS_ASSERT(buffer || 0 == length);
374 BSLS_ASSERT(0 <= length);
375
376 return setbuf(buffer, length);
377}
378
379inline
381 bsl::streamsize length)
382{
383 BSLS_ASSERT(buffer || 0 == length);
384 BSLS_ASSERT(0 <= length);
385
386 return setbuf(buffer, length);
387}
388
389// ACCESSORS
390inline
391const char *FixedMemInStreamBuf::data() const
392{
393 return d_buffer_p;
394}
395
396inline
398{
399 return egptr() - gptr();
400}
401
402} // close package namespace
403
404
405#endif
406
407// ----------------------------------------------------------------------------
408// Copyright 2015 Bloomberg Finance L.P.
409//
410// Licensed under the Apache License, Version 2.0 (the "License");
411// you may not use this file except in compliance with the License.
412// You may obtain a copy of the License at
413//
414// http://www.apache.org/licenses/LICENSE-2.0
415//
416// Unless required by applicable law or agreed to in writing, software
417// distributed under the License is distributed on an "AS IS" BASIS,
418// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
419// See the License for the specific language governing permissions and
420// limitations under the License.
421// ----------------------------- END-OF-FILE ----------------------------------
422
423/** @} */
424/** @} */
425/** @} */
Definition bdlsb_fixedmeminstreambuf.h:187
FixedMemInStreamBuf * setbuf(char *buffer, bsl::streamsize length) BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:301
const char * data() const
Definition bdlsb_fixedmeminstreambuf.h:391
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:336
pos_type seekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::in) BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:293
~FixedMemInStreamBuf() BSLS_KEYWORD_OVERRIDE
Destroy this stream buffer.
Definition bdlsb_fixedmeminstreambuf.h:364
FixedMemInStreamBuf * pubsetbuf(char *buffer, bsl::streamsize length)
Definition bdlsb_fixedmeminstreambuf.h:380
bsl::size_t length() const
Definition bdlsb_fixedmeminstreambuf.h:397
bsl::streamsize showmanyc() BSLS_KEYWORD_OVERRIDE
Definition bdlsb_fixedmeminstreambuf.h:326
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#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