BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bslx_streambufinstream.h
Go to the documentation of this file.
1/// @file bslx_streambufinstream.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslx_streambufinstream.h -*-C++-*-
8#ifndef INCLUDED_BSLX_STREAMBUFINSTREAM
9#define INCLUDED_BSLX_STREAMBUFINSTREAM
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslx_streambufinstream bslx_streambufinstream
15/// @brief Unexternalization of fundamental types from a `bsl::streambuf`.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslx
19/// @{
20/// @addtogroup bslx_streambufinstream
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslx_streambufinstream-purpose"> Purpose</a>
25/// * <a href="#bslx_streambufinstream-classes"> Classes </a>
26/// * <a href="#bslx_streambufinstream-description"> Description </a>
27/// * <a href="#bslx_streambufinstream-usage"> Usage </a>
28/// * <a href="#bslx_streambufinstream-example-1-basic-unexternalization"> Example 1: Basic Unexternalization </a>
29///
30/// # Purpose {#bslx_streambufinstream-purpose}
31/// Unexternalization of fundamental types from a `bsl::streambuf`.
32///
33/// # Classes {#bslx_streambufinstream-classes}
34///
35/// - bslx::StreambufInStream: `bsl::streambuf` input stream for fundamentals
36///
37/// @see bslx_streambufoutstream, bslx_genericinstream
38///
39/// # Description {#bslx_streambufinstream-description}
40/// This component implements a `bsl::streambuf` input stream
41/// class, `bslx::StreambufInStream`, that provides platform-independent input
42/// methods ("unexternalization") on values, and arrays of values, of
43/// fundamental types, and on `bsl::string`.
44///
45/// The `bslx::StreambufInStream` type reads from a user-supplied
46/// `bsl::streambuf` directly, with no data copying or assumption of ownership.
47/// The user must therefore make sure that the lifetime and visibility of the
48/// buffer is sufficient to satisfy the needs of the input stream.
49///
50/// This component is intended to be used in conjunction with the
51/// @ref bslx_streambufoutstream "externalization" component. Each input method of
52/// `bslx::StreambufInStream` reads either a value or a homogeneous array of
53/// values of a fundamental type, in a format that was written by the
54/// corresponding `bslx::StreambufOutStream` method. In general, the user of
55/// this component cannot rely on being able to read data that was written by
56/// any mechanism other than `bslx::StreambufOutStream`.
57///
58/// The supported types and required content are listed in the `bslx`
59/// package-level documentation under "Supported Types".
60///
61/// Note that input streams can be *invalidated* explicitly and queried for
62/// *validity*. Reading from an initially invalid stream has no effect.
63/// Attempting to read beyond the end of a stream will automatically invalidate
64/// the stream. Whenever an inconsistent value is detected, the stream should
65/// be invalidated explicitly.
66///
67/// ## Usage {#bslx_streambufinstream-usage}
68///
69///
70/// This section illustrates intended use of this component.
71///
72/// ### Example 1: Basic Unexternalization {#bslx_streambufinstream-example-1-basic-unexternalization}
73///
74///
75/// Suppose we wish to implement a (deliberately simple) `MyPerson` class as a
76/// value-semantic object that supports BDEX externalization and
77/// unexternalization. In addition to whatever data and methods that we choose
78/// to put into our design, we must supply three methods having specific names
79/// and signatures in order to comply with the BDEX protocol: a class method
80/// `maxSupportedBdexVersion`, an accessor (i.e., a `const` method)
81/// `bdexStreamOut`, and a manipulator (i.e., a non-`const` method)
82/// `bdexStreamIn`. This example shows how to implement those three methods.
83///
84/// In this example we will not worry overly about "good design" of the
85/// `MyPerson` component, and we will declare but not implement illustrative
86/// methods and free operators, except for the three required BDEX methods,
87/// which are implemented in full. In particular, we will not make explicit use
88/// of `bslma` allocators; a more complete design would do so:
89///
90/// First, we implement `MyPerson`:
91/// @code
92/// class MyPerson {
93/// bsl::string d_firstName;
94/// bsl::string d_lastName;
95/// int d_age;
96///
97/// friend bool operator==(const MyPerson&, const MyPerson&);
98///
99/// public:
100/// // CLASS METHODS
101///
102/// /// Return the maximum valid BDEX format version, as indicated by
103/// /// the specified `versionSelector`, to be passed to the
104/// /// `bdexStreamOut` method. Note that it is highly recommended that
105/// /// `versionSelector` be formatted as "YYYYMMDD", a date
106/// /// representation. Also note that `versionSelector` should be a
107/// /// *compile*-time-chosen value that selects a format version
108/// /// supported by both externalizer and unexternalizer. See the
109/// /// `bslx` package-level documentation for more information on BDEX
110/// /// streaming of value-semantic types and containers.
111/// static int maxSupportedBdexVersion(int versionSelector);
112///
113/// // CREATORS
114///
115/// /// Create a default person.
116/// MyPerson();
117///
118/// /// Create a person having the specified `firstName`, `lastName`,
119/// /// and `age`.
120/// MyPerson(const char *firstName, const char *lastName, int age);
121///
122/// /// Create a person having the value of the specified `original` person.
123/// MyPerson(const MyPerson& original);
124///
125/// /// Destroy this object.
126/// ~MyPerson();
127///
128/// // MANIPULATORS
129///
130/// /// Assign to this person the value of the specified `rhs` person,
131/// /// and return a reference to this person.
132/// MyPerson& operator=(const MyPerson& rhs);
133///
134/// /// Assign to this object the value read from the specified input
135/// /// `stream` using the specified `version` format, and return a
136/// /// reference to `stream`. If `stream` is initially invalid, this
137/// /// operation has no effect. If `version` is not supported, this
138/// /// object is unaltered and `stream` is invalidated, but otherwise
139/// /// unmodified. If `version` is supported but `stream` becomes
140/// /// invalid during this operation, this object has an undefined, but
141/// /// valid, state. Note that no version is read from `stream`. See
142/// /// the `bslx` package-level documentation for more information on
143/// /// BDEX streaming of value-semantic types and containers.
144/// template <class STREAM>
145/// STREAM& bdexStreamIn(STREAM& stream, int version);
146///
147/// //...
148///
149/// // ACCESSORS
150///
151/// /// Return the age of this person.
152/// int age() const;
153///
154/// /// Write the value of this object, using the specified `version`
155/// /// format, to the specified output `stream`, and return a reference
156/// /// to `stream`. If `stream` is initially invalid, this operation
157/// /// has no effect. If `version` is not supported, `stream` is
158/// /// invalidated, but otherwise unmodified. Note that `version` is
159/// /// not written to `stream`. See the `bslx` package-level
160/// /// documentation for more information on BDEX streaming of
161/// /// value-semantic types and containers.
162/// template <class STREAM>
163/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
164///
165/// /// Return the first name of this person.
166/// const bsl::string& firstName() const;
167///
168/// /// Return the last name of this person.
169/// const bsl::string& lastName() const;
170///
171/// //...
172///
173/// };
174///
175/// // FREE OPERATORS
176///
177/// /// Return `true` if the specified `lhs` and `rhs` person objects have
178/// /// the same value, and `false` otherwise. Two person objects have the
179/// /// same value if they have the same first name, last name, and age.
180/// bool operator==(const MyPerson& lhs, const MyPerson& rhs);
181///
182/// /// Return `true` if the specified `lhs` and `rhs` person objects do not
183/// /// have the same value, and `false` otherwise. Two person objects
184/// /// differ in value if they differ in first name, last name, or age.
185/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs);
186///
187/// // ========================================================================
188/// // INLINE FUNCTION DEFINITIONS
189/// // ========================================================================
190///
191/// // CLASS METHODS
192/// inline
193/// int MyPerson::maxSupportedBdexVersion(int /* versionSelector */) {
194/// return 1;
195/// }
196///
197/// // CREATORS
198/// inline
199/// MyPerson::MyPerson()
200/// : d_firstName("")
201/// , d_lastName("")
202/// , d_age(0)
203/// {
204/// }
205///
206/// inline
207/// MyPerson::MyPerson(const char *firstName, const char *lastName, int age)
208/// : d_firstName(firstName)
209/// , d_lastName(lastName)
210/// , d_age(age)
211/// {
212/// }
213///
214/// inline
215/// MyPerson::~MyPerson()
216/// {
217/// }
218///
219/// template <class STREAM>
220/// STREAM& MyPerson::bdexStreamIn(STREAM& stream, int version)
221/// {
222/// if (stream) {
223/// switch (version) { // switch on the 'bslx' version
224/// case 1: {
225/// stream.getString(d_firstName);
226/// if (!stream) {
227/// d_firstName = "stream error"; // *might* be corrupted;
228/// // value for testing
229/// return stream; // RETURN
230/// }
231/// stream.getString(d_lastName);
232/// if (!stream) {
233/// d_lastName = "stream error"; // *might* be corrupted;
234/// // value for testing
235/// return stream; // RETURN
236/// }
237/// stream.getInt32(d_age);
238/// if (!stream) {
239/// d_age = 999; // *might* be corrupted; value for testing
240/// return stream; // RETURN
241/// }
242/// } break;
243/// default: {
244/// stream.invalidate();
245/// }
246/// }
247/// }
248/// return stream;
249/// }
250///
251/// // ACCESSORS
252/// inline
253/// int MyPerson::age() const
254/// {
255/// return d_age;
256/// }
257///
258/// template <class STREAM>
259/// STREAM& MyPerson::bdexStreamOut(STREAM& stream, int version) const
260/// {
261/// switch (version) {
262/// case 1: {
263/// stream.putString(d_firstName);
264/// stream.putString(d_lastName);
265/// stream.putInt32(d_age);
266/// } break;
267/// default: {
268/// stream.invalidate();
269/// } break;
270/// }
271/// return stream;
272/// }
273///
274/// inline
275/// const bsl::string& MyPerson::firstName() const
276/// {
277/// return d_firstName;
278/// }
279///
280/// inline
281/// const bsl::string& MyPerson::lastName() const
282/// {
283/// return d_lastName;
284/// }
285///
286/// // FREE OPERATORS
287/// inline
288/// bool operator==(const MyPerson& lhs, const MyPerson& rhs)
289/// {
290/// return lhs.d_firstName == rhs.d_firstName &&
291/// lhs.d_lastName == rhs.d_lastName &&
292/// lhs.d_age == rhs.d_age;
293/// }
294///
295/// inline
296/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs)
297/// {
298/// return !(lhs == rhs);
299/// }
300/// @endcode
301/// Then, we can exercise the new `MyPerson` value-semantic class by
302/// externalizing and reconstituting an object. First, create a `MyPerson`
303/// `janeSmith` and a `bslx::StreambufOutStream` `outStream`:
304/// @code
305/// MyPerson janeSmith("Jane", "Smith", 42);
306/// bsl::stringbuf buffer;
307/// bslx::StreambufOutStream outStream(&buffer, 20131127);
308/// const int VERSION = 1;
309/// outStream.putVersion(VERSION);
310/// janeSmith.bdexStreamOut(outStream, VERSION);
311/// assert(outStream.isValid());
312/// @endcode
313/// Next, create a `MyPerson` `janeCopy` initialized to the default value, and
314/// assert that `janeCopy` is different from `janeSmith`:
315/// @code
316/// MyPerson janeCopy;
317/// assert(janeCopy != janeSmith);
318/// @endcode
319/// Then, create a `bslx::StreambufInStream` `inStream` initialized with the
320/// buffer from the `bslx::StreambufOutStream` object `outStream` and
321/// unexternalize this data into `janeCopy`:
322/// @code
323/// bslx::StreambufInStream inStream(&buffer);
324/// int version;
325/// inStream.getVersion(version);
326/// janeCopy.bdexStreamIn(inStream, version);
327/// assert(inStream.isValid());
328/// @endcode
329/// Finally, `assert` the obtained values are as expected and display the
330/// results to `bsl::stdout`:
331/// @code
332/// assert(version == VERSION);
333/// assert(janeCopy == janeSmith);
334///
335/// if (janeCopy == janeSmith) {
336/// bsl::cout << "Successfully serialized and de-serialized Jane Smith:"
337/// << "\n\tFirstName: " << janeCopy.firstName()
338/// << "\n\tLastName : " << janeCopy.lastName()
339/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
340/// }
341/// else {
342/// bsl::cout << "Serialization unsuccessful. 'janeCopy' holds:"
343/// << "\n\tFirstName: " << janeCopy.firstName()
344/// << "\n\tLastName : " << janeCopy.lastName()
345/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
346/// }
347/// @endcode
348/// @}
349/** @} */
350/** @} */
351
352/** @addtogroup bsl
353 * @{
354 */
355/** @addtogroup bslx
356 * @{
357 */
358/** @addtogroup bslx_streambufinstream
359 * @{
360 */
361
362#include <bslscm_version.h>
363
364#include <bslx_genericinstream.h>
365
366#include <bsl_streambuf.h>
367
368
369namespace bslx {
370
371 // =======================
372 // class StreambufInStream
373 // =======================
374
375/// This class facilitates the unexternalization of values (and C-style
376/// arrays of values) of the fundamental integral and floating-point types
377/// in a data-independent, platform-neutral representation. It is currently
378/// a `typedef` for `bslx::GenericInStream<bsl::streambuf>`.
380
381} // close package namespace
382
383
384#endif
385
386// ----------------------------------------------------------------------------
387// Copyright 2014 Bloomberg Finance L.P.
388//
389// Licensed under the Apache License, Version 2.0 (the "License");
390// you may not use this file except in compliance with the License.
391// You may obtain a copy of the License at
392//
393// http://www.apache.org/licenses/LICENSE-2.0
394//
395// Unless required by applicable law or agreed to in writing, software
396// distributed under the License is distributed on an "AS IS" BASIS,
397// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
398// See the License for the specific language governing permissions and
399// limitations under the License.
400// ----------------------------- END-OF-FILE ----------------------------------
401
402/** @} */
403/** @} */
404/** @} */
Definition bslx_genericinstream.h:591
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslx_byteinstream.h:377
GenericInStream< bsl::streambuf > StreambufInStream
Definition bslx_streambufinstream.h:379