BDE 4.39.x 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 = 0;
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 the buffer.
161///
162/// \note Note that this class is not designed to be derived from.
163///
164/// See @ref bdlsb_fixedmeminput
166
167 public:
168 // TYPES
169 typedef char char_type;
170 typedef bsl::char_traits<char> traits_type;
171 typedef traits_type::int_type int_type;
172 typedef traits_type::pos_type pos_type;
173 typedef traits_type::off_type off_type;
174
175 private:
176 // PRIVATE DATA MEMBERS
177 const char *d_buffer_p; // buffer (held, not owned)
178 bsl::size_t d_bufferSize; // buffer size (not length of stream)
179 bsl::size_t d_pos; // current read position
180
181 private:
182 // NOT IMPLEMENTED
184 FixedMemInput& operator=(const FixedMemInput&);
185
186 public:
187 // CREATORS
188
189 /// Create a `FixedMemInput` using the specified `buffer` of the
190 /// specified `length`. The position indicator is set to the beginning of the `buffer`.
191 ///
192 /// \pre The behavior is undefined unless `buffer != 0 && length > 0` or `length == 0`.
193 ///
194 /// \note Note that `buffer` is
195 /// held but not owned.
196 FixedMemInput(const char *buffer, bsl::size_t length);
197
198 /// Destroy this stream buffer.
199 ~FixedMemInput() = default;
200
201 // MANIPULATORS
202
203 /// Return the number of characters available from the current read
204 /// position in this stream buffer.
205 bsl::streamsize in_avail();
206
207 // *** 27.5.2.2.2 buffer and positioning: ***
208
209 /// Reinitialize this stream buffer to use the specified character `buffer`
210 /// having the specified `length`. Return a pointer providing modifiable access to this stream buffer.
211 ///
212 /// \pre The behaviour is undefined unless
213 /// `buffer != 0 && length > 0` or `length == 0`. Upon reinitialization
214 /// for use of the new buffer, the position indicator is set to the beginning of the `buffer`.
215 ///
216 /// \note Note that `buffer` is held but not owned.
217 FixedMemInput *pubsetbuf(const char *buffer, bsl::streamsize length);
218
219 /// Set the position indicator to the relative specified `offset` from the
220 /// base position indicated by the specified `way` and return the resulting
221 /// absolute position on success or pos_type(-1) on failure. Optionally
222 /// specify `which` area of the stream buffer. The seek operation will
223 /// fail if `which` does not include the flag `bsl::ios_base::in` or if the
224 /// resulting absolute position is less than zero or greater than the value
225 /// returned by `length`.
227 bsl::ios_base::seekdir way,
228 bsl::ios_base::openmode which = bsl::ios_base::in);
229
230 /// Set the position indicator to the specified `position` and return the
231 /// resulting absolute position on success or pos_type(-1) on failure.
232 /// Optionally specify `which` area of the stream buffer. The `seekpos`
233 /// operation will fail if `which` does not include the flag
234 /// `bsl::ios_base::in` or if position is less then zero or greater than
235 /// the value returned by `length`.
237 bsl::ios_base::openmode which = bsl::ios_base::in);
238
239 // *** 27.5.2.2.3 Get area: ***
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 and advance
243 /// read position indicator.
245
246 /// Return the character at the current read position from this buffer, or
247 /// `traits_type::eof()` if the end of the buffer is reached.
248 int_type sgetc();
249
250 /// Read the specified `length` characters to the specified `destination`.
251 /// Return the number of characters successfully read from this buffer,
252 /// which is either equal to the `length` parameter or equal to the
253 /// distance from the current read position to the end of the input buffer,
254 /// whichever is smaller, and move the read cursor position by this amount.
255 ///
256 /// \pre The behavior is undefined unless '0 <= length'.
257 bsl::streamsize sgetn(char_type *destination, bsl::streamsize length);
258
259 /// Advance the current read position and return the character at the
260 /// resulting position from this buffer, or `traits_type::eof()` if the end
261 /// of the buffer is reached.
263
264 // *** 27.5.2.2.4 Putback: ***
265
266 /// Move the current read position back one character if the current read
267 /// position is not at the beginning of the buffer and the previous
268 /// position contains the specified character `c`, and return that
269 /// character. Otherwise, return `traits_type::eof()` and do not move the
270 /// current read position.
271 int_type sputbackc(char c);
272
273 /// Move the current read position back one character if the current read
274 /// position is not at the beginning of the buffer, and return the
275 /// character at the resulting current read position from this buffer.
276 /// Return `traits_type::eof()` otherwise.
278
279 // ACCESSORS
280
281 /// Return the size for the buffer held by this buffer, in bytes, supplied
282 /// at construction.
283 bsl::size_t capacity() const;
284
285 /// Return the address of the non-modifiable character buffer held by this
286 /// stream buffer.
287 const char *data() const;
288
289 /// Return the number of characters that can be successfully read from this
290 /// stream buffer before reading `traits_type::eof()` -- i.e., the number
291 /// of characters between the current read position and the end of this
292 /// buffer.
293 bsl::size_t length() const;
294};
295
296// ============================================================================
297// INLINE DEFINITIONS
298// ============================================================================
299
300 // -------------------
301 // class FixedMemInput
302 // -------------------
303
304// CREATORS
305inline
306FixedMemInput::FixedMemInput(const char *buffer, bsl::size_t length)
307: d_buffer_p(const_cast<char *>(buffer))
308, d_bufferSize(length)
309, d_pos(0)
310{
311 BSLS_ASSERT(buffer || 0 == length);
312}
313
314// MANIPULATORS
315inline
316bsl::streamsize FixedMemInput::in_avail()
317{
318 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos == d_bufferSize)) {
319 return bsl::streamsize(-1); // RETURN
320 }
321 return static_cast<bsl::streamsize>(d_bufferSize - d_pos);
322}
323
324inline
326 bsl::streamsize length)
327
328{
329 BSLS_ASSERT(buffer || 0 == length);
330 BSLS_ASSERT(0 <= length);
331
332 d_buffer_p = buffer;
333 d_bufferSize = static_cast<bsl::size_t>(length);
334 d_pos = 0;
335 return this;
336}
337
338inline
340{
341 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
342 return traits_type::eof(); // RETURN
343 }
344 const int_type i = traits_type::to_int_type(d_buffer_p[d_pos]);
345 d_pos += 1;
346 return i;
347}
348
349inline
351{
352 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
353 return traits_type::eof(); // RETURN
354 }
355 //return traits_type::to_int_type(d_buffer_p[static_cast<IntPtr>(d_pos)]);
356 return traits_type::to_int_type(d_buffer_p[d_pos]);
357}
358
359inline
360bsl::streamsize
361FixedMemInput::sgetn(char *destination, bsl::streamsize length)
362{
363 BSLS_ASSERT(0 <= length);
364
365 const bsl::size_t current = d_pos;
366 d_pos += static_cast<bsl::size_t>(length);
367
368 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY((d_pos > d_bufferSize) ||
369 (d_pos < current) )) {
370 d_pos = d_bufferSize;
371 length = static_cast<bsl::streamsize>(d_bufferSize - current);
372 }
373 bsl::memcpy(destination, d_buffer_p+current, length);
374 return length;
375}
376
377inline
379{
380 if (BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(d_pos >= d_bufferSize)) {
381 return traits_type::eof(); // RETURN
382 }
383 d_pos += 1;
384 return sgetc();
385}
386
387inline
389{
391 || BSLS_PERFORMANCEHINT_PREDICT_UNLIKELY(c != d_buffer_p[d_pos-1])) {
392 return traits_type::eof(); // RETURN
393 }
394 d_pos -= 1;
395 return traits_type::to_int_type(c);
396}
397
398inline
400{
402 return traits_type::eof(); // RETURN
403 }
404 d_pos -= 1;
405 return traits_type::to_int_type(d_buffer_p[d_pos]);
406}
407
408// ACCESSORS
409inline
410bsl::size_t FixedMemInput::capacity() const
411{
412 return d_bufferSize;
413}
414
415inline
416const char *FixedMemInput::data() const
417{
418 return d_buffer_p;
419}
420
421inline
422bsl::size_t FixedMemInput::length() const
423{
424 return (d_bufferSize - d_pos);
425}
426
427} // close package namespace
428
429
430#endif
431
432// ----------------------------------------------------------------------------
433// Copyright 2015 Bloomberg Finance L.P.
434//
435// Licensed under the Apache License, Version 2.0 (the "License");
436// you may not use this file except in compliance with the License.
437// You may obtain a copy of the License at
438//
439// http://www.apache.org/licenses/LICENSE-2.0
440//
441// Unless required by applicable law or agreed to in writing, software
442// distributed under the License is distributed on an "AS IS" BASIS,
443// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
444// See the License for the specific language governing permissions and
445// limitations under the License.
446// ----------------------------- END-OF-FILE ----------------------------------
447
448
449/** @} */
450/** @} */
451/** @} */
Definition bdlsb_fixedmeminput.h:165
bsl::streamsize in_avail()
Definition bdlsb_fixedmeminput.h:316
bsl::size_t capacity() const
Definition bdlsb_fixedmeminput.h:410
char char_type
Definition bdlsb_fixedmeminput.h:169
pos_type pubseekpos(pos_type position, bsl::ios_base::openmode which=bsl::ios_base::in)
bsl::size_t length() const
Definition bdlsb_fixedmeminput.h:422
traits_type::off_type off_type
Definition bdlsb_fixedmeminput.h:173
int_type sputbackc(char c)
Definition bdlsb_fixedmeminput.h:388
traits_type::pos_type pos_type
Definition bdlsb_fixedmeminput.h:172
int_type sgetc()
Definition bdlsb_fixedmeminput.h:350
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:399
int_type snextc()
Definition bdlsb_fixedmeminput.h:378
int_type sbumpc()
Definition bdlsb_fixedmeminput.h:339
bsl::streamsize sgetn(char_type *destination, bsl::streamsize length)
Definition bdlsb_fixedmeminput.h:361
traits_type::int_type int_type
Definition bdlsb_fixedmeminput.h:171
~FixedMemInput()=default
Destroy this stream buffer.
FixedMemInput * pubsetbuf(const char *buffer, bsl::streamsize length)
Definition bdlsb_fixedmeminput.h:325
bsl::char_traits< char > traits_type
Definition bdlsb_fixedmeminput.h:170
const char * data() const
Definition bdlsb_fixedmeminput.h:416
#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_PERFORMANCEHINT_PREDICT_UNLIKELY(expr)
Definition bsls_performancehint.h:452
Definition bdlsb_fixedmeminput.h:145