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