BDE 4.14.0 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/// static int maxSupportedBdexVersion(int versionSelector);
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///
112/// // CREATORS
113/// MyPerson();
114/// // Create a default person.
115///
116/// MyPerson(const char *firstName, const char *lastName, int age);
117/// // Create a person having the specified 'firstName', 'lastName',
118/// // and 'age'.
119///
120/// MyPerson(const MyPerson& original);
121/// // Create a person having the value of the specified 'original'
122/// // person.
123///
124/// ~MyPerson();
125/// // Destroy this object.
126///
127/// // MANIPULATORS
128/// MyPerson& operator=(const MyPerson& rhs);
129/// // Assign to this person the value of the specified 'rhs' person,
130/// // and return a reference to this person.
131///
132/// template <class STREAM>
133/// STREAM& bdexStreamIn(STREAM& stream, int version);
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///
145/// //...
146///
147/// // ACCESSORS
148/// int age() const;
149/// // Return the age of this person.
150///
151/// template <class STREAM>
152/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
153/// // Write the value of this object, using the specified 'version'
154/// // format, to the specified output 'stream', and return a reference
155/// // to 'stream'. If 'stream' is initially invalid, this operation
156/// // has no effect. If 'version' is not supported, 'stream' is
157/// // invalidated, but otherwise unmodified. Note that 'version' is
158/// // not written to 'stream'. See the 'bslx' package-level
159/// // documentation for more information on BDEX streaming of
160/// // value-semantic types and containers.
161///
162/// const bsl::string& firstName() const;
163/// // Return the first name of this person.
164///
165/// const bsl::string& lastName() const;
166/// // Return the last name of this person.
167///
168/// //...
169///
170/// };
171///
172/// // FREE OPERATORS
173/// bool operator==(const MyPerson& lhs, const MyPerson& rhs);
174/// // Return 'true' if the specified 'lhs' and 'rhs' person objects have
175/// // the same value, and 'false' otherwise. Two person objects have the
176/// // same value if they have the same first name, last name, and age.
177///
178/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs);
179/// // Return 'true' if the specified 'lhs' and 'rhs' person objects do not
180/// // have the same value, and 'false' otherwise. Two person objects
181/// // differ in value if they differ in first name, last name, or age.
182///
183/// // ========================================================================
184/// // INLINE FUNCTION DEFINITIONS
185/// // ========================================================================
186///
187/// // CLASS METHODS
188/// inline
189/// int MyPerson::maxSupportedBdexVersion(int /* versionSelector */) {
190/// return 1;
191/// }
192///
193/// // CREATORS
194/// inline
195/// MyPerson::MyPerson()
196/// : d_firstName("")
197/// , d_lastName("")
198/// , d_age(0)
199/// {
200/// }
201///
202/// inline
203/// MyPerson::MyPerson(const char *firstName, const char *lastName, int age)
204/// : d_firstName(firstName)
205/// , d_lastName(lastName)
206/// , d_age(age)
207/// {
208/// }
209///
210/// inline
211/// MyPerson::~MyPerson()
212/// {
213/// }
214///
215/// template <class STREAM>
216/// STREAM& MyPerson::bdexStreamIn(STREAM& stream, int version)
217/// {
218/// if (stream) {
219/// switch (version) { // switch on the 'bslx' version
220/// case 1: {
221/// stream.getString(d_firstName);
222/// if (!stream) {
223/// d_firstName = "stream error"; // *might* be corrupted;
224/// // value for testing
225/// return stream; // RETURN
226/// }
227/// stream.getString(d_lastName);
228/// if (!stream) {
229/// d_lastName = "stream error"; // *might* be corrupted;
230/// // value for testing
231/// return stream; // RETURN
232/// }
233/// stream.getInt32(d_age);
234/// if (!stream) {
235/// d_age = 999; // *might* be corrupted; value for testing
236/// return stream; // RETURN
237/// }
238/// } break;
239/// default: {
240/// stream.invalidate();
241/// }
242/// }
243/// }
244/// return stream;
245/// }
246///
247/// // ACCESSORS
248/// inline
249/// int MyPerson::age() const
250/// {
251/// return d_age;
252/// }
253///
254/// template <class STREAM>
255/// STREAM& MyPerson::bdexStreamOut(STREAM& stream, int version) const
256/// {
257/// switch (version) {
258/// case 1: {
259/// stream.putString(d_firstName);
260/// stream.putString(d_lastName);
261/// stream.putInt32(d_age);
262/// } break;
263/// default: {
264/// stream.invalidate();
265/// } break;
266/// }
267/// return stream;
268/// }
269///
270/// inline
271/// const bsl::string& MyPerson::firstName() const
272/// {
273/// return d_firstName;
274/// }
275///
276/// inline
277/// const bsl::string& MyPerson::lastName() const
278/// {
279/// return d_lastName;
280/// }
281///
282/// // FREE OPERATORS
283/// inline
284/// bool operator==(const MyPerson& lhs, const MyPerson& rhs)
285/// {
286/// return lhs.d_firstName == rhs.d_firstName &&
287/// lhs.d_lastName == rhs.d_lastName &&
288/// lhs.d_age == rhs.d_age;
289/// }
290///
291/// inline
292/// bool operator!=(const MyPerson& lhs, const MyPerson& rhs)
293/// {
294/// return !(lhs == rhs);
295/// }
296/// @endcode
297/// Then, we can exercise the new `MyPerson` value-semantic class by
298/// externalizing and reconstituting an object. First, create a `MyPerson`
299/// `janeSmith` and a `bslx::StreambufOutStream` `outStream`:
300/// @code
301/// MyPerson janeSmith("Jane", "Smith", 42);
302/// bsl::stringbuf buffer;
303/// bslx::StreambufOutStream outStream(&buffer, 20131127);
304/// const int VERSION = 1;
305/// outStream.putVersion(VERSION);
306/// janeSmith.bdexStreamOut(outStream, VERSION);
307/// assert(outStream.isValid());
308/// @endcode
309/// Next, create a `MyPerson` `janeCopy` initialized to the default value, and
310/// assert that `janeCopy` is different from `janeSmith`:
311/// @code
312/// MyPerson janeCopy;
313/// assert(janeCopy != janeSmith);
314/// @endcode
315/// Then, create a `bslx::StreambufInStream` `inStream` initialized with the
316/// buffer from the `bslx::StreambufOutStream` object `outStream` and
317/// unexternalize this data into `janeCopy`:
318/// @code
319/// bslx::StreambufInStream inStream(&buffer);
320/// int version;
321/// inStream.getVersion(version);
322/// janeCopy.bdexStreamIn(inStream, version);
323/// assert(inStream.isValid());
324/// @endcode
325/// Finally, `assert` the obtained values are as expected and display the
326/// results to `bsl::stdout`:
327/// @code
328/// assert(version == VERSION);
329/// assert(janeCopy == janeSmith);
330///
331/// if (janeCopy == janeSmith) {
332/// bsl::cout << "Successfully serialized and de-serialized Jane Smith:"
333/// << "\n\tFirstName: " << janeCopy.firstName()
334/// << "\n\tLastName : " << janeCopy.lastName()
335/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
336/// }
337/// else {
338/// bsl::cout << "Serialization unsuccessful. 'janeCopy' holds:"
339/// << "\n\tFirstName: " << janeCopy.firstName()
340/// << "\n\tLastName : " << janeCopy.lastName()
341/// << "\n\tAge : " << janeCopy.age() << bsl::endl;
342/// }
343/// @endcode
344/// @}
345/** @} */
346/** @} */
347
348/** @addtogroup bsl
349 * @{
350 */
351/** @addtogroup bslx
352 * @{
353 */
354/** @addtogroup bslx_streambufinstream
355 * @{
356 */
357
358#include <bslscm_version.h>
359
360#include <bslx_genericinstream.h>
361
362#include <bsl_streambuf.h>
363
364
365namespace bslx {
366
367 // =======================
368 // class StreambufInStream
369 // =======================
370
371/// This class facilitates the unexternalization of values (and C-style
372/// arrays of values) of the fundamental integral and floating-point types
373/// in a data-independent, platform-neutral representation. It is currently
374/// a `typedef` for `bslx::GenericInStream<bsl::streambuf>`.
376
377} // close package namespace
378
379
380#endif
381
382// ----------------------------------------------------------------------------
383// Copyright 2014 Bloomberg Finance L.P.
384//
385// Licensed under the Apache License, Version 2.0 (the "License");
386// you may not use this file except in compliance with the License.
387// You may obtain a copy of the License at
388//
389// http://www.apache.org/licenses/LICENSE-2.0
390//
391// Unless required by applicable law or agreed to in writing, software
392// distributed under the License is distributed on an "AS IS" BASIS,
393// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
394// See the License for the specific language governing permissions and
395// limitations under the License.
396// ----------------------------- END-OF-FILE ----------------------------------
397
398/** @} */
399/** @} */
400/** @} */
Definition bslx_genericinstream.h:590
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslx_byteinstream.h:377
GenericInStream< bsl::streambuf > StreambufInStream
Definition bslx_streambufinstream.h:375