BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlsb_fixedmeminput.h
Go to the documentation of this file.
1/// @file bdlsb_fixedmeminput.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlsb_fixedmeminput.h -*-C++-*-
8#ifndef INCLUDED_BDLSB_FIXEDMEMINPUT
9#define INCLUDED_BDLSB_FIXEDMEMINPUT
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlsb_fixedmeminput bdlsb_fixedmeminput
15/// @brief Provide a basic input stream buffer using a client buffer.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlsb
19/// @{
20/// @addtogroup bdlsb_fixedmeminput
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlsb_fixedmeminput-purpose"> Purpose</a>
25/// * <a href="#bdlsb_fixedmeminput-classes"> Classes </a>
26/// * <a href="#bdlsb_fixedmeminput-description"> Description </a>
27/// * <a href="#bdlsb_fixedmeminput-usage"> Usage </a>
28/// * <a href="#bdlsb_fixedmeminput-example-1-basic-use-of-bdlsb-fixedmeminput"> Example 1: Basic Use of bdlsb::FixedMemInput </a>
29///
30/// # Purpose {#bdlsb_fixedmeminput-purpose}
31/// Provide a basic input stream buffer using a client buffer.
32///
33/// # Classes {#bdlsb_fixedmeminput-classes}
34///
35/// - bdlsb::FixedMemInput: basic input stream buffer using client memory
36///
37/// @see bdlsb_fixedmeminstreambuf
38///
39/// # Description {#bdlsb_fixedmeminput-description}
40/// This component provides a mechanism, `bdlsb::FixedMemInput`,
41/// that implements the input portion of the `bsl::basic_streambuf` protocol
42/// using a client-supplied memory buffer. Method names necessarily correspond
43/// to the protocol-specified method names. Clients supply the character buffer
44/// at stream buffer construction, and can later reinitialize the stream buffer
45/// with a different character buffer by calling the `pubsetbuf` method. This
46/// component provides none of the output-related functionality of
47/// `bsl::basic_streambuf` nor does it use locales in any way. The only
48/// difference between this component and `bdlsb::FixedMemInStreamBuf` is that
49/// the class `bdlsb::FixedMemInput` does *not* derive from a `bsl::streambuf`,
50/// and is generally more efficient (at initialization and due to the lack of
51/// virtual functions). It is especially designed for streaming a very small
52/// amount of information from a fixed-length buffer using a
53/// @ref bslx_genericinstream .
54///
55/// ## Usage {#bdlsb_fixedmeminput-usage}
56///
57///
58/// This section illustrates intended use of this component.
59///
60/// ### Example 1: Basic Use of bdlsb::FixedMemInput {#bdlsb_fixedmeminput-example-1-basic-use-of-bdlsb-fixedmeminput}
61///
62///
63/// The `bdlsb::FixedMemInput` class is intended to be used as a template
64/// parameter to the `bslx::GenericInStream` class. Such specialization
65/// provides user with performance efficient way to unexternalize BDEX encoded
66/// data from an existing character buffer.
67///
68/// See the @ref bslx_genericinstream component usage example for a more practical
69/// example of using `bslx` streams.
70///
71/// This example demonstrates instantiating a template, `bslx::GenericInStream`,
72/// on a `bdlsb::FixedMemInput` object and using the `bslx::GenericInStream`
73/// object to stream in some data.
74///
75/// First, create `bslx::ByteOutStream` `outStream` and externalize some user
76/// data to it. Note that this code only prepares the character buffer that is
77/// used to illustrate the purpose of the `bdlsb::FixedMemInput` class.
78/// @code
79/// bslx::ByteOutStream outStream(20131127);
80///
81/// unsigned int MAGIC = 0x1812;
82///
83/// outStream.putUint32(MAGIC);
84/// outStream.putInt32(83);
85/// outStream.putString(bsl::string("test"));
86/// assert(outStream.isValid());
87/// @endcode
88/// Next, create a `bdlsb::FixedMemInput` stream buffer initialized with the
89/// buffer from the `bslx::ByteOutStream` object `outStream`:
90/// @code
91/// bdlsb::FixedMemInput streamBuffer(outStream.data(), outStream.length());
92/// @endcode
93/// Then, create the `bslx::GenericInStream` stream parameterized with
94/// `bdlsb::FixedMemInput`:
95/// @code
96/// bslx::GenericInStream<bdlsb::FixedMemInput> inStream(&streamBuffer);
97/// @endcode
98/// Now, use resulting `inStream` to unexternalize user data:
99/// @code
100/// unsigned int magic = 0;
101/// int key;
102/// bsl::string value;
103///
104/// inStream.getUint32(magic);
105/// inStream.getInt32(key);
106/// inStream.getString(value);
107/// assert(inStream.isValid());
108/// @endcode
109/// Finally, verify that the data from the supplied buffer was unexternalized
110/// correctly:
111/// @code
112/// assert(MAGIC == magic);
113/// assert(83 == key);
114/// assert("test" == value);
115/// @endcode
116/// @}
117/** @} */
118/** @} */
119
120/** @addtogroup bdl
121 * @{
122 */
123/** @addtogroup bdlsb
124 * @{
125 */
126/** @addtogroup bdlsb_fixedmeminput
127 * @{
128 */
129
130#include <bdlscm_version.h>
131
132#include <bsls_assert.h>
133#include <bsls_performancehint.h>
134#include <bsls_platform.h>
135#include <bsls_review.h>
136#include <bsls_types.h>
137
138#include <bsl_algorithm.h>
139#include <bsl_cstdlib.h>
140#include <bsl_cstring.h>
141#include <bsl_ios.h>
142#include <bsl_iosfwd.h>
143
144
145namespace bdlsb {
146
147 // ===================
148 // class FixedMemInput
149 // ===================
150
151/// This class, like `bdlsb::FixedMemInStreamBuf`, implements the input
152/// functionality of the @ref basic_streambuf interface, using client-supplied
153/// `char *` memory. It has an interface identical to
154/// `bdlsb::FixedMemInStreamBuf` but does *not* inherit from
155/// `bsl::streambuf`. This implementation is advantageous for performance
156/// reasons, as the overhead of the initialization and virtual function
157/// calls of a `bsl::streambuf` can be undesirable. It is especially
158/// designed for streaming a very small amount of information from a
159/// fixed-length buffer using a @ref bslx_genericinstream when the number of
160/// characters read from the input is guaranteed not to exceed the length of
161/// the buffer. Note that this class is not designed to be derived from.
162///
163/// See @ref bdlsb_fixedmeminput
165
166 public:
167 // TYPES
168 typedef char char_type;
169 typedef bsl::char_traits<char> traits_type;
170 typedef traits_type::int_type int_type;
171 typedef traits_type::pos_type pos_type;
172 typedef traits_type::off_type off_type;
173
174 private:
175 // PRIVATE DATA MEMBERS
176 const char *d_buffer_p; // buffer (held, not owned)
177 bsl::size_t d_bufferSize; // buffer size (not length of stream)
178 bsl::size_t d_pos; // current read position
179
180 private:
181 // NOT IMPLEMENTED
183 FixedMemInput& operator=(const FixedMemInput&);
184
185 public:
186 // CREATORS
187
188 /// Create a `FixedMemInput` using the specified `buffer` of the
189 /// specified `length`. The position indicator is set to the beginning
190 /// of the `buffer`. The behavior is undefined unless
191 /// `buffer != 0 && length > 0` or `length == 0`. Note that `buffer` is
192 /// held but not owned.
193 FixedMemInput(const char *buffer, bsl::size_t length);
194
195 /// Destroy this stream buffer.
196 ~FixedMemInput() = default;
197
198 // MANIPULATORS
199
200 /// Return the number of characters available from the current read
201 /// position in this stream buffer.
202 bsl::streamsize in_avail();
203
204 // *** 27.5.2.2.2 buffer and positioning: ***
205
206 /// Reinitialize this stream buffer to use the specified character `buffer`
207 /// having the specified `length`. Return a pointer providing modifiable
208 /// access to this stream buffer. The behaviour is undefined unless
209 /// `buffer != 0 && length > 0` or `length == 0`. Upon reinitialization
210 /// for use of the new buffer, the position indicator is set to the
211 /// beginning of the `buffer`. Note that `buffer` is held but not owned.
212 FixedMemInput *pubsetbuf(const char *buffer, bsl::streamsize length);
213
214 /// Set the position indicator to the relative specified `offset` from the
215 /// base position indicated by the specified `way` and return the resulting
216 /// absolute position on success or pos_type(-1) on failure. Optionally
217 /// specify `which` area of the stream buffer. The seek operation will
218 /// fail if `which` does not include the flag `bsl::ios_base::in` or if the
219 /// resulting absolute position is less than zero or greater than the value
220 /// returned by `length`.
222 bsl::ios_base::seekdir way,
223 bsl::ios_base::openmode which = bsl::ios_base::in);
224
225 /// Set the position indicator to the specified `position` and return the
226 /// resulting absolute position on success or pos_type(-1) on failure.
227 /// Optionally specify `which` area of the stream buffer. The `seekpos`
228 /// operation will fail if `which` does not include the flag
229 /// `bsl::ios_base::in` or if position is less then zero or greater than
230 /// the value returned by `length`.
232 bsl::ios_base::openmode which = bsl::ios_base::in);
233
234 // *** 27.5.2.2.3 Get area: ***
235
236 /// Return the character at the current read position from this buffer, or
237 /// `traits_type::eof()` if the end of the buffer is reached and advance
238 /// read position indicator.
240
241 /// Return the character at the current read position from this buffer, or
242 /// `traits_type::eof()` if the end of the buffer is reached.
243 int_type sgetc();
244
245 /// Read the specified `length` characters to the specified `destination`.
246 /// Return the number of characters successfully read from this buffer,
247 /// which is either equal to the `length` parameter or equal to the
248 /// distance from the current read position to the end of the input buffer,
249 /// whichever is smaller, and move the read cursor position by this amount.
250 /// The behavior is undefined unless '0 <= length'.
251 bsl::streamsize sgetn(char_type *destination, bsl::streamsize length);
252
253 /// Advance the current read position and return the character at the
254 /// resulting position from this buffer, or `traits_type::eof()` if the end
255 /// of the buffer is reached.
257
258 // *** 27.5.2.2.4 Putback: ***
259
260 /// Move the current read position back one character if the current read
261 /// position is not at the beginning of the buffer and the previous
262 /// position contains the specified character `c`, and return that
263 /// character. Otherwise, return `traits_type::eof()` and do not move the
264 /// current read position.
265 int_type sputbackc(char c);
266
267 /// Move the current read position back one character if the current read
268 /// position is not at the beginning of the buffer, and return the
269 /// character at the resulting current read position from this buffer.
270 /// Return `traits_type::eof()` otherwise.
272
273 // ACCESSORS
274
275 /// Return the size for the buffer held by this buffer, in bytes, supplied
276 /// at construction.
277 bsl::size_t capacity() const;
278
279 /// Return the address of the non-modifiable character buffer held by this
280 /// stream buffer.
281 const char *data() const;
282
283 /// Return the number of characters that can be successfully read from this
284 /// stream buffer before reading `traits_type::eof()` -- i.e., the number
285 /// of characters between the current read position and the end of this
286 /// buffer.
287 bsl::size_t length() const;
288};
289
290// ============================================================================
291// INLINE DEFINITIONS
292// ============================================================================
293
294 // -------------------
295 // class FixedMemInput
296 // -------------------
297
298// CREATORS
299inline
300FixedMemInput::FixedMemInput(const char *buffer, bsl::size_t length)
301: d_buffer_p(const_cast<char *>(buffer))
302, d_bufferSize(length)
303, d_pos(0)
304{
305 BSLS_ASSERT(buffer || 0 == length);
306}
307
308// MANIPULATORS
309inline
310bsl::streamsize FixedMemInput::in_avail()
311{
312 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos == d_bufferSize)) {
313 return bsl::streamsize(-1); // RETURN
314 }
315 return static_cast<bsl::streamsize>(d_bufferSize - d_pos);
316}
317
318inline
320 bsl::streamsize length)
321
322{
323 BSLS_ASSERT(buffer || 0 == length);
324 BSLS_ASSERT(0 <= length);
325
326 d_buffer_p = buffer;
327 d_bufferSize = static_cast<bsl::size_t>(length);
328 d_pos = 0;
329 return this;
330}
331
332inline
334{
335 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
336 return traits_type::eof(); // RETURN
337 }
338 const int_type i = traits_type::to_int_type(d_buffer_p[d_pos]);
339 d_pos += 1;
340 return i;
341}
342
343inline
345{
346 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
347 return traits_type::eof(); // RETURN
348 }
349 //return traits_type::to_int_type(d_buffer_p[static_cast<IntPtr>(d_pos)]);
350 return traits_type::to_int_type(d_buffer_p[d_pos]);
351}
352
353inline
354bsl::streamsize
355FixedMemInput::sgetn(char *destination, bsl::streamsize length)
356{
357 BSLS_ASSERT(0 <= length);
358
359 const bsl::size_t current = d_pos;
360 d_pos += static_cast<bsl::size_t>(length);
361
362 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY((d_pos > d_bufferSize) ||
363 (d_pos < current) )) {
364 d_pos = d_bufferSize;
365 length = static_cast<bsl::streamsize>(d_bufferSize - current);
366 }
367 bsl::memcpy(destination, d_buffer_p+current, length);
368 return length;
369}
370
371inline
373{
374 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
375 return traits_type::eof(); // RETURN
376 }
377 d_pos += 1;
378 return sgetc();
379}
380
381inline
383{
385 || BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(c != d_buffer_p[d_pos-1])) {
386 return traits_type::eof(); // RETURN
387 }
388 d_pos -= 1;
389 return traits_type::to_int_type(c);
390}
391
392inline
394{
396 return traits_type::eof(); // RETURN
397 }
398 d_pos -= 1;
399 return traits_type::to_int_type(d_buffer_p[d_pos]);
400}
401
402// ACCESSORS
403inline
404bsl::size_t FixedMemInput::capacity() const
405{
406 return d_bufferSize;
407}
408
409inline
410const char *FixedMemInput::data() const
411{
412 return d_buffer_p;
413}
414
415inline
416bsl::size_t FixedMemInput::length() const
417{
418 return (d_bufferSize - d_pos);
419}
420
421} // close package namespace
422
423
424#endif
425
426// ----------------------------------------------------------------------------
427// Copyright 2015 Bloomberg Finance L.P.
428//
429// Licensed under the Apache License, Version 2.0 (the "License");
430// you may not use this file except in compliance with the License.
431// You may obtain a copy of the License at
432//
433// http://www.apache.org/licenses/LICENSE-2.0
434//
435// Unless required by applicable law or agreed to in writing, software
436// distributed under the License is distributed on an "AS IS" BASIS,
437// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
438// See the License for the specific language governing permissions and
439// limitations under the License.
440// ----------------------------- END-OF-FILE ----------------------------------
441
442
443/** @} */
444/** @} */
445/** @} */
Definition bdlsb_fixedmeminput.h:164
bsl::streamsize in_avail()
Definition bdlsb_fixedmeminput.h:310
bsl::size_t capacity() const
Definition bdlsb_fixedmeminput.h:404
char char_type
Definition bdlsb_fixedmeminput.h:168
pos_type pubseekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::in)
bsl::size_t length() const
Definition bdlsb_fixedmeminput.h:416
traits_type::off_type off_type
Definition bdlsb_fixedmeminput.h:172
int_type sputbackc(char c)
Definition bdlsb_fixedmeminput.h:382
traits_type::pos_type pos_type
Definition bdlsb_fixedmeminput.h:171
int_type sgetc()
Definition bdlsb_fixedmeminput.h:344
pos_type pubseekoff(off_type offset, bsl::ios_base::seekdir way, bsl::ios_base::openmode which=bsl::ios_base::in)
int_type sungetc()
Definition bdlsb_fixedmeminput.h:393
int_type snextc()
Definition bdlsb_fixedmeminput.h:372
int_type sbumpc()
Definition bdlsb_fixedmeminput.h:333
bsl::streamsize sgetn(char_type *destination, bsl::streamsize length)
Definition bdlsb_fixedmeminput.h:355
traits_type::int_type int_type
Definition bdlsb_fixedmeminput.h:170
~FixedMemInput()=default
Destroy this stream buffer.
FixedMemInput * pubsetbuf(const char *buffer, bsl::streamsize length)
Definition bdlsb_fixedmeminput.h:319
bsl::char_traits< char > traits_type
Definition bdlsb_fixedmeminput.h:169
const char * data() const
Definition bdlsb_fixedmeminput.h:410
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
#define BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition bdlsb_fixedmeminput.h:145