BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslx.h
Go to the documentation of this file.
1/// @file bslx.h
2///
3///
4/// @defgroup bslx Package bslx
5/// @brief Basic Standard Library eXternalization (bslx)
6/// @addtogroup bsl
7/// @{
8/// @addtogroup bslx
9/// [bslx]: group__bslx.html
10/// @{
11///
12/// # Purpose {#bslx-purpose}
13/// Define externalization protocols and provide implementations.
14///
15/// # Mnemonic {#bslx-mnemonic}
16/// Basic Standard Library eXternalization (bslx)
17///
18/// # Description {#bslx-description}
19/// The 'bslx' package defines (via documentation) the BDEX protocol
20/// for externalization (i.e., for an "out stream") and "unexternalization" (i.e.,
21/// for an "in stream"), and provides concrete byte-array-based stream
22/// implementations of each kind of stream, including streams for testing. In
23/// general, concrete streams must be used in matched pairs, as described in more
24/// detail below; see also {Security Warning} below.
25///
26/// ## Hierarchical Synopsis
27///
28/// The 'bslx' package currently has 14 components having 5 levels of physical
29/// dependency. The list below shows the hierarchical ordering of the components.
30/// The order of components within each level is not architecturally significant,
31/// just alphabetical.
32/// @code
33/// 5. bslx_streambufinstream
34/// bslx_testinstream
35///
36/// 4. bslx_byteinstream
37/// bslx_genericinstream
38/// bslx_streambufoutstream
39/// bslx_testoutstream
40///
41/// 3. bslx_byteoutstream
42/// bslx_genericoutstream
43///
44/// 2. bslx_instreamfunctions
45/// bslx_outstreamfunctions
46/// bslx_testinstreamexception
47///
48/// 1. bslx_marshallingutil
49/// bslx_typecode
50/// bslx_versionfunctions
51/// @endcode
52///
53/// ## Component Synopsis
54///
55/// @ref bslx_byteinstream :
56/// Provide a stream class for unexternalization of fundamental types.
57///
58/// @ref bslx_byteoutstream :
59/// Provide a stream class for externalization of fundamental types.
60///
61/// @ref bslx_genericinstream :
62/// Unexternalization of fundamental types from a parameterized stream.
63///
64/// @ref bslx_genericoutstream :
65/// Externalization of fundamental types to a parameterized stream.
66///
67/// @ref bslx_instreamfunctions :
68/// Facilitate uniform unexternalization of user and fundamental types.
69///
70/// @ref bslx_marshallingutil :
71/// Support platform-independent marshalling of fundamental types.
72///
73/// @ref bslx_outstreamfunctions :
74/// Facilitate uniform externalization of user and fundamental types.
75///
76/// @ref bslx_streambufinstream :
77/// Unexternalization of fundamental types from a `bsl::streambuf`.
78///
79/// @ref bslx_streambufoutstream :
80/// Externalization of fundamental types to a `bsl::streambuf`.
81///
82/// @ref bslx_testinstream :
83/// Enable unexternalization of fundamental types with identification.
84///
85/// @ref bslx_testinstreamexception :
86/// Provide an exception class for unexternalization operations.
87///
88/// @ref bslx_testoutstream :
89/// Enable externalization of fundamental types with identification.
90///
91/// @ref bslx_typecode :
92/// Enumerate the fundamental types supported by BDEX.
93///
94/// @ref bslx_versionfunctions :
95/// Provide functions to return BDEX version information for types.
96///
97/// ## Security Warning
98///
99/// *Warning:* BDEX is *not* a secure protocol. In particular, data purported to
100/// be in BDEX format should be streamed in (i.e., via a BDEX input stream) only
101/// when provided by a *trusted* source. 'bslx' is a low-level facility for
102/// externalizing and unexternalizing data represented in C++ objects. 'bslx'
103/// natively provides support for externalizing fundamental types, arrays, and
104/// critical Standard Library types ('bsl::string' and 'bsl::vector');
105/// higher-level user-defined types (i.e., classes and 'struct's) implement the
106/// BDEX concepts on their own, and are responsible for performing validation when
107/// data is streamed in from a BDEX byte stream. Any input validation for
108/// higher-level types is to be implemented in those types themselves -- i.e.,
109/// there is no central facility for validating input -- so the strength of the
110/// validation performed on an input stream is determined by the strength of the
111/// validation for all of the individual types that will process input from the
112/// stream.
113///
114/// ## Externalization
115///
116/// Externalization is the process of creating another representation for an
117/// in-memory object (also referred to as an "in-core" object) that can be, but
118/// need not be, stored external to processor memory. Often this is done by
119/// streaming the object as a sequence (or array) of bytes, sometimes called
120/// "flattening" the object, because of the one-dimensional structure of a
121/// sequence or array. Such flattening allows easy externalization of the object,
122/// since a byte sequence can be written to a disk file without further
123/// modification. It is similarly the native *format* for other externalization
124/// *mechanisms*, such as OS sockets, and in conjunction with these can be used to
125/// stream the object outside of processor memory. Other externalizations include
126/// storing the relevant data members among various tables and fields of a
127/// relational database.
128///
129/// The 'bslx' streams provide better support for externalization than 'iostream'
130/// objects because BDEX specifies a canonical, optimized representation for
131/// fundamental types, provides component authors the tools to externalize in a
132/// platform-neutral way any in-core object, and allows versioning of types not
133/// directly supported by BDEX.
134///
135/// When externalizing data, the version to be used must be supplied to the
136/// objects directly serialized (objects nested within these "top-level" objects
137/// obtain their version from the parent object explicitly), and this version is
138/// typically externalized as well. Likewise, the unexternalization process
139/// typically obtains the version information from the data for the top-level
140/// objects and the implementation of these top-level objects provides the
141/// corresponding version information for nested objects.
142///
143/// As such, any implementation of 'bdexStreamOut' is required to use only the
144/// methods provided by the BDEX-compliant stream and the methods defined in
145/// 'bslx::OutStreamFunctions' that require a version to be specified. For
146/// externalization of types not needing a version, the value
147/// 'bslx::VersionFunctions::k_NO_VERSION' should be supplied for this parameter.
148///
149/// However, when using 'operator<<' it is impractical to directly supply the
150/// version to be used with each top-level object. As such, an indirect method of
151/// versioning is employed, which incorporates data provided to the stream during
152/// the stream's construction, the 'versionSelector'. One requirement of all
153/// BDEX-compliant serializable types is to implement the
154/// 'maxSupportedBdexVersion' method, which converts this 'versionSelector' to the
155/// needed version on a per object-type basis. While the list of versions
156/// supported by an object is typically a sequential set of numbers starting with
157/// 1, the 'versionSelector' is expected to be formatted as "YYYYMMDD", a date
158/// representation. For example, an integral 'versionSelector' value of 20140402
159/// represents the date 2014/04/02 (April 2, 2014).
160///
161/// If a top-level object is of a type directly supported by the BDEX-compliant
162/// stream, no version is externalized for the data. For the stream-supported
163/// arrays, no version is externalized and the unexternalization of this data must
164/// use the corresponding stream-supported array unexternalization method. All
165/// 'vector' externalizations include a version, which, for directly supported
166/// types, is explicitly the value 1. For nested vectors, the most-nested type is
167/// used to determine the version. If this type is directly supported by the
168/// stream, the value 1 is used; otherwise, the 'maxSupportedBdexVersion' method
169/// provided for that type is used to obtain the version information.
170///
171/// ## Supported Types
172///
173/// The supported types and required content are listed in the table below. All
174/// of the fundamental types in the table may be streamed as scalar values or as
175/// homogeneous arrays. 'bsl::string' is streamed as an 'int' representing the
176/// string's length and a homogeneous 'char' array for the string's data. Note
177/// that 'Int64' and 'Uint64' denote 'bsls::Types::Int64' and
178/// 'bsls::Types::Uint64', respectively, which in turn are 'typedef' names for the
179/// signed and unsigned 64-bit integer types, respectively, on the host platform:
180/// @code
181/// C++ TYPE REQUIRED CONTENT OF ANY PLATFORM-NEUTRAL FORMAT
182/// -------------- -----------------------------------------------
183/// Int64 64 bits (signed)
184/// Uint64 64 bits (unsigned)
185/// int 32 bits (signed)
186/// unsigned int 32 bits (unsigned)
187/// short 16 bits (signed)
188/// unsigned short 16 bits (unsigned)
189/// char 8 bits (platform-dependent)
190/// signed char 8 bits (signed)
191/// unsigned char 8 bits (unsigned)
192/// double IEEE standard 8-byte floating-point value
193/// float IEEE standard 4-byte floating-point value
194///
195/// bsl::string BDE implementation of the STL string class
196/// @endcode
197/// BDEX also supports compact streaming of integer types. In particular, 64-bit
198/// integers can be streamed as 40-, 48-, 56-, or 64-bit values, and 32-bit
199/// integers can be streamed as 24- or 32-bit values, at the user's discretion.
200/// In all cases, the least-significant bytes of the fundamental integer type are
201/// written to the stream. Therefore, outputting a signed value may not preserve
202/// the sign of the original value; it is the user's responsibility to choose
203/// output methods appropriate to the data. On input, however, the non-standard
204/// bit patterns are sign-extended, so that correctly-written values will always
205/// be correctly read.
206///
207/// ### The BDEX Protocols
208///
209/// The BDEX protocols are primarily "documentation-only" protocols whereby
210/// BDEX-compliant value-semantic types and streams each adhere to a published
211/// documentation standard (this document) in order to interoperate correctly.
212/// The protocols specify what types that wish to support BDEX streaming must
213/// provide (three specifically-named methods), and what services the type can
214/// expect from all compliant streams (various "put" and "get" methods). In
215/// addition, BDEX also documents two interfaces, 'InStream' and 'OutStream', that
216/// serve as the "documentation protocols" for input and output streams,
217/// respectively.
218///
219/// ## Requirements for a BDEX-Compliant Class to be Streamable
220///
221/// In this section we give a brief synopsis of the required member functions for
222/// a class in order to be BDEX-streamable. See the "Using BDEX with Your Own
223/// Class" section below for implementation details.
224///
225/// The required signatures and typical documentation (some behavioral details may
226/// be implementation-specific) of the three required methods for a BDEX-compliant
227/// class are as follows:
228/// @code
229/// // CLASS METHODS
230/// static int maxSupportedBdexVersion(int versionSelector);
231/// // Return the maximum valid BDEX format version, as indicated by the
232/// // specified 'versionSelector', to be passed to the 'bdexStreamOut'
233/// // method. Note that it is highly recommended that 'versionSelector' be
234/// // formatted as "YYYYMMDD", a date representation. Also note that
235/// // 'versionSelector' should be a *compile*-time-chosen value that selects
236/// // a format version supported by both externalizer and unexternalizer.
237/// // See the 'bslx' package-level documentation for more information on
238/// // BDEX streaming of value-semantic types and containers.
239///
240/// // MANIPULATORS
241/// template <class STREAM>
242/// STREAM& bdexStreamIn(STREAM& stream, int version);
243/// // Assign to this object the value read from the specified input 'stream'
244/// // using the specified 'version' format, and return a reference to
245/// // 'stream'. If 'stream' is initially invalid, this operation has no
246/// // effect. If 'version' is not supported, this object is unaltered and
247/// // 'stream' is invalidated, but otherwise unmodified. If 'version' is
248/// // supported but 'stream' becomes invalid during this operation, this
249/// // object has an undefined, but valid, state. Note that no version is
250/// // read from 'stream'. See the 'bslx' package-level documentation for
251/// // more information on BDEX streaming of value-semantic types and
252/// // containers.
253///
254/// // ACCESSORS
255/// template <class STREAM>
256/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
257/// // Write the value of this object, using the specified 'version' format,
258/// // to the specified output 'stream', and return a reference to 'stream'.
259/// // If 'stream' is initially invalid, this operation has no effect. If
260/// // 'version' is not supported, 'stream' is invalidated, but otherwise
261/// // unmodified. Note that 'version' is not written to 'stream'. See the
262/// // 'bslx' package-level documentation for more information on BDEX
263/// // streaming of value-semantic types and containers.
264/// @endcode
265///
266/// ### Selection of Streams
267///
268/// At present, there are two pairs of concrete BDEX-compliant streams in 'bslx':
269/// @code
270/// Out Stream In Stream Informal Designation
271/// ------------------- ------------------ --------------------
272/// bslx::ByteOutStream bslx::ByteInStream "Production Streams"
273/// bslx::TestOutStream bslx::TestInStream "Test Streams"
274/// @endcode
275/// The informal designations are used throughout this document.
276///
277/// In general, the concrete "in streams" and "out streams" must be used in
278/// matched pairs. For example, the user should not expect correct behavior if an
279/// object is externalized to a 'bslx::TestOutStream' and then unexternalized from
280/// a seemingly-appropriately-constructed 'bslx::ByteInStream'. Each pair of
281/// streams is designed with different aims in mind, and so their exact formats
282/// may vary.
283///
284/// The typical user will probably be content to use the production streams for
285/// most purposes. We will assume that the production stream is the "correct"
286/// choice without further explicit discussion in most usage examples. See the
287/// individual stream component documentation for specific details about using
288/// test streams. The test streams are meant for testing *only*.
289///
290/// ## Using BDEX with Your Own Class
291///
292/// We will show a very brief example of a fictitious 'MyPoint' class whose
293/// intended purpose is to hold a pair of 'int' values representing a point in a
294/// two-dimensional rectilinear coordinate space. We will first define the class
295/// without BDEX support and then add that support. Note that, in this example,
296/// most of the required documentation and some required methods and free
297/// operators are omitted for ease of viewing.
298///
299/// A simple implementation of 'MyPoint' might be:
300/// @code
301/// class MyPoint {
302/// int d_x;
303/// int d_y;
304///
305/// public:
306/// // CREATORS
307/// MyPoint() : d_x(0), d_y(0) { }
308/// MyPoint(int x, int y) : d_x(x), d_y(y) { }
309/// MyPoint(const MyPoint& original)
310/// : d_x(original.d_x), d_y(original.d_y) { }
311/// ~MyPoint() { }
312///
313/// // MANIPULATORS
314/// MyPoint& operator=(const MyPoint& rhs)
315/// { d_x = rhs.d_x; d_y = rhs.d_y; return *this; }
316/// void setX(int x) { d_x = x; }
317/// void setY(int y) { d_y = y; }
318///
319/// // ACCESSORS
320/// int x() const { return d_x; }
321/// int y() const { return d_y; }
322/// };
323/// @endcode
324/// Putting other design decisions to one side for this discussion, we may ask:
325/// How would we incorporate BDEX streaming into such a class? We observe that
326/// the actual data footprint of such a point class is two 'int' values. If BDEX
327/// succeeds in externalizing these two 'int' values (preserving their order),
328/// then the task is accomplished.
329///
330/// The function-level documentation should make the purpose of each method clear,
331/// and we will show the implementations for 'MyPoint' soon, but first let's just
332/// say a few words about "version". In a nutshell, the version is set to 1 in
333/// the initial release of the class, and in the best of all worlds, the version
334/// stays 1 forever. If, however, for some reason the developer wishes to alter
335/// the BDEX streaming contract (e.g., for some performance reasons), the explicit
336/// version maintains backward compatibility.
337///
338/// Adding the three methods to 'MyPoint' that are required for BDEX-compliance is
339/// straightforward:
340/// @code
341/// class MyPoint {
342/// int d_x;
343/// int d_y;
344///
345/// public:
346/// // CLASS METHODS
347/// static int maxSupportedBdexVersion(int versionSelector);
348/// // Return the maximum valid BDEX format version, as indicated by the
349/// // specified 'versionSelector', to be passed to the 'bdexStreamOut'
350/// // method. Note that it is highly recommended that
351/// // 'versionSelector' be formatted as "YYYYMMDD", a date
352/// // representation. Also note that 'versionSelector' should be a
353/// // *compile*-time-chosen value that selects a format version
354/// // supported by both externalizer and unexternalizer. See the
355/// // 'bslx' package-level documentation for more information on BDEX
356/// // streaming of value-semantic types and containers.
357///
358/// // CREATORS
359/// MyPoint() : d_x(0), d_y(0) { }
360/// MyPoint(int x, int y) : d_x(x), d_y(y) { }
361/// MyPoint(const MyPoint& original)
362/// : d_x(original.d_x), d_y(original.d_y) { }
363/// ~MyPoint() { }
364///
365/// // MANIPULATORS
366/// MyPoint& operator=(const MyPoint& rhs)
367/// { d_x = rhs.d_x; d_y = rhs.d_y; return *this; }
368/// void setX(int x) { d_x = x; }
369/// void setY(int y) { d_y = y; }
370///
371/// template <class STREAM>
372/// STREAM& bdexStreamIn(STREAM& stream, int version);
373/// // Assign to this object the value read from the specified input
374/// // 'stream' using the specified 'version' format, and return a
375/// // reference to 'stream'. If 'stream' is initially invalid, this
376/// // operation has no effect. If 'version' is not supported, this
377/// // object is unaltered and 'stream' is invalidated, but otherwise
378/// // unmodified. If 'version' is supported but 'stream' becomes
379/// // invalid during this operation, this object has an undefined, but
380/// // valid, state. Note that no version is read from 'stream'. See
381/// // the 'bslx' package-level documentation for more information on
382/// // BDEX streaming of value-semantic types and containers.
383///
384/// // ACCESSORS
385/// int x() const { return d_x; }
386/// int y() const { return d_y; }
387///
388/// template <class STREAM>
389/// STREAM& bdexStreamOut(STREAM& stream, int version) const;
390/// // Write the value of this object, using the specified 'version'
391/// // format, to the specified output 'stream', and return a reference
392/// // to 'stream'. If 'stream' is initially invalid, this operation
393/// // has no effect. If 'version' is not supported, 'stream' is
394/// // invalidated, but otherwise unmodified. Note that 'version' is
395/// // not written to 'stream'. See the 'bslx' package-level
396/// // documentation for more information on BDEX streaming of
397/// // value-semantic types and containers.
398/// };
399/// @endcode
400/// The implementations of the new BDEX-required methods might be as follows. The
401/// 'maxSupportedBdexVersion' method simply returns the value 1 regardless of the
402/// 'versionSelector' requested:
403/// @code
404/// inline
405/// int MyPoint::maxSupportedBdexVersion(int versionSelector)
406/// {
407/// return 1;
408/// }
409/// @endcode
410/// The 'bdexStreamOut' method is an accessor (i.e., a 'const' instance method),
411/// and is therefore a bit simpler, so we'll show that one first. Anyway, it's a
412/// bit more logical to see the output format before implementing the input
413/// format. The method is a template method parameterized by 'STREAM', and the
414/// "protocol" of that 'STREAM' must be compatible with the BDEX contract. We can
415/// therefore safely assume that the 'stream' object has the required methods.
416/// See the "The BDEX Protocols" section above for the contracts. The heart of
417/// the method is the two sequential calls to 'putInt32', which externalize the
418/// 'x' and 'y' coordinates of the point value, in that order. These two lines
419/// are all the "new" code that the developer must understand and implement.
420/// Except for changing the class name from our 'MyPoint' example, the rest of the
421/// code can be copied into the new component implementation directly. Note that
422/// this template method is implemented in the header of the component defining
423/// 'MyClass':
424/// @code
425/// template <class STREAM>
426/// STREAM& MyPoint::bdexStreamOut(STREAM& stream, int version) const
427/// {
428/// switch (version) {
429/// case 1: { // Implementation-specific code goes here.
430/// stream.putInt32(d_x);
431/// stream.putInt32(d_y);
432/// } break;
433/// default: {
434/// stream.invalidate();
435/// } break;
436/// }
437/// return stream;
438/// }
439/// @endcode
440/// Having implemented 'bdexStreamOut', implementing 'bdexStreamIn' is extremely
441/// straightforward, involving a template member function whose body can be safely
442/// copied from this example or from any appropriate component. Note that the two
443/// sequential calls to 'getInt32' must match, in both method selection and data
444/// member order, the 'putInt32' methods used in the 'bdexStreamOut' method:
445/// @code
446/// template <class STREAM>
447/// STREAM& MyPoint::bdexStreamIn(STREAM& stream, int version)
448/// {
449/// if (stream) {
450/// switch (version) {
451/// // switch on the schema version (starting with 1)
452/// case 1: { // Implementation-specific code goes here.
453/// stream.getInt32(d_x);
454/// stream.getInt32(d_y);
455/// } break;
456/// default: {
457/// stream.invalidate();
458/// } break;
459/// }
460/// }
461/// return stream;
462/// }
463/// @endcode
464/// The above implementation is sufficient for our point class, and with a very
465/// few additional considerations, illustrates the general recipe for
466/// incorporating BDEX streaming into a class that has an externalizable value.
467///
468/// Very briefly, we will mention two considerations that may be important when
469/// implementing a type that is more complicated than our simple point class.
470///
471/// For our first consideration, notice that, for our simple point class, any
472/// pattern of bits within the two 'int' data members represents a valid value.
473/// However, in general, since we require the state of an object to be valid in
474/// the face of a stream error (e.g., an exception being thrown during streaming
475/// in), the manipulator method 'bdexStreamIn' must validate the input data, set
476/// the object to some valid state in the case of an error, and invalidate the
477/// stream before returning.
478///
479/// The second consideration is that if the new type being implemented has as a
480/// data member a type that is already BDEX-compliant, the new implementation
481/// would use that data member's BDEX methods rather than the stream's methods
482/// directly. This is important for encapsulation.
483///
484/// ## Recommended Selection of versionSelector
485///
486/// BDEX provides two concepts that support versioning the BDEX serialization
487/// format of a type: 'version' and 'versionSelector'. A 'version' is a 1-based
488/// integer indicating one of the supported formats (e.g., format 1, format 2,
489/// etc.). A 'versionSelector' is a value that is mapped to a 'version' for a
490/// type by the type's implementation of 'maxSupportedBdexVersion'.
491///
492/// Selecting a value for a 'versionSelector' is required at two different points:
493/// (1) when implementing a new 'version' format within the 'bdexStreamIn' and
494/// 'bdexStreamOut' methods of a type, and (2) when implementing code that
495/// constructs a BDEX 'OutStream'. In both cases, the value should be a
496/// *compile*-time-selected value.
497///
498/// When a new 'version' format is implemented within the 'bdexStreamIn' and
499/// 'bdexStreamOut' methods of a type, a new mapping in 'maxSupportedBdexVersion'
500/// should be created to expose this new 'version' with a 'versionSelector'. A
501/// simple - and the recommended - approach is to use a value having the pattern
502/// "YYYYMMDD", where "YYYYMMDD" corresponds to the "go-live" date of the
503/// corresponding 'version' format.
504///
505/// When constructing an 'OutStream', a simple approach is to use the current date
506/// as a *compile*-time constant value (but see {Updating Production Systems}).
507/// In combination with the recommended selection of 'versionSelector' values for
508/// 'maxSupportedBdexVersion', this will result in consistent and predictable
509/// behavior while externalizing types. Note that this recommendation is chosen
510/// for its simplicity: to ensure the largest possible audience for an
511/// externalized representation, clients can select the minimum date value that
512/// will result in the desired version of all types externalized with 'operator<<'
513/// being selected.
514///
515/// Clients streaming one or more objects with BDEX create a stream and supply a
516/// 'versionSelector':
517/// @code
518/// MyObject foo( /* some value */ );
519/// bslx::ByteOutStream stream(20140725); // The minimum date that will
520/// // result in all streamed types
521/// // using the correct versions
522/// // during externalization.
523/// stream << foo;
524/// @endcode
525/// Notice that the 'versionSelector' is a *compile*-time-selected value (in this
526/// case, the minimum date that will result in all streamed types using the
527/// correct versions during externalization) that can be mapped to the
528/// serialization format version of the types being serialized. The receiver of
529/// this information must support all these versions as well. Specifying future
530/// dates or allowing a run-time selection of 'versionSelector' is error prone:
531/// tasks exchanging serialized data are often compiled and deployed at different
532/// times, which would result in serialization errors if they were selecting a
533/// serialization version at run-time (there is no guarantee the receiver has been
534/// rebuilt to accept the updated format version).
535///
536/// For an example, assume the 'MyPoint' class is determined to need 64-bit
537/// storage for the coordinate values. The new 'bdexStreamIn' and 'bdexStreamOut'
538/// code might be implemented as:
539/// @code
540/// template <class STREAM>
541/// STREAM& MyPoint::bdexStreamIn(STREAM& stream, int version)
542/// {
543/// if (stream) {
544/// switch (version) {
545/// // switch on the schema version (starting with 1)
546/// case 2: { // Implementation-specific code goes here.
547/// stream.getInt64(d_x);
548/// stream.getInt64(d_y);
549/// } break;
550/// case 1: { // NOTE: 'd_x' and 'd_y' were switched to 64-bit
551/// int tmp;
552/// stream.getInt32(tmp);
553/// d_x = static_cast<bsls::Types::Int64>(tmp);
554/// stream.getInt32(tmp);
555/// d_y = static_cast<bsls::Types::Int64>(tmp);
556/// } break;
557/// default: {
558/// stream.invalidate();
559/// } break;
560/// }
561/// }
562/// return stream;
563/// }
564///
565/// template <class STREAM>
566/// STREAM& MyPoint::bdexStreamOut(STREAM& stream, int version) const
567/// {
568/// switch (version) {
569/// case 2: {
570/// stream.putInt64(d_x);
571/// stream.putInt64(d_y);
572/// } break;
573/// case 1: { // NOTE: 'd_x' and 'd_y' were switched to 64-bit
574/// stream.putInt32(static_cast<int>(d_x));
575/// stream.putInt32(static_cast<int>(d_y));
576/// } break;
577/// default: {
578/// stream.invalidate();
579/// } break;
580/// }
581/// return stream;
582/// }
583/// @endcode
584/// The corresponding 'maxSupportedBdexVersion', where 2014/04/02 is the date on
585/// which the new version is introduced, might look something like:
586/// @code
587/// inline
588/// int MyPoint::maxSupportedBdexVersion(int versionSelector)
589/// {
590/// if (versionSelector >= 20140402) {
591/// return 2; // RETURN
592/// }
593/// return 1;
594/// }
595/// @endcode
596///
597////Updating Production Systems
598///----------------------------
599/// The basic recommendation for choosing a 'versionSelector' (which is supplied
600/// to the BDEX 'OutStream' constructor) is to use the current date as a
601/// *compile*-time constant value. Using the current date will select the most
602/// recent BDEX version. However, in environments were multiple tasks may be
603/// reading the resulting serialized value, it is important to ensure that all the
604/// tasks participating in the system are capable of reading that BDEX version
605/// before selecting it as an output version.
606///
607/// The roll-out of a new BDEX version for an existing type ('A') in a production
608/// system typically involves these steps:
609///
610/// 1. Update Type 'A', introducing a new BDEX version, and version selector for
611/// that version that is the date the change is expected to "go-live".
612///
613/// 2. Rebuild and redeploy all the tasks that de-serialize 'A'.
614///
615/// 3. Update the version selector for tasks that serialize 'A' (choosing the date
616/// used in step 1).
617///
618/// 4. Rebuild and redeploy all the tasks that serialize 'A'.
619///
620/// ## Overloading BDEX Free Functions
621///
622/// For third-party components, and potentially enumerations, three free functions
623/// are available for overloading to allow BDEX streaming of these types.
624/// Overloading these methods takes priority over any class methods defined for
625/// similar functionality. Note that either none or all three must be overloaded
626/// to ensure proper behavior.
627///
628/// Within the component's namespace, the following methods may be overloaded:
629/// @code
630/// template <class STREAM, class TYPE>
631/// STREAM& bdexStreamIn(STREAM& stream, TYPE& variable, int version);
632/// // Assign to the specified 'variable' the 'TYPE' value read from the
633/// // specified input 'stream' using the specified 'version' format, and
634/// // return a reference to 'stream'. If 'stream' is initially invalid,
635/// // this operation has no effect. If 'version' is not supported by
636/// // 'TYPE', 'variable' is unaltered and 'stream' is invalidated, but
637/// // otherwise unmodified. If 'version' is supported by 'TYPE' but
638/// // 'stream' becomes invalid during this operation, 'variable' has an
639/// // undefined, but valid, state. The behavior is undefined unless
640/// // 'STREAM' and 'TYPE' are BDEX-compliant. Note that no version is read
641/// // from 'stream'. See the 'bslx' package-level documentation for more
642/// // information on BDEX streaming of value-semantic types and containers.
643///
644/// template <class STREAM, class TYPE>
645/// STREAM& bdexStreamOut(STREAM& stream, const TYPE& value, int version);
646/// // Write the specified 'value', using the specified 'version' format, to
647/// // the specified output 'stream', and return a reference to 'stream'. If
648/// // 'stream' is initially invalid, this operation has no effect. If
649/// // 'version' is not supported by 'TYPE', 'stream' is invalidated, but
650/// // otherwise unmodified. The behavior is undefined unless 'STREAM' and
651/// // 'TYPE' are BDEX-compliant. Note that 'version' is not written to
652/// // 'stream'. See the 'bslx' package-level documentation for more
653/// // information on BDEX streaming of value-semantic types and containers.
654///
655/// template <class TYPE>
656/// int maxSupportedBdexVersion(const TYPE *, int versionSelector);
657/// // Return the maximum valid BDEX format version, as indicated by the
658/// // specified 'versionSelector', to be passed to the 'bdexStreamOut'
659/// // method while streaming an object of the (template parameter) type
660/// // 'TYPE'. Note that it is highly recommended that 'versionSelector' be
661/// // formatted as "YYYYMMDD", a date representation. Also note that
662/// // 'versionSelector' should be a *compile*-time-chosen value that selects
663/// // a format version supported by both externalizer and unexternalizer.
664/// // See the 'bslx' package-level documentation for more information on
665/// // BDEX streaming of value-semantic types and containers.
666/// @endcode
667/// As a brief example, consider the following enumeration that is to be streamed
668/// as an 8-bit integer as opposed to the default 32-bit integer:
669/// @code
670/// namespace ThirdParty {
671///
672/// struct MyStruct {
673/// public:
674/// enum Value {
675/// e_A = 7,
676/// e_B = 8,
677/// e_C = 9
678/// };
679/// };
680///
681/// template <class STREAM>
682/// STREAM& bdexStreamIn(STREAM& stream, MyStruct::Value& value, int version)
683/// {
684/// using bslx::InStreamFunctions::bdexStreamIn;
685///
686/// if (stream) {
687/// switch (version) {
688/// case 1: {
689/// char newValue;
690/// stream.getInt8(newValue);
691/// if (stream) {
692/// value = static_cast<MyStruct::Value>(newValue);
693/// }
694/// } break;
695/// default: {
696/// stream.invalidate();
697/// } break;
698/// }
699/// }
700/// return stream;
701/// }
702///
703/// template <class STREAM>
704/// STREAM& bdexStreamOut(STREAM& stream,
705/// const MyStruct::Value& value,
706/// int version)
707/// {
708/// using bslx::OutStreamFunctions::bdexStreamOut;
709///
710/// if (stream) {
711/// switch (version) {
712/// case 1: {
713/// stream.putInt8(static_cast<char>(value));
714/// } break;
715/// default: {
716/// stream.invalidate();
717/// } break;
718/// }
719/// }
720/// return stream;
721/// }
722///
723/// inline
724/// int maxSupportedBdexVersion(const MyStruct::Value *,
725/// int versionSelector)
726/// {
727/// using bslx::VersionFunctions::maxSupportedBdexVersion;
728///
729/// return 1;
730/// }
731///
732/// } // close ThirdParty namespace
733/// @endcode
734///
735/// ## Backward Compatibility with Older BDEX Serialization Packages
736///
737/// Users of the previous implementation of the BDEX concept can find
738/// documentation on compatibility in the older package documentation.
739///
740/// ### Appendix I: The BDEX OutStream Protocol
741///
742/// In this section we present the function documentation of BDEX 'OutStream',
743/// which serves as the "documentation protocol" for all BDEX-compliant output
744/// streams:
745/// @code
746/// // MANIPULATORS
747/// void invalidate();
748/// // Put this output stream in an invalid state. This function has no
749/// // effect if this stream is already invalid.
750///
751/// OutStream& putLength(int length);
752/// // If the specified 'length' is less than 128, write to this stream
753/// // the one-byte integer comprised of the least-significant one byte
754/// // of the 'length'; otherwise, write to this stream the four-byte,
755/// // two's complement integer (in network byte order) comprised of the
756/// // least-significant four bytes of the 'length' (in host byte order)
757/// // with the most-significant bit set. Return a reference to this
758/// // stream. If this stream is initially invalid, this operation has
759/// // no effect. The behavior is undefined unless '0 <= length'.
760///
761/// OutStream& putVersion(int version);
762/// // Write to this stream the one-byte, two's complement unsigned
763/// // integer comprised of the least-significant one byte of the
764/// // specified 'version', and return a reference to this stream. If
765/// // this stream is initially invalid, this operation has no effect.
766///
767/// void reserveCapacity(int newCapacity);
768/// // Set the internal buffer size of this stream to be at least the
769/// // specified 'newCapacity' (in bytes). The behavior is undefined
770/// // unless '0 <= newCapacity'.
771///
772/// void reset();
773/// // Remove all content in this stream and validate this stream if it
774/// // is currently invalid.
775///
776/// // *** scalar integer values ***
777///
778/// OutStream& putInt64(bsls::Types::Int64 value);
779/// // Write to this stream the eight-byte, two's complement integer (in
780/// // network byte order) comprised of the least-significant eight bytes
781/// // of the specified 'value' (in host byte order), and return a
782/// // reference to this stream. If this stream is initially invalid,
783/// // this operation has no effect.
784///
785/// OutStream& putUint64(bsls::Types::Uint64 value);
786/// // Write to this stream the eight-byte, two's complement unsigned
787/// // integer (in network byte order) comprised of the least-significant
788/// // eight bytes of the specified 'value' (in host byte order), and
789/// // return a reference to this stream. If this stream is initially
790/// // invalid, this operation has no effect.
791///
792/// OutStream& putInt56(bsls::Types::Int64 value);
793/// // Write to this stream the seven-byte, two's complement integer (in
794/// // network byte order) comprised of the least-significant seven bytes
795/// // of the specified 'value' (in host byte order), and return a
796/// // reference to this stream. If this stream is initially invalid,
797/// // this operation has no effect.
798///
799/// OutStream& putUint56(bsls::Types::Uint64 value);
800/// // Write to this stream the seven-byte, two's complement unsigned
801/// // integer (in network byte order) comprised of the least-significant
802/// // seven bytes of the specified 'value' (in host byte order), and
803/// // return a reference to this stream. If this stream is initially
804/// // invalid, this operation has no effect.
805///
806/// OutStream& putInt48(bsls::Types::Int64 value);
807/// // Write to this stream the six-byte, two's complement integer (in
808/// // network byte order) comprised of the least-significant six bytes
809/// // of the specified 'value' (in host byte order), and return a
810/// // reference to this stream. If this stream is initially invalid,
811/// // this operation has no effect.
812///
813/// OutStream& putUint48(bsls::Types::Uint64 value);
814/// // Write to this stream the six-byte, two's complement unsigned
815/// // integer (in network byte order) comprised of the least-significant
816/// // six bytes of the specified 'value' (in host byte order), and
817/// // return a reference to this stream. If this stream is initially
818/// // invalid, this operation has no effect.
819///
820/// OutStream& putInt40(bsls::Types::Int64 value);
821/// // Write to this stream the five-byte, two's complement integer (in
822/// // network byte order) comprised of the least-significant five bytes
823/// // of the specified 'value' (in host byte order), and return a
824/// // reference to this stream. If this stream is initially invalid,
825/// // this operation has no effect.
826///
827/// OutStream& putUint40(bsls::Types::Uint64 value);
828/// // Write to this stream the five-byte, two's complement unsigned
829/// // integer (in network byte order) comprised of the least-significant
830/// // five bytes of the specified 'value' (in host byte order), and
831/// // return a reference to this stream. If this stream is initially
832/// // invalid, this operation has no effect.
833///
834/// OutStream& putInt32(int value);
835/// // Write to this stream the four-byte, two's complement integer (in
836/// // network byte order) comprised of the least-significant four bytes
837/// // of the specified 'value' (in host byte order), and return a
838/// // reference to this stream. If this stream is initially invalid,
839/// // this operation has no effect.
840///
841/// OutStream& putUint32(unsigned int value);
842/// // Write to this stream the four-byte, two's complement unsigned
843/// // integer (in network byte order) comprised of the least-significant
844/// // four bytes of the specified 'value' (in host byte order), and
845/// // return a reference to this stream. If this stream is initially
846/// // invalid, this operation has no effect.
847///
848/// OutStream& putInt24(int value);
849/// // Write to this stream the three-byte, two's complement integer (in
850/// // network byte order) comprised of the least-significant three bytes
851/// // of the specified 'value' (in host byte order), and return a
852/// // reference to this stream. If this stream is initially invalid,
853/// // this operation has no effect.
854///
855/// OutStream& putUint24(unsigned int value);
856/// // Write to this stream the three-byte, two's complement unsigned
857/// // integer (in network byte order) comprised of the least-significant
858/// // three bytes of the specified 'value' (in host byte order), and
859/// // return a reference to this stream. If this stream is initially
860/// // invalid, this operation has no effect.
861///
862/// OutStream& putInt16(int value);
863/// // Write to this stream the two-byte, two's complement integer (in
864/// // network byte order) comprised of the least-significant two bytes
865/// // of the specified 'value' (in host byte order), and return a
866/// // reference to this stream. If this stream is initially invalid,
867/// // this operation has no effect.
868///
869/// OutStream& putUint16(unsigned int value);
870/// // Write to this stream the two-byte, two's complement unsigned
871/// // integer (in network byte order) comprised of the least-significant
872/// // two bytes of the specified 'value' (in host byte order), and
873/// // return a reference to this stream. If this stream is initially
874/// // invalid, this operation has no effect.
875///
876/// OutStream& putInt8(int value);
877/// // Write to this stream the one-byte, two's complement integer
878/// // comprised of the least-significant one byte of the specified
879/// // 'value', and return a reference to this stream. If this stream is
880/// // initially invalid, this operation has no effect.
881///
882/// OutStream& putUint8(unsigned int value);
883/// // Write to this stream the one-byte, two's complement unsigned
884/// // integer comprised of the least-significant one byte of the
885/// // specified 'value', and return a reference to this stream. If this
886/// // stream is initially invalid, this operation has no effect.
887///
888/// // *** scalar floating-point values ***
889///
890/// OutStream& putFloat64(double value);
891/// // Write to this stream the eight-byte IEEE double-precision
892/// // floating-point number (in network byte order) comprised of the
893/// // most-significant eight bytes of the specified 'value' (in host
894/// // byte order), and return a reference to this stream. If this
895/// // stream is initially invalid, this operation has no effect. Note
896/// // that for non-conforming platforms, this operation may be lossy.
897///
898/// OutStream& putFloat32(float value);
899/// // Write to this stream the four-byte IEEE single-precision
900/// // floating-point number (in network byte order) comprised of the
901/// // most-significant four bytes of the specified 'value' (in host byte
902/// // order), and return a reference to this stream. If this stream is
903/// // initially invalid, this operation has no effect. Note that for
904/// // non-conforming platforms, this operation may be lossy.
905///
906/// // *** string values ***
907///
908/// OutStream& putString(const bsl::string& value);
909/// // Write to this stream the length of the specified 'value' (see
910/// // 'putLength') and an array of one-byte, two's complement unsigned
911/// // integers comprised of the least-significant one byte of each
912/// // character in the 'value', and return a reference to this stream.
913/// // If this stream is initially invalid, this operation has no effect.
914///
915/// // *** arrays of integer values ***
916///
917/// OutStream& putArrayInt64(const bsls::Types::Int64 *values,
918/// int numValues);
919/// // Write to this stream the consecutive eight-byte, two's complement
920/// // integers (in network byte order) comprised of the
921/// // least-significant eight bytes of each of the specified 'numValues'
922/// // leading entries in the specified 'values' (in host byte order),
923/// // and return a reference to this stream. If this stream is
924/// // initially invalid, this operation has no effect. The behavior is
925/// // undefined unless '0 <= numValues' and 'values' has sufficient
926/// // contents.
927///
928/// OutStream& putArrayUint64(const bsls::Types::Uint64 *values,
929/// int numValues);
930/// // Write to this stream the consecutive eight-byte, two's complement
931/// // unsigned integers (in network byte order) comprised of the
932/// // least-significant eight bytes of each of the specified 'numValues'
933/// // leading entries in the specified 'values' (in host byte order),
934/// // and return a reference to this stream. If this stream is
935/// // initially invalid, this operation has no effect. The behavior is
936/// // undefined unless '0 <= numValues' and 'values' has sufficient
937/// // contents.
938///
939/// OutStream& putArrayInt56(const bsls::Types::Int64 *values,
940/// int numValues);
941/// // Write to this stream the consecutive seven-byte, two's complement
942/// // integers (in network byte order) comprised of the
943/// // least-significant seven bytes of each of the specified 'numValues'
944/// // leading entries in the specified 'values' (in host byte order),
945/// // and return a reference to this stream. If this stream is
946/// // initially invalid, this operation has no effect. The behavior is
947/// // undefined unless '0 <= numValues' and 'values' has sufficient
948/// // contents.
949///
950/// OutStream& putArrayUint56(const bsls::Types::Uint64 *values,
951/// int numValues);
952/// // Write to this stream the consecutive seven-byte, two's complement
953/// // unsigned integers (in network byte order) comprised of the
954/// // least-significant seven bytes of each of the specified 'numValues'
955/// // leading entries in the specified 'values' (in host byte order),
956/// // and return a reference to this stream. If this stream is
957/// // initially invalid, this operation has no effect. The behavior is
958/// // undefined unless '0 <= numValues' and 'values' has sufficient
959/// // contents.
960///
961/// OutStream& putArrayInt48(const bsls::Types::Int64 *values,
962/// int numValues);
963/// // Write to this stream the consecutive six-byte, two's complement
964/// // integers (in network byte order) comprised of the
965/// // least-significant six bytes of each of the specified 'numValues'
966/// // leading entries in the specified 'values' (in host byte order),
967/// // and return a reference to this stream. If this stream is
968/// // initially invalid, this operation has no effect. The behavior is
969/// // undefined unless '0 <= numValues' and 'values' has sufficient
970/// // contents.
971///
972/// OutStream& putArrayUint48(const bsls::Types::Uint64 *values,
973/// int numValues);
974/// // Write to this stream the consecutive six-byte, two's complement
975/// // unsigned integers (in network byte order) comprised of the
976/// // least-significant six bytes of each of the specified 'numValues'
977/// // leading entries in the specified 'values' (in host byte order),
978/// // and return a reference to this stream. If this stream is
979/// // initially invalid, this operation has no effect. The behavior is
980/// // undefined unless '0 <= numValues' and 'values' has sufficient
981/// // contents.
982///
983/// OutStream& putArrayInt40(const bsls::Types::Int64 *values,
984/// int numValues);
985/// // Write to this stream the consecutive five-byte, two's complement
986/// // integers (in network byte order) comprised of the
987/// // least-significant five bytes of each of the specified 'numValues'
988/// // leading entries in the specified 'values' (in host byte order),
989/// // and return a reference to this stream. If this stream is
990/// // initially invalid, this operation has no effect. The behavior is
991/// // undefined unless '0 <= numValues' and 'values' has sufficient
992/// // contents.
993///
994/// OutStream& putArrayUint40(const bsls::Types::Uint64 *values,
995/// int numValues);
996/// // Write to this stream the consecutive five-byte, two's complement
997/// // unsigned integers (in network byte order) comprised of the
998/// // least-significant five bytes of each of the specified 'numValues'
999/// // leading entries in the specified 'values' (in host byte order),
1000/// // and return a reference to this stream. If this stream is
1001/// // initially invalid, this operation has no effect. The behavior is
1002/// // undefined unless '0 <= numValues' and 'values' has sufficient
1003/// // contents.
1004///
1005/// OutStream& putArrayInt32(const int *values, int numValues);
1006/// // Write to this stream the consecutive four-byte, two's complement
1007/// // integers (in network byte order) comprised of the
1008/// // least-significant four bytes of each of the specified 'numValues'
1009/// // leading entries in the specified 'values' (in host byte order),
1010/// // and return a reference to this stream. If this stream is
1011/// // initially invalid, this operation has no effect. The behavior is
1012/// // undefined unless '0 <= numValues' and 'values' has sufficient
1013/// // contents.
1014///
1015/// OutStream& putArrayUint32(const unsigned int *values, int numValues);
1016/// // Write to this stream the consecutive four-byte, two's complement
1017/// // unsigned integers (in network byte order) comprised of the
1018/// // least-significant four bytes of each of the specified 'numValues'
1019/// // leading entries in the specified 'values' (in host byte order),
1020/// // and return a reference to this stream. If this stream is
1021/// // initially invalid, this operation has no effect. The behavior is
1022/// // undefined unless '0 <= numValues' and 'values' has sufficient
1023/// // contents.
1024///
1025/// OutStream& putArrayInt24(const int *values, int numValues);
1026/// // Write to this stream the consecutive three-byte, two's complement
1027/// // integers (in network byte order) comprised of the
1028/// // least-significant three bytes of each of the specified 'numValues'
1029/// // leading entries in the specified 'values' (in host byte order),
1030/// // and return a reference to this stream. If this stream is
1031/// // initially invalid, this operation has no effect. The behavior is
1032/// // undefined unless '0 <= numValues' and 'values' has sufficient
1033/// // contents.
1034///
1035/// OutStream& putArrayUint24(const unsigned int *values, int numValues);
1036/// // Write to this stream the consecutive three-byte, two's complement
1037/// // unsigned integers (in network byte order) comprised of the
1038/// // least-significant three bytes of each of the specified 'numValues'
1039/// // leading entries in the specified 'values' (in host byte order),
1040/// // and return a reference to this stream. If this stream is
1041/// // initially invalid, this operation has no effect. The behavior is
1042/// // undefined unless '0 <= numValues' and 'values' has sufficient
1043/// // contents.
1044///
1045/// OutStream& putArrayInt16(const short *values, int numValues);
1046/// // Write to this stream the consecutive two-byte, two's complement
1047/// // integers (in network byte order) comprised of the
1048/// // least-significant two bytes of each of the specified 'numValues'
1049/// // leading entries in the specified 'values' (in host byte order),
1050/// // and return a reference to this stream. If this stream is
1051/// // initially invalid, this operation has no effect. The behavior is
1052/// // undefined unless '0 <= numValues' and 'values' has sufficient
1053/// // contents.
1054///
1055/// OutStream& putArrayUint16(const unsigned short *values, int numValues);
1056/// // Write to this stream the consecutive two-byte, two's complement
1057/// // unsigned integers (in network byte order) comprised of the
1058/// // least-significant two bytes of each of the specified 'numValues'
1059/// // leading entries in the specified 'values' (in host byte order),
1060/// // and return a reference to this stream. If this stream is
1061/// // initially invalid, this operation has no effect. The behavior is
1062/// // undefined unless '0 <= numValues' and 'values' has sufficient
1063/// // contents.
1064///
1065/// OutStream& putArrayInt8(const char *values, int numValues);
1066/// OutStream& putArrayInt8(const signed char *values, int numValues);
1067/// // Write to this stream the consecutive one-byte, two's complement
1068/// // integers comprised of the least-significant one byte of each of
1069/// // the specified 'numValues' leading entries in the specified
1070/// // 'values', and return a reference to this stream. If this stream
1071/// // is initially invalid, this operation has no effect. The behavior
1072/// // is undefined unless '0 <= numValues' and 'values' has sufficient
1073/// // contents.
1074///
1075/// OutStream& putArrayUint8(const char *values, int numValues);
1076/// OutStream& putArrayUint8(const unsigned char *values, int numValues);
1077/// // Write to this stream the consecutive one-byte, two's complement
1078/// // unsigned integers comprised of the least-significant one byte of
1079/// // each of the specified 'numValues' leading entries in the specified
1080/// // 'values', and return a reference to this stream. If this stream
1081/// // is initially invalid, this operation has no effect. The behavior
1082/// // is undefined unless '0 <= numValues' and 'values' has sufficient
1083/// // contents.
1084///
1085/// // *** arrays of floating-point values ***
1086///
1087/// OutStream& putArrayFloat64(const double *values, int numValues);
1088/// // Write to this stream the consecutive eight-byte IEEE
1089/// // double-precision floating-point numbers (in network byte order)
1090/// // comprised of the most-significant eight bytes of each of the
1091/// // specified 'numValues' leading entries in the specified 'values'
1092/// // (in host byte order), and return a reference to this stream. If
1093/// // this stream is initially invalid, this operation has no effect.
1094/// // The behavior is undefined unless '0 <= numValues' and 'values' has
1095/// // sufficient contents. Note that for non-conforming platforms, this
1096/// // operation may be lossy.
1097///
1098/// OutStream& putArrayFloat32(const float *values, int numValues);
1099/// // Write to this stream the consecutive four-byte IEEE
1100/// // single-precision floating-point numbers (in network byte order)
1101/// // comprised of the most-significant four bytes of each of the
1102/// // specified 'numValues' leading entries in the specified 'values'
1103/// // (in host byte order), and return a reference to this stream. If
1104/// // this stream is initially invalid, this operation has no effect.
1105/// // The behavior is undefined unless '0 <= numValues' and 'values' has
1106/// // sufficient contents. Note that for non-conforming platforms, this
1107/// // operation may be lossy.
1108///
1109/// // ACCESSORS
1110/// operator const void *() const;
1111/// // Return a non-zero value if this stream is valid, and 0 otherwise.
1112/// // An invalid stream is a stream for which an output operation was
1113/// // detected to have failed or 'invalidate' was called.
1114///
1115/// int bdexVersionSelector() const;
1116/// // Return the 'versionSelector' to be used with 'operator<<' for BDEX
1117/// // streaming as per the 'bslx' package-level documentation.
1118///
1119/// const char *data() const;
1120/// // Return the address of the contiguous, non-modifiable internal
1121/// // memory buffer of this stream. The address will remain valid as
1122/// // long as this stream is not destroyed or modified. The behavior of
1123/// // accessing elements outside the range
1124/// // '[ data() .. data() + (length() - 1) ]' is undefined.
1125///
1126/// bool isValid() const;
1127/// // Return 'true' if this stream is valid, and 'false' otherwise. An
1128/// // invalid stream is a stream for which an output operation was
1129/// // detected to have failed or 'invalidate' was called.
1130///
1131/// bsl::size_t length() const;
1132/// // Return the number of bytes in this stream.
1133///
1134/// // FREE OPERATORS
1135/// template <class TYPE>
1136/// OutStream& operator<<(OutStream& stream, const TYPE& value);
1137/// // Write the specified 'value' to the specified output 'stream' following
1138/// // the requirements of the BDEX protocol (see the 'bslx' package-level
1139/// // documentation), and return a reference to 'stream'. The behavior is
1140/// // undefined unless 'TYPE' is BDEX-compliant.
1141/// @endcode
1142///
1143/// ### Appendix II: The BDEX InStream Protocol
1144///
1145/// In this section we present the function documentation of BDEX 'InStream',
1146/// which serves as the "documentation protocol" for all BDEX-compliant input
1147/// streams:
1148/// @code
1149/// // MANIPULATORS
1150/// InStream& getLength(int& length);
1151/// // If the most-significant bit of the one byte of this stream at the
1152/// // current cursor location is set, assign to the specified 'length'
1153/// // the four-byte, two's complement integer (in host byte order)
1154/// // comprised of the four bytes of this stream at the current cursor
1155/// // location (in network byte order) with the most-significant bit
1156/// // unset; otherwise, assign to 'length' the one-byte, two's
1157/// // complement integer comprised of the one byte of this stream at the
1158/// // current cursor location. Update the cursor location and return a
1159/// // reference to this stream. If this stream is initially invalid,
1160/// // this operation has no effect. If this function otherwise fails to
1161/// // extract a valid value, this stream is marked invalid and the value
1162/// // of 'length' is undefined. Note that the value will be
1163/// // zero-extended.
1164///
1165/// InStream& getVersion(int& version);
1166/// // Assign to the specified 'version' the one-byte, two's complement
1167/// // unsigned integer comprised of the one byte of this stream at the
1168/// // current cursor location, update the cursor location, and return a
1169/// // reference to this stream. If this stream is initially invalid,
1170/// // this operation has no effect. If this function otherwise fails to
1171/// // extract a valid value, this stream is marked invalid and the value
1172/// // of 'version' is undefined. Note that the value will be
1173/// // zero-extended.
1174///
1175/// void invalidate();
1176/// // Put this input stream in an invalid state. This function has no
1177/// // effect if this stream is already invalid. Note that this function
1178/// // should be called whenever a value extracted from this stream is
1179/// // determined to be invalid, inconsistent, or otherwise incorrect.
1180///
1181/// void reset();
1182/// // Set the index of the next byte to be extracted from this stream to
1183/// // 0 (i.e., the beginning of the stream) and validate this stream if
1184/// // it is currently invalid.
1185///
1186/// void reset(const char *buffer, bsl::size_t numBytes);
1187/// // Reset this stream to extract from the specified 'buffer'
1188/// // containing the specified 'numBytes', set the index of the next
1189/// // byte to be extracted to 0 (i.e., the beginning of the stream), and
1190/// // validate this stream if it is currently invalid. The behavior is
1191/// // undefined unless '0 == numBytes' if '0 == buffer'.
1192///
1193/// void reset(const bslstl::StringRef& srcData);
1194/// // Reset this stream to extract from the specified 'srcData', set the
1195/// // index of the next byte to be extracted to 0 (i.e., the beginning
1196/// // of the stream), and validate this stream if it is currently
1197/// // invalid.
1198///
1199/// // *** scalar integer values ***
1200///
1201/// InStream& getInt64(bsls::Types::Int64& variable);
1202/// // Assign to the specified 'variable' the eight-byte, two's
1203/// // complement integer (in host byte order) comprised of the eight
1204/// // bytes of this stream at the current cursor location (in network
1205/// // byte order), update the cursor location, and return a reference to
1206/// // this stream. If this stream is initially invalid, this operation
1207/// // has no effect. If this function otherwise fails to extract a
1208/// // valid value, this stream is marked invalid and the value of
1209/// // 'variable' is undefined. Note that the value will be
1210/// // sign-extended.
1211///
1212/// InStream& getUint64(bsls::Types::Uint64& variable);
1213/// // Assign to the specified 'variable' the eight-byte, two's
1214/// // complement unsigned integer (in host byte order) comprised of the
1215/// // eight bytes of this stream at the current cursor location (in
1216/// // network byte order), update the cursor location, and return a
1217/// // reference to this stream. If this stream is initially invalid,
1218/// // this operation has no effect. If this function otherwise fails to
1219/// // extract a valid value, this stream is marked invalid and the value
1220/// // of 'variable' is undefined. Note that the value will be
1221/// // zero-extended.
1222///
1223/// InStream& getInt56(bsls::Types::Int64& variable);
1224/// // Assign to the specified 'variable' the seven-byte, two's
1225/// // complement integer (in host byte order) comprised of the seven
1226/// // bytes of this stream at the current cursor location (in network
1227/// // byte order), update the cursor location, and return a reference to
1228/// // this stream. If this stream is initially invalid, this operation
1229/// // has no effect. If this function otherwise fails to extract a
1230/// // valid value, this stream is marked invalid and the value of
1231/// // 'variable' is undefined. Note that the value will be
1232/// // sign-extended.
1233///
1234/// InStream& getUint56(bsls::Types::Uint64& variable);
1235/// // Assign to the specified 'variable' the seven-byte, two's
1236/// // complement unsigned integer (in host byte order) comprised of the
1237/// // seven bytes of this stream at the current cursor location (in
1238/// // network byte order), update the cursor location, and return a
1239/// // reference to this stream. If this stream is initially invalid,
1240/// // this operation has no effect. If this function otherwise fails to
1241/// // extract a valid value, this stream is marked invalid and the value
1242/// // of 'variable' is undefined. Note that the value will be
1243/// // zero-extended.
1244///
1245/// InStream& getInt48(bsls::Types::Int64& variable);
1246/// // Assign to the specified 'variable' the six-byte, two's complement
1247/// // integer (in host byte order) comprised of the six bytes of this
1248/// // stream at the current cursor location (in network byte order),
1249/// // update the cursor location, and return a reference to this stream.
1250/// // If this stream is initially invalid, this operation has no effect.
1251/// // If this function otherwise fails to extract a valid value, this
1252/// // stream is marked invalid and the value of 'variable' is undefined.
1253/// // Note that the value will be sign-extended.
1254///
1255/// InStream& getUint48(bsls::Types::Uint64& variable);
1256/// // Assign to the specified 'variable' the six-byte, two's complement
1257/// // unsigned integer (in host byte order) comprised of the six bytes
1258/// // of this stream at the current cursor location (in network byte
1259/// // order), update the cursor location, and return a reference to this
1260/// // stream. If this stream is initially invalid, this operation has
1261/// // no effect. If this function otherwise fails to extract a valid
1262/// // value, this stream is marked invalid and the value of 'variable'
1263/// // is undefined. Note that the value will be zero-extended.
1264///
1265/// InStream& getInt40(bsls::Types::Int64& variable);
1266/// // Assign to the specified 'variable' the five-byte, two's complement
1267/// // integer (in host byte order) comprised of the five bytes of this
1268/// // stream at the current cursor location (in network byte order),
1269/// // update the cursor location, and return a reference to this stream.
1270/// // If this stream is initially invalid, this operation has no effect.
1271/// // If this function otherwise fails to extract a valid value, this
1272/// // stream is marked invalid and the value of 'variable' is undefined.
1273/// // Note that the value will be sign-extended.
1274///
1275/// InStream& getUint40(bsls::Types::Uint64& variable);
1276/// // Assign to the specified 'variable' the five-byte, two's complement
1277/// // unsigned integer (in host byte order) comprised of the five bytes
1278/// // of this stream at the current cursor location (in network byte
1279/// // order), update the cursor location, and return a reference to this
1280/// // stream. If this stream is initially invalid, this operation has
1281/// // no effect. If this function otherwise fails to extract a valid
1282/// // value, this stream is marked invalid and the value of 'variable'
1283/// // is undefined. Note that the value will be zero-extended.
1284///
1285/// InStream& getInt32(int& variable);
1286/// // Assign to the specified 'variable' the four-byte, two's complement
1287/// // integer (in host byte order) comprised of the four bytes of this
1288/// // stream at the current cursor location (in network byte order),
1289/// // update the cursor location, and return a reference to this stream.
1290/// // If this stream is initially invalid, this operation has no effect.
1291/// // If this function otherwise fails to extract a valid value, this
1292/// // stream is marked invalid and the value of 'variable' is undefined.
1293/// // Note that the value will be sign-extended.
1294///
1295/// InStream& getUint32(unsigned int& variable);
1296/// // Assign to the specified 'variable' the four-byte, two's complement
1297/// // unsigned integer (in host byte order) comprised of the four bytes
1298/// // of this stream at the current cursor location (in network byte
1299/// // order), update the cursor location, and return a reference to this
1300/// // stream. If this stream is initially invalid, this operation has
1301/// // no effect. If this function otherwise fails to extract a valid
1302/// // value, this stream is marked invalid and the value of 'variable'
1303/// // is undefined. Note that the value will be zero-extended.
1304///
1305/// InStream& getInt24(int& variable);
1306/// // Assign to the specified 'variable' the three-byte, two's
1307/// // complement integer (in host byte order) comprised of the three
1308/// // bytes of this stream at the current cursor location (in network
1309/// // byte order), update the cursor location, and return a reference to
1310/// // this stream. If this stream is initially invalid, this operation
1311/// // has no effect. If this function otherwise fails to extract a
1312/// // valid value, this stream is marked invalid and the value of
1313/// // 'variable' is undefined. Note that the value will be
1314/// // sign-extended.
1315///
1316/// InStream& getUint24(unsigned int& variable);
1317/// // Assign to the specified 'variable' the three-byte, two's
1318/// // complement unsigned integer (in host byte order) comprised of the
1319/// // three bytes of this stream at the current cursor location (in
1320/// // network byte order), update the cursor location, and return a
1321/// // reference to this stream. If this stream is initially invalid,
1322/// // this operation has no effect. If this function otherwise fails to
1323/// // extract a valid value, this stream is marked invalid and the value
1324/// // of 'variable' is undefined. Note that the value will be
1325/// // zero-extended.
1326///
1327/// InStream& getInt16(short& variable);
1328/// // Assign to the specified 'variable' the two-byte, two's complement
1329/// // integer (in host byte order) comprised of the two bytes of this
1330/// // stream at the current cursor location (in network byte order),
1331/// // update the cursor location, and return a reference to this stream.
1332/// // If this stream is initially invalid, this operation has no effect.
1333/// // If this function otherwise fails to extract a valid value, this
1334/// // stream is marked invalid and the value of 'variable' is undefined.
1335/// // Note that the value will be sign-extended.
1336///
1337/// InStream& getUint16(unsigned short& variable);
1338/// // Assign to the specified 'variable' the two-byte, two's complement
1339/// // unsigned integer (in host byte order) comprised of the two bytes
1340/// // of this stream at the current cursor location (in network byte
1341/// // order), update the cursor location, and return a reference to this
1342/// // stream. If this stream is initially invalid, this operation has
1343/// // no effect. If this function otherwise fails to extract a valid
1344/// // value, this stream is marked invalid and the value of 'variable'
1345/// // is undefined. Note that the value will be zero-extended.
1346///
1347/// InStream& getInt8(char& variable);
1348/// InStream& getInt8(signed char& variable);
1349/// // Assign to the specified 'variable' the one-byte, two's complement
1350/// // integer comprised of the one byte of this stream at the current
1351/// // cursor location, update the cursor location, and return a
1352/// // reference to this stream. If this stream is initially invalid,
1353/// // this operation has no effect. If this function otherwise fails to
1354/// // extract a valid value, this stream is marked invalid and the value
1355/// // of 'variable' is undefined. Note that the value will be
1356/// // sign-extended.
1357///
1358/// InStream& getUint8(char& variable);
1359/// InStream& getUint8(unsigned char& variable);
1360/// // Assign to the specified 'variable' the one-byte, two's complement
1361/// // unsigned integer comprised of the one byte of this stream at the
1362/// // current cursor location, update the cursor location, and return a
1363/// // reference to this stream. If this stream is initially invalid,
1364/// // this operation has no effect. If this function otherwise fails to
1365/// // extract a valid value, this stream is marked invalid and the value
1366/// // of 'variable' is undefined. Note that the value will be
1367/// // zero-extended.
1368///
1369/// // *** scalar floating-point values ***
1370///
1371/// InStream& getFloat64(double& variable);
1372/// // Assign to the specified 'variable' the eight-byte IEEE
1373/// // double-precision floating-point number (in host byte order)
1374/// // comprised of the eight bytes of this stream at the current cursor
1375/// // location (in network byte order), update the cursor location, and
1376/// // return a reference to this stream. If this stream is initially
1377/// // invalid, this operation has no effect. If this function otherwise
1378/// // fails to extract a valid value, this stream is marked invalid and
1379/// // the value of 'variable' is undefined.
1380///
1381/// InStream& getFloat32(float& variable);
1382/// // Assign to the specified 'variable' the four-byte IEEE
1383/// // single-precision floating-point number (in host byte order)
1384/// // comprised of the four bytes of this stream at the current cursor
1385/// // location (in network byte order), update the cursor location, and
1386/// // return a reference to this stream. If this stream is initially
1387/// // invalid, this operation has no effect. If this function otherwise
1388/// // fails to extract a valid value, this stream is marked invalid and
1389/// // the value of 'variable' is undefined.
1390///
1391/// // *** string values ***
1392///
1393/// InStream& getString(bsl::string& variable);
1394/// // Assign to the specified 'variable' the string comprised of the
1395/// // length of the string (see 'getLength') and the string data (see
1396/// // 'getUint8'), update the cursor location, and return a reference to
1397/// // this stream. If this stream is initially invalid, this operation
1398/// // has no effect. If this function otherwise fails to extract a
1399/// // valid value, this stream is marked invalid and the value of
1400/// // 'variable' is undefined.
1401///
1402/// // *** arrays of integer values ***
1403///
1404/// InStream& getArrayInt64(bsls::Types::Int64 *variables, int numVariables);
1405/// // Assign to the specified 'variables' the consecutive eight-byte,
1406/// // two's complement integers (in host byte order) comprised of each
1407/// // of the specified 'numVariables' eight-byte sequences of this
1408/// // stream at the current cursor location (in network byte order),
1409/// // update the cursor location, and return a reference to this stream.
1410/// // If this stream is initially invalid, this operation has no effect.
1411/// // If this function otherwise fails to extract a valid value, this
1412/// // stream is marked invalid and the value of 'variables' is
1413/// // undefined. The behavior is undefined unless '0 <= numVariables'
1414/// // and 'variables' has sufficient capacity. Note that each of the
1415/// // values will be sign-extended.
1416///
1417/// InStream& getArrayUint64(bsls::Types::Uint64 *variables,
1418/// int numVariables);
1419/// // Assign to the specified 'variables' the consecutive eight-byte,
1420/// // two's complement unsigned integers (in host byte order) comprised
1421/// // of each of the specified 'numVariables' eight-byte sequences of
1422/// // this stream at the current cursor location (in network byte
1423/// // order), update the cursor location, and return a reference to this
1424/// // stream. If this stream is initially invalid, this operation has
1425/// // no effect. If this function otherwise fails to extract a valid
1426/// // value, this stream is marked invalid and the value of 'variables'
1427/// // is undefined. The behavior is undefined unless
1428/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1429/// // that each of the values will be zero-extended.
1430///
1431/// InStream& getArrayInt56(bsls::Types::Int64 *variables, int numVariables);
1432/// // Assign to the specified 'variables' the consecutive seven-byte,
1433/// // two's complement integers (in host byte order) comprised of each
1434/// // of the specified 'numVariables' seven-byte sequences of this
1435/// // stream at the current cursor location (in network byte order),
1436/// // update the cursor location, and return a reference to this stream.
1437/// // If this stream is initially invalid, this operation has no effect.
1438/// // If this function otherwise fails to extract a valid value, this
1439/// // stream is marked invalid and the value of 'variables' is
1440/// // undefined. The behavior is undefined unless '0 <= numVariables'
1441/// // and 'variables' has sufficient capacity. Note that each of the
1442/// // values will be sign-extended.
1443///
1444/// InStream& getArrayUint56(bsls::Types::Uint64 *variables,
1445/// int numVariables);
1446/// // Assign to the specified 'variables' the consecutive seven-byte,
1447/// // two's complement unsigned integers (in host byte order) comprised
1448/// // of each of the specified 'numVariables' seven-byte sequences of
1449/// // this stream at the current cursor location (in network byte
1450/// // order), update the cursor location, and return a reference to this
1451/// // stream. If this stream is initially invalid, this operation has
1452/// // no effect. If this function otherwise fails to extract a valid
1453/// // value, this stream is marked invalid and the value of 'variables'
1454/// // is undefined. The behavior is undefined unless
1455/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1456/// // that each of the values will be zero-extended.
1457///
1458/// InStream& getArrayInt48(bsls::Types::Int64 *variables, int numVariables);
1459/// // Assign to the specified 'variables' the consecutive six-byte,
1460/// // two's complement integers (in host byte order) comprised of each
1461/// // of the specified 'numVariables' six-byte sequences of this stream
1462/// // at the current cursor location (in network byte order), update the
1463/// // cursor location, and return a reference to this stream. If this
1464/// // stream is initially invalid, this operation has no effect. If
1465/// // this function otherwise fails to extract a valid value, this
1466/// // stream is marked invalid and the value of 'variables' is
1467/// // undefined. The behavior is undefined unless '0 <= numVariables'
1468/// // and 'variables' has sufficient capacity. Note that each of the
1469/// // values will be sign-extended.
1470///
1471/// InStream& getArrayUint48(bsls::Types::Uint64 *variables,
1472/// int numVariables);
1473/// // Assign to the specified 'variables' the consecutive six-byte,
1474/// // two's complement unsigned integers (in host byte order) comprised
1475/// // of each of the specified 'numVariables' six-byte sequences of this
1476/// // stream at the current cursor location (in network byte order),
1477/// // update the cursor location, and return a reference to this stream.
1478/// // If this stream is initially invalid, this operation has no effect.
1479/// // If this function otherwise fails to extract a valid value, this
1480/// // stream is marked invalid and the value of 'variables' is
1481/// // undefined. The behavior is undefined unless '0 <= numVariables'
1482/// // and 'variables' has sufficient capacity. Note that each of the
1483/// // values will be zero-extended.
1484///
1485/// InStream& getArrayInt40(bsls::Types::Int64 *variables, int numVariables);
1486/// // Assign to the specified 'variables' the consecutive five-byte,
1487/// // two's complement integers (in host byte order) comprised of each
1488/// // of the specified 'numVariables' five-byte sequences of this stream
1489/// // at the current cursor location (in network byte order), update the
1490/// // cursor location, and return a reference to this stream. If this
1491/// // stream is initially invalid, this operation has no effect. If
1492/// // this function otherwise fails to extract a valid value, this
1493/// // stream is marked invalid and the value of 'variables' is
1494/// // undefined. The behavior is undefined unless '0 <= numVariables'
1495/// // and 'variables' has sufficient capacity. Note that each of the
1496/// // values will be sign-extended.
1497///
1498/// InStream& getArrayUint40(bsls::Types::Uint64 *variables,
1499/// int numVariables);
1500/// // Assign to the specified 'variables' the consecutive five-byte,
1501/// // two's complement unsigned integers (in host byte order) comprised
1502/// // of each of the specified 'numVariables' five-byte sequences of
1503/// // this stream at the current cursor location (in network byte
1504/// // order), update the cursor location, and return a reference to this
1505/// // stream. If this stream is initially invalid, this operation has
1506/// // no effect. If this function otherwise fails to extract a valid
1507/// // value, this stream is marked invalid and the value of 'variables'
1508/// // is undefined. The behavior is undefined unless
1509/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1510/// // that each of the values will be zero-extended.
1511///
1512/// InStream& getArrayInt32(int *variables, int numVariables);
1513/// // Assign to the specified 'variables' the consecutive four-byte,
1514/// // two's complement integers (in host byte order) comprised of each
1515/// // of the specified 'numVariables' four-byte sequences of this stream
1516/// // at the current cursor location (in network byte order), update the
1517/// // cursor location, and return a reference to this stream. If this
1518/// // stream is initially invalid, this operation has no effect. If
1519/// // this function otherwise fails to extract a valid value, this
1520/// // stream is marked invalid and the value of 'variables' is
1521/// // undefined. The behavior is undefined unless '0 <= numVariables'
1522/// // and 'variables' has sufficient capacity. Note that each of the
1523/// // values will be sign-extended.
1524///
1525/// InStream& getArrayUint32(unsigned int *variables, int numVariables);
1526/// // Assign to the specified 'variables' the consecutive four-byte,
1527/// // two's complement unsigned integers (in host byte order) comprised
1528/// // of each of the specified 'numVariables' four-byte sequences of
1529/// // this stream at the current cursor location (in network byte
1530/// // order), update the cursor location, and return a reference to this
1531/// // stream. If this stream is initially invalid, this operation has
1532/// // no effect. If this function otherwise fails to extract a valid
1533/// // value, this stream is marked invalid and the value of 'variables'
1534/// // is undefined. The behavior is undefined unless
1535/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1536/// // that each of the values will be zero-extended.
1537///
1538/// InStream& getArrayInt24(int *variables, int numVariables);
1539/// // Assign to the specified 'variables' the consecutive three-byte,
1540/// // two's complement integers (in host byte order) comprised of each
1541/// // of the specified 'numVariables' three-byte sequences of this
1542/// // stream at the current cursor location (in network byte order),
1543/// // update the cursor location, and return a reference to this stream.
1544/// // If this stream is initially invalid, this operation has no effect.
1545/// // If this function otherwise fails to extract a valid value, this
1546/// // stream is marked invalid and the value of 'variables' is
1547/// // undefined. The behavior is undefined unless '0 <= numVariables'
1548/// // and 'variables' has sufficient capacity. Note that each of the
1549/// // values will be sign-extended.
1550///
1551/// InStream& getArrayUint24(unsigned int *variables, int numVariables);
1552/// // Assign to the specified 'variables' the consecutive three-byte,
1553/// // two's complement unsigned integers (in host byte order) comprised
1554/// // of each of the specified 'numVariables' three-byte sequences of
1555/// // this stream at the current cursor location (in network byte
1556/// // order), update the cursor location, and return a reference to this
1557/// // stream. If this stream is initially invalid, this operation has
1558/// // no effect. If this function otherwise fails to extract a valid
1559/// // value, this stream is marked invalid and the value of 'variables'
1560/// // is undefined. The behavior is undefined unless
1561/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1562/// // that each of the values will be zero-extended.
1563///
1564/// InStream& getArrayInt16(short *variables, int numVariables);
1565/// // Assign to the specified 'variables' the consecutive two-byte,
1566/// // two's complement integers (in host byte order) comprised of each
1567/// // of the specified 'numVariables' two-byte sequences of this stream
1568/// // at the current cursor location (in network byte order), update the
1569/// // cursor location, and return a reference to this stream. If this
1570/// // stream is initially invalid, this operation has no effect. If
1571/// // this function otherwise fails to extract a valid value, this
1572/// // stream is marked invalid and the value of 'variables' is
1573/// // undefined. The behavior is undefined unless '0 <= numVariables'
1574/// // and 'variables' has sufficient capacity. Note that each of the
1575/// // values will be sign-extended.
1576///
1577/// InStream& getArrayUint16(unsigned short *variables, int numVariables);
1578/// // Assign to the specified 'variables' the consecutive two-byte,
1579/// // two's complement unsigned integers (in host byte order) comprised
1580/// // of each of the specified 'numVariables' two-byte sequences of this
1581/// // stream at the current cursor location (in network byte order),
1582/// // update the cursor location, and return a reference to this stream.
1583/// // If this stream is initially invalid, this operation has no effect.
1584/// // If this function otherwise fails to extract a valid value, this
1585/// // stream is marked invalid and the value of 'variables' is
1586/// // undefined. The behavior is undefined unless '0 <= numVariables'
1587/// // and 'variables' has sufficient capacity. Note that each of the
1588/// // values will be zero-extended.
1589///
1590/// InStream& getArrayInt8(char *variables, int numVariables);
1591/// InStream& getArrayInt8(signed char *variables, int numVariables);
1592/// // Assign to the specified 'variables' the consecutive one-byte,
1593/// // two's complement integers comprised of each of the specified
1594/// // 'numVariables' one-byte sequences of this stream at the current
1595/// // cursor location, update the cursor location, and return a
1596/// // reference to this stream. If this stream is initially invalid,
1597/// // this operation has no effect. If this function otherwise fails to
1598/// // extract a valid value, this stream is marked invalid and the value
1599/// // of 'variables' is undefined. The behavior is undefined unless
1600/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1601/// // that each of the values will be sign-extended.
1602///
1603/// InStream& getArrayUint8(char *variables, int numVariables);
1604/// InStream& getArrayUint8(unsigned char *variables, int numVariables);
1605/// // Assign to the specified 'variables' the consecutive one-byte,
1606/// // two's complement unsigned integers comprised of each of the
1607/// // specified 'numVariables' one-byte sequences of this stream at the
1608/// // current cursor location, update the cursor location, and return a
1609/// // reference to this stream. If this stream is initially invalid,
1610/// // this operation has no effect. If this function otherwise fails to
1611/// // extract a valid value, this stream is marked invalid and the value
1612/// // of 'variables' is undefined. The behavior is undefined unless
1613/// // '0 <= numVariables' and 'variables' has sufficient capacity. Note
1614/// // that each of the values will be zero-extended.
1615///
1616/// // *** arrays of floating-point values ***
1617///
1618/// InStream& getArrayFloat64(double *variables, int numVariables);
1619/// // Assign to the specified 'variables' the consecutive eight-byte
1620/// // IEEE double-precision floating-point numbers (in host byte order)
1621/// // comprised of each of the specified 'numVariables' eight-byte
1622/// // sequences of this stream at the current cursor location (in
1623/// // network byte order), update the cursor location, and return a
1624/// // reference to this stream. If this stream is initially invalid,
1625/// // this operation has no effect. If this function otherwise fails to
1626/// // extract a valid value, this stream is marked invalid and the value
1627/// // of 'variables' is undefined. The behavior is undefined unless
1628/// // '0 <= numVariables' and 'variables' has sufficient capacity.
1629///
1630/// InStream& getArrayFloat32(float *variables, int numVariables);
1631/// // Assign to the specified 'variables' the consecutive four-byte IEEE
1632/// // single-precision floating-point numbers (in host byte order)
1633/// // comprised of each of the specified 'numVariables' four-byte
1634/// // sequences of this stream at the current cursor location (in
1635/// // network byte order), update the cursor location, and return a
1636/// // reference to this stream. If this stream is initially invalid,
1637/// // this operation has no effect. If this function otherwise fails to
1638/// // extract a valid value, this stream is marked invalid and the value
1639/// // of 'variables' is undefined. The behavior is undefined unless
1640/// // '0 <= numVariables' and 'variables' has sufficient capacity.
1641///
1642/// // ACCESSORS
1643/// operator const void *() const;
1644/// // Return a non-zero value if this stream is valid, and 0 otherwise.
1645/// // An invalid stream is a stream for which an input operation was
1646/// // detected to have failed.
1647///
1648/// bsl::size_t cursor() const;
1649/// // Return the index of the next byte to be extracted from this
1650/// // stream.
1651///
1652/// const char *data() const;
1653/// // Return the address of the contiguous, non-modifiable external
1654/// // memory buffer of this stream. The behavior of accessing elements
1655/// // outside the range '[ data() .. data() + (length() - 1) ]' is
1656/// // undefined.
1657///
1658/// bool isValid() const;
1659/// // Return 'true' if this stream is valid, and 'false' otherwise. An
1660/// // invalid stream is a stream in which insufficient or invalid data
1661/// // was detected during an extraction operation. Note that an empty
1662/// // stream will be valid unless an extraction attempt or explicit
1663/// // invalidation causes it to be otherwise.
1664///
1665/// bool isEmpty() const;
1666/// // Return 'true' if this stream is empty, and 'false' otherwise.
1667/// // Note that this function enables higher-level types to verify that,
1668/// // after successfully reading all expected data, no data remains.
1669///
1670/// bsl::size_t length() const;
1671/// // Return the total number of bytes stored in the external memory
1672/// // buffer.
1673///
1674/// // FREE OPERATORS
1675/// template <class TYPE>
1676/// InStream& operator>>(InStream& stream, TYPE& value);
1677/// // Read the specified 'value' from the specified input 'stream'
1678/// // following the requirements of the BDEX protocol (see the 'bslx'
1679/// // package-level documentation), and return a reference to 'stream'.
1680/// // The behavior is undefined unless 'TYPE' is BDEX-compliant.
1681/// @endcode
1682///
1683/// @}
1684/** @} */